@travetto/schema 3.1.0-rc.1 → 3.1.0-rc.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.
- package/README.md +35 -19
- package/package.json +2 -2
- package/src/decorator/field.ts +36 -43
package/README.md
CHANGED
|
@@ -62,25 +62,25 @@ User:
|
|
|
62
62
|
|
|
63
63
|
### Fields
|
|
64
64
|
This schema provides a powerful base for data binding and validation at runtime. Additionally there may be types that cannot be detected, or some information that the programmer would like to override. Below are the supported field decorators:
|
|
65
|
-
* [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
66
|
-
* [@Required](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
67
|
-
* [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
68
|
-
* [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
69
|
-
* [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
70
|
-
* [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
71
|
-
* [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
72
|
-
* [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
73
|
-
* [@Email](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
74
|
-
* [@Telephone](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
75
|
-
* [@Url](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
76
|
-
* [@Ignore](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
77
|
-
* [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
78
|
-
* [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
79
|
-
* [@Currency](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
80
|
-
* [@Text](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
81
|
-
* [@LongText](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
82
|
-
* [@Readonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
83
|
-
* [@Writeonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
65
|
+
* [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L31) defines a field that will be serialized.
|
|
66
|
+
* [@Required](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L71) defines a that field should be required
|
|
67
|
+
* [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L78) defines the allowable values that a field can have
|
|
68
|
+
* [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L99) defines a regular expression that the field value should match
|
|
69
|
+
* [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L107) enforces min length of a string
|
|
70
|
+
* [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L117) enforces max length of a string
|
|
71
|
+
* [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L107) enforces min value for a date or a number
|
|
72
|
+
* [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L117) enforces max value for a date or a number
|
|
73
|
+
* [@Email](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L144) ensures string field matches basic email regex
|
|
74
|
+
* [@Telephone](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L151) ensures string field matches basic telephone regex
|
|
75
|
+
* [@Url](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L158) ensures string field matches basic url regex
|
|
76
|
+
* [@Ignore](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L197) exclude from auto schema registration
|
|
77
|
+
* [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L172) ensures number passed in is only a whole number
|
|
78
|
+
* [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L178) ensures number passed in allows fractional values
|
|
79
|
+
* [@Currency](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L190) provides support for standard currency
|
|
80
|
+
* [@Text](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L86) indicates that a field is expecting natural language input, not just discrete values
|
|
81
|
+
* [@LongText](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L91) same as text, but expects longer form content
|
|
82
|
+
* [@Readonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L58) defines a that field should not be bindable external to the class
|
|
83
|
+
* [@Writeonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L52) defines a that field should not be exported in serialization, but that it can be bound to
|
|
84
84
|
Additionally, schemas can be nested to form more complex data structures that are able to bound and validated.
|
|
85
85
|
|
|
86
86
|
Just like the class, all fields can be defined with
|
|
@@ -88,6 +88,22 @@ Just like the class, all fields can be defined with
|
|
|
88
88
|
* `examples` - A set of examples as [JSON](https://www.json.org) or [YAML](https://en.wikipedia.org/wiki/YAML)
|
|
89
89
|
And similarly, the `description` will be picked up from the [JSDoc](http://usejsdoc.org/about-getting-started.html) comments, and additionally all fields can be set using the [@Describe](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/common.ts#L15) decorator.
|
|
90
90
|
|
|
91
|
+
### Parameters
|
|
92
|
+
Parameters are available in certain scenarios (e.g. [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") endpoints and [Command Line Interface](https://github.com/travetto/travetto/tree/main/module/cli#readme "CLI infrastructure for Travetto framework") main methods). In these scenarios, all of the field decorators are valid, but need to be called slightly differently to pass the typechecker. The simple solution is to use the `Arg` field of the decorator to convince Typescript its the correct type.
|
|
93
|
+
|
|
94
|
+
**Code: Sample Parameter Usage**
|
|
95
|
+
```typescript
|
|
96
|
+
import { Match, Min } from '../__index__';
|
|
97
|
+
|
|
98
|
+
const NAME_REGEX = /[A-Z][a-z]+(\s+[A-Z][a-z]+)*/;
|
|
99
|
+
|
|
100
|
+
export class ParamUsage {
|
|
101
|
+
main(@Match(NAME_REGEX).Param name: string, @Min(20).Param age?: number) {
|
|
102
|
+
console.log('Valid name and age!', { name, age });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
91
107
|
## Binding/Validation
|
|
92
108
|
At runtime, once a schema is registered, a programmer can utilize this structure to perform specific operations. Specifically binding and validation.
|
|
93
109
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/schema",
|
|
3
|
-
"version": "3.1.0-rc.
|
|
3
|
+
"version": "3.1.0-rc.2",
|
|
4
4
|
"description": "Data type registry for runtime validation, reflection and binding.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"schema",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@travetto/registry": "^3.1.0-rc.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@travetto/transformer": "^3.1.0-rc.
|
|
33
|
+
"@travetto/transformer": "^3.1.0-rc.1"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"@travetto/transformer": {
|
package/src/decorator/field.ts
CHANGED
|
@@ -4,30 +4,23 @@ import { SchemaRegistry } from '../service/registry';
|
|
|
4
4
|
import { CommonRegExp } from '../validate/regexp';
|
|
5
5
|
import { ClassList, FieldConfig } from '../service/types';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
type PropType<V> = (<T extends Partial<Record<K, V>>, K extends string>(t: T, k: K, idx?: number) => void) & {
|
|
8
|
+
Param: (t: unknown, k: string, idx: number) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function prop<V>(obj: Partial<FieldConfig>): PropType<V> {
|
|
12
|
+
const fn = (t: ClassInstance, k: string, idx?: number): void => {
|
|
9
13
|
if (idx !== undefined && typeof idx === 'number') {
|
|
10
14
|
SchemaRegistry.registerPendingParamFacet(t.constructor, k, idx, obj);
|
|
11
15
|
} else {
|
|
12
16
|
SchemaRegistry.registerPendingFieldFacet(t.constructor, k, obj);
|
|
13
17
|
}
|
|
14
18
|
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// eslint-disable-next-line max-len
|
|
18
|
-
const stringArrProp: (obj: Partial<FieldConfig>) => <T extends Partial<Record<K, string | unknown[]>>, K extends string>(t: T, k: K, idx?: number | PropertyDescriptor) => void = prop;
|
|
19
|
-
|
|
20
|
-
// eslint-disable-next-line max-len
|
|
21
|
-
const stringArrStringProp: (obj: Partial<FieldConfig>) => <T extends Partial<Record<K, string | string[]>>, K extends string>(t: T, k: K, idx?: number | PropertyDescriptor) => void = prop;
|
|
19
|
+
fn.Param = fn; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
22
20
|
|
|
23
|
-
// eslint-disable-next-line
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// eslint-disable-next-line max-len
|
|
27
|
-
const stringNumberProp: (obj: Partial<FieldConfig>) => <T extends Partial<Record<K, string | number>>, K extends string>(t: T, k: K, idx?: number | PropertyDescriptor) => void = prop;
|
|
28
|
-
|
|
29
|
-
// eslint-disable-next-line max-len
|
|
30
|
-
const dateNumberProp: (obj: Partial<FieldConfig>) => <T extends Partial<Record<K, Date | number>>, K extends string>(t: T, k: K, idx?: number | PropertyDescriptor) => void = prop;
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
22
|
+
return fn as PropType<V>;
|
|
23
|
+
}
|
|
31
24
|
|
|
32
25
|
/**
|
|
33
26
|
* Registering a field
|
|
@@ -36,7 +29,7 @@ const dateNumberProp: (obj: Partial<FieldConfig>) => <T extends Partial<Record<K
|
|
|
36
29
|
* @augments `@travetto/schema:Field`
|
|
37
30
|
*/
|
|
38
31
|
export function Field(type: ClassList, config?: Partial<FieldConfig>) {
|
|
39
|
-
return (f: ClassInstance, k: string, idx?: number
|
|
32
|
+
return (f: ClassInstance, k: string, idx?: number): void => {
|
|
40
33
|
if (idx !== undefined && typeof idx === 'number') {
|
|
41
34
|
SchemaRegistry.registerPendingParamConfig(f.constructor, k, idx, type, config);
|
|
42
35
|
} else {
|
|
@@ -50,52 +43,52 @@ export function Field(type: ClassList, config?: Partial<FieldConfig>) {
|
|
|
50
43
|
* @param aliases List of all aliases for a field
|
|
51
44
|
* @augments `@travetto/schema:Field`
|
|
52
45
|
*/
|
|
53
|
-
export function Alias(...aliases: string[]):
|
|
46
|
+
export function Alias(...aliases: string[]): PropType<unknown> { return prop({ aliases }); }
|
|
54
47
|
/**
|
|
55
48
|
* Mark a field as writeonly
|
|
56
49
|
* @param active This determines if this field is readonly or not.
|
|
57
50
|
* @augments `@travetto/schema:Field`
|
|
58
51
|
*/
|
|
59
|
-
export function Writeonly(active = true):
|
|
52
|
+
export function Writeonly(active = true): PropType<unknown> { return prop({ access: 'writeonly' }); }
|
|
60
53
|
/**
|
|
61
54
|
* Mark a field as readonly
|
|
62
55
|
* @param active This determines if this field is readonly or not.
|
|
63
56
|
* @augments `@travetto/schema:Field`
|
|
64
57
|
*/
|
|
65
|
-
export function Readonly(active = true):
|
|
58
|
+
export function Readonly(active = true): PropType<unknown> { return prop({ access: 'readonly' }); }
|
|
66
59
|
/**
|
|
67
60
|
* Mark a field as sensitive
|
|
68
61
|
* @param active This determines if this field is sensitive or not.
|
|
69
62
|
* @augments `@travetto/schema:Field`
|
|
70
63
|
*/
|
|
71
|
-
export function Secret(active = true):
|
|
64
|
+
export function Secret(active = true): PropType<unknown> { return prop({ secret: active }); }
|
|
72
65
|
/**
|
|
73
66
|
* Mark a field as required
|
|
74
67
|
* @param active This determines if this field is required or not.
|
|
75
68
|
* @param message The error message when a the constraint fails.
|
|
76
69
|
* @augments `@travetto/schema:Field`
|
|
77
70
|
*/
|
|
78
|
-
export function Required(active = true, message?: string):
|
|
71
|
+
export function Required(active = true, message?: string): PropType<unknown> { return prop({ required: { active, message } }); }
|
|
79
72
|
/**
|
|
80
73
|
* Define a field as a set of enumerated values
|
|
81
74
|
* @param values The list of values allowed for the enumeration
|
|
82
75
|
* @param message The error message to show when the constraint fails
|
|
83
76
|
* @augments `@travetto/schema:Field`
|
|
84
77
|
*/
|
|
85
|
-
export function Enum(values: string[], message?: string):
|
|
78
|
+
export function Enum(values: string[], message?: string): PropType<string | number> {
|
|
86
79
|
message = message || `{path} is only allowed to be "${values.join('" or "')}"`;
|
|
87
|
-
return
|
|
80
|
+
return prop({ enum: { values, message } });
|
|
88
81
|
}
|
|
89
82
|
/**
|
|
90
83
|
* Mark the field as indicating it's storing textual data
|
|
91
84
|
* @augments `@travetto/schema:Field`
|
|
92
85
|
*/
|
|
93
|
-
export function Text():
|
|
86
|
+
export function Text(): PropType<string | string[]> { return prop({ specifier: 'text' }); }
|
|
94
87
|
/**
|
|
95
88
|
* Mark the field to indicate it's for long form text
|
|
96
89
|
* @augments `@travetto/schema:Field`
|
|
97
90
|
*/
|
|
98
|
-
export function LongText():
|
|
91
|
+
export function LongText(): PropType<string | string[]> { return prop({ specifier: 'text-long' }); }
|
|
99
92
|
|
|
100
93
|
/**
|
|
101
94
|
* Require the field to match a specific RegExp
|
|
@@ -103,7 +96,7 @@ export function LongText(): ReturnType<typeof stringArrStringProp> { return stri
|
|
|
103
96
|
* @param message The message to show when the constraint fails
|
|
104
97
|
* @augments `@travetto/schema:Field`
|
|
105
98
|
*/
|
|
106
|
-
export function Match(re: RegExp, message?: string):
|
|
99
|
+
export function Match(re: RegExp, message?: string): PropType<string | string[]> { return prop({ match: { re, message } }); }
|
|
107
100
|
|
|
108
101
|
/**
|
|
109
102
|
* The minimum length for the string or array
|
|
@@ -111,8 +104,8 @@ export function Match(re: RegExp, message?: string): ReturnType<typeof stringArr
|
|
|
111
104
|
* @param message The message to show when the constraint fails
|
|
112
105
|
* @augments `@travetto/schema:Field`
|
|
113
106
|
*/
|
|
114
|
-
export function MinLength(n: number, message?: string):
|
|
115
|
-
return
|
|
107
|
+
export function MinLength(n: number, message?: string): PropType<string | unknown[]> {
|
|
108
|
+
return prop({ minlength: { n, message }, ...(n === 0 ? { required: { active: false } } : {}) });
|
|
116
109
|
}
|
|
117
110
|
|
|
118
111
|
/**
|
|
@@ -121,7 +114,7 @@ export function MinLength(n: number, message?: string): ReturnType<typeof string
|
|
|
121
114
|
* @param message The message to show when the constraint fails
|
|
122
115
|
* @augments `@travetto/schema:Field`
|
|
123
116
|
*/
|
|
124
|
-
export function MaxLength(n: number, message?: string):
|
|
117
|
+
export function MaxLength(n: number, message?: string): PropType<string | unknown[]> { return prop({ maxlength: { n, message } }); }
|
|
125
118
|
|
|
126
119
|
/**
|
|
127
120
|
* The minimum value
|
|
@@ -129,8 +122,8 @@ export function MaxLength(n: number, message?: string): ReturnType<typeof string
|
|
|
129
122
|
* @param message The message to show when the constraint fails
|
|
130
123
|
* @augments `@travetto/schema:Field`
|
|
131
124
|
*/
|
|
132
|
-
export function Min<T extends number | Date>(n: T, message?: string):
|
|
133
|
-
return
|
|
125
|
+
export function Min<T extends number | Date>(n: T, message?: string): PropType<Date | number> {
|
|
126
|
+
return prop({ min: { n, message } });
|
|
134
127
|
}
|
|
135
128
|
|
|
136
129
|
/**
|
|
@@ -139,8 +132,8 @@ export function Min<T extends number | Date>(n: T, message?: string): ReturnType
|
|
|
139
132
|
* @param message The message to show when the constraint fails
|
|
140
133
|
* @augments `@travetto/schema:Field`
|
|
141
134
|
*/
|
|
142
|
-
export function Max<T extends number | Date>(n: T, message?: string):
|
|
143
|
-
return
|
|
135
|
+
export function Max<T extends number | Date>(n: T, message?: string): PropType<Date | number> {
|
|
136
|
+
return prop({ max: { n, message } });
|
|
144
137
|
}
|
|
145
138
|
|
|
146
139
|
/**
|
|
@@ -148,21 +141,21 @@ export function Max<T extends number | Date>(n: T, message?: string): ReturnType
|
|
|
148
141
|
* @param message The message to show when the constraint fails
|
|
149
142
|
* @augments `@travetto/schema:Field`
|
|
150
143
|
*/
|
|
151
|
-
export function Email(message?: string):
|
|
144
|
+
export function Email(message?: string): PropType<string | string[]> { return Match(CommonRegExp.email, message); }
|
|
152
145
|
|
|
153
146
|
/**
|
|
154
147
|
* Mark a field as an telephone number
|
|
155
148
|
* @param message The message to show when the constraint fails
|
|
156
149
|
* @augments `@travetto/schema:Field`
|
|
157
150
|
*/
|
|
158
|
-
export function Telephone(message?: string):
|
|
151
|
+
export function Telephone(message?: string): PropType<string | string[]> { return Match(CommonRegExp.telephone, message); }
|
|
159
152
|
|
|
160
153
|
/**
|
|
161
154
|
* Mark a field as a url
|
|
162
155
|
* @param message The message to show when the constraint fails
|
|
163
156
|
* @augments `@travetto/schema:Field`
|
|
164
157
|
*/
|
|
165
|
-
export function Url(message?: string):
|
|
158
|
+
export function Url(message?: string): PropType<string | string[]> { return Match(CommonRegExp.url, message); }
|
|
166
159
|
|
|
167
160
|
/**
|
|
168
161
|
* Determine the numeric precision of the value
|
|
@@ -170,31 +163,31 @@ export function Url(message?: string): ReturnType<typeof Match> { return Match(C
|
|
|
170
163
|
* @param decimals The number of decimal digits to support
|
|
171
164
|
* @augments `@travetto/schema:Field`
|
|
172
165
|
*/
|
|
173
|
-
export function Precision(digits: number, decimals?: number):
|
|
166
|
+
export function Precision(digits: number, decimals?: number): PropType<number> { return prop({ precision: [digits, decimals] }); }
|
|
174
167
|
|
|
175
168
|
/**
|
|
176
169
|
* Mark a number as an integer
|
|
177
170
|
* @augments `@travetto/schema:Field`
|
|
178
171
|
*/
|
|
179
|
-
export function Integer():
|
|
172
|
+
export function Integer(): PropType<number> { return Precision(0); }
|
|
180
173
|
|
|
181
174
|
/**
|
|
182
175
|
* Mark a number as a float
|
|
183
176
|
* @augments `@travetto/schema:Field`
|
|
184
177
|
*/
|
|
185
|
-
export function Float():
|
|
178
|
+
export function Float(): PropType<number> { return Precision(10, 7); }
|
|
186
179
|
|
|
187
180
|
/**
|
|
188
181
|
* Mark a number as a long value
|
|
189
182
|
* @augments `@travetto/schema:Field`
|
|
190
183
|
*/
|
|
191
|
-
export function Long():
|
|
184
|
+
export function Long(): PropType<number> { return Precision(19, 0); }
|
|
192
185
|
|
|
193
186
|
/**
|
|
194
187
|
* Mark a number as a currency
|
|
195
188
|
* @augments `@travetto/schema:Field`
|
|
196
189
|
*/
|
|
197
|
-
export function Currency():
|
|
190
|
+
export function Currency(): PropType<number> { return Precision(13, 2); }
|
|
198
191
|
|
|
199
192
|
/**
|
|
200
193
|
* Mark a field as ignored
|