valgen 3.2.0 → 4.0.0-alpha.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/CHANGELOG.md +6 -0
- package/README.md +12 -7
- package/cjs/core/constants.js +5 -0
- package/cjs/core/context.js +65 -0
- package/cjs/core/index.js +21 -0
- package/cjs/core/types.js +2 -0
- package/cjs/core/validation-error.js +11 -0
- package/cjs/core/validator.js +61 -0
- package/cjs/helpers/object.utils.js +19 -0
- package/cjs/helpers/string.utils.js +9 -0
- package/cjs/index.js +18 -0
- package/cjs/package.json +3 -0
- package/cjs/rules/index.js +38 -0
- package/cjs/rules/is-any.js +12 -0
- package/cjs/rules/is-array.js +38 -0
- package/cjs/rules/is-boolean.js +30 -0
- package/cjs/rules/is-date.js +63 -0
- package/cjs/rules/is-empty.js +68 -0
- package/cjs/rules/is-enum.js +30 -0
- package/cjs/rules/is-integer.js +26 -0
- package/cjs/rules/is-matches.js +24 -0
- package/cjs/rules/is-null.js +40 -0
- package/cjs/rules/is-number.js +26 -0
- package/cjs/rules/is-object-id.js +28 -0
- package/cjs/rules/is-object.js +103 -0
- package/cjs/rules/is-record.js +41 -0
- package/cjs/rules/is-string.js +79 -0
- package/cjs/rules/is-tuple.js +32 -0
- package/cjs/rules/length.js +41 -0
- package/cjs/rules/optional.js +44 -0
- package/cjs/rules/pipe.js +43 -0
- package/cjs/rules/range.js +89 -0
- package/cjs/rules/string-formats.js +296 -0
- package/cjs/rules/union.js +31 -0
- package/cjs/rules/utilities.js +31 -0
- package/esm/core/constants.js +2 -0
- package/esm/core/context.js +61 -0
- package/esm/core/index.js +5 -0
- package/esm/core/types.js +1 -0
- package/esm/core/validation-error.js +7 -0
- package/esm/core/validator.js +56 -0
- package/esm/helpers/object.utils.js +14 -0
- package/esm/helpers/string.utils.js +5 -0
- package/esm/index.js +2 -0
- package/esm/rules/index.js +22 -0
- package/esm/rules/is-any.js +8 -0
- package/esm/rules/is-array.js +34 -0
- package/esm/rules/is-boolean.js +26 -0
- package/esm/rules/is-date.js +55 -0
- package/esm/rules/is-empty.js +63 -0
- package/esm/rules/is-enum.js +26 -0
- package/esm/rules/is-integer.js +22 -0
- package/esm/rules/is-matches.js +20 -0
- package/esm/rules/is-null.js +34 -0
- package/esm/rules/is-number.js +22 -0
- package/esm/rules/is-object-id.js +21 -0
- package/esm/rules/is-object.js +99 -0
- package/esm/rules/is-record.js +37 -0
- package/esm/rules/is-string.js +70 -0
- package/esm/rules/is-tuple.js +28 -0
- package/esm/rules/length.js +35 -0
- package/esm/rules/optional.js +38 -0
- package/esm/rules/pipe.js +38 -0
- package/esm/rules/range.js +81 -0
- package/esm/rules/string-formats.js +266 -0
- package/esm/rules/union.js +27 -0
- package/esm/rules/utilities.js +26 -0
- package/package.json +33 -37
- package/typings/core/constants.d.ts +2 -0
- package/typings/core/context.d.ts +26 -0
- package/typings/core/index.d.ts +6 -0
- package/typings/core/types.d.ts +18 -0
- package/typings/core/validation-error.d.ts +5 -0
- package/typings/core/validator.d.ts +18 -0
- package/typings/helpers/object.utils.d.ts +2 -0
- package/typings/helpers/string.utils.d.ts +1 -0
- package/typings/index.d.ts +2 -0
- package/typings/rules/index.d.ts +22 -0
- package/typings/rules/is-any.d.ts +5 -0
- package/typings/rules/is-array.d.ts +7 -0
- package/typings/rules/is-boolean.d.ts +7 -0
- package/typings/rules/is-date.d.ts +19 -0
- package/typings/rules/is-empty.d.ts +13 -0
- package/typings/rules/is-enum.d.ts +9 -0
- package/typings/rules/is-integer.d.ts +7 -0
- package/typings/rules/is-matches.d.ts +9 -0
- package/typings/rules/is-null.d.ts +16 -0
- package/typings/rules/is-number.d.ts +7 -0
- package/typings/rules/is-object-id.d.ts +10 -0
- package/typings/rules/is-object.d.ts +22 -0
- package/typings/rules/is-record.d.ts +7 -0
- package/typings/rules/is-string.d.ts +42 -0
- package/typings/rules/is-tuple.d.ts +27 -0
- package/typings/rules/length.d.ts +21 -0
- package/typings/rules/optional.d.ts +17 -0
- package/typings/rules/pipe.d.ts +11 -0
- package/typings/rules/range.d.ts +48 -0
- package/typings/rules/string-formats.d.ts +140 -0
- package/typings/rules/union.d.ts +5 -0
- package/typings/rules/utilities.d.ts +11 -0
- package/lib/ArrayType.d.ts +0 -5
- package/lib/ArrayType.js +0 -43
- package/lib/DataType.d.ts +0 -25
- package/lib/DataType.js +0 -214
- package/lib/ObjectType.d.ts +0 -5
- package/lib/ObjectType.js +0 -78
- package/lib/SchemaError.d.ts +0 -3
- package/lib/SchemaError.js +0 -17
- package/lib/UnionType.d.ts +0 -5
- package/lib/UnionType.js +0 -54
- package/lib/Valgen.d.ts +0 -88
- package/lib/Valgen.js +0 -289
- package/lib/ValidationError.d.ts +0 -2
- package/lib/ValidationError.js +0 -4
- package/lib/factories/AnyFactory.d.ts +0 -28
- package/lib/factories/AnyFactory.js +0 -73
- package/lib/factories/ArrayFactory.d.ts +0 -16
- package/lib/factories/ArrayFactory.js +0 -148
- package/lib/factories/Base64Factory.d.ts +0 -12
- package/lib/factories/Base64Factory.js +0 -31
- package/lib/factories/BooleanFactory.d.ts +0 -12
- package/lib/factories/BooleanFactory.js +0 -49
- package/lib/factories/DateFactory.d.ts +0 -40
- package/lib/factories/DateFactory.js +0 -239
- package/lib/factories/FunctionFactory.d.ts +0 -12
- package/lib/factories/FunctionFactory.js +0 -28
- package/lib/factories/IntegerFactory.d.ts +0 -14
- package/lib/factories/IntegerFactory.js +0 -33
- package/lib/factories/NilFactory.d.ts +0 -4
- package/lib/factories/NilFactory.js +0 -20
- package/lib/factories/NumberFactory.d.ts +0 -36
- package/lib/factories/NumberFactory.js +0 -178
- package/lib/factories/ObjectFactory.d.ts +0 -38
- package/lib/factories/ObjectFactory.js +0 -326
- package/lib/factories/StringFactory.d.ts +0 -16
- package/lib/factories/StringFactory.js +0 -94
- package/lib/factories/UnionFactory.d.ts +0 -13
- package/lib/factories/UnionFactory.js +0 -62
- package/lib/index.d.ts +0 -19
- package/lib/index.js +0 -37
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const {coerceToBoolean, coerceToNumber, coalesce, mapDistinct} = require('putil-varhelpers');
|
|
3
|
-
const {AnyFactory} = require('./AnyFactory');
|
|
4
|
-
|
|
5
|
-
const MinValues = {
|
|
6
|
-
int64: null,
|
|
7
|
-
bigint: null,
|
|
8
|
-
int32: -2147483648,
|
|
9
|
-
int: -9007199254740991,
|
|
10
|
-
int16: -32768,
|
|
11
|
-
int8: -128,
|
|
12
|
-
long: 0,
|
|
13
|
-
uint64: 0,
|
|
14
|
-
uint32: 0,
|
|
15
|
-
uint16: 0,
|
|
16
|
-
uint8: 0
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const MaxValues = {
|
|
20
|
-
int64: null,
|
|
21
|
-
bigint: null,
|
|
22
|
-
int32: 2147483647,
|
|
23
|
-
int: 9007199254740991,
|
|
24
|
-
int16: 32767,
|
|
25
|
-
int8: 127,
|
|
26
|
-
long: null,
|
|
27
|
-
uint64: null,
|
|
28
|
-
uint32: 4294967295,
|
|
29
|
-
uint16: 65535,
|
|
30
|
-
uint8: 255
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const IntegerFormats = ['int64', 'bigint', 'int32', 'int', 'int16', 'int8',
|
|
34
|
-
'uint64', 'uint32', 'uint16', 'uint8', 'long'];
|
|
35
|
-
const NumberFormats = [...IntegerFormats, 'float', 'double'];
|
|
36
|
-
|
|
37
|
-
class NumberFactory extends AnyFactory {
|
|
38
|
-
|
|
39
|
-
constructor(options) {
|
|
40
|
-
super();
|
|
41
|
-
this.format = options && options.format;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
normalizeCompileOptions(options) {
|
|
45
|
-
const o = super.normalizeCompileOptions(options);
|
|
46
|
-
o.strictFormat = coerceToBoolean(options.strictFormat);
|
|
47
|
-
o.coerceTypes = coerceToBoolean(options.coerceTypes);
|
|
48
|
-
return o;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
normalizeAttribute(attr, v) {
|
|
52
|
-
switch (attr) {
|
|
53
|
-
case 'default':
|
|
54
|
-
case 'minimum':
|
|
55
|
-
case 'maximum':
|
|
56
|
-
case 'multipleOf':
|
|
57
|
-
return coerceToNumber(v);
|
|
58
|
-
case 'enum':
|
|
59
|
-
if (!Array.isArray(v))
|
|
60
|
-
throw new TypeError(`"${v}" is not an array value.`);
|
|
61
|
-
return mapDistinct(v, coerceToNumber);
|
|
62
|
-
case 'format': {
|
|
63
|
-
if (v && !NumberFormats.includes(v))
|
|
64
|
-
throw new TypeError(`"${v}" is not a valid number format identifier.`);
|
|
65
|
-
return v;
|
|
66
|
-
}
|
|
67
|
-
case 'strictFormat':
|
|
68
|
-
return coerceToBoolean(v);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
_generateValidationCode(dataType, options) {
|
|
73
|
-
const data = super._generateValidationCode(dataType, options);
|
|
74
|
-
const format = coalesce(dataType.get('format'), dataType.options.format, this.format);
|
|
75
|
-
const bigFormat = ['bigint', 'int64', 'uint64', 'long'].includes(format);
|
|
76
|
-
/* istanbul ignore next */
|
|
77
|
-
if (bigFormat && !global.BigInt)
|
|
78
|
-
throw new Error('Your JavaScript version does not support BigInt values');
|
|
79
|
-
const intFormat = IntegerFormats.includes(format);
|
|
80
|
-
|
|
81
|
-
const strictFormat = coalesce(options.strictFormat,
|
|
82
|
-
dataType.get('strictFormat'), dataType.options.strictFormat);
|
|
83
|
-
let minimum = coalesce(dataType.get('minimum'), dataType.options.minimum,
|
|
84
|
-
MinValues[format]);
|
|
85
|
-
let maximum = coalesce(dataType.get('maximum'), dataType.options.maximum,
|
|
86
|
-
MaxValues[format]);
|
|
87
|
-
const multipleOf = coalesce(dataType.get('multipleOf'), dataType.options.multipleOf);
|
|
88
|
-
|
|
89
|
-
data.variables.errorMsg1 = 'Value must be ' +
|
|
90
|
-
(intFormat ? 'an integer' : 'a number') +
|
|
91
|
-
(strictFormat ? '' : ' or ' +
|
|
92
|
-
(intFormat ? 'integer' : 'number') +
|
|
93
|
-
' formatted string');
|
|
94
|
-
|
|
95
|
-
data.code += `
|
|
96
|
-
if (!((typeof value === 'number' || typeof value === 'bigint')`;
|
|
97
|
-
if (!strictFormat)
|
|
98
|
-
data.code += ` || (typeof value === 'string' && value)`;
|
|
99
|
-
data.code += `)
|
|
100
|
-
)
|
|
101
|
-
return typeCheck ? Failed : ctx.logError({
|
|
102
|
-
message: errorMsg1,
|
|
103
|
-
errorType: 'invalid-data-type'
|
|
104
|
-
});
|
|
105
|
-
`;
|
|
106
|
-
|
|
107
|
-
data.code += `
|
|
108
|
-
let n;
|
|
109
|
-
try {
|
|
110
|
-
n = ${bigFormat ? 'BigInt(value)' : 'Number(value)'};
|
|
111
|
-
} catch (e) {
|
|
112
|
-
return typeCheck ? Failed : ctx.logError({
|
|
113
|
-
message: errorMsg1,
|
|
114
|
-
errorType: 'invalid-data-type'
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (!(typeof n === 'bigint' || !isNaN(n))) {
|
|
119
|
-
return typeCheck ? Failed : ctx.logError({
|
|
120
|
-
message: errorMsg1,
|
|
121
|
-
errorType: 'invalid-data-type'
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
`;
|
|
125
|
-
if (intFormat)
|
|
126
|
-
data.code += `
|
|
127
|
-
if (typeof n === 'number' && (n - Math.floor(n) > 0)) {
|
|
128
|
-
return typeCheck ? Failed : ctx.logError({
|
|
129
|
-
message: errorMsg1,
|
|
130
|
-
errorType: 'invalid-data-type'
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
`;
|
|
134
|
-
|
|
135
|
-
data.code += `
|
|
136
|
-
if (typeCheck) return;`;
|
|
137
|
-
|
|
138
|
-
if (multipleOf)
|
|
139
|
-
data.code += `
|
|
140
|
-
const c = typeof n === 'bigint' ?
|
|
141
|
-
n / BigInt(${multipleOf}) * BigInt(${multipleOf}) :
|
|
142
|
-
Math.trunc(n / ${multipleOf}) * ${multipleOf};
|
|
143
|
-
if (n !== c)
|
|
144
|
-
return ctx.logError({
|
|
145
|
-
message: 'Numeric value must be multiple of ${multipleOf}',
|
|
146
|
-
errorType: 'invalid-value'
|
|
147
|
-
});`;
|
|
148
|
-
if (minimum != null)
|
|
149
|
-
data.code += `
|
|
150
|
-
if (n < ${minimum})
|
|
151
|
-
return ctx.logError({
|
|
152
|
-
message: 'Minimum accepted value is ${minimum}, actual ' + n,
|
|
153
|
-
errorType: 'range-error',
|
|
154
|
-
min: ${minimum},
|
|
155
|
-
actual: n
|
|
156
|
-
});`;
|
|
157
|
-
if (maximum)
|
|
158
|
-
data.code += `
|
|
159
|
-
if (n > ${maximum})
|
|
160
|
-
return ctx.logError({
|
|
161
|
-
message: 'Maximum accepted value is ${maximum}, actual ' + n,
|
|
162
|
-
errorType: 'range-error',
|
|
163
|
-
max: ${maximum},
|
|
164
|
-
actual: n
|
|
165
|
-
});`;
|
|
166
|
-
if (options.coerceTypes)
|
|
167
|
-
data.code += '\n value = n;';
|
|
168
|
-
return data;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
module.exports = {
|
|
173
|
-
NumberFactory,
|
|
174
|
-
NumberFormats,
|
|
175
|
-
IntegerFormats,
|
|
176
|
-
MinValues,
|
|
177
|
-
MaxValues
|
|
178
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import {AnyFactory} from './AnyFactory';
|
|
2
|
-
import {Valgen} from '../Valgen';
|
|
3
|
-
import {DataType} from '../DataType';
|
|
4
|
-
|
|
5
|
-
export namespace ObjectFactory {
|
|
6
|
-
export interface IPropertySchema extends Valgen.ITypeSchema {
|
|
7
|
-
required?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface ITypeSchema extends Valgen.ITypeSchema {
|
|
10
|
-
discriminator?: string;
|
|
11
|
-
discriminatorValue?: any;
|
|
12
|
-
additionalProperties?: boolean;
|
|
13
|
-
minProperties?: number;
|
|
14
|
-
maxProperties?: number;
|
|
15
|
-
isTypeOf: (value: any, t: ObjectFactory) => boolean;
|
|
16
|
-
properties: {
|
|
17
|
-
[index: string]: IPropertySchema;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export interface IOptions {
|
|
21
|
-
required?: boolean;
|
|
22
|
-
additionalProperties?: boolean;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class ObjectFactory extends AnyFactory {
|
|
27
|
-
schema: ObjectFactory.ITypeSchema;
|
|
28
|
-
options: {
|
|
29
|
-
required?: boolean;
|
|
30
|
-
additionalProperties?: boolean;
|
|
31
|
-
};
|
|
32
|
-
properties: {
|
|
33
|
-
[index: string]: DataType;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
constructor(options?: ObjectFactory.IOptions);
|
|
37
|
-
|
|
38
|
-
}
|
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {coalesce, coerceToString, coerceToInt, coerceToBoolean} = require('putil-varhelpers');
|
|
4
|
-
const {AnyFactory} = require('./AnyFactory');
|
|
5
|
-
|
|
6
|
-
class ObjectFactory extends AnyFactory {
|
|
7
|
-
|
|
8
|
-
normalizeCompileOptions(options) {
|
|
9
|
-
const o = super.normalizeCompileOptions(options);
|
|
10
|
-
o.coerceTypes = coerceToBoolean(options.coerceTypes);
|
|
11
|
-
o.removeAdditional = coerceToBoolean(options.removeAdditional);
|
|
12
|
-
o.removeNull = coerceToBoolean(options.removeNull);
|
|
13
|
-
o.maxObjectErrors = coerceToInt(options.maxObjectErrors);
|
|
14
|
-
o.operation = coerceToString(options.operation);
|
|
15
|
-
return o;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
normalizeAttribute(attr, v) {
|
|
19
|
-
switch (attr) {
|
|
20
|
-
case 'discriminator':
|
|
21
|
-
return coerceToString(v);
|
|
22
|
-
case 'discriminatorValue':
|
|
23
|
-
case 'additionalProperties':
|
|
24
|
-
return v;
|
|
25
|
-
case 'minProperties':
|
|
26
|
-
case 'maxProperties':
|
|
27
|
-
return coerceToInt(v);
|
|
28
|
-
case 'isTypeOf':
|
|
29
|
-
if (v && typeof v !== 'function')
|
|
30
|
-
throw new TypeError('Value must be a Function.');
|
|
31
|
-
return v;
|
|
32
|
-
case 'properties':
|
|
33
|
-
return v;
|
|
34
|
-
}
|
|
35
|
-
return super.normalizeAttribute(attr, v);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
_generateValidationCode(dataType, options) {
|
|
39
|
-
const data = super._generateValidationCode(dataType, options);
|
|
40
|
-
const maxErrors = data.variables.maxErrors = options.maxObjectErrors || 0;
|
|
41
|
-
const propOptions = maxErrors > 1 ? {
|
|
42
|
-
...options,
|
|
43
|
-
throwOnError: false
|
|
44
|
-
} : options;
|
|
45
|
-
|
|
46
|
-
// Merge all properties together
|
|
47
|
-
const properties = {};
|
|
48
|
-
const mergeProperties = (dt) => {
|
|
49
|
-
if (dt.predecessors) {
|
|
50
|
-
for (const t of dt.predecessors) {
|
|
51
|
-
mergeProperties(t);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (dt.properties) {
|
|
55
|
-
for (const [k, p] of Object.entries(dt.properties)) {
|
|
56
|
-
properties[k] = p;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
mergeProperties(dataType);
|
|
61
|
-
|
|
62
|
-
const propertyKeys = (properties && Object.keys(properties)) || [];
|
|
63
|
-
let propFns;
|
|
64
|
-
let rxproperties;
|
|
65
|
-
if (propertyKeys.length) {
|
|
66
|
-
data.variables.propertyKeys = propertyKeys;
|
|
67
|
-
propFns = data.variables.properties = {};
|
|
68
|
-
rxproperties = data.variables.rxproperties = [];
|
|
69
|
-
for (const k of propertyKeys) {
|
|
70
|
-
const property = properties[k];
|
|
71
|
-
const required = property.required != null ? property.required :
|
|
72
|
-
(dataType.options.required != null ?
|
|
73
|
-
dataType.options.required : true);
|
|
74
|
-
const fn = property.generate(propOptions);
|
|
75
|
-
const m = k.match(/^\/(.*)\/$/);
|
|
76
|
-
const regexp = m && new RegExp(m[1]);
|
|
77
|
-
propFns[k] = {
|
|
78
|
-
property,
|
|
79
|
-
fn,
|
|
80
|
-
required,
|
|
81
|
-
regexp
|
|
82
|
-
};
|
|
83
|
-
if (regexp)
|
|
84
|
-
rxproperties.push(propFns[k]);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const discriminator = data.variables.discriminator =
|
|
89
|
-
dataType.get('discriminator');
|
|
90
|
-
if (discriminator)
|
|
91
|
-
data.variables.discriminatorValue =
|
|
92
|
-
dataType.get('discriminatorValue') || dataType.name;
|
|
93
|
-
|
|
94
|
-
const isTypeOf = dataType.get('isTypeOf');
|
|
95
|
-
if (isTypeOf)
|
|
96
|
-
data.variables.isTypeOf = isTypeOf;
|
|
97
|
-
|
|
98
|
-
const library = dataType.library;
|
|
99
|
-
|
|
100
|
-
let additionalProperties = coalesce(
|
|
101
|
-
dataType.get('additionalProperties'),
|
|
102
|
-
dataType.options.additionalProperties, true);
|
|
103
|
-
additionalProperties = !propertyKeys.length ||
|
|
104
|
-
(!options.removeAdditional && additionalProperties);
|
|
105
|
-
|
|
106
|
-
if (typeof additionalProperties !== 'boolean')
|
|
107
|
-
additionalProperties =
|
|
108
|
-
library.getType(additionalProperties)
|
|
109
|
-
.generate({...propOptions, strictFormat: true});
|
|
110
|
-
|
|
111
|
-
data.variables.additionalProperties = additionalProperties;
|
|
112
|
-
data.variables.operation = options.operation;
|
|
113
|
-
data.variables.removeNull = options.removeNull;
|
|
114
|
-
const minProperties = dataType.get('minProperties');
|
|
115
|
-
const maxProperties = dataType.get('maxProperties');
|
|
116
|
-
|
|
117
|
-
const needResult = options.coerceTypes ||
|
|
118
|
-
options.removeAdditional || options.removeNull;
|
|
119
|
-
|
|
120
|
-
data.code += `
|
|
121
|
-
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
122
|
-
return typeCheck ? Failed :
|
|
123
|
-
ctx.logError({
|
|
124
|
-
message: 'Value must be an object',
|
|
125
|
-
errorType: 'invalid-data-type'
|
|
126
|
-
}
|
|
127
|
-
);
|
|
128
|
-
}`;
|
|
129
|
-
|
|
130
|
-
if (isTypeOf)
|
|
131
|
-
data.code += `
|
|
132
|
-
if (!isTypeOf(value, dataType)) {
|
|
133
|
-
return typeCheck ? Failed :
|
|
134
|
-
ctx.logError({
|
|
135
|
-
message: 'Value does not match to'+
|
|
136
|
-
(name ? 'to "' + name + '"' : ''),
|
|
137
|
-
errorType: 'invalid-data-type'
|
|
138
|
-
});
|
|
139
|
-
}`;
|
|
140
|
-
|
|
141
|
-
if (discriminator) {
|
|
142
|
-
data.code += `
|
|
143
|
-
if (value[discriminator] !== discriminatorValue) {
|
|
144
|
-
return typeCheck ? Failed : ctx.logError({
|
|
145
|
-
message: 'Value is not a type of "' + discriminatorValue + '"',
|
|
146
|
-
errorType: 'invalid-data',
|
|
147
|
-
discriminatorValue,
|
|
148
|
-
actual: value[discriminator],
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
if (typeCheck) return 1;`;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!additionalProperties || minProperties || maxProperties || propFns)
|
|
155
|
-
data.code += `
|
|
156
|
-
const valueKeys = Object.keys(value);`;
|
|
157
|
-
|
|
158
|
-
if (!discriminator && propFns) {
|
|
159
|
-
data.code += `
|
|
160
|
-
if (typeCheck) {
|
|
161
|
-
let matchedCount = 0;
|
|
162
|
-
const xctx = {...ctx};
|
|
163
|
-
for (let i = 0; i < ${propertyKeys.length}; i++) {
|
|
164
|
-
const k = propertyKeys[i];
|
|
165
|
-
const p = properties[k];
|
|
166
|
-
const regexp = p.regexp;
|
|
167
|
-
if (regexp) {
|
|
168
|
-
xctx.name = k;
|
|
169
|
-
const len = valueKeys.length;
|
|
170
|
-
let h = 0;
|
|
171
|
-
for (let j = 0; j < len; j ++) {
|
|
172
|
-
if (valueKeys[j].match(regexp) &&
|
|
173
|
-
p.fn(value[valueKeys[j]], xctx).valid)
|
|
174
|
-
h++;
|
|
175
|
-
}
|
|
176
|
-
matchedCount += (h / len);
|
|
177
|
-
continue;
|
|
178
|
-
} else if (value.hasOwnProperty(k)) {
|
|
179
|
-
xctx.name = k;
|
|
180
|
-
if (p.fn(value[k], xctx).valid)
|
|
181
|
-
matchedCount++;
|
|
182
|
-
} else
|
|
183
|
-
if (p.required && (!Array.isArray(p.required) || p.required.includes(operation)))
|
|
184
|
-
return Failed;
|
|
185
|
-
}
|
|
186
|
-
return matchedCount / ${propertyKeys.length};
|
|
187
|
-
}
|
|
188
|
-
`;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
data.code += `
|
|
192
|
-
if (typeCheck) return;
|
|
193
|
-
let numErrors = 0;
|
|
194
|
-
${needResult ? 'const result = {};' : ''}`;
|
|
195
|
-
|
|
196
|
-
if (minProperties) {
|
|
197
|
-
data.code += `
|
|
198
|
-
if (valueKeys.length < ${minProperties}) {
|
|
199
|
-
return ctx.logError({
|
|
200
|
-
message: 'Minimum accepted properties is ${minProperties}, actual ' + valueKeys.length,
|
|
201
|
-
errorType: 'invalid-value-length',
|
|
202
|
-
min: ${minProperties},
|
|
203
|
-
actual: valueKeys.length
|
|
204
|
-
});
|
|
205
|
-
}`;
|
|
206
|
-
}
|
|
207
|
-
if (maxProperties)
|
|
208
|
-
data.code += `
|
|
209
|
-
if (valueKeys.length > ${maxProperties}) {
|
|
210
|
-
return ctx.logError({
|
|
211
|
-
message: 'Maximum allowed properties is ${maxProperties}, actual ' + valueKeys.length,
|
|
212
|
-
errorType: 'invalid-value-length',
|
|
213
|
-
max: ${maxProperties},
|
|
214
|
-
actual: valueKeys.length
|
|
215
|
-
});
|
|
216
|
-
}`;
|
|
217
|
-
|
|
218
|
-
if (!propFns && additionalProperties === true) {
|
|
219
|
-
data.code += `
|
|
220
|
-
${needResult ? 'return value;' : 'return;'}`;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Iterate over value properties than iterate over type properties
|
|
224
|
-
if (propFns) {
|
|
225
|
-
data.code += `
|
|
226
|
-
const _logError = (...args) => {
|
|
227
|
-
numErrors++;
|
|
228
|
-
return ctx.logError(...args);
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const xprops = Object.assign({}, properties);
|
|
232
|
-
let keysLen = valueKeys.length;
|
|
233
|
-
const xctx = {...ctx, logError: _logError}
|
|
234
|
-
const path = ctx.path;
|
|
235
|
-
for (let i = 0; i < keysLen; i++) {
|
|
236
|
-
const k = valueKeys[i];
|
|
237
|
-
const p = properties[k] || (
|
|
238
|
-
rxproperties.length &&
|
|
239
|
-
rxproperties.find(x=> k.match(x.regexp)))
|
|
240
|
-
let vv;
|
|
241
|
-
if (p) {
|
|
242
|
-
delete xprops[k];
|
|
243
|
-
xctx.name = k;
|
|
244
|
-
path.push(k);
|
|
245
|
-
vv = p.fn(value[k], xctx);
|
|
246
|
-
${maxErrors > 1 ? 'if (numErrors >= maxErrors) return Failed;' : ''}
|
|
247
|
-
if (!vv.valid) vv = Failed;${needResult ? ' else vv = vv.value;' : ''};
|
|
248
|
-
path.pop();
|
|
249
|
-
}`;
|
|
250
|
-
|
|
251
|
-
if (additionalProperties) {
|
|
252
|
-
if (typeof additionalProperties === 'function') {
|
|
253
|
-
data.code += ` else {
|
|
254
|
-
path.push(k);
|
|
255
|
-
xctx.name = k;
|
|
256
|
-
xctx.typeCheck = true;
|
|
257
|
-
vv = additionalProperties(value[k], {...xctx, typeCheck: true});
|
|
258
|
-
xctx.typeCheck = undefined;
|
|
259
|
-
if (!vv.valid) vv = Failed;${needResult ? 'else vv = vv.value;' : ''}
|
|
260
|
-
path.pop();
|
|
261
|
-
}`;
|
|
262
|
-
} else if (needResult)
|
|
263
|
-
data.code += ' else vv = value[k]';
|
|
264
|
-
} else if (!options.removeAdditional)
|
|
265
|
-
data.code += ' else vv = Failed;';
|
|
266
|
-
|
|
267
|
-
data.code += `
|
|
268
|
-
if (!p && vv === Failed) {
|
|
269
|
-
path.push(k);
|
|
270
|
-
ctx.logError({
|
|
271
|
-
message: 'Additional property "' + k + '" is not allowed.',
|
|
272
|
-
errorType: 'no-additional-allowed'
|
|
273
|
-
}
|
|
274
|
-
);
|
|
275
|
-
${propFns && maxErrors > 1 ?
|
|
276
|
-
'if (++numErrors >= maxErrors) return Failed;' : 'return Failed;'}
|
|
277
|
-
path.pop();
|
|
278
|
-
}`;
|
|
279
|
-
|
|
280
|
-
if (needResult)
|
|
281
|
-
data.code += `
|
|
282
|
-
if (vv !== undefined && vv !== Failed && (vv != null || !removeNull)) result[k] = vv;`;
|
|
283
|
-
data.code += `
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const keys = Object.keys(xprops);
|
|
287
|
-
keysLen = keys.length;
|
|
288
|
-
for (let i = 0; i < keysLen; i++) {
|
|
289
|
-
const k = keys[i];
|
|
290
|
-
const p = xprops[k];
|
|
291
|
-
if (p.regexp)
|
|
292
|
-
continue;
|
|
293
|
-
let vv = value[k];
|
|
294
|
-
path.push(k);
|
|
295
|
-
if (!removeNull && vv == null &&
|
|
296
|
-
p.required && (!Array.isArray(p.required) || p.required.includes(operation))
|
|
297
|
-
) {
|
|
298
|
-
ctx.logError({
|
|
299
|
-
message: 'Value required.',
|
|
300
|
-
errorType: 'value-required'
|
|
301
|
-
}
|
|
302
|
-
);
|
|
303
|
-
${maxErrors > 1 ?
|
|
304
|
-
'if (++numErrors >= maxErrors) return Failed;' : 'return Failed;'}
|
|
305
|
-
}
|
|
306
|
-
xctx.name = k;
|
|
307
|
-
vv = p.fn(vv, xctx);
|
|
308
|
-
if (!vv.valid) {
|
|
309
|
-
${maxErrors > 1 ?
|
|
310
|
-
'if (numErrors >= maxErrors) return Failed;' :
|
|
311
|
-
'return Failed;'}
|
|
312
|
-
}${needResult ? `
|
|
313
|
-
vv = vv.value;
|
|
314
|
-
if (vv !== undefined && (vv != null || !removeNull)) result[k] = vv;` : ''}
|
|
315
|
-
path.pop();
|
|
316
|
-
}
|
|
317
|
-
`;
|
|
318
|
-
}
|
|
319
|
-
if (needResult)
|
|
320
|
-
data.code += '\n value = !numErrors ? result: undefined;';
|
|
321
|
-
|
|
322
|
-
return data;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
module.exports = {ObjectFactory};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {AnyFactory} from './AnyFactory';
|
|
2
|
-
import {Valgen} from '../Valgen';
|
|
3
|
-
|
|
4
|
-
export namespace StringFactory {
|
|
5
|
-
export interface ITypeSchema extends Valgen.ITypeSchema {
|
|
6
|
-
default?: string;
|
|
7
|
-
enum?: string[];
|
|
8
|
-
pattern?: string;
|
|
9
|
-
minLength?: number;
|
|
10
|
-
maxLength?: number;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class StringFactory extends AnyFactory {
|
|
15
|
-
schema: StringFactory.ITypeSchema;
|
|
16
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const {
|
|
3
|
-
coalesce, coerceToBoolean, coerceToString, coerceToInt, mapDistinct
|
|
4
|
-
} = require('putil-varhelpers');
|
|
5
|
-
const {AnyFactory} = require('./AnyFactory');
|
|
6
|
-
|
|
7
|
-
class StringFactory extends AnyFactory {
|
|
8
|
-
|
|
9
|
-
normalizeCompileOptions(options) {
|
|
10
|
-
const o = super.normalizeCompileOptions(options);
|
|
11
|
-
o.strictFormat = coerceToBoolean(options.strictFormat);
|
|
12
|
-
o.coerceTypes = coerceToBoolean(options.coerceTypes);
|
|
13
|
-
return o;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
normalizeAttribute(attr, v) {
|
|
17
|
-
switch (attr) {
|
|
18
|
-
case 'default':
|
|
19
|
-
case 'pattern':
|
|
20
|
-
return coerceToString(v);
|
|
21
|
-
case 'enum':
|
|
22
|
-
if (!Array.isArray(v))
|
|
23
|
-
throw new TypeError(`"${v}" is not an array value.`);
|
|
24
|
-
return mapDistinct(v, coerceToString);
|
|
25
|
-
case 'minLength':
|
|
26
|
-
case 'maxLength':
|
|
27
|
-
return coerceToInt(v);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
_generateValidationCode(dataType, options) {
|
|
32
|
-
const data = super._generateValidationCode(dataType, options);
|
|
33
|
-
const strictFormat = coalesce(options.strictFormat,
|
|
34
|
-
dataType.get('strictFormat'), dataType.options.strictFormat);
|
|
35
|
-
const pattern = coalesce(dataType.get('pattern'), dataType.options.pattern);
|
|
36
|
-
if (pattern)
|
|
37
|
-
data.variables.pattern = new RegExp(pattern);
|
|
38
|
-
const minLength = coalesce(dataType.get('minLength'), dataType.options.minLength);
|
|
39
|
-
const maxLength = coalesce(dataType.get('maxLength'), dataType.options.maxLength);
|
|
40
|
-
|
|
41
|
-
data.code += `
|
|
42
|
-
if (!(typeof value === 'string'`;
|
|
43
|
-
if (!strictFormat)
|
|
44
|
-
data.code +=
|
|
45
|
-
` || typeof value === 'boolean' || typeof value === 'number' || typeof value === 'bigint'`;
|
|
46
|
-
|
|
47
|
-
data.code += `)
|
|
48
|
-
) {
|
|
49
|
-
return typeCheck ? Failed : ctx.logError({
|
|
50
|
-
message: 'Value must be a string',
|
|
51
|
-
errorType: 'invalid-data-type'
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
const v = ''+ value;`;
|
|
55
|
-
|
|
56
|
-
if (pattern)
|
|
57
|
-
data.code += `
|
|
58
|
-
if (!v.match(pattern))
|
|
59
|
-
return typeCheck ? Failed : ctx.logError({
|
|
60
|
-
message: 'Value does not match required format',
|
|
61
|
-
errorType: 'invalid-value-format'
|
|
62
|
-
});`;
|
|
63
|
-
|
|
64
|
-
data.code += `
|
|
65
|
-
if (typeCheck) return;`;
|
|
66
|
-
|
|
67
|
-
if (minLength != null)
|
|
68
|
-
data.code += `
|
|
69
|
-
if (v.length < ${minLength}) {
|
|
70
|
-
return ctx.logError({
|
|
71
|
-
message: 'Minimum accepted length is ${minLength}, actual ' + v.length,
|
|
72
|
-
errorType: 'invalid-value-length',
|
|
73
|
-
min: ${minLength},
|
|
74
|
-
actual: v.length
|
|
75
|
-
});
|
|
76
|
-
}`;
|
|
77
|
-
|
|
78
|
-
if (maxLength)
|
|
79
|
-
data.code += `
|
|
80
|
-
if (v.length > ${maxLength})
|
|
81
|
-
return ctx.logError({
|
|
82
|
-
message: 'Maximum accepted length is ${maxLength}, actual ' + v.length,
|
|
83
|
-
errorType: 'invalid-value-length',
|
|
84
|
-
max: ${maxLength},
|
|
85
|
-
actual: v.length
|
|
86
|
-
});`;
|
|
87
|
-
|
|
88
|
-
if (options.coerceTypes)
|
|
89
|
-
data.code += '\n value = v;';
|
|
90
|
-
return data;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
module.exports = {StringFactory};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import {AnyFactory} from './AnyFactory';
|
|
2
|
-
import {Valgen} from '../Valgen';
|
|
3
|
-
|
|
4
|
-
export namespace UnionFactory {
|
|
5
|
-
export interface ITypeSchema extends Valgen.ITypeSchema {
|
|
6
|
-
anyOf?: Array<string | Valgen.ITypeSchema>;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class UnionFactory extends AnyFactory {
|
|
11
|
-
schema: UnionFactory.ITypeSchema;
|
|
12
|
-
anyOf?: AnyFactory[];
|
|
13
|
-
}
|