@wener/common 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/lib/cn/DivisionCode.js +311 -0
  2. package/lib/cn/DivisionCode.js.map +1 -0
  3. package/lib/cn/Mod11Checksum.js +42 -0
  4. package/lib/cn/Mod11Checksum.js.map +1 -0
  5. package/lib/cn/Mod31Checksum.js +48 -0
  6. package/lib/cn/Mod31Checksum.js.map +1 -0
  7. package/lib/cn/ResidentIdentityCardNumber.js +50 -0
  8. package/lib/cn/ResidentIdentityCardNumber.js.map +1 -0
  9. package/lib/cn/UnifiedSocialCreditCode.js +118 -0
  10. package/lib/cn/UnifiedSocialCreditCode.js.map +1 -0
  11. package/lib/cn/formatDate.js +15 -0
  12. package/lib/cn/formatDate.js.map +1 -0
  13. package/lib/cn/index.js +4 -0
  14. package/lib/cn/index.js.map +1 -0
  15. package/lib/cn/parseSex.js +22 -0
  16. package/lib/cn/parseSex.js.map +1 -0
  17. package/lib/cn/types.d.js +8 -0
  18. package/lib/cn/types.d.js.map +1 -0
  19. package/lib/meta/defineFileType.js +44 -0
  20. package/lib/meta/defineFileType.js.map +1 -0
  21. package/lib/meta/defineMetadata.js +14 -3
  22. package/lib/meta/defineMetadata.js.map +1 -1
  23. package/lib/meta/index.js +1 -0
  24. package/lib/meta/index.js.map +1 -1
  25. package/lib/parseSort.js +15 -0
  26. package/lib/parseSort.js.map +1 -1
  27. package/lib/search/formatAdvanceSearch.js +1 -1
  28. package/lib/search/formatAdvanceSearch.js.map +1 -1
  29. package/lib/search/parser.js +380 -76
  30. package/lib/search/parser.js.map +1 -1
  31. package/lib/search/types.d.js.map +1 -1
  32. package/package.json +8 -4
  33. package/src/cn/DivisionCode.test.ts +50 -0
  34. package/src/cn/DivisionCode.ts +253 -0
  35. package/src/cn/Mod11Checksum.ts +24 -0
  36. package/src/cn/Mod31Checksum.ts +36 -0
  37. package/src/cn/ResidentIdentityCardNumber.test.ts +21 -0
  38. package/src/cn/ResidentIdentityCardNumber.ts +96 -0
  39. package/src/cn/UnifiedSocialCreditCode.test.ts +16 -0
  40. package/src/cn/UnifiedSocialCreditCode.ts +148 -0
  41. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +15 -0
  42. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +41 -0
  43. package/src/cn/formatDate.ts +12 -0
  44. package/src/cn/index.ts +3 -0
  45. package/src/cn/parseSex.ts +27 -0
  46. package/src/cn/types.d.ts +51 -0
  47. package/src/meta/defineFileType.tsx +68 -0
  48. package/src/meta/defineMetadata.ts +16 -3
  49. package/src/meta/index.ts +2 -0
  50. package/src/parseSort.ts +18 -0
  51. package/src/search/AdvanceSearch.test.ts +2 -2
  52. package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +3 -3
  53. package/src/search/formatAdvanceSearch.ts +1 -1
  54. package/src/search/parser.js +325 -73
  55. package/src/search/parser.peggy +42 -9
  56. package/src/search/types.d.ts +1 -1
@@ -0,0 +1,15 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`ResidentIdentityCardNumber > should parse 1`] = `
4
+ {
5
+ "age": 75,
6
+ "birthDate": "19491231",
7
+ "checksum": "X",
8
+ "division": "110105",
9
+ "female": true,
10
+ "male": false,
11
+ "sequence": 2,
12
+ "sex": "Female",
13
+ "valid": true,
14
+ }
15
+ `;
@@ -0,0 +1,41 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`UnifiedSocialCreditCode > should parse 1`] = `
4
+ {
5
+ "bureau": "9",
6
+ "checksum": "P",
7
+ "codes": [
8
+ "9",
9
+ "1",
10
+ "330106",
11
+ "673959654",
12
+ ],
13
+ "division": "330106",
14
+ "labels": [
15
+ "工商",
16
+ "企业",
17
+ ],
18
+ "subject": "673959654",
19
+ "subjectType": "1",
20
+ }
21
+ `;
22
+
23
+ exports[`UnifiedSocialCreditCode > should parse 2`] = `
24
+ {
25
+ "bureau": "9",
26
+ "checksum": "R",
27
+ "codes": [
28
+ "9",
29
+ "1",
30
+ "330106",
31
+ "MA2CFLDG4",
32
+ ],
33
+ "division": "330106",
34
+ "labels": [
35
+ "工商",
36
+ "企业",
37
+ ],
38
+ "subject": "MA2CFLDG4",
39
+ "subjectType": "1",
40
+ }
41
+ `;
@@ -0,0 +1,12 @@
1
+ export function formatDate(date: Date, format: 'yyyyMMDD') {
2
+ switch (format) {
3
+ case 'yyyyMMDD': {
4
+ const year = date.getFullYear();
5
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
6
+ const day = date.getDate().toString().padStart(2, '0');
7
+ return `${year}${month}${day}`;
8
+ }
9
+ default:
10
+ throw new Error(`Invalid format`);
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ export { ResidentIdentityCardNumber } from './ResidentIdentityCardNumber';
2
+ export { DivisionCode } from './DivisionCode';
3
+ export { UnifiedSocialCreditCode } from './UnifiedSocialCreditCode';
@@ -0,0 +1,27 @@
1
+ export function parseSex(s: string):
2
+ | undefined
3
+ | {
4
+ sex: 'Male' | 'Female';
5
+ male: boolean;
6
+ female: boolean;
7
+ } {
8
+ if (!s) return undefined;
9
+
10
+ switch (s.toLowerCase()) {
11
+ case '男':
12
+ case 'male':
13
+ return {
14
+ sex: 'Male',
15
+ male: true,
16
+ female: false,
17
+ };
18
+ case '女':
19
+ case 'female':
20
+ return {
21
+ sex: 'Female',
22
+ male: false,
23
+ female: true,
24
+ };
25
+ }
26
+ return undefined;
27
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 居民身份证
3
+ *
4
+ * @see https://en.wikipedia.org/wiki/Resident_Identity_Card
5
+ * @see https://en.wikipedia.org/wiki/Foreign_Permanent_Resident_ID_Card
6
+ */
7
+ export interface ResidentIdentityCardInfo {
8
+ /**
9
+ * @title 姓名
10
+ */
11
+ name: string;
12
+ /**
13
+ * @title 性别
14
+ */
15
+ sex: 'Male' | 'Female';
16
+ /**
17
+ * @title 民族
18
+ * 例如 '汉'/'满'/'回'
19
+ */
20
+ ethnicity: string;
21
+ /**
22
+ * @title 出生日期
23
+ * @format date
24
+ */
25
+ birthDate: string;
26
+ /**
27
+ * @title 地址
28
+ *
29
+ * - 通常为 domicile/户籍地
30
+ */
31
+ address: string;
32
+ /**
33
+ * @title 身份证号
34
+ */
35
+ identityCardNumber: string;
36
+ /**
37
+ * @title 签发机关
38
+ */
39
+ issuer: string;
40
+ /**
41
+ * @title 有效期开始日期
42
+ * @format date
43
+ */
44
+ validStartDate: string;
45
+ /**
46
+ * @title 有效期结束日期
47
+ * @format date
48
+ * @description 如长期有效则为 空
49
+ */
50
+ validEndDate?: string;
51
+ }
@@ -0,0 +1,68 @@
1
+ type DefineFileTypeOptions = {
2
+ name: string;
3
+ title?: string;
4
+ description?: string;
5
+ type?: string;
6
+ types?: string[];
7
+ extension?: string;
8
+ extensions?: string[];
9
+ tags?: string[];
10
+ metadata?: Record<string, any>;
11
+ };
12
+ export type FileTypeDef = {
13
+ name: string;
14
+ title: string;
15
+ description?: string;
16
+ type: string; // primary type
17
+ extension: string; // primary extension
18
+ types: string[];
19
+ extensions: string[];
20
+ tags: string[];
21
+ metadata: Record<string, any>;
22
+ };
23
+
24
+ let _all: FileTypeDef[] = [];
25
+
26
+ export function defineFileType({
27
+ type = '',
28
+ types = [],
29
+ extension = '',
30
+ extensions = [],
31
+ ...opts
32
+ }: DefineFileTypeOptions): FileTypeDef {
33
+ if (!type) {
34
+ type = types[0] || '';
35
+ }
36
+ if (!extension) {
37
+ extension = extensions[0] || '';
38
+ }
39
+ if (!types.includes(type)) {
40
+ types = [type, ...types];
41
+ }
42
+ if (!extensions.includes(extension)) {
43
+ extensions = [extension, ...extensions];
44
+ }
45
+
46
+ const def: FileTypeDef = {
47
+ title: opts.title || opts.name,
48
+ type,
49
+ extension,
50
+ types,
51
+ extensions,
52
+ tags: [],
53
+ metadata: {},
54
+ ...opts,
55
+ };
56
+ let idx = _all.findIndex((v) => v.name === def.name);
57
+ if (idx >= 0) {
58
+ _all[idx] = def;
59
+ console.warn(`File type ${def.name} is redefined`);
60
+ } else {
61
+ _all.push(def);
62
+ }
63
+ return def;
64
+ }
65
+
66
+ export function getFileType(): FileTypeDef[] {
67
+ return _all;
68
+ }
@@ -46,9 +46,22 @@ export function createMetadataKey<T = never>(a: any, b?: any): MetadataKey<T> {
46
46
  return k;
47
47
  }
48
48
 
49
- export function defineMetadata<T>(res: HasMetadata, key: MetadataKey<T>, opts: T) {
50
- res.metadata = res.metadata || {};
51
- set(res.metadata, key.key, opts);
49
+ export function defineMetadata<T>(res: HasMetadata, key: MetadataKey<T>, opts: T): void;
50
+ export function defineMetadata<T>(key: MetadataKey<T>, items: Array<[HasMetadata, T]>): void;
51
+ export function defineMetadata<T>(a: any, b: any, c?: any) {
52
+ if (Array.isArray(b)) {
53
+ const key = a;
54
+ const items = b;
55
+ for (const [res, opts] of items) {
56
+ defineMetadata(res, key, opts);
57
+ }
58
+ } else {
59
+ const res = a;
60
+ const key = b;
61
+ const opts = c;
62
+ res.metadata = res.metadata || {};
63
+ set(res.metadata, key.key, opts);
64
+ }
52
65
  }
53
66
 
54
67
  export function getMetadata<T>(res: HasMetadata | undefined | null, key: MetadataKey<T>): T | undefined {
package/src/meta/index.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { createMetadataKey, defineMetadata, getMetadata } from './defineMetadata';
2
2
 
3
3
  export { defineInit, type InitDef, runInit } from './defineInit';
4
+
5
+ export { defineFileType, getFileType, type FileTypeDef } from './defineFileType';
package/src/parseSort.ts CHANGED
@@ -113,3 +113,21 @@ function _parse(v: string) {
113
113
  nulls,
114
114
  };
115
115
  }
116
+
117
+ export function formatSort(s: SortRule[]): string[] {
118
+ return s
119
+ .map(({ field, order, nulls }) => {
120
+ if (field) {
121
+ let r = field;
122
+ if (order) {
123
+ r += ` ${order}`;
124
+ }
125
+ if (nulls) {
126
+ r += ` nulls ${nulls}`;
127
+ }
128
+ return r;
129
+ }
130
+ return '';
131
+ })
132
+ .filter(Boolean);
133
+ }
@@ -73,8 +73,8 @@ describe('AdvanceSearch', () => {
73
73
  ],
74
74
  ['"Hello"', [{ type: 'keyword', value: 'Hello', exact: true }]],
75
75
  ['-"Hello"', [{ type: 'keyword', value: 'Hello', exact: true, negative: true }]],
76
- ['is:ok', [{ type: 'compare', field: 'is', operator: 'has', value: { value: 'ok' } }]],
77
- ['-is:ok', [{ type: 'compare', field: 'is', negative: true, operator: 'has', value: { value: 'ok' } }]],
76
+ ['is:ok', [{ type: 'compare', field: 'is', operator: 'match', value: { value: 'ok' } }]],
77
+ ['-is:ok', [{ type: 'compare', field: 'is', negative: true, operator: 'match', value: { value: 'ok' } }]],
78
78
  ];
79
79
 
80
80
  for (const [input, expected] of cases) {
@@ -288,7 +288,7 @@ exports[`AdvanceSearch > should parse 48`] = `
288
288
  [
289
289
  {
290
290
  "field": "a",
291
- "operator": "has",
291
+ "operator": "match",
292
292
  "type": "compare",
293
293
  "value": {
294
294
  "type": "literal",
@@ -495,7 +495,7 @@ exports[`AdvanceSearch > should parse 51`] = `
495
495
  "value": [
496
496
  {
497
497
  "field": "a",
498
- "operator": "has",
498
+ "operator": "match",
499
499
  "type": "compare",
500
500
  "value": {
501
501
  "type": "literal",
@@ -607,7 +607,7 @@ exports[`AdvanceSearch > should parse 63`] = `
607
607
  {
608
608
  "field": "AI",
609
609
  "mention": true,
610
- "operator": "has",
610
+ "operator": "match",
611
611
  "type": "compare",
612
612
  "value": {
613
613
  "value": "Where is my car",
@@ -3,7 +3,7 @@ import { AdvanceSearch } from './AdvanceSearch';
3
3
 
4
4
  export function formatAdvanceSearch(input: AdvanceSearch.Expr[]) {
5
5
  const OP = {
6
- has: ':',
6
+ match: ':',
7
7
  eq: ':=',
8
8
  ne: ':!=',
9
9
  gt: ':>',