@wener/common 1.0.5 → 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 (222) hide show
  1. package/lib/cn/ChineseResidentIdNo.js +41 -0
  2. package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
  3. package/lib/cn/ChineseResidentIdNo.test.js +22 -0
  4. package/lib/cn/DivisionCode.js +214 -280
  5. package/lib/cn/DivisionCode.mod.js +1 -0
  6. package/lib/cn/DivisionCode.test.js +134 -0
  7. package/lib/cn/Mod11.js +86 -0
  8. package/lib/cn/Mod31.js +98 -0
  9. package/lib/cn/UnifiedSocialCreditCode.js +130 -109
  10. package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
  11. package/lib/cn/UnifiedSocialCreditCode.test.js +16 -0
  12. package/lib/cn/index.js +1 -4
  13. package/lib/cn/mod.js +6 -0
  14. package/lib/cn/types.d.js +0 -2
  15. package/lib/consola/createStandardConsolaReporter.js +6 -6
  16. package/lib/consola/formatLogObject.js +147 -34
  17. package/lib/consola/index.js +0 -1
  18. package/lib/data/formatSort.js +5 -6
  19. package/lib/data/formatSort.test.js +34 -0
  20. package/lib/data/index.js +0 -1
  21. package/lib/data/maybeNumber.js +11 -5
  22. package/lib/data/parseSort.js +28 -22
  23. package/lib/data/parseSort.test.js +188 -0
  24. package/lib/data/resolvePagination.js +27 -16
  25. package/lib/data/resolvePagination.test.js +232 -0
  26. package/lib/data/types.d.js +0 -2
  27. package/lib/dayjs/dayjs.js +38 -0
  28. package/lib/dayjs/formatDuration.js +58 -0
  29. package/lib/dayjs/formatDuration.test.js +90 -0
  30. package/lib/dayjs/index.js +3 -0
  31. package/lib/dayjs/parseDuration.js +32 -0
  32. package/lib/decimal/index.js +1 -0
  33. package/lib/decimal/parseDecimal.js +13 -0
  34. package/lib/foundation/schema/SexType.js +14 -0
  35. package/lib/foundation/schema/index.js +1 -0
  36. package/lib/foundation/schema/parseSexType.js +18 -0
  37. package/lib/foundation/schema/types.js +5 -0
  38. package/lib/index.js +0 -1
  39. package/lib/jsonschema/JsonSchema.js +78 -52
  40. package/lib/jsonschema/JsonSchema.test.js +137 -0
  41. package/lib/jsonschema/index.js +0 -1
  42. package/lib/jsonschema/types.d.js +5 -3
  43. package/lib/meta/defineFileType.js +103 -20
  44. package/lib/meta/defineInit.js +250 -31
  45. package/lib/meta/defineMetadata.js +140 -24
  46. package/lib/meta/defineMetadata.test.js +13 -0
  47. package/lib/meta/index.js +0 -1
  48. package/lib/password/PHC.js +87 -63
  49. package/lib/password/PHC.test.js +539 -0
  50. package/lib/password/Password.js +295 -30
  51. package/lib/password/Password.test.js +362 -0
  52. package/lib/password/createArgon2PasswordAlgorithm.js +191 -35
  53. package/lib/password/createBase64PasswordAlgorithm.js +141 -8
  54. package/lib/password/createBcryptPasswordAlgorithm.js +168 -13
  55. package/lib/password/createPBKDF2PasswordAlgorithm.js +228 -46
  56. package/lib/password/createScryptPasswordAlgorithm.js +211 -55
  57. package/lib/password/index.js +0 -1
  58. package/lib/password/server/index.js +0 -1
  59. package/lib/resource/Identifiable.js +1 -0
  60. package/lib/resource/ListQuery.js +119 -0
  61. package/lib/resource/getTitleOfResource.js +10 -0
  62. package/lib/resource/index.js +2 -0
  63. package/lib/resource/schema/AnyResourceSchema.js +89 -0
  64. package/lib/resource/schema/BaseResourceSchema.js +29 -0
  65. package/lib/resource/schema/ResourceActionType.js +118 -0
  66. package/lib/resource/schema/ResourceStatus.js +93 -0
  67. package/lib/resource/schema/ResourceType.js +24 -0
  68. package/lib/resource/schema/index.js +5 -0
  69. package/lib/resource/schema/types.js +89 -0
  70. package/lib/resource/schema/types.test.js +14 -0
  71. package/lib/schema/SchemaRegistry.js +45 -0
  72. package/lib/schema/SchemaRegistry.mod.js +2 -0
  73. package/lib/schema/TypeSchema.d.js +1 -0
  74. package/lib/schema/createSchemaData.js +173 -0
  75. package/lib/schema/findJsonSchemaByPath.js +49 -0
  76. package/lib/schema/getSchemaCache.js +11 -0
  77. package/lib/schema/getSchemaOptions.js +24 -0
  78. package/lib/schema/index.js +6 -0
  79. package/lib/schema/toJsonSchema.js +441 -0
  80. package/lib/schema/toJsonSchema.test.js +27 -0
  81. package/lib/schema/validate.js +124 -0
  82. package/lib/tools/generateSchema.js +197 -39
  83. package/lib/tools/renderJsonSchemaToMarkdownDoc.js +143 -55
  84. package/lib/utils/getEstimateProcessTime.js +20 -0
  85. package/lib/utils/index.js +1 -0
  86. package/package.json +38 -17
  87. package/src/cn/ChineseResidentIdNo.mod.ts +7 -0
  88. package/src/cn/ChineseResidentIdNo.test.ts +18 -0
  89. package/src/cn/ChineseResidentIdNo.ts +66 -0
  90. package/src/cn/DivisionCode.mod.ts +7 -0
  91. package/src/cn/DivisionCode.test.ts +3 -13
  92. package/src/cn/DivisionCode.ts +132 -195
  93. package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
  94. package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
  95. package/src/cn/UnifiedSocialCreditCode.mod.ts +7 -0
  96. package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
  97. package/src/cn/UnifiedSocialCreditCode.ts +105 -125
  98. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
  99. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +18 -12
  100. package/src/cn/index.ts +1 -3
  101. package/src/cn/mod.ts +3 -0
  102. package/src/consola/formatLogObject.ts +12 -4
  103. package/src/data/maybeNumber.ts +5 -1
  104. package/src/data/resolvePagination.test.ts +1 -1
  105. package/src/data/resolvePagination.ts +18 -7
  106. package/src/data/types.d.ts +12 -0
  107. package/src/dayjs/dayjs.ts +40 -0
  108. package/src/dayjs/formatDuration.test.ts +14 -0
  109. package/src/dayjs/formatDuration.ts +86 -0
  110. package/src/dayjs/index.ts +3 -0
  111. package/src/dayjs/parseDuration.ts +40 -0
  112. package/src/decimal/index.ts +1 -0
  113. package/src/decimal/parseDecimal.ts +16 -0
  114. package/src/foundation/schema/SexType.ts +21 -0
  115. package/src/foundation/schema/index.ts +1 -0
  116. package/src/foundation/schema/parseSexType.ts +19 -0
  117. package/src/foundation/schema/types.ts +8 -0
  118. package/src/jsonschema/JsonSchema.test.ts +17 -0
  119. package/src/jsonschema/JsonSchema.ts +2 -2
  120. package/src/jsonschema/types.d.ts +63 -12
  121. package/src/password/Password.ts +2 -2
  122. package/src/resource/Identifiable.ts +3 -0
  123. package/src/resource/ListQuery.ts +53 -0
  124. package/src/resource/getTitleOfResource.tsx +6 -0
  125. package/src/resource/index.ts +4 -0
  126. package/src/resource/schema/AnyResourceSchema.ts +113 -0
  127. package/src/resource/schema/BaseResourceSchema.ts +32 -0
  128. package/src/resource/schema/ResourceActionType.ts +123 -0
  129. package/src/resource/schema/ResourceStatus.ts +94 -0
  130. package/src/resource/schema/ResourceType.ts +25 -0
  131. package/src/resource/schema/index.ts +5 -0
  132. package/src/resource/schema/types.test.ts +18 -0
  133. package/src/resource/schema/types.ts +105 -0
  134. package/src/schema/SchemaRegistry.mod.ts +1 -0
  135. package/src/schema/SchemaRegistry.ts +46 -0
  136. package/src/schema/TypeSchema.d.ts +32 -0
  137. package/src/schema/createSchemaData.ts +81 -0
  138. package/src/schema/findJsonSchemaByPath.ts +37 -0
  139. package/src/schema/getSchemaCache.ts +21 -0
  140. package/src/schema/getSchemaOptions.ts +24 -0
  141. package/src/schema/index.ts +7 -0
  142. package/src/schema/toJsonSchema.test.ts +37 -0
  143. package/src/schema/toJsonSchema.ts +200 -0
  144. package/src/schema/validate.ts +135 -0
  145. package/src/tools/generateSchema.ts +28 -28
  146. package/src/utils/getEstimateProcessTime.ts +36 -0
  147. package/src/utils/index.ts +1 -0
  148. package/lib/cn/DivisionCode.js.map +0 -1
  149. package/lib/cn/Mod11Checksum.js +0 -42
  150. package/lib/cn/Mod11Checksum.js.map +0 -1
  151. package/lib/cn/Mod31Checksum.js +0 -48
  152. package/lib/cn/Mod31Checksum.js.map +0 -1
  153. package/lib/cn/ResidentIdentityCardNumber.js +0 -50
  154. package/lib/cn/ResidentIdentityCardNumber.js.map +0 -1
  155. package/lib/cn/UnifiedSocialCreditCode.js.map +0 -1
  156. package/lib/cn/formatDate.js +0 -15
  157. package/lib/cn/formatDate.js.map +0 -1
  158. package/lib/cn/index.js.map +0 -1
  159. package/lib/cn/parseSex.js +0 -22
  160. package/lib/cn/parseSex.js.map +0 -1
  161. package/lib/cn/types.d.js.map +0 -1
  162. package/lib/consola/createStandardConsolaReporter.js.map +0 -1
  163. package/lib/consola/formatLogObject.js.map +0 -1
  164. package/lib/consola/index.js.map +0 -1
  165. package/lib/data/formatSort.js.map +0 -1
  166. package/lib/data/index.js.map +0 -1
  167. package/lib/data/maybeNumber.js.map +0 -1
  168. package/lib/data/parseSort.js.map +0 -1
  169. package/lib/data/resolvePagination.js.map +0 -1
  170. package/lib/data/types.d.js.map +0 -1
  171. package/lib/index.js.map +0 -1
  172. package/lib/jsonschema/JsonSchema.js.map +0 -1
  173. package/lib/jsonschema/index.js.map +0 -1
  174. package/lib/jsonschema/types.d.js.map +0 -1
  175. package/lib/meta/defineFileType.js.map +0 -1
  176. package/lib/meta/defineInit.js.map +0 -1
  177. package/lib/meta/defineMetadata.js.map +0 -1
  178. package/lib/meta/index.js.map +0 -1
  179. package/lib/password/PHC.js.map +0 -1
  180. package/lib/password/Password.js.map +0 -1
  181. package/lib/password/createArgon2PasswordAlgorithm.js.map +0 -1
  182. package/lib/password/createBase64PasswordAlgorithm.js.map +0 -1
  183. package/lib/password/createBcryptPasswordAlgorithm.js.map +0 -1
  184. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +0 -1
  185. package/lib/password/createScryptPasswordAlgorithm.js.map +0 -1
  186. package/lib/password/index.js.map +0 -1
  187. package/lib/password/server/index.js.map +0 -1
  188. package/lib/search/AdvanceSearch.js +0 -10
  189. package/lib/search/AdvanceSearch.js.map +0 -1
  190. package/lib/search/formatAdvanceSearch.js +0 -64
  191. package/lib/search/formatAdvanceSearch.js.map +0 -1
  192. package/lib/search/index.js +0 -2
  193. package/lib/search/index.js.map +0 -1
  194. package/lib/search/optimizeAdvanceSearch.js +0 -89
  195. package/lib/search/optimizeAdvanceSearch.js.map +0 -1
  196. package/lib/search/parseAdvanceSearch.js +0 -20
  197. package/lib/search/parseAdvanceSearch.js.map +0 -1
  198. package/lib/search/parser.d.js +0 -3
  199. package/lib/search/parser.d.js.map +0 -1
  200. package/lib/search/parser.js +0 -3065
  201. package/lib/search/parser.js.map +0 -1
  202. package/lib/search/types.d.js +0 -3
  203. package/lib/search/types.d.js.map +0 -1
  204. package/lib/tools/generateSchema.js.map +0 -1
  205. package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +0 -1
  206. package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
  207. package/src/cn/ResidentIdentityCardNumber.ts +0 -96
  208. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
  209. package/src/cn/formatDate.ts +0 -12
  210. package/src/cn/parseSex.ts +0 -13
  211. package/src/search/AdvanceSearch.test.ts +0 -149
  212. package/src/search/AdvanceSearch.ts +0 -14
  213. package/src/search/Makefile +0 -2
  214. package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
  215. package/src/search/formatAdvanceSearch.ts +0 -52
  216. package/src/search/index.ts +0 -1
  217. package/src/search/optimizeAdvanceSearch.ts +0 -77
  218. package/src/search/parseAdvanceSearch.ts +0 -23
  219. package/src/search/parser.d.ts +0 -8
  220. package/src/search/parser.js +0 -2794
  221. package/src/search/parser.peggy +0 -237
  222. package/src/search/types.d.ts +0 -45
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod/v4';
2
+ import type { EnumValues } from '../../resource/schema';
3
+
4
+ // Sex 指的是生理性别/生物性别,通常由出生时的生物特征决定
5
+ export const SexType = Object.freeze({
6
+ __proto__: null,
7
+ Male: 'Male',
8
+ Female: 'Female',
9
+ });
10
+ export type SexType = EnumValues<typeof SexType>;
11
+
12
+ export const SexTypeSchema = z
13
+ .union([
14
+ //
15
+ z.literal(SexType.Male).describe('男'),
16
+ z.literal(SexType.Female).describe('女'),
17
+ ])
18
+ .describe('性别')
19
+ .meta({
20
+ title: 'SexType',
21
+ });
@@ -0,0 +1 @@
1
+ export { SexType, SexTypeSchema } from './SexType';
@@ -0,0 +1,19 @@
1
+ import { SexType } from './SexType';
2
+
3
+ export function parseSexType(s: string | null | undefined): undefined | SexType {
4
+ if (!s) return undefined;
5
+
6
+ switch (s.toLowerCase()) {
7
+ case '♂':
8
+ case '男':
9
+ case 'male':
10
+ case 'man':
11
+ return SexType.Male;
12
+ case '♀':
13
+ case '女':
14
+ case 'female':
15
+ case 'woman':
16
+ return SexType.Female;
17
+ }
18
+ return undefined;
19
+ }
@@ -0,0 +1,8 @@
1
+ import z from 'zod/v4';
2
+
3
+ export const CoordinatesSchema = z
4
+ .object({
5
+ latitude: z.number().min(-90).max(90).describe('纬度'),
6
+ longitude: z.number().min(-180).max(180).describe('经度'),
7
+ })
8
+ .describe('坐标信息');
@@ -1,5 +1,8 @@
1
+ import type { TObject } from '@sinclair/typebox';
2
+ import type { AnySchemaObject, JSONSchemaType } from 'ajv';
1
3
  import { describe, expect, it } from 'vitest';
2
4
  import { JsonSchema } from './JsonSchema';
5
+ import type { JsonSchemaDef } from './types';
3
6
 
4
7
  describe('jsonschema', () => {
5
8
  it('should create from schema', () => {
@@ -15,4 +18,18 @@ describe('jsonschema', () => {
15
18
  expect(JsonSchema.create(a)).toEqual(b);
16
19
  }
17
20
  });
21
+
22
+ it('should match typebox types', () => {
23
+ let a: JsonSchemaDef | undefined;
24
+ let b: TObject<{}> | undefined;
25
+ a = b;
26
+ });
27
+
28
+ it('should match ajv types', () => {
29
+ let a: JsonSchemaDef | undefined;
30
+ let b: AnySchemaObject | undefined;
31
+ let c: JSONSchemaType<{}> | undefined;
32
+ a = b;
33
+ // a = c;
34
+ });
18
35
  });
@@ -55,7 +55,7 @@ type TypeOfSchema<S> = S extends TSchema ? Static<S> : any;
55
55
  export namespace JsonSchema {
56
56
  export let schemas: JsonSchemaDef[] = [];
57
57
 
58
- export const createAjv = _createAjv;
58
+ export let createAjv = _createAjv;
59
59
 
60
60
  export function addSchema(
61
61
  schema: JsonSchemaDef,
@@ -113,7 +113,7 @@ export namespace JsonSchema {
113
113
  // will not ensure value match the rule
114
114
  return match(schema as JsonSchemaDef)
115
115
  .returnType<any>()
116
- .with({ const: P.select() }, (v) => v)
116
+ .with({ const: P.nonNullable }, (v) => v)
117
117
  .with({ default: P.select() }, (v) => v)
118
118
  .with({ anyOf: P.nonNullable }, (schema) => {
119
119
  return create(schema.anyOf[0]);
@@ -5,7 +5,8 @@ type JsonSchemaTypeName =
5
5
  | 'boolean'
6
6
  | 'object'
7
7
  | 'array'
8
- | 'null';
8
+ | 'null'
9
+ | undefined;
9
10
 
10
11
  type JsonValue =
11
12
  | string //
@@ -13,15 +14,21 @@ type JsonValue =
13
14
  | boolean
14
15
  | { [key: string]: JsonValue }
15
16
  | JsonValue[]
16
- | null;
17
+ | null
18
+ | undefined; //
17
19
 
18
20
  type JsonSchemaVersion =
19
21
  | 'http://json-schema.org/schema' // latest
22
+ //
20
23
  | 'https://json-schema.org/draft/2020-12/schema'
24
+ | 'https://json-schema.org/draft/2019-09/schema'
21
25
  // draft-07
22
- | 'http://json-schema.org/draft-07/schema#' //
23
- | 'http://json-schema.org/draft-07/hyper-schema#';
24
-
26
+ | 'https://json-schema.org/draft-07/schema'
27
+ | 'http://json-schema.org/draft-07/schema'
28
+ | 'https://json-schema.org/draft-07/hyper-schema'
29
+ | 'http://json-schema.org/draft-07/hyper-schema'
30
+ //
31
+ | 'https://json-schema.org/draft-04/schema';
25
32
  type JsonSchemaFormatName =
26
33
  //
27
34
  | 'date-time'
@@ -47,7 +54,12 @@ type JsonSchemaFormatName =
47
54
  | 'json-pointer'
48
55
  | 'relative-json-pointer';
49
56
 
50
- export type JsonSchemaDef = {
57
+ /**
58
+ * JSON Schema Definition
59
+ *
60
+ * @see https://json-schema.org/specification-links.html
61
+ */
62
+ export type JsonSchemaDef<I = any, O = I> = {
51
63
  $id?: string;
52
64
  $ref?: string;
53
65
  /**
@@ -67,7 +79,7 @@ export type JsonSchemaDef = {
67
79
  $defs?: { [key: string]: JsonSchemaDef };
68
80
 
69
81
  type?: JsonSchemaTypeName | JsonSchemaTypeName[];
70
- enum?: JsonValue[];
82
+ enum?: JsonValue;
71
83
  const?: JsonValue;
72
84
 
73
85
  //region Numeric Validation
@@ -90,12 +102,23 @@ export type JsonSchemaDef = {
90
102
 
91
103
  //region Array Validation
92
104
 
105
+ /**
106
+ * schema for array items
107
+ * @see https://json-schema.org/understanding-json-schema/reference/array.html#items
108
+ */
93
109
  items?: JsonSchemaDef | JsonSchemaDef[];
94
- additionalItems?: JsonSchemaDef;
110
+ additionalItems?: JsonSchemaDef | boolean;
95
111
  maxItems?: number;
96
112
  minItems?: number;
97
113
  uniqueItems?: boolean;
98
114
  contains?: JsonSchemaDef;
115
+
116
+ //region Draft 2022-12
117
+ minContains?: number;
118
+ maxContains?: number;
119
+ prefixItems?: JsonSchemaDef[];
120
+ //endregion
121
+
99
122
  //endregion
100
123
 
101
124
  //region Object Validation
@@ -105,9 +128,25 @@ export type JsonSchemaDef = {
105
128
  required?: string[];
106
129
  properties?: { [key: string]: JsonSchemaDef };
107
130
  patternProperties?: { [key: string]: JsonSchemaDef };
108
- additionalProperties?: JsonSchemaDef;
109
- dependencies?: { [key: string]: JsonSchemaDef | string[] };
131
+ /**
132
+ * Replaced by {@link unevaluatedProperties} in Draft 2019-09+
133
+ */
134
+ additionalProperties?: JsonSchemaDef | boolean; // true = {}
135
+ /**
136
+ * Superseded by {@link dependentSchemas}, {@link dependentRequired} in Draft 2019-09+
137
+ */
138
+ dependencies?: { [key: string]: undefined | JsonSchemaDef | string[] };
110
139
  propertyNames?: JsonSchemaDef;
140
+
141
+ //region Draft 2019-09+
142
+
143
+ dependentSchemas?: { [key: string]: JsonSchemaDef };
144
+ dependentRequired?: { [key: string]: string[] };
145
+ unevaluatedProperties?: JsonSchemaDef | boolean;
146
+ unevaluatedItems?: JsonSchemaDef | boolean;
147
+
148
+ //endregion
149
+
111
150
  //endregion
112
151
 
113
152
  //region Conditional
@@ -120,9 +159,9 @@ export type JsonSchemaDef = {
120
159
 
121
160
  //region Boolean Logic
122
161
 
123
- allOf?: JsonSchemaDef[];
162
+ allOf?: JsonSchemaDef[]; // extends, merge
124
163
  anyOf?: JsonSchemaDef[];
125
- oneOf?: JsonSchemaDef[];
164
+ oneOf?: JsonSchemaDef[]; // polymorphism, enum
126
165
  not?: JsonSchemaDef;
127
166
  //endregion
128
167
 
@@ -159,5 +198,17 @@ export type JsonSchemaDef = {
159
198
 
160
199
  //endregion
161
200
 
201
+ //region OpenAPI Spec
202
+
162
203
  nullable?: boolean;
204
+
205
+ discriminator?: {
206
+ propertyName: string;
207
+ mapping?: { [key: string]: string };
208
+ };
209
+
210
+ //endregion
211
+
212
+ // [key: `x-${string}`]: JsonValue;
213
+ [key: string]: JsonValue;
163
214
  };
@@ -68,10 +68,10 @@ export namespace Password {
68
68
  return f;
69
69
  }
70
70
 
71
- export async function check(password: string, hash: string) {
71
+ export async function validate(password: string, hash: string) {
72
72
  let res = await parse(hash);
73
73
  let f = resolveAlgorithm(res.id);
74
- return { result: f.verify(password, hash, res), parsed: res };
74
+ return { result: await f.verify(password, hash, res), parsed: res };
75
75
  }
76
76
 
77
77
  export async function verify(password: string, hash: string) {
@@ -0,0 +1,3 @@
1
+ export type Identifiable = {
2
+ id: string;
3
+ };
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod/v4';
2
+
3
+ export type ListQueryInput = z.input<typeof ListQuerySchema>;
4
+ export type ListQuery = z.infer<typeof ListQuerySchema>;
5
+ const IntLikeSchema = z.coerce
6
+ .number()
7
+ .multipleOf(1)
8
+ .min(0)
9
+ .optional()
10
+ .overwrite((v) => v || undefined);
11
+ export const ListQuerySchema = z.object({
12
+ id: z.coerce.string().optional(),
13
+ ids: z.array(z.coerce.string()).optional(),
14
+ filter: z.string().optional().describe('sql-like filter string'),
15
+ filters: z.array(z.any()).optional().describe('sql-like filter string'),
16
+ where: z.record(z.string(), z.any()).optional().describe('document query filter'),
17
+ search: z.string().optional(),
18
+ limit: IntLikeSchema,
19
+ offset: IntLikeSchema,
20
+ order: z.array(z.string()).optional().describe('order like "a,-b,c desc null last"'),
21
+ pageIndex: IntLikeSchema.describe('0-based page index'),
22
+ pageNumber: IntLikeSchema.describe('1-based page number'),
23
+ pageSize: IntLikeSchema,
24
+ cursor: z.string().optional(),
25
+ deleted: z.coerce.boolean().optional(),
26
+ });
27
+
28
+ type ListQueryOverride = ListQueryInput | undefined | ((input: ListQueryInput) => ListQueryInput | undefined | void);
29
+
30
+ export function resolveListQuery(target: ListQueryInput | undefined, ...args: ListQueryOverride[]): ListQuery {
31
+ let out = args.reduce((a: ListQueryInput, source) => {
32
+ if (typeof source === 'function') {
33
+ const result = source(a);
34
+ // do not use the result as merge source
35
+ return result || a;
36
+ }
37
+
38
+ let b: ListQueryInput | undefined = source;
39
+ if (!b) return a;
40
+
41
+ // do not resolve id to ids
42
+ let ids = [...(a.ids || []), ...(b.ids || [])];
43
+ return {
44
+ ...a,
45
+ ...b,
46
+ ids: ids,
47
+ filters: [...(a.filters || []), ...(b.filters || [])],
48
+ search: b.search || a.search,
49
+ // NOTE maybe should merge where ?
50
+ };
51
+ }, target || {});
52
+ return ListQuerySchema.parse(out);
53
+ }
@@ -0,0 +1,6 @@
1
+ export function getTitleOfResource(res?: any): string | undefined {
2
+ if (res && typeof res === 'object') {
3
+ return res.displayName || res.title || res.fullName || res.loginName || res.topic || res.code;
4
+ }
5
+ return undefined;
6
+ }
@@ -0,0 +1,4 @@
1
+ export { type AnyResource } from './schema/AnyResourceSchema';
2
+ export { type Identifiable } from './Identifiable';
3
+ export { getTitleOfResource } from './getTitleOfResource';
4
+ export { type ListQueryInput, type ListQuery, resolveListQuery, ListQuerySchema } from './ListQuery';
@@ -0,0 +1,113 @@
1
+ import { z } from 'zod/v4';
2
+ import { SexTypeSchema } from '../../foundation/schema/SexType';
3
+ import { rz } from './types';
4
+
5
+ export type AnyResource = z.infer<typeof AnyResourceSchema>;
6
+ export const AnyResourceSchema = z
7
+ .object({
8
+ id: rz.resourceId.readonly().describe('ID'),
9
+ uid: z.guid().nullish().readonly().describe('唯一ID'),
10
+ tid: rz.resourceId.nullish().readonly().describe('租户ID'),
11
+ sid: z.coerce.number().nullish().readonly().describe('序号'),
12
+ eid: z.string().nullish().readonly().describe('外部ID'),
13
+ cid: z.string().nullish().readonly().describe('服务商ID'),
14
+ rid: z.string().nullish().readonly().describe('服务商资源ID'),
15
+
16
+ code: z.string().nullish().describe('编号'),
17
+
18
+ fullName: rz.friendlyName.optional().describe('名称'),
19
+ displayName: rz.friendlyName.nullish().describe('显示名'),
20
+ loginName: rz.loginName.nullish().describe('登录名'),
21
+ email: z.string().nullish().describe('邮箱'),
22
+ emailVerifiedAt: rz.date.nullish().describe('邮箱验证时间'),
23
+ phoneNumber: rz.phoneNumber.nullish().describe('电话号码'),
24
+ phoneNumberVerifiedAt: rz.date.nullish().describe('电话号码验证时间'),
25
+
26
+ jobNumber: z.string().nullish().describe('工号'),
27
+ jobTitle: z.string().nullish().describe('职位'),
28
+ birthDate: rz.date.nullish().describe('出生日期'),
29
+
30
+ password: rz.password.nullish().describe('密码'),
31
+ sex: SexTypeSchema.nullish().describe('性别'),
32
+
33
+ contactName: rz.friendlyName.nullish().describe('联系人'),
34
+ contactPhone: rz.phoneNumber.nullish().describe('联系电话'),
35
+ contactEmail: z.string().nullish().describe('联系邮箱'),
36
+ contactAddress: z.string().nullish().describe('联系地址'),
37
+ alternativeName: rz.friendlyName.nullish().describe('备用联系人'),
38
+ alternativeEmail: z.string().nullish().describe('备用联系邮箱'),
39
+ alternativePhone: rz.phoneNumber.nullish().describe('备用联系电话'),
40
+ alternativeAddress: z.string().nullish().describe('备用联系地址'),
41
+
42
+ title: z.string().trim().nullish().describe('标题'),
43
+ description: z.string().trim().nullish().describe('描述'),
44
+ topic: z.string().nullish().describe('主题'),
45
+ summary: z.string().nullish().describe('摘要'),
46
+
47
+ avatarUrl: z.string().nullish().describe('头像'),
48
+ photoUrl: z.string().nullish().describe('照片'),
49
+ imageUrl: z.string().nullish().describe('图片'),
50
+ bannerUrl: z.string().nullish().describe('横幅图片'),
51
+
52
+ type: z.string().nullish().describe('类型'),
53
+ data: z.record(z.string(), z.any()).nullish().describe('数据'),
54
+
55
+ licenseNumber: z.string().nullish().describe('证件号码'),
56
+ licenseStartDate: rz.date.nullish().describe('证件有效期开始日期'),
57
+ licenseEndDate: rz.date.nullish().describe('证件有效期结束日期'),
58
+ licenseAddress: z.string().nullish().describe('证件地址'),
59
+ licenseFrontUrl: z.string().nullish().describe('证件正面照片'),
60
+ licenseBackUrl: z.string().nullish().describe('证件背面照片'),
61
+
62
+ address: z.string().nullish().describe('地址'),
63
+ divisionCode: z.string().nullish().describe('行政区划代码'),
64
+ province: z.string().nullish().describe('省'),
65
+ city: z.string().nullish().describe('市'),
66
+
67
+ startDate: rz.date.nullish().describe('开始日期'),
68
+ endDate: rz.date.nullish().describe('结束日期'),
69
+ startTime: rz.dateTime.nullish().describe('开始时间'),
70
+ endTime: rz.dateTime.nullish().describe('结束时间'),
71
+
72
+ userId: rz.resourceIdOf('User').nullish(),
73
+ entityId: rz.resourceId.nullish().describe('关联的实体'),
74
+ entityType: z.string().nullish().describe('关联的实体类型'),
75
+ customerId: rz.resourceId.nullish().describe('客户'),
76
+ customerType: z.string().nullish().describe('客户类型'),
77
+ contactId: rz.resourceId.nullish().describe('联系人'),
78
+ accountId: rz.resourceId.nullish().describe('账户'),
79
+
80
+ ownerId: rz.resourceId.nullish(),
81
+ ownerType: z.string().nullish().describe('负责人类型'),
82
+ owningUserId: rz.resourceId.nullish().describe('负责人'),
83
+
84
+ parentId: rz.resourceId.nullish().describe('父级'),
85
+
86
+ metadata: z.record(z.string(), z.any()).nullish().describe('元数据'),
87
+ tags: z.array(z.string()).nullish().describe('标记'),
88
+ notes: z.string().nullish().describe('备注'),
89
+
90
+ state: z.string().nullish().describe('系统状态'),
91
+ status: z.string().nullish().describe('状态'),
92
+ statusReason: z.string().nullish().describe('状态原因'),
93
+ statusUpdatedAt: rz.dateTime.nullish().describe('状态更新时间'),
94
+ statusUpdatedById: rz.resourceId.nullish().describe('状态更新人'),
95
+
96
+ createdAt: rz.dateTime.nullish().readonly().describe('创建时间'),
97
+ updatedAt: rz.dateTime.nullish().readonly().describe('更新时间'),
98
+ deletedAt: rz.dateTime.nullish().readonly().describe('删除时间'),
99
+
100
+ createdById: z.string().nullish().readonly().describe('创建人'),
101
+ updatedById: z.string().nullish().readonly().describe('更新人'),
102
+ deletedById: z.string().nullish().readonly().describe('删除人'),
103
+
104
+ attributes: z.record(z.string(), z.any()).nullish().describe('自定义属性'),
105
+ properties: z.record(z.string(), z.any()).nullish().describe('属性'),
106
+ extensions: z.record(z.string(), z.any()).nullish().describe('扩展属性'),
107
+
108
+ __typename: z.coerce.string().nullish().describe('类型'),
109
+ })
110
+ .meta({
111
+ title: 'AnyResource',
112
+ description: '任意资源',
113
+ });
@@ -0,0 +1,32 @@
1
+ import { AnyResourceSchema } from './AnyResourceSchema';
2
+
3
+ export const BaseResourceSchema = AnyResourceSchema.pick({
4
+ id: true,
5
+ uid: true,
6
+ tid: true,
7
+ eid: true,
8
+
9
+ state: true,
10
+ status: true,
11
+ statusReason: true,
12
+ statusUpdatedAt: true,
13
+ statusUpdatedById: true,
14
+
15
+ createdAt: true,
16
+ updatedAt: true,
17
+ deletedAt: true,
18
+ createdById: true,
19
+ updatedById: true,
20
+ deletedById: true,
21
+ attributes: true,
22
+ properties: true,
23
+ }).required({
24
+ uid: true,
25
+ tid: true,
26
+ state: true,
27
+ status: true,
28
+ createdAt: true,
29
+ updatedAt: true,
30
+ attributes: true,
31
+ properties: true,
32
+ });
@@ -0,0 +1,123 @@
1
+ import { z } from 'zod/v4';
2
+ import type { EnumValues } from './types';
3
+
4
+ export const ResourceActionType = Object.freeze({
5
+ __proto__: null,
6
+ Approve: 'Approve',
7
+ AssignOwner: 'AssignOwner',
8
+ Bind: 'Bind',
9
+ BindCustomer: 'BindCustomer',
10
+ BindEntity: 'BindEntity',
11
+ BindUser: 'BindUser',
12
+ Cancel: 'Cancel',
13
+ ChangePassword: 'ChangePassword',
14
+ ClaimOwner: 'ClaimOwner',
15
+ Close: 'Close',
16
+ Communicate: 'Communicate',
17
+ Complete: 'Complete',
18
+ Create: 'Create',
19
+ Delete: 'Delete',
20
+ Deny: 'Deny',
21
+ Disable: 'Disable',
22
+ Download: 'Download',
23
+ Edit: 'Edit',
24
+ Enable: 'Enable',
25
+ List: 'List',
26
+ Login: 'Login',
27
+ Logout: 'Logout',
28
+ Manage: 'Manage',
29
+ Publish: 'Publish',
30
+ Purge: 'Purge',
31
+ Read: 'Read',
32
+ Reject: 'Reject',
33
+ ReleaseOwner: 'ReleaseOwner',
34
+ ResetPassword: 'ResetPassword',
35
+ ReturnForRevision: 'ReturnForRevision',
36
+ Revise: 'Revise',
37
+ SaveDraft: 'SaveDraft',
38
+ Signup: 'Signup',
39
+ Submit: 'Submit',
40
+ SubmitAgency: 'SubmitAgency',
41
+ SubmitVendor: 'SubmitVendor',
42
+ Suspend: 'Suspend',
43
+ Terminate: 'Terminate',
44
+ Timeout: 'Timeout',
45
+ Unbind: 'Unbind',
46
+ UnbindCustomer: 'UnbindCustomer',
47
+ UnbindEntity: 'UnbindEntity',
48
+ UnbindUser: 'UnbindUser',
49
+ Undelete: 'Undelete',
50
+ Unpublish: 'Unpublish',
51
+ Update: 'Update',
52
+ UpdateNotes: 'UpdateNotes',
53
+ UpdateTags: 'UpdateTags',
54
+ Upload: 'Upload',
55
+ Validate: 'Validate',
56
+ View: 'View',
57
+ Write: 'Write',
58
+ } as const);
59
+ export type ResourceActionType = EnumValues<typeof ResourceActionType>;
60
+ export const ResourceActionTypeSchema = z
61
+ .union([
62
+ z.literal(ResourceActionType.Approve).describe('批准'),
63
+ z.literal(ResourceActionType.AssignOwner).describe('分配负责人'),
64
+ z.literal(ResourceActionType.Bind).describe('绑定'),
65
+ z.literal(ResourceActionType.BindCustomer).describe('绑定客户'),
66
+ z.literal(ResourceActionType.BindEntity).describe('绑定实体'),
67
+ z.literal(ResourceActionType.BindUser).describe('绑定用户'),
68
+ z.literal(ResourceActionType.Cancel).describe('取消'),
69
+ z.literal(ResourceActionType.ChangePassword).describe('修改密码'),
70
+ z.literal(ResourceActionType.ClaimOwner).describe('认领负责人'),
71
+ z.literal(ResourceActionType.Close).describe('关闭'),
72
+ z.literal(ResourceActionType.Communicate).describe('沟通'),
73
+ z.literal(ResourceActionType.Complete).describe('完成'),
74
+ z.literal(ResourceActionType.Create).describe('创建'),
75
+ z.literal(ResourceActionType.Delete).describe('删除'),
76
+ z.literal(ResourceActionType.Deny).describe('拒绝'),
77
+ z.literal(ResourceActionType.Disable).describe('禁用'),
78
+ z.literal(ResourceActionType.Download).describe('下载'),
79
+ z.literal(ResourceActionType.Edit).describe('编辑'),
80
+ z.literal(ResourceActionType.Enable).describe('启用'),
81
+ z.literal(ResourceActionType.List).describe('列表'),
82
+ z.literal(ResourceActionType.Login).describe('登录'),
83
+ z.literal(ResourceActionType.Logout).describe('登出'),
84
+ z.literal(ResourceActionType.Manage).describe('管理'),
85
+ z.literal(ResourceActionType.Publish).describe('发布'),
86
+ z.literal(ResourceActionType.Purge).describe('彻底删除'),
87
+ z.literal(ResourceActionType.Read).describe('读取'),
88
+ z.literal(ResourceActionType.Reject).describe('驳回'),
89
+ z.literal(ResourceActionType.ReleaseOwner).describe('释放负责人'),
90
+ z.literal(ResourceActionType.ResetPassword).describe('重置密码'),
91
+ z.literal(ResourceActionType.ReturnForRevision).describe('退回修订'),
92
+ z.literal(ResourceActionType.Revise).describe('修订'),
93
+ z.literal(ResourceActionType.SaveDraft).describe('保存草稿'),
94
+ z.literal(ResourceActionType.Signup).describe('注册'),
95
+ z.literal(ResourceActionType.Submit).describe('提交'),
96
+ z.literal(ResourceActionType.SubmitAgency).describe('提交机构'),
97
+ z.literal(ResourceActionType.SubmitVendor).describe('提交供应商'),
98
+ z.literal(ResourceActionType.Suspend).describe('暂停'),
99
+ z.literal(ResourceActionType.Terminate).describe('终止'),
100
+ z.literal(ResourceActionType.Timeout).describe('超时'),
101
+ z.literal(ResourceActionType.Unbind).describe('解绑'),
102
+ z.literal(ResourceActionType.UnbindCustomer).describe('解绑客户'),
103
+ z.literal(ResourceActionType.UnbindEntity).describe('解绑实体'),
104
+ z.literal(ResourceActionType.UnbindUser).describe('解绑用户'),
105
+ z.literal(ResourceActionType.Undelete).describe('恢复删除'),
106
+ z.literal(ResourceActionType.Unpublish).describe('取消发布'),
107
+ z.literal(ResourceActionType.Update).describe('更新'),
108
+ z.literal(ResourceActionType.UpdateNotes).describe('修改备注'),
109
+ z.literal(ResourceActionType.UpdateNotes).describe('更新备注'),
110
+ z.literal(ResourceActionType.UpdateTags).describe('更新标签'),
111
+ z.literal(ResourceActionType.Upload).describe('上传'),
112
+ z.literal(ResourceActionType.Validate).describe('校验'),
113
+ z.literal(ResourceActionType.View).describe('查看'),
114
+ z.literal(ResourceActionType.Write).describe('写入'),
115
+ ])
116
+ .meta({
117
+ title: 'ResourceAction',
118
+ description: '资源操作',
119
+ type: 'string',
120
+ });
121
+ export const ResourceActionDataSchema = z.object({
122
+ reason: z.string().optional().describe('操作原因'),
123
+ });