@travetto/schema 7.0.0-rc.1 → 7.0.0-rc.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.
- package/README.md +34 -34
- package/__index__.ts +3 -3
- package/package.json +3 -3
- package/src/bind-util.ts +90 -90
- package/src/data.ts +40 -39
- package/src/decorator/common.ts +5 -5
- package/src/decorator/field.ts +9 -7
- package/src/decorator/input.ts +28 -26
- package/src/decorator/method.ts +3 -1
- package/src/decorator/schema.ts +2 -2
- package/src/internal/types.ts +4 -4
- package/src/name.ts +3 -3
- package/src/service/registry-adapter.ts +64 -61
- package/src/service/registry-index.ts +18 -73
- package/src/service/types.ts +14 -18
- package/src/types.ts +1 -1
- package/src/validate/error.ts +2 -2
- package/src/validate/messages.ts +10 -10
- package/src/validate/regex.ts +22 -0
- package/src/validate/types.ts +4 -4
- package/src/validate/validator.ts +80 -80
- package/support/transformer/util.ts +29 -26
- package/support/transformer.schema.ts +7 -7
- package/src/service/changes.ts +0 -152
- package/src/validate/regexp.ts +0 -22
package/src/data.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNumberObject
|
|
1
|
+
import { isNumberObject, isBooleanObject, isStringObject } from 'node:util/types';
|
|
2
2
|
|
|
3
3
|
import { asConstructable, castTo, Class, asFull, TypedObject } from '@travetto/runtime';
|
|
4
4
|
import { UnknownType } from './types.ts';
|
|
@@ -12,24 +12,26 @@ export class DataUtil {
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Is a value a plain JS object, created using {}
|
|
15
|
-
* @param
|
|
15
|
+
* @param value Object to check
|
|
16
16
|
*/
|
|
17
|
-
static isPlainObject(
|
|
18
|
-
return typeof
|
|
19
|
-
&&
|
|
20
|
-
&&
|
|
21
|
-
&&
|
|
22
|
-
&& Object.prototype.toString.call(
|
|
17
|
+
static isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
18
|
+
return typeof value === 'object' // separate from primitives
|
|
19
|
+
&& value !== undefined
|
|
20
|
+
&& value !== null // is obvious
|
|
21
|
+
&& value.constructor === Object // separate instances (Array, DOM, ...)
|
|
22
|
+
&& Object.prototype.toString.call(value) === '[object Object]'; // separate build-in like Math
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Is a value of primitive type
|
|
27
|
-
* @param
|
|
27
|
+
* @param value Value to check
|
|
28
28
|
*/
|
|
29
|
-
static isPrimitive(
|
|
30
|
-
switch (typeof
|
|
29
|
+
static isPrimitive(value: unknown): value is (string | boolean | number | RegExp) {
|
|
30
|
+
switch (typeof value) {
|
|
31
31
|
case 'string': case 'boolean': case 'number': case 'bigint': return true;
|
|
32
|
-
case 'object': return !!
|
|
32
|
+
case 'object': return !!value && (
|
|
33
|
+
value instanceof RegExp || value instanceof Date || isStringObject(value) || isNumberObject(value) || isBooleanObject(value)
|
|
34
|
+
);
|
|
33
35
|
default: return false;
|
|
34
36
|
}
|
|
35
37
|
}
|
|
@@ -37,8 +39,8 @@ export class DataUtil {
|
|
|
37
39
|
/**
|
|
38
40
|
* Is simple, as a primitive, function or class
|
|
39
41
|
*/
|
|
40
|
-
static isSimpleValue(
|
|
41
|
-
return this.isPrimitive(
|
|
42
|
+
static isSimpleValue(value: unknown): value is Function | Class | string | number | RegExp | Date {
|
|
43
|
+
return this.isPrimitive(value) || typeof value === 'function';
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
static #deepAssignRaw(a: unknown, b: unknown, mode: 'replace' | 'loose' | 'strict' | 'coerce' = 'loose'): unknown {
|
|
@@ -68,10 +70,10 @@ export class DataUtil {
|
|
|
68
70
|
if (mode === 'replace') {
|
|
69
71
|
value = b;
|
|
70
72
|
} else {
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
for (let i = 0; i <
|
|
74
|
-
|
|
73
|
+
const valueArray: unknown[] = castTo(value);
|
|
74
|
+
const bArray = b;
|
|
75
|
+
for (let i = 0; i < bArray.length; i++) {
|
|
76
|
+
valueArray[i] = this.#deepAssignRaw(valueArray[i], bArray[i], mode);
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
} else if (isSimpB) { // Scalars
|
|
@@ -87,14 +89,14 @@ export class DataUtil {
|
|
|
87
89
|
}
|
|
88
90
|
} else { // Object merge
|
|
89
91
|
value = a;
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
+
const bObject: Record<string, unknown> = castTo(b);
|
|
93
|
+
const valueObject: Record<string, unknown> = castTo(value);
|
|
92
94
|
|
|
93
|
-
for (const key of Object.keys(
|
|
95
|
+
for (const key of Object.keys(bObject)) {
|
|
94
96
|
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
95
97
|
continue;
|
|
96
98
|
}
|
|
97
|
-
|
|
99
|
+
valueObject[key] = this.#deepAssignRaw(valueObject[key], bObject[key], mode);
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
}
|
|
@@ -119,7 +121,7 @@ export class DataUtil {
|
|
|
119
121
|
/**
|
|
120
122
|
* Coerce an input of any type to the class provided
|
|
121
123
|
* @param input Input value
|
|
122
|
-
* @param type Class to coerce to (String, Boolean, Number, Date,
|
|
124
|
+
* @param type Class to coerce to (String, Boolean, Number, Date, RegExp, Object)
|
|
123
125
|
* @param strict Should a failure to coerce throw an error?
|
|
124
126
|
*/
|
|
125
127
|
static coerceType(input: unknown, type: typeof String, strict?: boolean): string;
|
|
@@ -226,10 +228,10 @@ export class DataUtil {
|
|
|
226
228
|
|
|
227
229
|
/**
|
|
228
230
|
* Clone top level properties to a new object
|
|
229
|
-
* @param
|
|
231
|
+
* @param value Object to clone
|
|
230
232
|
*/
|
|
231
|
-
static shallowClone<T>(
|
|
232
|
-
return castTo(Array.isArray(
|
|
233
|
+
static shallowClone<T>(value: T): T {
|
|
234
|
+
return castTo(Array.isArray(value) ? value.slice(0) : (this.isSimpleValue(value) ? value : { ...castTo<object>(value) }));
|
|
233
235
|
}
|
|
234
236
|
|
|
235
237
|
/**
|
|
@@ -247,29 +249,28 @@ export class DataUtil {
|
|
|
247
249
|
|
|
248
250
|
/**
|
|
249
251
|
* Filter object by excluding specific keys
|
|
250
|
-
* @param
|
|
252
|
+
* @param input A value to filter, primitives will be untouched
|
|
251
253
|
* @param exclude Strings or patterns to exclude against
|
|
252
254
|
* @returns
|
|
253
255
|
*/
|
|
254
|
-
static filterByKeys<T>(
|
|
255
|
-
if (Array.isArray(
|
|
256
|
-
return castTo(
|
|
257
|
-
} else if (
|
|
256
|
+
static filterByKeys<T>(input: T, exclude: (string | RegExp)[]): T {
|
|
257
|
+
if (Array.isArray(input)) {
|
|
258
|
+
return castTo(input.map(value => this.filterByKeys(value, exclude)));
|
|
259
|
+
} else if (input !== null && input !== undefined && typeof input === 'object') {
|
|
258
260
|
const out: Partial<T> = {};
|
|
259
|
-
for (const key of TypedObject.keys(
|
|
260
|
-
if (!exclude.some(
|
|
261
|
-
const
|
|
262
|
-
if (typeof
|
|
263
|
-
out[key] = this.filterByKeys(
|
|
261
|
+
for (const key of TypedObject.keys(input)) {
|
|
262
|
+
if (!exclude.some(toMatch => typeof key === 'string' && (typeof toMatch === 'string' ? toMatch === key : toMatch.test(key)))) {
|
|
263
|
+
const value = input[key];
|
|
264
|
+
if (typeof value === 'object') {
|
|
265
|
+
out[key] = this.filterByKeys(value, exclude);
|
|
264
266
|
} else {
|
|
265
|
-
out[key] =
|
|
267
|
+
out[key] = value;
|
|
266
268
|
}
|
|
267
269
|
}
|
|
268
270
|
}
|
|
269
271
|
return asFull(out);
|
|
270
272
|
} else {
|
|
271
|
-
return
|
|
273
|
+
return input;
|
|
272
274
|
}
|
|
273
275
|
}
|
|
274
|
-
|
|
275
276
|
}
|
package/src/decorator/common.ts
CHANGED
|
@@ -10,14 +10,14 @@ import { SchemaRegistryIndex } from '../service/registry-index.ts';
|
|
|
10
10
|
* @kind decorator
|
|
11
11
|
*/
|
|
12
12
|
export function Describe(config: Partial<Omit<SchemaCoreConfig, 'metadata'>>) {
|
|
13
|
-
return (instanceOrCls: Class | ClassInstance, property?: string
|
|
13
|
+
return (instanceOrCls: Class | ClassInstance, property?: string, descriptorOrIdx?: PropertyDescriptor | number): void => {
|
|
14
14
|
const adapter = SchemaRegistryIndex.getForRegister(getClass(instanceOrCls));
|
|
15
15
|
if (!property) {
|
|
16
16
|
adapter.register(config);
|
|
17
17
|
} else {
|
|
18
|
-
if (
|
|
19
|
-
adapter.registerParameter(property,
|
|
20
|
-
} else if (typeof
|
|
18
|
+
if (descriptorOrIdx !== undefined && typeof descriptorOrIdx === 'number') {
|
|
19
|
+
adapter.registerParameter(property, descriptorOrIdx, config);
|
|
20
|
+
} else if (typeof descriptorOrIdx === 'object' && typeof descriptorOrIdx.value === 'function') {
|
|
21
21
|
adapter.registerMethod(property, config);
|
|
22
22
|
} else {
|
|
23
23
|
adapter.registerField(property, config);
|
|
@@ -31,7 +31,7 @@ export function Describe(config: Partial<Omit<SchemaCoreConfig, 'metadata'>>) {
|
|
|
31
31
|
* @augments `@travetto/schema:Input`
|
|
32
32
|
* @kind decorator
|
|
33
33
|
*/
|
|
34
|
-
export const IsPrivate = (): (instanceOrCls: Class | ClassInstance, property?: string
|
|
34
|
+
export const IsPrivate = (): (instanceOrCls: Class | ClassInstance, property?: string) => void => Describe({ private: true });
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Mark a field/method as ignored
|
package/src/decorator/field.ts
CHANGED
|
@@ -3,23 +3,25 @@ import { Any, ClassInstance, getClass } from '@travetto/runtime';
|
|
|
3
3
|
import { SchemaFieldConfig } from '../service/types.ts';
|
|
4
4
|
import { SchemaRegistryIndex } from '../service/registry-index.ts';
|
|
5
5
|
|
|
6
|
-
type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(
|
|
6
|
+
type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(
|
|
7
|
+
instance: T, property: K, idx?: TypedPropertyDescriptor<Any> | number
|
|
8
|
+
) => void);
|
|
7
9
|
|
|
8
|
-
function field<V>(...
|
|
9
|
-
return (instance: ClassInstance, property: string
|
|
10
|
-
SchemaRegistryIndex.getForRegister(getClass(instance)).registerField(property, ...
|
|
10
|
+
function field<V>(...configs: Partial<SchemaFieldConfig>[]): PropType<V> {
|
|
11
|
+
return (instance: ClassInstance, property: string): void => {
|
|
12
|
+
SchemaRegistryIndex.getForRegister(getClass(instance)).registerField(property, ...configs);
|
|
11
13
|
};
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Registering a field
|
|
16
18
|
* @param type The type for the field
|
|
17
|
-
* @param
|
|
19
|
+
* @param configs The field configuration
|
|
18
20
|
* @augments `@travetto/schema:Input`
|
|
19
21
|
* @kind decorator
|
|
20
22
|
*/
|
|
21
|
-
export function Field(type: Pick<SchemaFieldConfig, 'type' | 'array'>, ...
|
|
22
|
-
return field(type, ...
|
|
23
|
+
export function Field(type: Pick<SchemaFieldConfig, 'type' | 'array'>, ...configs: Partial<SchemaFieldConfig>[]): PropType<unknown> {
|
|
24
|
+
return field(type, ...configs);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/**
|
package/src/decorator/input.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { Any, Class, ClassInstance, getClass } from '@travetto/runtime';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { CommonRegex } from '../validate/regex.ts';
|
|
4
4
|
import { CONSTRUCTOR_PROPERTY, SchemaInputConfig } from '../service/types.ts';
|
|
5
5
|
import { SchemaRegistryIndex } from '../service/registry-index.ts';
|
|
6
6
|
|
|
7
|
-
type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(
|
|
7
|
+
type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(
|
|
8
|
+
instance: T, property: K, idx?: TypedPropertyDescriptor<Any> | number
|
|
9
|
+
) => void);
|
|
8
10
|
|
|
9
|
-
function input<V>(...
|
|
10
|
-
return (instanceOrCls: ClassInstance | Class, property: string
|
|
11
|
+
function input<V>(...configs: Partial<SchemaInputConfig>[]): PropType<V> {
|
|
12
|
+
return (instanceOrCls: ClassInstance | Class, property: string, idx?: number | TypedPropertyDescriptor<Any>): void => {
|
|
11
13
|
const adapter = SchemaRegistryIndex.getForRegister(getClass(instanceOrCls));
|
|
12
14
|
const propertyKey = property ?? CONSTRUCTOR_PROPERTY;
|
|
13
15
|
if (typeof idx === 'number') {
|
|
14
|
-
adapter.registerParameter(propertyKey, idx, ...
|
|
16
|
+
adapter.registerParameter(propertyKey, idx, ...configs);
|
|
15
17
|
} else {
|
|
16
|
-
adapter.registerField(propertyKey, ...
|
|
18
|
+
adapter.registerField(propertyKey, ...configs);
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
21
|
}
|
|
@@ -21,12 +23,12 @@ function input<V>(...obj: Partial<SchemaInputConfig>[]): PropType<V> {
|
|
|
21
23
|
/**
|
|
22
24
|
* Registering an input
|
|
23
25
|
* @param type The type for the input
|
|
24
|
-
* @param
|
|
26
|
+
* @param configs The input configuration
|
|
25
27
|
* @augments `@travetto/schema:Input`
|
|
26
28
|
* @kind decorator
|
|
27
29
|
*/
|
|
28
|
-
export function Input(type: Pick<SchemaInputConfig, 'type' | 'array'>, ...
|
|
29
|
-
return input(type, ...
|
|
30
|
+
export function Input(type: Pick<SchemaInputConfig, 'type' | 'array'>, ...configs: Partial<SchemaInputConfig>[]): PropType<unknown> {
|
|
31
|
+
return input(type, ...configs);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -74,53 +76,53 @@ export function LongText(): PropType<string | string[]> { return input({ specifi
|
|
|
74
76
|
|
|
75
77
|
/**
|
|
76
78
|
* Require the input to match a specific RegExp
|
|
77
|
-
* @param
|
|
79
|
+
* @param regex The regular expression to match against
|
|
78
80
|
* @param message The message to show when the constraint fails
|
|
79
81
|
* @augments `@travetto/schema:Input`
|
|
80
82
|
* @kind decorator
|
|
81
83
|
*/
|
|
82
|
-
export function Match(
|
|
84
|
+
export function Match(regex: RegExp, message?: string): PropType<string | string[]> { return input({ match: { regex, message } }); }
|
|
83
85
|
|
|
84
86
|
/**
|
|
85
87
|
* The minimum length for the string or array
|
|
86
|
-
* @param
|
|
88
|
+
* @param limit The minimum length
|
|
87
89
|
* @param message The message to show when the constraint fails
|
|
88
90
|
* @augments `@travetto/schema:Input`
|
|
89
91
|
* @kind decorator
|
|
90
92
|
*/
|
|
91
|
-
export function MinLength(
|
|
92
|
-
return input({ minlength: {
|
|
93
|
+
export function MinLength(limit: number, message?: string): PropType<string | unknown[]> {
|
|
94
|
+
return input({ minlength: { limit, message }, ...(limit === 0 ? { required: { active: false } } : {}) });
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
/**
|
|
96
98
|
* The maximum length for the string or array
|
|
97
|
-
* @param
|
|
99
|
+
* @param limit The maximum length
|
|
98
100
|
* @param message The message to show when the constraint fails
|
|
99
101
|
* @augments `@travetto/schema:Input`
|
|
100
102
|
* @kind decorator
|
|
101
103
|
*/
|
|
102
|
-
export function MaxLength(
|
|
104
|
+
export function MaxLength(limit: number, message?: string): PropType<string | unknown[]> { return input({ maxlength: { limit, message } }); }
|
|
103
105
|
|
|
104
106
|
/**
|
|
105
107
|
* The minimum value
|
|
106
|
-
* @param
|
|
108
|
+
* @param limit The minimum value
|
|
107
109
|
* @param message The message to show when the constraint fails
|
|
108
110
|
* @augments `@travetto/schema:Input`
|
|
109
111
|
* @kind decorator
|
|
110
112
|
*/
|
|
111
|
-
export function Min<T extends number | Date>(
|
|
112
|
-
return input({ min: {
|
|
113
|
+
export function Min<T extends number | Date>(limit: T, message?: string): PropType<Date | number> {
|
|
114
|
+
return input({ min: { limit, message } });
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
/**
|
|
116
118
|
* The maximum value
|
|
117
|
-
* @param
|
|
119
|
+
* @param limit The maximum value
|
|
118
120
|
* @param message The message to show when the constraint fails
|
|
119
121
|
* @augments `@travetto/schema:Input`
|
|
120
122
|
* @kind decorator
|
|
121
123
|
*/
|
|
122
|
-
export function Max<T extends number | Date>(
|
|
123
|
-
return input({ max: {
|
|
124
|
+
export function Max<T extends number | Date>(limit: T, message?: string): PropType<Date | number> {
|
|
125
|
+
return input({ max: { limit, message } });
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
/**
|
|
@@ -129,7 +131,7 @@ export function Max<T extends number | Date>(n: T, message?: string): PropType<D
|
|
|
129
131
|
* @augments `@travetto/schema:Input`
|
|
130
132
|
* @kind decorator
|
|
131
133
|
*/
|
|
132
|
-
export function Email(message?: string): PropType<string | string[]> { return Match(
|
|
134
|
+
export function Email(message?: string): PropType<string | string[]> { return Match(CommonRegex.email, message); }
|
|
133
135
|
|
|
134
136
|
/**
|
|
135
137
|
* Mark an input as an telephone number
|
|
@@ -137,7 +139,7 @@ export function Email(message?: string): PropType<string | string[]> { return Ma
|
|
|
137
139
|
* @augments `@travetto/schema:Input`
|
|
138
140
|
* @kind decorator
|
|
139
141
|
*/
|
|
140
|
-
export function Telephone(message?: string): PropType<string | string[]> { return Match(
|
|
142
|
+
export function Telephone(message?: string): PropType<string | string[]> { return Match(CommonRegex.telephone, message); }
|
|
141
143
|
|
|
142
144
|
/**
|
|
143
145
|
* Mark an input as a url
|
|
@@ -145,7 +147,7 @@ export function Telephone(message?: string): PropType<string | string[]> { retur
|
|
|
145
147
|
* @augments `@travetto/schema:Input`
|
|
146
148
|
* @kind decorator
|
|
147
149
|
*/
|
|
148
|
-
export function Url(message?: string): PropType<string | string[]> { return Match(
|
|
150
|
+
export function Url(message?: string): PropType<string | string[]> { return Match(CommonRegex.url, message); }
|
|
149
151
|
|
|
150
152
|
/**
|
|
151
153
|
* Determine the numeric precision of the value
|
|
@@ -197,7 +199,7 @@ export function Specifier(...specifiers: string[]): PropType<unknown> { return i
|
|
|
197
199
|
* @augments `@travetto/schema:Input`
|
|
198
200
|
* @kind decorator
|
|
199
201
|
*/
|
|
200
|
-
export function DiscriminatorField(): ((
|
|
202
|
+
export function DiscriminatorField(): ((instance: ClassInstance, property: string) => void) {
|
|
201
203
|
return (instance: ClassInstance, property: string): void => {
|
|
202
204
|
SchemaRegistryIndex.getForRegister(getClass(instance)).register({
|
|
203
205
|
discriminatedBase: true,
|
package/src/decorator/method.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { SchemaMethodConfig } from '../service/types';
|
|
|
4
4
|
import { SchemaRegistryIndex } from '../service/registry-index';
|
|
5
5
|
import { MethodValidatorFn } from '../validate/types';
|
|
6
6
|
|
|
7
|
+
type MethodDecorator = (instance: ClassInstance, property: string, descriptor: PropertyDescriptor) => PropertyDescriptor | void;
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* Registering a method
|
|
9
11
|
* @param config The method configuration
|
|
@@ -11,7 +13,7 @@ import { MethodValidatorFn } from '../validate/types';
|
|
|
11
13
|
* @kind decorator
|
|
12
14
|
*/
|
|
13
15
|
export function Method(...config: Partial<SchemaMethodConfig>[]) {
|
|
14
|
-
return (instanceOrCls: ClassInstance, property: string
|
|
16
|
+
return (instanceOrCls: ClassInstance, property: string): void => {
|
|
15
17
|
SchemaRegistryIndex.getForRegister(getClass(instanceOrCls)).registerMethod(property, ...config);
|
|
16
18
|
};
|
|
17
19
|
}
|
package/src/decorator/schema.ts
CHANGED
|
@@ -16,12 +16,12 @@ type ValidStringField<T> = { [K in Extract<keyof T, string>]: T[K] extends strin
|
|
|
16
16
|
* @augments `@travetto/schema:Schema`
|
|
17
17
|
* @kind decorator
|
|
18
18
|
*/
|
|
19
|
-
export function Schema(
|
|
19
|
+
export function Schema(config?: Partial<Pick<SchemaClassConfig, 'validators' | 'methods'>>) {
|
|
20
20
|
return <T, U extends Class<T>>(cls: U): void => {
|
|
21
21
|
cls.from ??= function <V>(this: Class<V>, data: DeepPartial<V>, view?: string): V {
|
|
22
22
|
return BindUtil.bindSchema(this, data, { view });
|
|
23
23
|
};
|
|
24
|
-
SchemaRegistryIndex.getForRegister(cls).registerClass(
|
|
24
|
+
SchemaRegistryIndex.getForRegister(cls).registerClass(config);
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
|
package/src/internal/types.ts
CHANGED
|
@@ -3,9 +3,9 @@ import { DataUtil } from '../data.ts';
|
|
|
3
3
|
const InvalidSymbol = Symbol();
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Point
|
|
6
|
+
* Point Contract
|
|
7
7
|
*/
|
|
8
|
-
export class
|
|
8
|
+
export class PointContract {
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Validate we have an actual point
|
|
@@ -20,7 +20,7 @@ export class PointImpl {
|
|
|
20
20
|
*/
|
|
21
21
|
static bindSchema(input: unknown): [number, number] | typeof InvalidSymbol | undefined {
|
|
22
22
|
if (Array.isArray(input) && input.length === 2) {
|
|
23
|
-
const [a, b] = input.map(
|
|
23
|
+
const [a, b] = input.map(value => DataUtil.coerceType(value, Number, false));
|
|
24
24
|
return [a, b];
|
|
25
25
|
} else {
|
|
26
26
|
return InvalidSymbol;
|
|
@@ -28,4 +28,4 @@ export class PointImpl {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
Object.defineProperty(
|
|
31
|
+
Object.defineProperty(PointContract, 'name', { value: 'Point' });
|
package/src/name.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SchemaClassConfig } from './service/types.ts';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const ID_REGEX = /(\d{1,100})Δ$/;
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Name resolver, specifically for synthetic types
|
|
@@ -17,9 +17,9 @@ export class SchemaNameResolver {
|
|
|
17
17
|
getName(schema: SchemaClassConfig): string {
|
|
18
18
|
const cls = schema.class;
|
|
19
19
|
const id = cls.Ⲑid;
|
|
20
|
-
if (
|
|
20
|
+
if (ID_REGEX.test(cls.name)) {
|
|
21
21
|
if (!this.#schemaIdToName.has(id)) {
|
|
22
|
-
const name = cls.name.replace(
|
|
22
|
+
const name = cls.name.replace(ID_REGEX, (_, uniqueId) => uniqueId.slice(-this.#digits));
|
|
23
23
|
this.#schemaIdToName.set(id, name);
|
|
24
24
|
}
|
|
25
25
|
return this.#schemaIdToName.get(id)!;
|