valgen 3.2.1 → 4.0.0-alpha.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/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 +39 -0
- package/cjs/rules/is-any.js +12 -0
- package/cjs/rules/is-array.js +38 -0
- package/cjs/rules/is-bigint.js +21 -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 +23 -0
- package/esm/rules/is-any.js +8 -0
- package/esm/rules/is-array.js +34 -0
- package/esm/rules/is-bigint.js +17 -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 +23 -0
- package/typings/rules/is-any.d.ts +5 -0
- package/typings/rules/is-array.d.ts +7 -0
- package/typings/rules/is-bigint.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,40 +0,0 @@
|
|
|
1
|
-
import {AnyFactory} from './AnyFactory';
|
|
2
|
-
import {Valgen} from '../Valgen';
|
|
3
|
-
|
|
4
|
-
export namespace DateFactory {
|
|
5
|
-
export interface ITypeSchema extends Valgen.ITypeSchema {
|
|
6
|
-
default?: string;
|
|
7
|
-
format?: string;
|
|
8
|
-
fast?: boolean;
|
|
9
|
-
}
|
|
10
|
-
export interface IDateFormatMap {
|
|
11
|
-
date?: string,
|
|
12
|
-
datetime?: string,
|
|
13
|
-
timestamp?: string,
|
|
14
|
-
time?: string,
|
|
15
|
-
rfc2616?: string
|
|
16
|
-
}
|
|
17
|
-
export interface IOptions {
|
|
18
|
-
dateFormats?: IDateFormatMap;
|
|
19
|
-
format?: string;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export class DateFactory extends AnyFactory {
|
|
25
|
-
|
|
26
|
-
schema: DateFactory.ITypeSchema;
|
|
27
|
-
format?: string;
|
|
28
|
-
dateFormats: DateFactory.IDateFormatMap;
|
|
29
|
-
|
|
30
|
-
TIMESTAMP_PATTERN: RegExp;
|
|
31
|
-
TIMESTAMP_STRICT_PATTERN: RegExp;
|
|
32
|
-
DATETIME_PATTERN: RegExp;
|
|
33
|
-
DATETIME_STRICT_PATTERN: RegExp;
|
|
34
|
-
DATE_PATTERN: RegExp;
|
|
35
|
-
DATE_STRICT_PATTERN: RegExp;
|
|
36
|
-
TIME_PATTERN: RegExp;
|
|
37
|
-
TIME_STRICT_PATTERN: RegExp;
|
|
38
|
-
|
|
39
|
-
constructor(options?: DateFactory.IOptions);
|
|
40
|
-
}
|
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {AnyFactory} = require('./AnyFactory');
|
|
4
|
-
const {coalesce, coerceToBoolean, coerceToString} = require('putil-varhelpers');
|
|
5
|
-
|
|
6
|
-
class DateFactory extends AnyFactory {
|
|
7
|
-
|
|
8
|
-
constructor(options) {
|
|
9
|
-
super();
|
|
10
|
-
this.TIMESTAMP_PATTERN =
|
|
11
|
-
/^(\d{4})-?(0[1-9]|1[012])?-?([123]0|[012][1-9]|31)?(?:T?([01][0-9]|2[0-3]):?([0-5][0-9]):?([0-5][0-9])?(?:\.(\d+))?(?:(Z)|(?:([+-])([01]?[0-9]|2[0-3]):?([0-5][0-9])?))?)?$/;
|
|
12
|
-
this.TIMESTAMP_STRICT_PATTERN =
|
|
13
|
-
/^(\d{4})-(0[1-9]|1[012])-([123]0|[012][1-9]|31)T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.?(\d+))?(?:(Z)|(?:([+-])([01]?[0-9]|2[0-3]):([0-5][0-9])))$/;
|
|
14
|
-
this.DATETIME_PATTERN =
|
|
15
|
-
/^(\d{4})-?(0[1-9]|1[012])?-?([123]0|[012][1-9]|31)?(?:T?([01][0-9]|2[0-3]):?([0-5][0-9]):?([0-5][0-9])?(?:\.?(\d+))?)?$/;
|
|
16
|
-
this.DATETIME_STRICT_PATTERN =
|
|
17
|
-
/^(\d{4})-(0[1-9]|1[012])-([123]0|[012][1-9]|31)T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.?(\d+))?$/;
|
|
18
|
-
this.DATE_PATTERN =
|
|
19
|
-
/^(\d{4})-?(0[1-9]|1[012])?-?([123]0|[012][1-9]|31)?$/;
|
|
20
|
-
this.DATE_STRICT_PATTERN =
|
|
21
|
-
/^(\d{4})-(0[1-9]|1[012])-([123]0|[012][1-9]|31)$/;
|
|
22
|
-
this.TIME_PATTERN =
|
|
23
|
-
/^([01][0-9]|2[0-3]):?([0-5][0-9]):?([0-5][0-9])?(?:\.(\d+))?$/;
|
|
24
|
-
this.TIME_STRICT_PATTERN =
|
|
25
|
-
/^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])?(?:\.(\d+))?$/;
|
|
26
|
-
this.dateFormats = (options && options.dateFormats) || {
|
|
27
|
-
'date': 'date',
|
|
28
|
-
'datetime': 'datetime',
|
|
29
|
-
'timestamp': 'timestamp',
|
|
30
|
-
'time': 'time',
|
|
31
|
-
'rfc2616': 'rfc2616'
|
|
32
|
-
};
|
|
33
|
-
this.format = options && options.format;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
normalizeCompileOptions(options) {
|
|
37
|
-
const o = super.normalizeCompileOptions(options);
|
|
38
|
-
o.strictFormat = coerceToBoolean(options.strictFormat);
|
|
39
|
-
o.coerceTypes = coerceToBoolean(options.coerceTypes);
|
|
40
|
-
o.convertDates = coerceToBoolean(options.convertDates);
|
|
41
|
-
return o;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
normalizeAttribute(attr, v) {
|
|
45
|
-
switch (attr) {
|
|
46
|
-
case 'default':
|
|
47
|
-
return coerceDateOrString(v);
|
|
48
|
-
case 'format':
|
|
49
|
-
if (v && !this.dateFormats[v])
|
|
50
|
-
throw new TypeError(`Unknown date format (${v})`);
|
|
51
|
-
return coerceToString(v);
|
|
52
|
-
case 'strictFormat':
|
|
53
|
-
return coerceToBoolean(v);
|
|
54
|
-
case 'fast':
|
|
55
|
-
return coerceToBoolean(v);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
_generateValidationCode(type, options) {
|
|
60
|
-
const data = super._generateValidationCode(type, options);
|
|
61
|
-
const convertDates = options.convertDates;
|
|
62
|
-
const coerceTypes = options.coerceTypes || convertDates;
|
|
63
|
-
const formatName = type.get('format') || this.format || 'timestamp';
|
|
64
|
-
const format = this.dateFormats[formatName] || formatName;
|
|
65
|
-
|
|
66
|
-
const fastDateValidation = type.get('fast') && !convertDates &&
|
|
67
|
-
format !== 'rfc2616';
|
|
68
|
-
const strictFormat = coalesce(options.strictFormat, type.get('strictFormat'));
|
|
69
|
-
const matchDatePattern = this._getMatchDatePatternFn(format, strictFormat);
|
|
70
|
-
const dateItemsToISO = this._getFormatDateItemsFn('timestamp');
|
|
71
|
-
const formatDate = this._getFormatDateFn(format);
|
|
72
|
-
const formatDateItems = this._getFormatDateItemsFn(format);
|
|
73
|
-
data.code += `
|
|
74
|
-
if (!(value instanceof Date || typeof value === 'string'))
|
|
75
|
-
return typeCheck ? Failed : ctx.logError({
|
|
76
|
-
message: 'Value must be ${formatName} formatted string or Date instance',
|
|
77
|
-
errorType: 'invalid-data-type'
|
|
78
|
-
});`;
|
|
79
|
-
data.code += `
|
|
80
|
-
let d;
|
|
81
|
-
let m;
|
|
82
|
-
if (typeof value === 'string') {`;
|
|
83
|
-
if (format === 'rfc2616') {
|
|
84
|
-
if (strictFormat) {
|
|
85
|
-
data.code += `
|
|
86
|
-
d = String(value).match(/^[A-Za-z]/) && new Date(value);`;
|
|
87
|
-
} else
|
|
88
|
-
data.code += `
|
|
89
|
-
m = matchDatePattern(value);
|
|
90
|
-
d = new Date(m ? dateItemsToISO(m) : value);`;
|
|
91
|
-
} else
|
|
92
|
-
data.code += `
|
|
93
|
-
m = matchDatePattern(value);
|
|
94
|
-
if (!m)
|
|
95
|
-
return typeCheck ? Failed : ctx.logError({
|
|
96
|
-
message: 'Value must be ${formatName} formatted string or Date instance',
|
|
97
|
-
errorType: 'invalid-data-type'
|
|
98
|
-
});
|
|
99
|
-
${fastDateValidation ?
|
|
100
|
-
`return ${coerceTypes ? 'formatDateItems(m)' : 'value'};` :
|
|
101
|
-
`d = new Date(dateItemsToISO(m));
|
|
102
|
-
d = isValidDate(d) && parseInt((m[3]||'01'), 10) === d.getUTCDate() ? d : null;`}
|
|
103
|
-
`;
|
|
104
|
-
data.code += `
|
|
105
|
-
} else d = value;
|
|
106
|
-
if (!isValidDate(d))
|
|
107
|
-
return typeCheck ? Failed : ctx.logError({
|
|
108
|
-
message: 'Value must be ${formatName} formatted string or Date instance',
|
|
109
|
-
errorType: 'invalid-data-type'
|
|
110
|
-
});`;
|
|
111
|
-
|
|
112
|
-
data.code += `
|
|
113
|
-
if (typeCheck) return;`;
|
|
114
|
-
|
|
115
|
-
if (convertDates)
|
|
116
|
-
data.code += '\n value = d;';
|
|
117
|
-
else if (coerceTypes) {
|
|
118
|
-
data.code += '\n value = m ? formatDateItems(m) : formatDate(d);';
|
|
119
|
-
}
|
|
120
|
-
data.variables = {
|
|
121
|
-
...data.variables,
|
|
122
|
-
isValidDate,
|
|
123
|
-
matchDatePattern, formatDateItems, formatDate,
|
|
124
|
-
dateItemsToISO,
|
|
125
|
-
};
|
|
126
|
-
return data;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
_getFormatDateFn(format) {
|
|
130
|
-
switch (format) {
|
|
131
|
-
case 'date':
|
|
132
|
-
return (d) => {
|
|
133
|
-
const s = d.toISOString();
|
|
134
|
-
return s.substring(0, 10);
|
|
135
|
-
};
|
|
136
|
-
case 'datetime':
|
|
137
|
-
return (d) => {
|
|
138
|
-
const s = d.toISOString();
|
|
139
|
-
return s.substring(0, s.length - 1);
|
|
140
|
-
};
|
|
141
|
-
case 'time':
|
|
142
|
-
return (d) => {
|
|
143
|
-
let s = d.toISOString();
|
|
144
|
-
return s.endsWith('.000Z') ?
|
|
145
|
-
s.substring(11, s.length - 5) : s.substring(11, s.length - 1);
|
|
146
|
-
};
|
|
147
|
-
case 'timestamp':
|
|
148
|
-
return (d) => d.toISOString();
|
|
149
|
-
case 'rfc2616':
|
|
150
|
-
/* istanbul ignore next : Timezone obstructs testing */
|
|
151
|
-
return (d) => d.toString();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
_getFormatDateItemsFn(format) {
|
|
156
|
-
let src = ` const v = `;
|
|
157
|
-
if (format === 'rfc2616' || format === 'date' ||
|
|
158
|
-
format === 'datetime' || format === 'timestamp') {
|
|
159
|
-
src += `
|
|
160
|
-
// Date part
|
|
161
|
-
m[1] + '-' + (m[2]||'01') + '-' + (m[3]||'01')`;
|
|
162
|
-
}
|
|
163
|
-
if (format === 'rfc2616' || format === 'datetime' ||
|
|
164
|
-
format === 'timestamp') {
|
|
165
|
-
src += ` +
|
|
166
|
-
// Time part
|
|
167
|
-
'T'`;
|
|
168
|
-
}
|
|
169
|
-
if (format === 'rfc2616' || format === 'datetime' ||
|
|
170
|
-
format === 'timestamp' || format === 'time') {
|
|
171
|
-
src += `+ (m[4] || '00') + ':' + (m[5] || '00') + ':' + (m[6] || '00') +
|
|
172
|
-
// Millisecond
|
|
173
|
-
(m[7] ? '.' + m[7] : '')`;
|
|
174
|
-
}
|
|
175
|
-
if (format === 'rfc2616' || format === 'timestamp') {
|
|
176
|
-
src += `+
|
|
177
|
-
// Time zone
|
|
178
|
-
(m[9] ? (m[9] + (m[10] || '00') + ':' + (m[11] || '00')) : 'Z')`;
|
|
179
|
-
}
|
|
180
|
-
if (format === 'rfc2616') {
|
|
181
|
-
src += ';\n return new Date(v).toString()';
|
|
182
|
-
} else src += ';\n return v;';
|
|
183
|
-
return new Function('m', src);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
_getMatchDatePatternFn(format, strict) {
|
|
187
|
-
if (format === 'time') {
|
|
188
|
-
return (v) => {
|
|
189
|
-
const m = v.match(strict ? this.TIME_STRICT_PATTERN : this.TIME_PATTERN);
|
|
190
|
-
return m && [v, '1970', '01', '01', ...m.slice(1)];
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
let src = `
|
|
194
|
-
return (v) => {
|
|
195
|
-
const m = v.match(pattern);
|
|
196
|
-
if (!m || (m[2] === '02' && m[3] > '29'))
|
|
197
|
-
return;
|
|
198
|
-
`;
|
|
199
|
-
if (!strict) {
|
|
200
|
-
if (format === 'date')
|
|
201
|
-
src += ' m[4]=null;m[5]=null;m[6]=null;m[7]=null;\n';
|
|
202
|
-
if (format === 'date' || format === 'datetime')
|
|
203
|
-
src += ' m[8]=null;m[9]=null;m[10]=null;m[11]=null;\n';
|
|
204
|
-
}
|
|
205
|
-
src += `
|
|
206
|
-
return m;
|
|
207
|
-
}`;
|
|
208
|
-
let pattern;
|
|
209
|
-
switch (format) {
|
|
210
|
-
case 'datetime':
|
|
211
|
-
pattern = strict ? this.DATETIME_STRICT_PATTERN :
|
|
212
|
-
this.DATETIME_PATTERN;
|
|
213
|
-
break;
|
|
214
|
-
case 'date':
|
|
215
|
-
pattern = strict ? this.DATE_STRICT_PATTERN :
|
|
216
|
-
this.DATE_PATTERN;
|
|
217
|
-
break;
|
|
218
|
-
default:
|
|
219
|
-
pattern = strict ?
|
|
220
|
-
this.TIMESTAMP_STRICT_PATTERN :
|
|
221
|
-
this.TIMESTAMP_PATTERN;
|
|
222
|
-
}
|
|
223
|
-
return new Function('pattern', src)(pattern);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function isValidDate(d) {
|
|
229
|
-
return d && !isNaN(d.getTime());
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function coerceDateOrString(v) {
|
|
233
|
-
if (v && !(typeof v === 'string' || v instanceof Date))
|
|
234
|
-
throw new TypeError(`"${v}" is not a string or Date instance`);
|
|
235
|
-
return v;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
module.exports = {DateFactory};
|
|
239
|
-
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import {AnyFactory} from './AnyFactory';
|
|
2
|
-
import {Valgen} from '../Valgen';
|
|
3
|
-
|
|
4
|
-
export namespace FunctionFactory {
|
|
5
|
-
export interface ITypeSchema extends Valgen.ITypeSchema {
|
|
6
|
-
default?: Function;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class FunctionFactory extends AnyFactory {
|
|
11
|
-
schema: FunctionFactory.ITypeSchema;
|
|
12
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const {AnyFactory} = require('./AnyFactory');
|
|
3
|
-
|
|
4
|
-
class FunctionFactory extends AnyFactory {
|
|
5
|
-
|
|
6
|
-
normalizeAttribute(attr, v) {
|
|
7
|
-
switch (attr) {
|
|
8
|
-
case 'default':
|
|
9
|
-
if (v && typeof v !== 'function')
|
|
10
|
-
throw new TypeError(`"${v}" is not a Function`);
|
|
11
|
-
return v;
|
|
12
|
-
}
|
|
13
|
-
return super.normalizeAttribute(attr, v);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
_generateValidationCode(dataType, options) {
|
|
17
|
-
const data = super._generateValidationCode(dataType, options);
|
|
18
|
-
data.code += `
|
|
19
|
-
if (typeof value !== 'function')
|
|
20
|
-
return typeCheck ? Failed : ctx.logError({
|
|
21
|
-
message: 'Value must be a function',
|
|
22
|
-
errorType: 'invalid-data-type'
|
|
23
|
-
});`;
|
|
24
|
-
return data;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = {FunctionFactory};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {NumberFactory} from './NumberFactory';
|
|
2
|
-
|
|
3
|
-
export namespace IntegerFactory {
|
|
4
|
-
export interface IOptions extends NumberFactory.IOptions {
|
|
5
|
-
format?: NumberFactory.IntegerFormatType;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class IntegerFactory extends NumberFactory {
|
|
10
|
-
|
|
11
|
-
format?: NumberFactory.IntegerFormatType;
|
|
12
|
-
|
|
13
|
-
constructor(options?: IntegerFactory.IOptions);
|
|
14
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const {coerceToInt, mapDistinct} = require('putil-varhelpers');
|
|
3
|
-
const {NumberFactory, IntegerFormats} = require('./NumberFactory');
|
|
4
|
-
|
|
5
|
-
class IntegerFactory extends NumberFactory {
|
|
6
|
-
|
|
7
|
-
create(instance) {
|
|
8
|
-
instance.options.format = 'int32';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
normalizeAttribute(attr, v) {
|
|
12
|
-
switch (attr) {
|
|
13
|
-
case 'default':
|
|
14
|
-
case 'minimum':
|
|
15
|
-
case 'maximum':
|
|
16
|
-
case 'multipleOf':
|
|
17
|
-
return coerceToInt(v);
|
|
18
|
-
case 'enum':
|
|
19
|
-
if (!Array.isArray(v))
|
|
20
|
-
throw new TypeError(`"${v}" is not an array value.`);
|
|
21
|
-
return mapDistinct(v, coerceToInt);
|
|
22
|
-
case 'format': {
|
|
23
|
-
if (v && !IntegerFormats.includes(v))
|
|
24
|
-
throw new TypeError(`"${v}" is not a valid integer format identifier.`);
|
|
25
|
-
return v;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return super.normalizeAttribute(attr, v);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
module.exports = {IntegerFactory};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const {AnyFactory} = require('./AnyFactory');
|
|
3
|
-
|
|
4
|
-
class NilFactory extends AnyFactory {
|
|
5
|
-
|
|
6
|
-
normalizeAttribute(attr, v) {
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
_generateValidationCode(dataType, options) {
|
|
10
|
-
const data = super._generateValidationCode(dataType, options);
|
|
11
|
-
data.code = ' if (value === undefined) value = null;' + data.code + `
|
|
12
|
-
return typeCheck ? Failed : ctx.logError({
|
|
13
|
-
message: 'Value must be null',
|
|
14
|
-
errorType: 'invalid-data-type'
|
|
15
|
-
}); `;
|
|
16
|
-
return data;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
module.exports = {NilFactory};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {AnyFactory} from './AnyFactory';
|
|
2
|
-
import {Valgen} from '../Valgen';
|
|
3
|
-
|
|
4
|
-
export namespace NumberFactory {
|
|
5
|
-
export type IntegerFormatType = 'int64' | 'bigint' | 'int32' | 'int' | 'int16' | 'int8' |
|
|
6
|
-
'uint64' | 'uint32' | 'uint16' | 'uint8' | 'long' | 'float';
|
|
7
|
-
export type FloatFormatType = 'float' | 'double';
|
|
8
|
-
export type NumberFormatType = IntegerFormatType | FloatFormatType;
|
|
9
|
-
|
|
10
|
-
export interface ITypeSchema extends Valgen.ITypeSchema {
|
|
11
|
-
default?: number;
|
|
12
|
-
enum?: number[];
|
|
13
|
-
minimum?: number;
|
|
14
|
-
maximum?: number;
|
|
15
|
-
multipleOf?: number;
|
|
16
|
-
strictFormat?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface IOptions {
|
|
20
|
-
format?: NumberFormatType;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const NumberFormats: string[];
|
|
26
|
-
export const IntegerFormats: string[];
|
|
27
|
-
export const MinValues: { [format: string]: number };
|
|
28
|
-
export const MaxValues: { [format: string]: number };
|
|
29
|
-
|
|
30
|
-
export class NumberFactory extends AnyFactory {
|
|
31
|
-
schema: NumberFactory.ITypeSchema;
|
|
32
|
-
format?: NumberFactory.NumberFormatType;
|
|
33
|
-
|
|
34
|
-
constructor(options?: NumberFactory.IOptions);
|
|
35
|
-
|
|
36
|
-
}
|
|
@@ -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
|
-
}
|