@wener/common 2.0.1 → 2.0.2

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 (107) hide show
  1. package/lib/cn/ChineseResidentIdNo.js +41 -0
  2. package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
  3. package/lib/cn/{ResidentIdentityCardNumber.test.js → ChineseResidentIdNo.test.js} +7 -6
  4. package/lib/cn/DivisionCode.js +211 -300
  5. package/lib/cn/DivisionCode.mod.js +1 -0
  6. package/lib/cn/DivisionCode.test.js +9 -15
  7. package/lib/cn/{Mod11Checksum.js → Mod11.js} +1 -0
  8. package/lib/cn/{Mod31Checksum.js → Mod31.js} +1 -0
  9. package/lib/cn/UnifiedSocialCreditCode.js +130 -115
  10. package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
  11. package/lib/cn/UnifiedSocialCreditCode.test.js +1 -1
  12. package/lib/cn/index.js +1 -3
  13. package/lib/cn/mod.js +6 -0
  14. package/lib/consola/formatLogObject.js +18 -6
  15. package/lib/dayjs/dayjs.js +38 -0
  16. package/lib/dayjs/formatDuration.js +58 -0
  17. package/lib/dayjs/formatDuration.test.js +90 -0
  18. package/lib/dayjs/index.js +3 -0
  19. package/lib/dayjs/parseDuration.js +32 -0
  20. package/lib/decimal/index.js +1 -0
  21. package/lib/decimal/parseDecimal.js +13 -0
  22. package/lib/{resource → foundation}/schema/SexType.js +5 -1
  23. package/lib/foundation/schema/index.js +1 -0
  24. package/lib/foundation/schema/parseSexType.js +18 -0
  25. package/lib/foundation/schema/types.js +5 -0
  26. package/lib/password/Password.js +10 -7
  27. package/lib/resource/ListQuery.js +119 -0
  28. package/lib/resource/index.js +1 -0
  29. package/lib/resource/schema/AnyResourceSchema.js +1 -1
  30. package/lib/resource/schema/index.js +5 -0
  31. package/lib/{resource/schema → schema}/SchemaRegistry.js +12 -5
  32. package/lib/schema/SchemaRegistry.mod.js +2 -0
  33. package/lib/schema/createSchemaData.js +1 -1
  34. package/lib/schema/getSchemaOptions.js +2 -2
  35. package/lib/schema/index.js +1 -0
  36. package/lib/utils/getEstimateProcessTime.js +20 -0
  37. package/lib/utils/index.js +1 -0
  38. package/package.json +23 -14
  39. package/src/cn/ChineseResidentIdNo.mod.ts +7 -0
  40. package/src/cn/ChineseResidentIdNo.test.ts +18 -0
  41. package/src/cn/ChineseResidentIdNo.ts +66 -0
  42. package/src/cn/DivisionCode.mod.ts +7 -0
  43. package/src/cn/DivisionCode.test.ts +3 -13
  44. package/src/cn/DivisionCode.ts +132 -195
  45. package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
  46. package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
  47. package/src/cn/UnifiedSocialCreditCode.mod.ts +7 -0
  48. package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
  49. package/src/cn/UnifiedSocialCreditCode.ts +105 -125
  50. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
  51. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +18 -12
  52. package/src/cn/index.ts +1 -3
  53. package/src/cn/mod.ts +3 -0
  54. package/src/consola/formatLogObject.ts +12 -4
  55. package/src/dayjs/dayjs.ts +40 -0
  56. package/src/dayjs/formatDuration.test.ts +14 -0
  57. package/src/dayjs/formatDuration.ts +86 -0
  58. package/src/dayjs/index.ts +3 -0
  59. package/src/dayjs/parseDuration.ts +40 -0
  60. package/src/decimal/index.ts +1 -0
  61. package/src/decimal/parseDecimal.ts +16 -0
  62. package/src/foundation/schema/SexType.ts +21 -0
  63. package/src/foundation/schema/index.ts +1 -0
  64. package/src/foundation/schema/parseSexType.ts +19 -0
  65. package/src/foundation/schema/types.ts +8 -0
  66. package/src/password/Password.ts +2 -2
  67. package/src/resource/ListQuery.ts +53 -0
  68. package/src/resource/index.ts +1 -0
  69. package/src/resource/schema/AnyResourceSchema.ts +1 -1
  70. package/src/resource/schema/index.ts +5 -0
  71. package/src/schema/SchemaRegistry.mod.ts +1 -0
  72. package/src/{resource/schema → schema}/SchemaRegistry.ts +12 -8
  73. package/src/schema/createSchemaData.ts +1 -1
  74. package/src/schema/getSchemaOptions.ts +2 -2
  75. package/src/schema/index.ts +1 -0
  76. package/src/utils/getEstimateProcessTime.ts +36 -0
  77. package/src/utils/index.ts +1 -0
  78. package/lib/cn/ResidentIdentityCardNumber.js +0 -50
  79. package/lib/cn/formatDate.js +0 -13
  80. package/lib/cn/parseSex.js +0 -20
  81. package/lib/search/AdvanceSearch.js +0 -9
  82. package/lib/search/AdvanceSearch.test.js +0 -435
  83. package/lib/search/formatAdvanceSearch.js +0 -78
  84. package/lib/search/index.js +0 -1
  85. package/lib/search/optimizeAdvanceSearch.js +0 -143
  86. package/lib/search/parseAdvanceSearch.js +0 -20
  87. package/lib/search/parser.d.js +0 -1
  88. package/lib/search/parser.js +0 -3088
  89. package/lib/search/types.d.js +0 -1
  90. package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
  91. package/src/cn/ResidentIdentityCardNumber.ts +0 -96
  92. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
  93. package/src/cn/formatDate.ts +0 -12
  94. package/src/cn/parseSex.ts +0 -13
  95. package/src/resource/schema/SexType.ts +0 -13
  96. package/src/search/AdvanceSearch.test.ts +0 -149
  97. package/src/search/AdvanceSearch.ts +0 -14
  98. package/src/search/Makefile +0 -2
  99. package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
  100. package/src/search/formatAdvanceSearch.ts +0 -52
  101. package/src/search/index.ts +0 -1
  102. package/src/search/optimizeAdvanceSearch.ts +0 -77
  103. package/src/search/parseAdvanceSearch.ts +0 -23
  104. package/src/search/parser.d.ts +0 -8
  105. package/src/search/parser.js +0 -2794
  106. package/src/search/parser.peggy +0 -237
  107. package/src/search/types.d.ts +0 -45
@@ -0,0 +1,119 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_without_holes(arr) {
7
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
8
+ }
9
+ function _define_property(obj, key, value) {
10
+ if (key in obj) {
11
+ Object.defineProperty(obj, key, {
12
+ value: value,
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true
16
+ });
17
+ } else {
18
+ obj[key] = value;
19
+ }
20
+ return obj;
21
+ }
22
+ function _iterable_to_array(iter) {
23
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
24
+ }
25
+ function _non_iterable_spread() {
26
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
27
+ }
28
+ function _object_spread(target) {
29
+ for(var i = 1; i < arguments.length; i++){
30
+ var source = arguments[i] != null ? arguments[i] : {};
31
+ var ownKeys = Object.keys(source);
32
+ if (typeof Object.getOwnPropertySymbols === "function") {
33
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
34
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
35
+ }));
36
+ }
37
+ ownKeys.forEach(function(key) {
38
+ _define_property(target, key, source[key]);
39
+ });
40
+ }
41
+ return target;
42
+ }
43
+ function ownKeys(object, enumerableOnly) {
44
+ var keys = Object.keys(object);
45
+ if (Object.getOwnPropertySymbols) {
46
+ var symbols = Object.getOwnPropertySymbols(object);
47
+ if (enumerableOnly) {
48
+ symbols = symbols.filter(function(sym) {
49
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
50
+ });
51
+ }
52
+ keys.push.apply(keys, symbols);
53
+ }
54
+ return keys;
55
+ }
56
+ function _object_spread_props(target, source) {
57
+ source = source != null ? source : {};
58
+ if (Object.getOwnPropertyDescriptors) {
59
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
60
+ } else {
61
+ ownKeys(Object(source)).forEach(function(key) {
62
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
63
+ });
64
+ }
65
+ return target;
66
+ }
67
+ function _to_consumable_array(arr) {
68
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
69
+ }
70
+ function _unsupported_iterable_to_array(o, minLen) {
71
+ if (!o) return;
72
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
73
+ var n = Object.prototype.toString.call(o).slice(8, -1);
74
+ if (n === "Object" && o.constructor) n = o.constructor.name;
75
+ if (n === "Map" || n === "Set") return Array.from(n);
76
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
77
+ }
78
+ import { z } from 'zod/v4';
79
+ var IntLikeSchema = z.coerce.number().multipleOf(1).min(0).optional().overwrite(function(v) {
80
+ return v || undefined;
81
+ });
82
+ export var ListQuerySchema = z.object({
83
+ id: z.coerce.string().optional(),
84
+ ids: z.array(z.coerce.string()).optional(),
85
+ filter: z.string().optional().describe('sql-like filter string'),
86
+ filters: z.array(z.any()).optional().describe('sql-like filter string'),
87
+ where: z.record(z.string(), z.any()).optional().describe('document query filter'),
88
+ search: z.string().optional(),
89
+ limit: IntLikeSchema,
90
+ offset: IntLikeSchema,
91
+ order: z.array(z.string()).optional().describe('order like "a,-b,c desc null last"'),
92
+ pageIndex: IntLikeSchema.describe('0-based page index'),
93
+ pageNumber: IntLikeSchema.describe('1-based page number'),
94
+ pageSize: IntLikeSchema,
95
+ cursor: z.string().optional(),
96
+ deleted: z.coerce.boolean().optional()
97
+ });
98
+ export function resolveListQuery(target) {
99
+ for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
100
+ args[_key - 1] = arguments[_key];
101
+ }
102
+ var out = args.reduce(function(a, source) {
103
+ if (typeof source === 'function') {
104
+ var result = source(a);
105
+ // do not use the result as merge source
106
+ return result || a;
107
+ }
108
+ var b = source;
109
+ if (!b) return a;
110
+ // do not resolve id to ids
111
+ var ids = _to_consumable_array(a.ids || []).concat(_to_consumable_array(b.ids || []));
112
+ return _object_spread_props(_object_spread({}, a, b), {
113
+ ids: ids,
114
+ filters: _to_consumable_array(a.filters || []).concat(_to_consumable_array(b.filters || [])),
115
+ search: b.search || a.search
116
+ });
117
+ }, target || {});
118
+ return ListQuerySchema.parse(out);
119
+ }
@@ -1 +1,2 @@
1
1
  export { getTitleOfResource } from "./getTitleOfResource.js";
2
+ export { resolveListQuery, ListQuerySchema } from "./ListQuery.js";
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod/v4";
2
- import { SexTypeSchema } from "./SexType.js";
2
+ import { SexTypeSchema } from "../../foundation/schema/SexType.js";
3
3
  import { rz } from "./types.js";
4
4
  export var AnyResourceSchema = z.object({
5
5
  id: rz.resourceId.readonly().describe("ID"),
@@ -0,0 +1,5 @@
1
+ export { ResourceStatus, ResourceStatusSchema } from "./ResourceStatus.js";
2
+ export { ResourceActionType, ResourceActionTypeSchema, ResourceActionDataSchema } from "./ResourceActionType.js";
3
+ export { AnyResourceSchema } from "./AnyResourceSchema.js";
4
+ export { rz } from "./types.js";
5
+ export { BaseResourceSchema } from "./BaseResourceSchema.js";
@@ -1,5 +1,9 @@
1
+ function _type_of(obj) {
2
+ "@swc/helpers - typeof";
3
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
4
+ }
1
5
  import { getGlobalStates } from "@wener/utils";
2
- import { toJsonSchema } from "../../schema/index.js";
6
+ import { toJsonSchema } from "./index.js";
3
7
  var types = getGlobalStates("@wener/common/resource/schema/SchemaRegistry", function () {
4
8
  return new Map();
5
9
  });
@@ -10,7 +14,7 @@ export function get(needle) {
10
14
  return found;
11
15
  }
12
16
  else {
13
- if (typeof needle !== "string") {
17
+ if (needle && typeof needle !== "string") {
14
18
  return toJsonSchema(needle);
15
19
  }
16
20
  }
@@ -30,9 +34,12 @@ function getKey(s) {
30
34
  }
31
35
  return key;
32
36
  }
33
- export function add(def) {
34
- types.set(getKey(def), toJsonSchema(def));
35
- }
36
37
  export function set(key, def) {
38
+ if (!def) {
39
+ def = key;
40
+ if (!def || (typeof def === "undefined" ? "undefined" : _type_of(def)) !== "object") {
41
+ throw new Error("Invalid schema definition for: ".concat(getKey(key)));
42
+ }
43
+ }
37
44
  types.set(getKey(key), toJsonSchema(def));
38
45
  }
@@ -0,0 +1,2 @@
1
+ import * as _SchemaRegistry from "./SchemaRegistry.js";
2
+ export { _SchemaRegistry as SchemaRegistry };
@@ -124,7 +124,7 @@ function _create(schema, options, ctx) {
124
124
  type: "object"
125
125
  }, function () {
126
126
  var out = {};
127
- var required = schema.required || [];
127
+ var required = Array.isArray(schema.required) ? schema.required : [];
128
128
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
129
129
  try {
130
130
  for (var _iterator = Object.entries(schema.properties || {})[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
@@ -1,8 +1,8 @@
1
1
  import { deepFreeze } from "@wener/utils";
2
2
  import { getSchemaCache } from "./getSchemaCache.js";
3
- import { toJsonSchema } from "./toJsonSchema.js";
3
+ import { SchemaRegistry } from "./SchemaRegistry.mod.js";
4
4
  export function getSchemaOptions(s) {
5
- var js = toJsonSchema(s);
5
+ var js = SchemaRegistry.get(s);
6
6
  return getSchemaCache(s, "options", function () {
7
7
  var _this;
8
8
  var out = ((_this = js.anyOf || js.oneOf) === null || _this === void 0 ? void 0 : _this.map(function (v) {
@@ -3,3 +3,4 @@ export { getSchemaOptions, getSchemaOptionLabel } from "./getSchemaOptions.js";
3
3
  export { toJsonSchema } from "./toJsonSchema.js";
4
4
  export { findJsonSchemaByPath } from "./findJsonSchemaByPath.js";
5
5
  export { createSchemaData } from "./createSchemaData.js";
6
+ export { SchemaRegistry } from "./SchemaRegistry.mod.js";
@@ -0,0 +1,20 @@
1
+ export function getEstimateProcessTime(param) {
2
+ var total = param.total, processed = param.processed, startTime = param.startTime, _param_elapsed = param.elapsed, elapsed = _param_elapsed === void 0 ? startTime ? (Date.now() - startTime.getTime()) / 1000 : undefined : _param_elapsed;
3
+ if (typeof total !== 'number' || typeof processed !== 'number' || !elapsed || processed === 0 || processed >= total) {
4
+ return undefined;
5
+ }
6
+ var now = new Date();
7
+ var rate = processed / elapsed;
8
+ if (rate === 0) {
9
+ return undefined;
10
+ }
11
+ var remaining = total - processed;
12
+ var eta = Math.round(remaining / rate);
13
+ var endTime = new Date(now.getTime() + eta * 1000);
14
+ return {
15
+ eta: eta,
16
+ elapsed: elapsed,
17
+ endTime: endTime,
18
+ rate: rate
19
+ };
20
+ }
@@ -0,0 +1 @@
1
+ export { getEstimateProcessTime } from "./getEstimateProcessTime.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wener/common",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "author": "",
@@ -22,6 +22,14 @@
22
22
  "types": "./src/data/index.ts",
23
23
  "default": "./lib/data/index.js"
24
24
  },
25
+ "./dayjs": {
26
+ "types": "./src/dayjs/index.ts",
27
+ "default": "./lib/dayjs/index.js"
28
+ },
29
+ "./decimal": {
30
+ "types": "./src/decimal/index.ts",
31
+ "default": "./lib/decimal/index.js"
32
+ },
25
33
  "./jsonschema": {
26
34
  "types": "./src/jsonschema/index.ts",
27
35
  "default": "./lib/jsonschema/index.js"
@@ -38,14 +46,14 @@
38
46
  "types": "./src/resource/index.ts",
39
47
  "default": "./lib/resource/index.js"
40
48
  },
49
+ "./resource/schema": {
50
+ "types": "./src/resource/schema/index.ts",
51
+ "default": "./lib/resource/schema/index.js"
52
+ },
41
53
  "./schema": {
42
54
  "types": "./src/schema/index.ts",
43
55
  "default": "./lib/schema/index.js"
44
56
  },
45
- "./search": {
46
- "types": "./src/search/index.ts",
47
- "default": "./lib/search/index.js"
48
- },
49
57
  "./package.json": "./package.json"
50
58
  },
51
59
  "files": [
@@ -62,27 +70,28 @@
62
70
  "@standard-schema/spec": "^1.0.0",
63
71
  "@wener/utils": "^1.1.51",
64
72
  "date-fns": "^4.1.0",
65
- "es-toolkit": "^1.37.2",
73
+ "es-toolkit": "^1.39.10",
66
74
  "std-env": "^3.9.0",
67
- "ts-pattern": "^5.7.0"
75
+ "ts-pattern": "^5.8.0"
68
76
  },
69
77
  "devDependencies": {
70
- "@sinclair/typebox": "^0.34.33",
78
+ "@sinclair/typebox": "^0.34.41",
71
79
  "@sinclair/typebox-codegen": "^0.11.1",
72
80
  "@types/argon2-browser": "^1.18.4",
73
- "@types/bcrypt": "^5.0.2",
81
+ "@types/bcrypt": "^6.0.0",
74
82
  "ajv": "^8.17.1",
75
83
  "ajv-formats": "^3.0.1",
76
84
  "ajv-i18n": "^4.2.0",
77
85
  "ajv-keywords": "^5.1.0",
78
- "argon2": "^0.43.0",
86
+ "argon2": "^0.44.0",
79
87
  "argon2-browser": "^1.18.0",
80
- "bcrypt": "^5.1.1",
88
+ "bcrypt": "^6.0.0",
81
89
  "bcryptjs": "^3.0.2",
82
- "chalk": "^5.4.1",
90
+ "chalk": "^5.6.2",
83
91
  "consola": "^3.4.2",
84
- "dayjs": "^1.11.13",
85
- "zod": "^3.25.63"
92
+ "dayjs": "^1.11.18",
93
+ "decimal.js": "^10.6.0",
94
+ "zod": "^4.1.8"
86
95
  },
87
96
  "scripts": {
88
97
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -0,0 +1,7 @@
1
+ export {
2
+ ChineseResidentIdNoRegex as regex,
3
+ parseChineseResidentIdNo as parse,
4
+ formatChineseResidentIdNo as format,
5
+ type ParsedChineseResidentIdNo as Result,
6
+ ParsedChineseResidentIdNoSchema as ResultSchema,
7
+ } from './ChineseResidentIdNo';
@@ -0,0 +1,18 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ChineseResidentIdNo } from './mod';
3
+
4
+ describe('ChineseResidentIdNo', () => {
5
+ it('should parse', () => {
6
+ for (const a of ['11010519491231002X']) {
7
+ let out = ChineseResidentIdNo.parse(a);
8
+ expect(out).toBeTruthy();
9
+ expect(ChineseResidentIdNo.format(out!)).toBe(a);
10
+ expect(out).toMatchSnapshot();
11
+ }
12
+ });
13
+ it('should format with partial', () => {
14
+ expect(ChineseResidentIdNo.format({ addressCode: '110105', birthDate: new Date('1949-12-31'), sequence: 2 })).toBe(
15
+ '11010519491231002X',
16
+ );
17
+ });
18
+ });
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod/v4';
2
+ import { SexType, SexTypeSchema } from '../foundation/schema';
3
+ import { Mod11 } from './Mod11';
4
+
5
+ export const ChineseResidentIdNoRegex =
6
+ /^(?<division>[1-9]\d{5})(?<year>(18|19|20)\d{2})(?<month>0[1-9]|1[0-2])(?<day>0[1-9]|[12]\d|3[01])(?<sequence>\d{3})(?<checkDigit>[0-9Xx])$/;
7
+
8
+ export type ParsedChineseResidentIdNo = z.infer<typeof ParsedChineseResidentIdNoSchema>;
9
+ export const ParsedChineseResidentIdNoSchema = z
10
+ .object({
11
+ raw: z.string().regex(ChineseResidentIdNoRegex, '无效的18位身份证号码格式').describe('身份证号码'),
12
+ addressCode: z.string().length(6).describe('地址码 '),
13
+ birthDate: z.iso.date().describe('出生日期'),
14
+ sequence: z.int().max(999).min(0).describe('顺序码'),
15
+ checkDigit: z.int().min(0).max(10).describe('校验码'),
16
+ sex: SexTypeSchema.describe('性别'),
17
+ age: z.number().optional(),
18
+ valid: z.boolean().optional().describe('是否有效'),
19
+ })
20
+ .describe('居民身份证号码解析内容');
21
+
22
+ export function parseChineseResidentIdNo(idNo: string): ParsedChineseResidentIdNo | undefined {
23
+ const reg = ChineseResidentIdNoRegex;
24
+ const match = idNo.match(reg);
25
+ if (!match || !match.groups) {
26
+ return undefined;
27
+ }
28
+ const { division, year, month, day, sequence, checkDigit } = match.groups;
29
+ let seq = parseInt(sequence, 10);
30
+ return {
31
+ raw: idNo,
32
+ addressCode: division,
33
+ birthDate: `${year}-${month}-${day}`,
34
+ sequence: seq,
35
+ checkDigit: checkDigit.toUpperCase() === 'X' ? 10 : parseInt(checkDigit),
36
+ sex: seq % 2 === 0 ? SexType.Male : SexType.Female,
37
+ age: new Date().getFullYear() - parseInt(year, 10),
38
+ valid: Mod11.validate(idNo),
39
+ };
40
+ }
41
+
42
+ export function formatChineseResidentIdNo({
43
+ addressCode,
44
+ birthDate,
45
+ sequence,
46
+ checkDigit,
47
+ }: {
48
+ addressCode: string;
49
+ birthDate: string | Date;
50
+ sequence: number | string;
51
+ checkDigit?: string | number;
52
+ }): string {
53
+ const date =
54
+ typeof birthDate === 'string'
55
+ ? birthDate.replace(/-/g, '')
56
+ : `${birthDate.getFullYear()}${String(birthDate.getMonth() + 1).padStart(2, '0')}${String(birthDate.getDate()).padStart(2, '0')}`;
57
+ const seq = String(sequence).padStart(3, '0');
58
+ const major = `${addressCode}${date}${seq}`;
59
+ const check =
60
+ typeof checkDigit === 'number'
61
+ ? checkDigit === 10
62
+ ? 'X'
63
+ : String(checkDigit)
64
+ : checkDigit?.toUpperCase() || Mod11.compute(major);
65
+ return `${major}${check}`;
66
+ }
@@ -0,0 +1,7 @@
1
+ export {
2
+ DivisionCodeRegex as regex,
3
+ type ParsedDivisionCode as Result,
4
+ ParsedDivisionCodeSchema as ResultSchema,
5
+ parseDivisionCode as parse,
6
+ formatDivisionCode as format,
7
+ } from './DivisionCode';
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { DivisionCode } from './DivisionCode';
2
+ import { DivisionCode } from './mod';
3
3
 
4
4
  describe('DivisionCode', () => {
5
5
  it('should parse', () => {
@@ -7,27 +7,17 @@ describe('DivisionCode', () => {
7
7
  [
8
8
  '441900003001',
9
9
  {
10
- province: '44',
11
- city: '19',
12
- county: '00',
13
- town: '003',
14
- village: '001',
15
10
  codes: ['44', '19', '00', '003', '001'],
16
11
  },
17
12
  ],
18
13
  [
19
14
  441900003001,
20
15
  {
21
- province: '44',
22
- city: '19',
23
- county: '00',
24
- town: '003',
25
- village: '001',
26
16
  codes: ['44', '19', '00', '003', '001'],
27
17
  },
28
18
  ],
29
- [441900, { province: '44', city: '19', county: '00' }],
30
- ['31', { province: '31' }],
19
+ [441900, { codes: ['44', '19', '00'] }],
20
+ ['31', { codes: ['31'] }],
31
21
  ['4', undefined],
32
22
  ['', undefined],
33
23
  [null, undefined],