Skip to content
This repository has been archived by the owner on Aug 13, 2020. It is now read-only.

feat: init version #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist/
test
build/
34 changes: 34 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"plugins": ["prettier", "@typescript-eslint"],
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"impliedStrict": true
},
"rules": {
"no-sparse-arrays": 0,
"no-self-assign": 0,
"no-unused-vars": 0, // @typescript-eslint/no-unused-vars
"no-inner-declarations": 0,
"prettier/prettier": 2,
"@typescript-eslint/no-unused-vars": 1,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-use-before-define": [2, { "functions": false }],
"@typescript-eslint/ban-ts-ignore": 0,
"@typescript-eslint/interface-name-prefix": 0,
"@typescript-eslint/no-empty-interface": 0,
"@typescript-eslint/camelcase": 0,
"@typescript-eslint/no-inferrable-types": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/type-annotation-spacing": 0,
"@typescript-eslint/no-empty-function": 1
}
}
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Build
# This workflow is triggered on pushes to the repository.
on: [push]

jobs:
build:
# Job name is Greeting
name: Build
# This job runs on Linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Use Node.js 12
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: install
run: npm i
- name: lint
run: npm run lint
- name: test
run: npm run test
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
coverage
node_modules
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"printWidth": 120,
"arrowParens": "always"
}
10 changes: 10 additions & 0 deletions __tests__/index-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { MAX } from '../src';

describe('data-set', () => {
it('#1', () => {
expect(MAX('f')).toEqual({
aggregate: 'max',
field: 'f',
});
});
});
32 changes: 31 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,37 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "jest",
"lint": "eslint --ext .ts ./src",
"fix": "eslint --ext .ts ./src -c .eslintrc --fix && prettier --write ./src"
},
"devDependencies": {
"@types/jest": "^26.0.9",
"@typescript-eslint/eslint-plugin": "^2.0.0",
"@typescript-eslint/parser": "^2.34.0",
"eslint": "^6.1.0",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-prettier": "^3.1.0",
"husky": "^4.2.5",
"jest": "^26.2.2",
"prettier": "^2.0.1",
"ts-jest": "^26.1.4",
"typescript": "^3.5.3"
},
"jest": {
"preset": "ts-jest",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.ts",
"!**/node_modules/**",
"!**/vendor/**"
],
"testRegex": "/__tests__/.*-spec\\.ts?$"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint && npm run test"
}
},
"repository": {
"type": "git",
Expand Down
3 changes: 3 additions & 0 deletions src/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const ID_COLUMN = '$$_id_$$';

export const X = 'x';
3 changes: 1 addition & 2 deletions src/data-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Query } from './query';

/** 前端数据集模块 */
export class DataSet {

private data = [];

constructor(data: Data) {
Expand All @@ -31,4 +30,4 @@ export class DataSet {
public query() {
return new Query(this.data);
}
}
}
14 changes: 7 additions & 7 deletions src/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Field } from './types';

/**
* 聚合求和
* @param field
* @param field
*/
export function SUM(field: string): Field {
return {
Expand All @@ -13,33 +13,33 @@ export function SUM(field: string): Field {

/**
* 聚合 MAX
* @param field
* @param field
*/
export function MAX(field: string): Field {
return {
aggregate: 'sum',
aggregate: 'max',
field,
};
}

/**
* 聚合 MIN
* @param field
* @param field
*/
export function MIN(field: string): Field {
return {
aggregate: 'sum',
aggregate: 'min',
field,
};
}

/**
* 无聚合字段
* @param field
* @param field
*/
export function RAW(field: string): Field {
return {
aggregate: 'raw',
field,
};
}
}
100 changes: 77 additions & 23 deletions src/query.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,120 @@
import { Data, Field } from './types';
import * as _ from 'lodash';
import { Data, Field, OrderBy, Datum } from './types';
import { ID_COLUMN } from './const';

export class Query {
/** 原始数据 */
private data: Data = [];

private data;
private selectOption: Field[] = [];
private orderByOption: OrderBy = {};
private groupByOption: string;
private limitOption: number = 10;

constructor(data: Data) {
this.data = data;
this.data = this.generateUniqueId(data);
}

/**
* 给每个数据设置唯一 id
*/
private generateUniqueId(data: Data) {
return _.map(data, (d: Datum) => {
return { ...d, [ID_COLUMN]: _.uniqueId() };
});
}

/**
* 选择字段
* @param fields
* @param fields
*/
public select(...fields: Field[]): Query {

// TODO
this.selectOption = fields;

return this;
}

/**
* 按照字段排序
* @param field
* @param asc
* @param field
* @param asc
*/
public orderBy(fields: string, asc?: boolean): Query {
public orderBy(field: string, asc?: boolean): Query {
this.orderByOption = {
field,
asc,
};

// TODO

return this;
}

/**
* 按照字段分组
* @param asc
* @param fields
* @param asc
* @param field
*/
public groupBy(fields: string): Query {
public groupBy(field: string): Query {
this.groupByOption = field;

// TODO

return this;
}

/**
* 取 n 条数据
* @param n
* @param n
*/
public limit(n: number): Query {
this.limitOption = n;

// TODO

return this;
}

/**
* 返回最后的查询数据
*/
public record(): Data {
const { data, selectOption, groupByOption, orderByOption, limitOption } = this;

const r = _(data);

// 1. 执行分组
r.groupBy(groupByOption ? groupByOption : ID_COLUMN);

// 2. 执行 select
const fields = _.map(selectOption, (f: Field) => f.field);
r.mapValues((v: Data, k: string) => {
// 1. 执行所有的 fields
const aggr = _.filter(selectOption, (f: Field) => f.aggregate !== 'raw');
const noneAggr = _.filter(selectOption, (f: Field) => f.aggregate === 'raw');

let record;
// 有聚合
if (aggr.length) {
// 按照 max 字段取去最大
record = _.maxBy(v, _.find(aggr, (f: Field) => f.aggregate === 'max').field);
record = record ? [record] : [];
} else {
// 无聚合
record = v;
}

// 只取这些字段
return _.map(record, (d: Datum) => _.pick(d, fields));
});

// 打平
r.flatten();

// 3. 执行 order by
if (orderByOption) {
r.sortBy((d: Datum) => d[orderByOption.field]); // 升降序
}

// 4. 执行 limit
if (limitOption) {
r.slice(0, limitOption);
}

// TODO

return [];
return r.values();
}
}
}
9 changes: 7 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export type Data = Datum[];
*/
export type Field = {
/** 聚合函数 */
readonly aggregate: 'sum' | 'max' | 'max' | 'raw'; // 可扩展
readonly aggregate: 'sum' | 'max' | 'min' | 'max' | 'raw'; // 可扩展
/** 字段名 */
readonly field: string;
}
};

export type OrderBy = {
readonly field?: string;
readonly asc?: boolean;
};
18 changes: 18 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"module": "commonjs",
"sourceMap": true,
"inlineSources": true,
"target": "es5",
"outDir": "lib",
"declaration": true,
"importHelpers": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"lib": ["esnext", "dom"]
},
"include": ["src"]
}