@travetto/schema 3.1.0-rc.0 → 3.1.0-rc.1
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.
- package/package.json +1 -1
- package/src/decorator/common.ts +3 -2
- package/src/service/registry.ts +20 -25
- package/src/service/types.ts +4 -4
- package/src/validate/validator.ts +8 -4
package/package.json
CHANGED
package/src/decorator/common.ts
CHANGED
|
@@ -16,9 +16,10 @@ export function Describe(config: Partial<DescribableConfig>) {
|
|
|
16
16
|
return (target: Class | ClassInstance, property?: string, descOrIdx?: PropertyDescriptor | number): void => {
|
|
17
17
|
if (isClassInstance(target, property)) {
|
|
18
18
|
if (descOrIdx !== undefined && typeof descOrIdx === 'number') {
|
|
19
|
-
property
|
|
19
|
+
SchemaRegistry.registerPendingParamFacet(target.constructor, property!, descOrIdx, config);
|
|
20
|
+
} else {
|
|
21
|
+
SchemaRegistry.registerPendingFieldFacet(target.constructor, property!, config);
|
|
20
22
|
}
|
|
21
|
-
SchemaRegistry.registerPendingFieldFacet(target.constructor, property!, config);
|
|
22
23
|
} else {
|
|
23
24
|
SchemaRegistry.register(target, config);
|
|
24
25
|
}
|
package/src/service/registry.ts
CHANGED
|
@@ -28,7 +28,6 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
28
28
|
#subTypes = new Map<Class, Map<string, Class>>();
|
|
29
29
|
#typeKeys = new Map<Class, string>();
|
|
30
30
|
#pendingViews = new Map<Class, Map<string, ViewFieldsConfig<unknown>>>();
|
|
31
|
-
#methodSchemas = new Map<Class, Map<string, FieldConfig[]>>();
|
|
32
31
|
|
|
33
32
|
constructor() {
|
|
34
33
|
super(RootRegistry);
|
|
@@ -191,6 +190,7 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
191
190
|
validators: [],
|
|
192
191
|
subType: false,
|
|
193
192
|
metadata: {},
|
|
193
|
+
methods: {},
|
|
194
194
|
views: {
|
|
195
195
|
[AllViewⲐ]: {
|
|
196
196
|
schema: {},
|
|
@@ -225,22 +225,7 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
225
225
|
* @param method
|
|
226
226
|
*/
|
|
227
227
|
getMethodSchema<T>(cls: Class<T>, method: string): FieldConfig[] {
|
|
228
|
-
|
|
229
|
-
this.#methodSchemas.set(cls, new Map());
|
|
230
|
-
}
|
|
231
|
-
const cache = this.#methodSchemas.get(cls)!;
|
|
232
|
-
if (!cache.has(method) && this.has(cls)) {
|
|
233
|
-
const { fields, schema } = this.getViewSchema(cls);
|
|
234
|
-
const out = [];
|
|
235
|
-
for (const el of fields) {
|
|
236
|
-
if (el.startsWith(`${method}.`) && schema[el].forMethod) {
|
|
237
|
-
out.push(schema[el]);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
out.sort((a, b) => a.index! - b.index!);
|
|
241
|
-
cache.set(method, out);
|
|
242
|
-
}
|
|
243
|
-
return cache.get(method)! ?? [];
|
|
228
|
+
return (this.get(cls)?.methods?.[method] ?? []).filter(x => !!x).sort((a, b) => a.index! - b.index!);
|
|
244
229
|
}
|
|
245
230
|
|
|
246
231
|
/**
|
|
@@ -265,9 +250,18 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
265
250
|
* @param idx The param index
|
|
266
251
|
* @param config The config to register
|
|
267
252
|
*/
|
|
268
|
-
registerPendingParamFacet(target: Class,
|
|
269
|
-
|
|
270
|
-
|
|
253
|
+
registerPendingParamFacet(target: Class, method: string, idx: number, config: Partial<FieldConfig>): Class {
|
|
254
|
+
const methods = this.getOrCreatePending(target)!.methods!;
|
|
255
|
+
const params = (methods[method] ??= []);
|
|
256
|
+
params[idx] = {
|
|
257
|
+
// @ts-expect-error
|
|
258
|
+
name: `${method}.${idx}`,
|
|
259
|
+
...params[idx] ?? {},
|
|
260
|
+
owner: target,
|
|
261
|
+
index: idx,
|
|
262
|
+
...config,
|
|
263
|
+
};
|
|
264
|
+
return target;
|
|
271
265
|
}
|
|
272
266
|
|
|
273
267
|
/**
|
|
@@ -300,10 +294,11 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
300
294
|
* @param conf Extra config
|
|
301
295
|
*/
|
|
302
296
|
registerPendingParamConfig(target: Class, method: string, idx: number, type: ClassList, conf?: Partial<FieldConfig>): Class {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
return this.registerPendingParamFacet(target, method, idx, {
|
|
298
|
+
...conf,
|
|
299
|
+
array: Array.isArray(type),
|
|
300
|
+
type: Array.isArray(type) ? type[0] : type,
|
|
301
|
+
});
|
|
307
302
|
}
|
|
308
303
|
|
|
309
304
|
/**
|
|
@@ -335,6 +330,7 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
335
330
|
schema: { ...dest.views[AllViewⲐ].schema, ...src.views?.[AllViewⲐ].schema },
|
|
336
331
|
fields: [...dest.views[AllViewⲐ].fields, ...src.views?.[AllViewⲐ].fields ?? []]
|
|
337
332
|
};
|
|
333
|
+
dest.methods = { ...src.methods ?? {}, ...dest.methods ?? {} };
|
|
338
334
|
dest.metadata = { ...src.metadata ?? {}, ...dest.metadata ?? {} };
|
|
339
335
|
dest.subType = src.subType || dest.subType;
|
|
340
336
|
dest.title = src.title || dest.title;
|
|
@@ -411,7 +407,6 @@ class $SchemaRegistry extends MetadataRegistry<ClassConfig, FieldConfig> {
|
|
|
411
407
|
// Recompute subtypes
|
|
412
408
|
this.#subTypes.clear();
|
|
413
409
|
this.#typeKeys.delete(cls);
|
|
414
|
-
this.#methodSchemas.delete(cls);
|
|
415
410
|
this.#accessorDescriptors.delete(cls);
|
|
416
411
|
|
|
417
412
|
// Recompute subtype mappings
|
package/src/service/types.ts
CHANGED
|
@@ -71,6 +71,10 @@ export interface ClassConfig extends DescribableConfig {
|
|
|
71
71
|
* Metadata that is related to the schema structure
|
|
72
72
|
*/
|
|
73
73
|
metadata?: Record<symbol, unknown>;
|
|
74
|
+
/**
|
|
75
|
+
* Method parameter configs
|
|
76
|
+
*/
|
|
77
|
+
methods: Record<string, FieldConfig[]>;
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
/**
|
|
@@ -160,10 +164,6 @@ export interface FieldConfig extends DescribableConfig {
|
|
|
160
164
|
* Is this field a getter or setter
|
|
161
165
|
*/
|
|
162
166
|
accessor?: string;
|
|
163
|
-
/**
|
|
164
|
-
* Is the field for a method
|
|
165
|
-
*/
|
|
166
|
-
forMethod?: boolean;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
export type ViewFieldsConfig<T> = { with: Extract<(keyof T), string>[] } | { without: Extract<(keyof T), string>[] };
|
|
@@ -40,7 +40,7 @@ export class SchemaValidator {
|
|
|
40
40
|
|
|
41
41
|
const fields = TypedObject.keys<SchemaConfig>(schema);
|
|
42
42
|
for (const field of fields) {
|
|
43
|
-
if (schema[field].access !== 'readonly'
|
|
43
|
+
if (schema[field].access !== 'readonly') { // Do not validate readonly fields
|
|
44
44
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
45
45
|
errors = errors.concat(this.#validateFieldSchema(schema[field], o[field as keyof T], relative));
|
|
46
46
|
}
|
|
@@ -107,20 +107,24 @@ export class SchemaValidator {
|
|
|
107
107
|
static #validateRange(field: FieldConfig, key: 'min' | 'max', value: string | number | Date): boolean {
|
|
108
108
|
|
|
109
109
|
const f = field[key]!;
|
|
110
|
-
|
|
110
|
+
const fn = f.n;
|
|
111
|
+
if (typeof fn === 'number') {
|
|
111
112
|
if (typeof value === 'string') {
|
|
112
113
|
value = parseInt(value, 10);
|
|
113
114
|
}
|
|
114
115
|
if (field.type === Date) {
|
|
115
116
|
value = new Date(value);
|
|
116
117
|
}
|
|
117
|
-
|
|
118
|
+
const valN = typeof value === 'number' ? value : value.getTime();
|
|
119
|
+
if (key === 'min' && valN < fn || key === 'max' && valN > fn) {
|
|
118
120
|
return true;
|
|
119
121
|
}
|
|
120
122
|
} else {
|
|
121
|
-
const date =
|
|
123
|
+
const date = fn.getTime();
|
|
122
124
|
if (typeof value === 'string') {
|
|
123
125
|
value = Date.parse(value);
|
|
126
|
+
} else if (value instanceof Date) {
|
|
127
|
+
value = value.getTime();
|
|
124
128
|
}
|
|
125
129
|
if (key === 'min' && value < date || key === 'max' && value > date) {
|
|
126
130
|
return true;
|