@cleverbrush/schema 0.0.17 → 1.0.0-beta.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/README.md +213 -163
- package/package.json +3 -3
- package/src/builders/ArraySchemaBuilder.test.ts +270 -0
- package/src/builders/ArraySchemaBuilder.ts +381 -0
- package/src/builders/BooleanSchemaBuilder.test.ts +196 -0
- package/src/builders/BooleanSchemaBuilder.ts +155 -0
- package/src/builders/FunctionSchemaBuilder.test.ts +134 -0
- package/src/builders/FunctionSchemaBuilder.ts +109 -0
- package/src/builders/NumberSchemaBuilder.test.ts +493 -0
- package/src/builders/NumberSchemaBuilder.ts +789 -0
- package/src/builders/ObjectSchemaBuilder.test.ts +657 -0
- package/src/builders/ObjectSchemaBuilder.ts +794 -0
- package/src/builders/SchemaBuilder.test.ts +73 -0
- package/src/builders/SchemaBuilder.ts +135 -0
- package/src/builders/StringSchemaBuilder.test.ts +318 -0
- package/src/builders/StringSchemaBuilder.ts +392 -0
- package/src/builders/UnionSchemaBuilder.test.ts +162 -0
- package/src/builders/UnionSchemaBuilder.ts +154 -0
- package/src/defaultSchemas.ts +44 -0
- package/src/index.ts +58 -190
- package/src/schema.ts +827 -0
- package/src/schemaRegistry.builders.test.ts +1393 -0
- package/src/schemaRegistry.test.ts +118 -0
- package/src/schemaRegistry.ts +461 -0
- package/src/validators/validateArray.ts +4 -7
- package/src/validators/validateBoolean.ts +2 -11
- package/src/validators/validateFunction.ts +25 -0
- package/src/validators/validateNumber.ts +2 -7
- package/src/validators/validateObject.ts +32 -21
- package/src/validators/validateString.ts +2 -7
- package/src/validators/validateUnion.ts +36 -0
- package/dist/index.d.ts +0 -94
- package/dist/index.js +0 -9
- package/dist/schemaValidator.d.ts +0 -16
- package/dist/schemaValidator.js +0 -234
- package/dist/validators/validateArray.d.ts +0 -2
- package/dist/validators/validateArray.js +0 -60
- package/dist/validators/validateBoolean.d.ts +0 -2
- package/dist/validators/validateBoolean.js +0 -33
- package/dist/validators/validateNumber.d.ts +0 -2
- package/dist/validators/validateNumber.js +0 -69
- package/dist/validators/validateObject.d.ts +0 -2
- package/dist/validators/validateObject.js +0 -73
- package/dist/validators/validateString.d.ts +0 -2
- package/dist/validators/validateString.js +0 -50
- package/src/schemaValidator.test.ts +0 -1656
- package/src/schemaValidator.ts +0 -367
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { deepEqual } from '@cleverbrush/deep';
|
|
2
|
+
|
|
3
|
+
import { Schema } from '../schema.js';
|
|
4
|
+
import { boolean } from './BooleanSchemaBuilder.js';
|
|
5
|
+
|
|
6
|
+
test('Clean', () => {
|
|
7
|
+
const schema = boolean();
|
|
8
|
+
expect(schema).toHaveProperty('type', 'boolean');
|
|
9
|
+
expect(schema).toHaveProperty('isRequired', true);
|
|
10
|
+
expect(schema).toHaveProperty('isNullable', false);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('optional', () => {
|
|
14
|
+
const schema = boolean().optional();
|
|
15
|
+
expect(schema).toHaveProperty('type', 'boolean');
|
|
16
|
+
expect(schema).toHaveProperty('isRequired', false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('optional - 2', () => {
|
|
20
|
+
const schema = boolean().optional().required();
|
|
21
|
+
expect(schema).toHaveProperty('type', 'boolean');
|
|
22
|
+
expect(schema).toHaveProperty('isRequired', true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('optional - 3', () => {
|
|
26
|
+
const schema1 = boolean();
|
|
27
|
+
const schema2 = schema1.optional();
|
|
28
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
29
|
+
const isRequiredEqual = (schema1 as any).isRequired !== schema2.isRequired;
|
|
30
|
+
expect(e).toEqual(false);
|
|
31
|
+
expect(isRequiredEqual).toEqual(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('optional - 4', () => {
|
|
35
|
+
const schema1 = boolean().optional();
|
|
36
|
+
const schema2 = schema1.optional();
|
|
37
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
38
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
39
|
+
expect(e).toEqual(true);
|
|
40
|
+
expect(isRequiredEqual).toEqual(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('optional - 5', () => {
|
|
44
|
+
const schema1 = boolean();
|
|
45
|
+
const schema2 = schema1.required();
|
|
46
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
47
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
48
|
+
expect(e).toEqual(true);
|
|
49
|
+
expect(isRequiredEqual).toEqual(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('optional - 6', () => {
|
|
53
|
+
const schema1 = boolean().optional();
|
|
54
|
+
const schema2 = schema1.required();
|
|
55
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
56
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
57
|
+
expect(e).toEqual(false);
|
|
58
|
+
expect(isRequiredEqual).toEqual(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('optional - 7', () => {
|
|
62
|
+
const schema1 = boolean().optional().required();
|
|
63
|
+
const schema2 = schema1.required();
|
|
64
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
65
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
66
|
+
expect(e).toEqual(true);
|
|
67
|
+
expect(isRequiredEqual).toEqual(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('nullable', () => {
|
|
71
|
+
const schema = boolean().nullable();
|
|
72
|
+
expect(schema).toHaveProperty('type', 'boolean');
|
|
73
|
+
expect(schema).toHaveProperty('isNullable', true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('nullable - 2', () => {
|
|
77
|
+
const schema = boolean().nullable().notNullable();
|
|
78
|
+
expect(schema).toHaveProperty('type', 'boolean');
|
|
79
|
+
expect(schema).toHaveProperty('isNullable', false);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('nullable - 3', () => {
|
|
83
|
+
const schema1 = boolean();
|
|
84
|
+
const schema2 = schema1.nullable();
|
|
85
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
86
|
+
const isNullableEqual = (schema1 as any).isNullable !== schema2.isNullable;
|
|
87
|
+
expect(e).toEqual(false);
|
|
88
|
+
expect(isNullableEqual).toEqual(true);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('nullable - 4', () => {
|
|
92
|
+
const schema1 = boolean().nullable();
|
|
93
|
+
const schema2 = schema1.nullable();
|
|
94
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
95
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
96
|
+
expect(e).toEqual(true);
|
|
97
|
+
expect(isNullableEqual).toEqual(true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('nullable - 5', () => {
|
|
101
|
+
const schema1 = boolean();
|
|
102
|
+
const schema2 = schema1.nullable();
|
|
103
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
104
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
105
|
+
expect(e).toEqual(false);
|
|
106
|
+
expect(isNullableEqual).toEqual(false);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('nullable - 6', () => {
|
|
110
|
+
const schema1 = boolean();
|
|
111
|
+
const schema2 = schema1.notNullable();
|
|
112
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
113
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
114
|
+
expect(e).toEqual(true);
|
|
115
|
+
expect(isNullableEqual).toEqual(true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('nullable - 7', () => {
|
|
119
|
+
const schema1 = boolean().nullable();
|
|
120
|
+
const schema2 = schema1.notNullable();
|
|
121
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
122
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
123
|
+
expect(e).toEqual(false);
|
|
124
|
+
expect(isNullableEqual).toEqual(false);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('equals - 1', () => {
|
|
128
|
+
const schema = boolean().equals(true);
|
|
129
|
+
expect(schema._schema).toHaveProperty('type', 'boolean');
|
|
130
|
+
expect(schema._schema).toHaveProperty('equals', true);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('equals - 2', () => {
|
|
134
|
+
const schema = boolean().equals(false);
|
|
135
|
+
expect(schema._schema).toHaveProperty('type', 'boolean');
|
|
136
|
+
expect(schema._schema).toHaveProperty('equals', false);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('equals - 3', () => {
|
|
140
|
+
const schema = boolean();
|
|
141
|
+
expect(schema._schema).toHaveProperty('type', 'boolean');
|
|
142
|
+
expect(schema._schema).not.toHaveProperty('equals');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('equals - 4', () => {
|
|
146
|
+
const schema = boolean().equals(true).clearEqualsTo();
|
|
147
|
+
expect(schema._schema).toHaveProperty('type', 'boolean');
|
|
148
|
+
expect(schema._schema).not.toHaveProperty('equals');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('equals - 5', () => {
|
|
152
|
+
const schema1 = boolean().equals(true);
|
|
153
|
+
const schema2 = schema1.equals(true);
|
|
154
|
+
const equal = (schema1 as any) === schema2;
|
|
155
|
+
expect(equal).toEqual(true);
|
|
156
|
+
expect(schema1._schema).toHaveProperty('equals', true);
|
|
157
|
+
expect(schema2._schema).toHaveProperty('equals', true);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('equals - 6', () => {
|
|
161
|
+
const schema1 = boolean();
|
|
162
|
+
const schema2 = schema1.equals(true);
|
|
163
|
+
const equal = (schema1 as any) === schema2;
|
|
164
|
+
expect(equal).toEqual(false);
|
|
165
|
+
expect(schema1._schema).not.toHaveProperty('equals');
|
|
166
|
+
expect(schema2._schema).toHaveProperty('equals', true);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('equals - 7', () => {
|
|
170
|
+
const schema1 = boolean();
|
|
171
|
+
const schema2 = schema1.clearEqualsTo();
|
|
172
|
+
const equal = (schema1 as any) === schema2;
|
|
173
|
+
expect(equal).toEqual(true);
|
|
174
|
+
expect(schema1._schema).not.toHaveProperty('equals');
|
|
175
|
+
expect(schema2._schema).not.toHaveProperty('equals');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test('equals - 8', () => {
|
|
179
|
+
const schema1 = boolean().clearEqualsTo();
|
|
180
|
+
const schema2 = schema1.equals(false);
|
|
181
|
+
const equal = (schema1 as any) === schema2;
|
|
182
|
+
expect(equal).toEqual(false);
|
|
183
|
+
expect(schema1._schema).not.toHaveProperty('equals');
|
|
184
|
+
expect(schema2._schema).toHaveProperty('equals', false);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('Clone', () => {
|
|
188
|
+
const schema1 = boolean()
|
|
189
|
+
.addValidator(() => ({ valid: true }))
|
|
190
|
+
.equals(true);
|
|
191
|
+
const schema2 = schema1.clone();
|
|
192
|
+
const equal = (schema1 as any) === schema2;
|
|
193
|
+
expect(equal).toEqual(false);
|
|
194
|
+
const equal2 = deepEqual(schema1._schema, schema2._schema);
|
|
195
|
+
expect(equal2).toEqual(true);
|
|
196
|
+
});
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Schema, Validator } from '../schema.js';
|
|
2
|
+
import { ISchemaBuilder, SchemaBuilder } from './SchemaBuilder.js';
|
|
3
|
+
import { defaultSchemas } from '../defaultSchemas.js';
|
|
4
|
+
|
|
5
|
+
export interface IBooleanSchemaBuilder<
|
|
6
|
+
TRequired extends boolean = true,
|
|
7
|
+
TNullable extends boolean = false,
|
|
8
|
+
TEqualsTo extends boolean | undefined = undefined
|
|
9
|
+
> extends ISchemaBuilder<TRequired, TNullable> {
|
|
10
|
+
equals<T extends boolean>(
|
|
11
|
+
val: T
|
|
12
|
+
): IBooleanSchemaBuilder<TRequired, TNullable, T>;
|
|
13
|
+
clearEqualsTo(): IBooleanSchemaBuilder<TRequired, TNullable, undefined>;
|
|
14
|
+
optional(): IBooleanSchemaBuilder<false, TNullable, TEqualsTo>;
|
|
15
|
+
required(): IBooleanSchemaBuilder<true, TNullable, TEqualsTo>;
|
|
16
|
+
nullable(): IBooleanSchemaBuilder<TRequired, true, TEqualsTo>;
|
|
17
|
+
notNullable(): IBooleanSchemaBuilder<TRequired, false, TEqualsTo>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class BooleanSchemaBuilder<
|
|
21
|
+
TRequired extends boolean = true,
|
|
22
|
+
TNullable extends boolean = false,
|
|
23
|
+
TEqualsTo extends boolean | undefined = undefined
|
|
24
|
+
>
|
|
25
|
+
extends SchemaBuilder<TRequired, TNullable>
|
|
26
|
+
implements IBooleanSchemaBuilder<TRequired, TNullable, TEqualsTo>
|
|
27
|
+
{
|
|
28
|
+
protected readonly type = 'boolean';
|
|
29
|
+
|
|
30
|
+
public get _schema(): Schema {
|
|
31
|
+
return Object.assign(
|
|
32
|
+
{
|
|
33
|
+
type: this.type
|
|
34
|
+
},
|
|
35
|
+
this.getCommonSchema(),
|
|
36
|
+
typeof this._equals !== 'undefined' ? { equals: this._equals } : {}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public clone(): this {
|
|
41
|
+
return BooleanSchemaBuilder.create(this._schema as any) as this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public static create<
|
|
45
|
+
TRequired extends boolean = true,
|
|
46
|
+
TNullable extends boolean = false,
|
|
47
|
+
TEqualsTo extends boolean | undefined = undefined
|
|
48
|
+
>(obj?: {
|
|
49
|
+
isRequired: TRequired;
|
|
50
|
+
isNullable: TNullable;
|
|
51
|
+
equals?: TEqualsTo;
|
|
52
|
+
validators?: Validator[];
|
|
53
|
+
preprocessor?:
|
|
54
|
+
| ((value: unknown) => unknown | Promise<unknown>)
|
|
55
|
+
| string;
|
|
56
|
+
}): IBooleanSchemaBuilder<TRequired, TNullable, TEqualsTo> {
|
|
57
|
+
return new BooleanSchemaBuilder(obj as any);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private constructor(obj: {
|
|
61
|
+
isRequired: TRequired;
|
|
62
|
+
isNullable: TNullable;
|
|
63
|
+
equals: TEqualsTo;
|
|
64
|
+
validators?: Validator[];
|
|
65
|
+
preprocessor?:
|
|
66
|
+
| ((value: unknown) => unknown | Promise<unknown>)
|
|
67
|
+
| string;
|
|
68
|
+
}) {
|
|
69
|
+
super(obj);
|
|
70
|
+
if (typeof obj === 'object' && obj) {
|
|
71
|
+
if (typeof obj.equals !== 'undefined') {
|
|
72
|
+
this._equals = obj.equals;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
const defaultSchema = defaultSchemas['boolean'] as any;
|
|
76
|
+
this.isRequired = defaultSchema.isRequired;
|
|
77
|
+
this.isNullable = defaultSchema.isNullable;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
protected _equals?: TEqualsTo;
|
|
82
|
+
|
|
83
|
+
equals<T extends boolean>(
|
|
84
|
+
val: T
|
|
85
|
+
): IBooleanSchemaBuilder<TRequired, TNullable, T> {
|
|
86
|
+
if ((this._equals as any) === val) {
|
|
87
|
+
return this as any as IBooleanSchemaBuilder<
|
|
88
|
+
TRequired,
|
|
89
|
+
TNullable,
|
|
90
|
+
T
|
|
91
|
+
>;
|
|
92
|
+
}
|
|
93
|
+
return BooleanSchemaBuilder.create({
|
|
94
|
+
...(this._schema as any),
|
|
95
|
+
equals: val
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
clearEqualsTo(): IBooleanSchemaBuilder<TRequired, TNullable, undefined> {
|
|
100
|
+
if (typeof this._equals === 'undefined') {
|
|
101
|
+
return this as IBooleanSchemaBuilder<
|
|
102
|
+
TRequired,
|
|
103
|
+
TNullable,
|
|
104
|
+
undefined
|
|
105
|
+
>;
|
|
106
|
+
}
|
|
107
|
+
return BooleanSchemaBuilder.create({
|
|
108
|
+
...(this._schema as any),
|
|
109
|
+
equals: undefined
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
optional(): IBooleanSchemaBuilder<false, TNullable, TEqualsTo> {
|
|
114
|
+
if (this.isRequired === false) {
|
|
115
|
+
return this as IBooleanSchemaBuilder<false, TNullable, TEqualsTo>;
|
|
116
|
+
}
|
|
117
|
+
return BooleanSchemaBuilder.create({
|
|
118
|
+
...(this._schema as any),
|
|
119
|
+
isRequired: false
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
required(): IBooleanSchemaBuilder<true, TNullable, TEqualsTo> {
|
|
124
|
+
if (this.isRequired === true) {
|
|
125
|
+
return this as IBooleanSchemaBuilder<true, TNullable, TEqualsTo>;
|
|
126
|
+
}
|
|
127
|
+
return BooleanSchemaBuilder.create({
|
|
128
|
+
...(this._schema as any),
|
|
129
|
+
isRequired: true
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
nullable(): IBooleanSchemaBuilder<TRequired, true, TEqualsTo> {
|
|
134
|
+
if (this.isNullable === true) {
|
|
135
|
+
return this as IBooleanSchemaBuilder<TRequired, true, TEqualsTo>;
|
|
136
|
+
}
|
|
137
|
+
return BooleanSchemaBuilder.create({
|
|
138
|
+
...(this._schema as any),
|
|
139
|
+
isNullable: true
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
notNullable(): IBooleanSchemaBuilder<TRequired, false, TEqualsTo> {
|
|
144
|
+
if (this.isNullable === false) {
|
|
145
|
+
return this as IBooleanSchemaBuilder<TRequired, false, TEqualsTo>;
|
|
146
|
+
}
|
|
147
|
+
return BooleanSchemaBuilder.create({
|
|
148
|
+
...(this._schema as any),
|
|
149
|
+
isNullable: false
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const boolean = (): IBooleanSchemaBuilder =>
|
|
155
|
+
BooleanSchemaBuilder.create();
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { deepEqual } from '@cleverbrush/deep';
|
|
2
|
+
|
|
3
|
+
import { Schema } from '../schema.js';
|
|
4
|
+
import { func } from './FunctionSchemaBuilder.js';
|
|
5
|
+
|
|
6
|
+
test('Clean', () => {
|
|
7
|
+
const schema = func();
|
|
8
|
+
expect(schema).toHaveProperty('type', 'function');
|
|
9
|
+
expect(schema).toHaveProperty('isRequired', true);
|
|
10
|
+
expect(schema).toHaveProperty('isNullable', false);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('optional', () => {
|
|
14
|
+
const schema = func().optional();
|
|
15
|
+
expect(schema).toHaveProperty('type', 'function');
|
|
16
|
+
expect(schema).toHaveProperty('isRequired', false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('optional - 2', () => {
|
|
20
|
+
const schema = func().optional().required();
|
|
21
|
+
expect(schema).toHaveProperty('type', 'function');
|
|
22
|
+
expect(schema).toHaveProperty('isRequired', true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('optional - 3', () => {
|
|
26
|
+
const schema1 = func();
|
|
27
|
+
const schema2 = schema1.optional();
|
|
28
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
29
|
+
const isRequiredEqual = (schema1 as any).isRequired !== schema2.isRequired;
|
|
30
|
+
expect(e).toEqual(false);
|
|
31
|
+
expect(isRequiredEqual).toEqual(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('optional - 4', () => {
|
|
35
|
+
const schema1 = func().optional();
|
|
36
|
+
const schema2 = schema1.optional();
|
|
37
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
38
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
39
|
+
expect(e).toEqual(true);
|
|
40
|
+
expect(isRequiredEqual).toEqual(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('optional - 5', () => {
|
|
44
|
+
const schema1 = func();
|
|
45
|
+
const schema2 = schema1.required();
|
|
46
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
47
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
48
|
+
expect(e).toEqual(true);
|
|
49
|
+
expect(isRequiredEqual).toEqual(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('optional - 6', () => {
|
|
53
|
+
const schema1 = func().optional();
|
|
54
|
+
const schema2 = schema1.required();
|
|
55
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
56
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
57
|
+
expect(e).toEqual(false);
|
|
58
|
+
expect(isRequiredEqual).toEqual(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('optional - 7', () => {
|
|
62
|
+
const schema1 = func().optional().required();
|
|
63
|
+
const schema2 = schema1.required();
|
|
64
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
65
|
+
const isRequiredEqual = (schema1 as any).isRequired === schema2.isRequired;
|
|
66
|
+
expect(e).toEqual(true);
|
|
67
|
+
expect(isRequiredEqual).toEqual(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('nullable', () => {
|
|
71
|
+
const schema = func().nullable();
|
|
72
|
+
expect(schema).toHaveProperty('type', 'function');
|
|
73
|
+
expect(schema).toHaveProperty('isNullable', true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('nullable - 2', () => {
|
|
77
|
+
const schema = func().nullable().notNullable();
|
|
78
|
+
expect(schema).toHaveProperty('type', 'function');
|
|
79
|
+
expect(schema).toHaveProperty('isNullable', false);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('nullable - 3', () => {
|
|
83
|
+
const schema1 = func();
|
|
84
|
+
const schema2 = schema1.nullable();
|
|
85
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
86
|
+
const isNullableEqual = (schema1 as any).isNullable !== schema2.isNullable;
|
|
87
|
+
expect(e).toEqual(false);
|
|
88
|
+
expect(isNullableEqual).toEqual(true);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('nullable - 4', () => {
|
|
92
|
+
const schema1 = func().nullable();
|
|
93
|
+
const schema2 = schema1.nullable();
|
|
94
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
95
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
96
|
+
expect(e).toEqual(true);
|
|
97
|
+
expect(isNullableEqual).toEqual(true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('nullable - 5', () => {
|
|
101
|
+
const schema1 = func();
|
|
102
|
+
const schema2 = schema1.nullable();
|
|
103
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
104
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
105
|
+
expect(e).toEqual(false);
|
|
106
|
+
expect(isNullableEqual).toEqual(false);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('nullable - 6', () => {
|
|
110
|
+
const schema1 = func();
|
|
111
|
+
const schema2 = schema1.notNullable();
|
|
112
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
113
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
114
|
+
expect(e).toEqual(true);
|
|
115
|
+
expect(isNullableEqual).toEqual(true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('nullable - 7', () => {
|
|
119
|
+
const schema1 = func().nullable();
|
|
120
|
+
const schema2 = schema1.notNullable();
|
|
121
|
+
const e = (schema1 as Schema) === (schema2 as Schema);
|
|
122
|
+
const isNullableEqual = (schema1 as any).isNullable === schema2.isNullable;
|
|
123
|
+
expect(e).toEqual(false);
|
|
124
|
+
expect(isNullableEqual).toEqual(false);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('Clone', () => {
|
|
128
|
+
const schema1 = func().addValidator(() => ({ valid: true }));
|
|
129
|
+
const schema2 = schema1.clone();
|
|
130
|
+
const equal = (schema1 as any) === schema2;
|
|
131
|
+
expect(equal).toEqual(false);
|
|
132
|
+
const equal2 = deepEqual(schema1._schema, schema2._schema);
|
|
133
|
+
expect(equal2).toEqual(true);
|
|
134
|
+
});
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Schema, Validator } from '../schema.js';
|
|
2
|
+
import { ISchemaBuilder, SchemaBuilder } from './SchemaBuilder.js';
|
|
3
|
+
import { defaultSchemas } from '../defaultSchemas.js';
|
|
4
|
+
|
|
5
|
+
export interface IFunctionSchemaBuilder<
|
|
6
|
+
TRequired extends boolean = true,
|
|
7
|
+
TNullable extends boolean = false
|
|
8
|
+
> extends ISchemaBuilder<TRequired, TNullable> {
|
|
9
|
+
optional(): IFunctionSchemaBuilder<false, TNullable>;
|
|
10
|
+
required(): IFunctionSchemaBuilder<true, TNullable>;
|
|
11
|
+
nullable(): IFunctionSchemaBuilder<TRequired, true>;
|
|
12
|
+
notNullable(): IFunctionSchemaBuilder<TRequired, false>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class FunctionSchemaBuilder<
|
|
16
|
+
TRequired extends boolean = true,
|
|
17
|
+
TNullable extends boolean = false
|
|
18
|
+
>
|
|
19
|
+
extends SchemaBuilder<TRequired, TNullable>
|
|
20
|
+
implements IFunctionSchemaBuilder<TRequired, TNullable>
|
|
21
|
+
{
|
|
22
|
+
protected readonly type = 'function';
|
|
23
|
+
|
|
24
|
+
public get _schema(): Schema {
|
|
25
|
+
return Object.assign(
|
|
26
|
+
{
|
|
27
|
+
type: this.type
|
|
28
|
+
},
|
|
29
|
+
this.getCommonSchema()
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public clone(): this {
|
|
34
|
+
return FunctionSchemaBuilder.create(this._schema as any) as this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public static create<
|
|
38
|
+
TRequired extends boolean = true,
|
|
39
|
+
TNullable extends boolean = false
|
|
40
|
+
>(obj?: {
|
|
41
|
+
isRequired: TRequired;
|
|
42
|
+
isNullable: TNullable;
|
|
43
|
+
validators?: Validator[];
|
|
44
|
+
preprocessor?:
|
|
45
|
+
| ((value: unknown) => unknown | Promise<unknown>)
|
|
46
|
+
| string;
|
|
47
|
+
}): IFunctionSchemaBuilder<TRequired, TNullable> {
|
|
48
|
+
return new FunctionSchemaBuilder(obj as any);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private constructor(obj: {
|
|
52
|
+
isRequired: TRequired;
|
|
53
|
+
isNullable: TNullable;
|
|
54
|
+
validators?: Validator[];
|
|
55
|
+
preprocessor?:
|
|
56
|
+
| ((value: unknown) => unknown | Promise<unknown>)
|
|
57
|
+
| string;
|
|
58
|
+
}) {
|
|
59
|
+
super(obj);
|
|
60
|
+
if (typeof obj !== 'object' || !obj) {
|
|
61
|
+
const defaultSchema = defaultSchemas['function'] as any;
|
|
62
|
+
this.isRequired = defaultSchema.isRequired;
|
|
63
|
+
this.isNullable = defaultSchema.isNullable;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
optional(): IFunctionSchemaBuilder<false, TNullable> {
|
|
68
|
+
if (this.isRequired === false) {
|
|
69
|
+
return this as IFunctionSchemaBuilder<false, TNullable>;
|
|
70
|
+
}
|
|
71
|
+
return FunctionSchemaBuilder.create({
|
|
72
|
+
...(this._schema as any),
|
|
73
|
+
isRequired: false
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
required(): IFunctionSchemaBuilder<true, TNullable> {
|
|
78
|
+
if (this.isRequired === true) {
|
|
79
|
+
return this as IFunctionSchemaBuilder<true, TNullable>;
|
|
80
|
+
}
|
|
81
|
+
return FunctionSchemaBuilder.create({
|
|
82
|
+
...(this._schema as any),
|
|
83
|
+
isRequired: true
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
nullable(): IFunctionSchemaBuilder<TRequired, true> {
|
|
88
|
+
if (this.isNullable === true) {
|
|
89
|
+
return this as IFunctionSchemaBuilder<TRequired, true>;
|
|
90
|
+
}
|
|
91
|
+
return FunctionSchemaBuilder.create({
|
|
92
|
+
...(this._schema as any),
|
|
93
|
+
isNullable: true
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
notNullable(): IFunctionSchemaBuilder<TRequired, false> {
|
|
98
|
+
if (this.isNullable === false) {
|
|
99
|
+
return this as IFunctionSchemaBuilder<TRequired, false>;
|
|
100
|
+
}
|
|
101
|
+
return FunctionSchemaBuilder.create({
|
|
102
|
+
...(this._schema as any),
|
|
103
|
+
isNullable: false
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const func = (): IFunctionSchemaBuilder =>
|
|
109
|
+
FunctionSchemaBuilder.create();
|