@sinclair/typebox 0.25.14 → 0.25.16
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/compiler/compiler.js +38 -22
- package/errors/errors.js +50 -31
- package/package.json +2 -1
- package/system/index.d.ts +1 -0
- package/system/index.js +44 -0
- package/system/system.d.ts +10 -0
- package/system/system.js +41 -0
- package/value/cast.js +6 -6
- package/value/check.js +44 -25
package/compiler/compiler.js
CHANGED
|
@@ -29,10 +29,11 @@ THE SOFTWARE.
|
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
30
|
exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.Property = exports.TypeCheck = void 0;
|
|
31
31
|
const index_1 = require("../errors/index");
|
|
32
|
-
const index_2 = require("../
|
|
33
|
-
const index_3 = require("../
|
|
34
|
-
const index_4 = require("../
|
|
35
|
-
const index_5 = require("../
|
|
32
|
+
const index_2 = require("../system/index");
|
|
33
|
+
const index_3 = require("../guard/index");
|
|
34
|
+
const index_4 = require("../format/index");
|
|
35
|
+
const index_5 = require("../custom/index");
|
|
36
|
+
const index_6 = require("../hash/index");
|
|
36
37
|
const Types = require("../typebox");
|
|
37
38
|
// -------------------------------------------------------------------
|
|
38
39
|
// TypeCheck
|
|
@@ -174,7 +175,12 @@ var TypeCompiler;
|
|
|
174
175
|
yield `(${value} === null)`;
|
|
175
176
|
}
|
|
176
177
|
function* Number(schema, value) {
|
|
177
|
-
|
|
178
|
+
if (index_2.TypeSystem.AllowNaN) {
|
|
179
|
+
yield `(typeof ${value} === 'number')`;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
yield `(typeof ${value} === 'number' && !isNaN(${value}))`;
|
|
183
|
+
}
|
|
178
184
|
if (IsNumber(schema.multipleOf))
|
|
179
185
|
yield `(${value} % ${schema.multipleOf} === 0)`;
|
|
180
186
|
if (IsNumber(schema.exclusiveMinimum))
|
|
@@ -187,29 +193,34 @@ var TypeCompiler;
|
|
|
187
193
|
yield `(${value} <= ${schema.maximum})`;
|
|
188
194
|
}
|
|
189
195
|
function* Object(schema, value) {
|
|
190
|
-
|
|
196
|
+
if (index_2.TypeSystem.AllowArrayObjects) {
|
|
197
|
+
yield `(typeof ${value} === 'object' && ${value} !== null)`;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
|
|
201
|
+
}
|
|
191
202
|
if (IsNumber(schema.minProperties))
|
|
192
|
-
yield `(Object.
|
|
203
|
+
yield `(Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties})`;
|
|
193
204
|
if (IsNumber(schema.maxProperties))
|
|
194
|
-
yield `(Object.
|
|
195
|
-
const propertyKeys = globalThis.Object.
|
|
205
|
+
yield `(Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties})`;
|
|
206
|
+
const propertyKeys = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
196
207
|
if (schema.additionalProperties === false) {
|
|
197
208
|
// Optimization: If the property key length matches the required keys length
|
|
198
209
|
// then we only need check that the values property key length matches that
|
|
199
210
|
// of the property key length. This is because exhaustive testing for values
|
|
200
211
|
// will occur in subsequent property tests.
|
|
201
212
|
if (schema.required && schema.required.length === propertyKeys.length) {
|
|
202
|
-
yield `(Object.
|
|
213
|
+
yield `(Object.getOwnPropertyNames(${value}).length === ${propertyKeys.length})`;
|
|
203
214
|
}
|
|
204
215
|
else {
|
|
205
216
|
const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
|
|
206
|
-
yield `(Object.
|
|
217
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key)))`;
|
|
207
218
|
}
|
|
208
219
|
}
|
|
209
|
-
if (
|
|
220
|
+
if (index_3.TypeGuard.TSchema(schema.additionalProperties)) {
|
|
210
221
|
const expression = CreateExpression(schema.additionalProperties, 'value[key]');
|
|
211
222
|
const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
|
|
212
|
-
yield `(Object.
|
|
223
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
|
|
213
224
|
}
|
|
214
225
|
for (const propertyKey of propertyKeys) {
|
|
215
226
|
const memberExpression = Property.Check(propertyKey) ? `${value}.${propertyKey}` : `${value}['${propertyKey}']`;
|
|
@@ -227,10 +238,15 @@ var TypeCompiler;
|
|
|
227
238
|
yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
|
|
228
239
|
}
|
|
229
240
|
function* Record(schema, value) {
|
|
230
|
-
|
|
241
|
+
if (index_2.TypeSystem.AllowArrayObjects) {
|
|
242
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date))`;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !Array.isArray(${value}))`;
|
|
246
|
+
}
|
|
231
247
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
232
248
|
const local = PushLocal(`new RegExp(/${keyPattern}/)`);
|
|
233
|
-
yield `(Object.
|
|
249
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${local}.test(key)))`;
|
|
234
250
|
const expression = CreateExpression(valueSchema, 'value');
|
|
235
251
|
yield `(Object.values(${value}).every(value => ${expression}))`;
|
|
236
252
|
}
|
|
@@ -359,7 +375,7 @@ var TypeCompiler;
|
|
|
359
375
|
case 'Void':
|
|
360
376
|
return yield* Void(anySchema, value);
|
|
361
377
|
default:
|
|
362
|
-
if (!
|
|
378
|
+
if (!index_5.Custom.Has(anySchema[Types.Kind]))
|
|
363
379
|
throw new TypeCompilerUnknownTypeError(schema);
|
|
364
380
|
return yield* UserDefined(anySchema, value);
|
|
365
381
|
}
|
|
@@ -419,23 +435,23 @@ var TypeCompiler;
|
|
|
419
435
|
}
|
|
420
436
|
/** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
|
|
421
437
|
function Compile(schema, references = []) {
|
|
422
|
-
|
|
438
|
+
index_3.TypeGuard.Assert(schema, references);
|
|
423
439
|
const code = Build(schema, references);
|
|
424
440
|
const custom_schemas = new Map(state_remote_custom_types);
|
|
425
441
|
const compiledFunction = globalThis.Function('custom', 'format', 'hash', code);
|
|
426
442
|
const checkFunction = compiledFunction((kind, schema_key, value) => {
|
|
427
|
-
if (!
|
|
443
|
+
if (!index_5.Custom.Has(kind) || !custom_schemas.has(schema_key))
|
|
428
444
|
return false;
|
|
429
445
|
const schema = custom_schemas.get(schema_key);
|
|
430
|
-
const func =
|
|
446
|
+
const func = index_5.Custom.Get(kind);
|
|
431
447
|
return func(schema, value);
|
|
432
448
|
}, (format, value) => {
|
|
433
|
-
if (!
|
|
449
|
+
if (!index_4.Format.Has(format))
|
|
434
450
|
return false;
|
|
435
|
-
const func =
|
|
451
|
+
const func = index_4.Format.Get(format);
|
|
436
452
|
return func(value);
|
|
437
453
|
}, (value) => {
|
|
438
|
-
return
|
|
454
|
+
return index_6.ValueHash.Create(value);
|
|
439
455
|
});
|
|
440
456
|
return new TypeCheck(schema, references, checkFunction, code);
|
|
441
457
|
}
|
package/errors/errors.js
CHANGED
|
@@ -29,9 +29,10 @@ THE SOFTWARE.
|
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
30
|
exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
|
|
31
31
|
const Types = require("../typebox");
|
|
32
|
-
const index_1 = require("../
|
|
33
|
-
const index_2 = require("../
|
|
34
|
-
const index_3 = require("../
|
|
32
|
+
const index_1 = require("../system/index");
|
|
33
|
+
const index_2 = require("../format/index");
|
|
34
|
+
const index_3 = require("../custom/index");
|
|
35
|
+
const index_4 = require("../hash/index");
|
|
35
36
|
// -------------------------------------------------------------------
|
|
36
37
|
// ValueErrorType
|
|
37
38
|
// -------------------------------------------------------------------
|
|
@@ -116,7 +117,7 @@ var ValueErrors;
|
|
|
116
117
|
}
|
|
117
118
|
// prettier-ignore
|
|
118
119
|
if (schema.uniqueItems === true && !((function () { const set = new Set(); for (const element of value) {
|
|
119
|
-
const hashed =
|
|
120
|
+
const hashed = index_4.ValueHash.Create(element);
|
|
120
121
|
if (set.has(hashed)) {
|
|
121
122
|
return false;
|
|
122
123
|
}
|
|
@@ -162,10 +163,7 @@ var ValueErrors;
|
|
|
162
163
|
}
|
|
163
164
|
function* Integer(schema, references, path, value) {
|
|
164
165
|
if (!(typeof value === 'number' && globalThis.Number.isInteger(value))) {
|
|
165
|
-
return yield { type: ValueErrorType.
|
|
166
|
-
}
|
|
167
|
-
if (!globalThis.Number.isInteger(value)) {
|
|
168
|
-
yield { type: ValueErrorType.Integer, schema, path, value, message: `Expected integer` };
|
|
166
|
+
return yield { type: ValueErrorType.Integer, schema, path, value, message: `Expected integer` };
|
|
169
167
|
}
|
|
170
168
|
if (IsNumber(schema.multipleOf) && !(value % schema.multipleOf === 0)) {
|
|
171
169
|
yield { type: ValueErrorType.IntegerMultipleOf, schema, path, value, message: `Expected integer to be a multiple of ${schema.multipleOf}` };
|
|
@@ -198,8 +196,15 @@ var ValueErrors;
|
|
|
198
196
|
}
|
|
199
197
|
}
|
|
200
198
|
function* Number(schema, references, path, value) {
|
|
201
|
-
if (
|
|
202
|
-
|
|
199
|
+
if (index_1.TypeSystem.AllowNaN) {
|
|
200
|
+
if (!(typeof value === 'number')) {
|
|
201
|
+
return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
if (!(typeof value === 'number' && !isNaN(value))) {
|
|
206
|
+
return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` };
|
|
207
|
+
}
|
|
203
208
|
}
|
|
204
209
|
if (IsNumber(schema.multipleOf) && !(value % schema.multipleOf === 0)) {
|
|
205
210
|
yield { type: ValueErrorType.NumberMultipleOf, schema, path, value, message: `Expected number to be a multiple of ${schema.multipleOf}` };
|
|
@@ -218,39 +223,46 @@ var ValueErrors;
|
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
225
|
function* Object(schema, references, path, value) {
|
|
221
|
-
if (
|
|
222
|
-
|
|
226
|
+
if (index_1.TypeSystem.AllowArrayObjects) {
|
|
227
|
+
if (!(typeof value === 'object' && value !== null)) {
|
|
228
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
229
|
+
}
|
|
223
230
|
}
|
|
224
|
-
|
|
231
|
+
else {
|
|
232
|
+
if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
|
|
233
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (IsNumber(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) {
|
|
225
237
|
yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` };
|
|
226
238
|
}
|
|
227
|
-
if (IsNumber(schema.maxProperties) && !(globalThis.Object.
|
|
239
|
+
if (IsNumber(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) {
|
|
228
240
|
yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` };
|
|
229
241
|
}
|
|
230
|
-
const
|
|
242
|
+
const propertyNames = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
231
243
|
if (schema.additionalProperties === false) {
|
|
232
|
-
for (const
|
|
233
|
-
if (!
|
|
234
|
-
yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${
|
|
244
|
+
for (const propertyName of globalThis.Object.getOwnPropertyNames(value)) {
|
|
245
|
+
if (!propertyNames.includes(propertyName)) {
|
|
246
|
+
yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${propertyName}`, value: value[propertyName], message: `Unexpected property` };
|
|
235
247
|
}
|
|
236
248
|
}
|
|
237
249
|
}
|
|
238
250
|
if (schema.required && schema.required.length > 0) {
|
|
239
|
-
const
|
|
251
|
+
const propertyNames = globalThis.Object.getOwnPropertyNames(value);
|
|
240
252
|
for (const requiredKey of schema.required) {
|
|
241
|
-
if (
|
|
253
|
+
if (propertyNames.includes(requiredKey))
|
|
242
254
|
continue;
|
|
243
255
|
yield { type: ValueErrorType.ObjectRequiredProperties, schema: schema.properties[requiredKey], path: `${path}/${requiredKey}`, value: undefined, message: `Expected required property` };
|
|
244
256
|
}
|
|
245
257
|
}
|
|
246
258
|
if (typeof schema.additionalProperties === 'object') {
|
|
247
|
-
for (const
|
|
248
|
-
if (
|
|
259
|
+
for (const propertyName of globalThis.Object.getOwnPropertyNames(value)) {
|
|
260
|
+
if (propertyNames.includes(propertyName))
|
|
249
261
|
continue;
|
|
250
|
-
yield* Visit(schema.additionalProperties, references, `${path}/${
|
|
262
|
+
yield* Visit(schema.additionalProperties, references, `${path}/${propertyName}`, value[propertyName]);
|
|
251
263
|
}
|
|
252
264
|
}
|
|
253
|
-
for (const propertyKey of
|
|
265
|
+
for (const propertyKey of propertyNames) {
|
|
254
266
|
const propertySchema = schema.properties[propertyKey];
|
|
255
267
|
if (schema.required && schema.required.includes(propertyKey)) {
|
|
256
268
|
yield* Visit(propertySchema, references, `${path}/${propertyKey}`, value[propertyKey]);
|
|
@@ -268,12 +280,19 @@ var ValueErrors;
|
|
|
268
280
|
}
|
|
269
281
|
}
|
|
270
282
|
function* Record(schema, references, path, value) {
|
|
271
|
-
if (
|
|
272
|
-
|
|
283
|
+
if (index_1.TypeSystem.AllowArrayObjects) {
|
|
284
|
+
if (!(typeof value === 'object' && value !== null && !(value instanceof globalThis.Date))) {
|
|
285
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
if (!(typeof value === 'object' && value !== null && !(value instanceof globalThis.Date) && !globalThis.Array.isArray(value))) {
|
|
290
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
291
|
+
}
|
|
273
292
|
}
|
|
274
293
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
275
294
|
const regex = new RegExp(keyPattern);
|
|
276
|
-
if (!globalThis.Object.
|
|
295
|
+
if (!globalThis.Object.getOwnPropertyNames(value).every((key) => regex.test(key))) {
|
|
277
296
|
const numeric = keyPattern === '^(0|[1-9][0-9]*)$';
|
|
278
297
|
const type = numeric ? ValueErrorType.RecordKeyNumeric : ValueErrorType.RecordKeyString;
|
|
279
298
|
const message = numeric ? 'Expected all object property keys to be numeric' : 'Expected all object property keys to be strings';
|
|
@@ -312,11 +331,11 @@ var ValueErrors;
|
|
|
312
331
|
}
|
|
313
332
|
}
|
|
314
333
|
if (schema.format !== undefined) {
|
|
315
|
-
if (!
|
|
334
|
+
if (!index_2.Format.Has(schema.format)) {
|
|
316
335
|
yield { type: ValueErrorType.StringFormatUnknown, schema, path, value, message: `Unknown string format '${schema.format}'` };
|
|
317
336
|
}
|
|
318
337
|
else {
|
|
319
|
-
const format =
|
|
338
|
+
const format = index_2.Format.Get(schema.format);
|
|
320
339
|
if (!format(value)) {
|
|
321
340
|
yield { type: ValueErrorType.StringFormat, schema, path, value, message: `Expected string to match format '${schema.format}'` };
|
|
322
341
|
}
|
|
@@ -378,7 +397,7 @@ var ValueErrors;
|
|
|
378
397
|
}
|
|
379
398
|
}
|
|
380
399
|
function* UserDefined(schema, references, path, value) {
|
|
381
|
-
const func =
|
|
400
|
+
const func = index_3.Custom.Get(schema[Types.Kind]);
|
|
382
401
|
if (!func(schema, value)) {
|
|
383
402
|
return yield { type: ValueErrorType.Custom, schema, path, value, message: `Expected kind ${schema[Types.Kind]}` };
|
|
384
403
|
}
|
|
@@ -434,7 +453,7 @@ var ValueErrors;
|
|
|
434
453
|
case 'Void':
|
|
435
454
|
return yield* Void(anySchema, anyReferences, path, value);
|
|
436
455
|
default:
|
|
437
|
-
if (!
|
|
456
|
+
if (!index_3.Custom.Has(anySchema[Types.Kind]))
|
|
438
457
|
throw new ValueErrorsUnknownTypeError(schema);
|
|
439
458
|
return yield* UserDefined(anySchema, anyReferences, path, value);
|
|
440
459
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinclair/typebox",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.16",
|
|
4
4
|
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"./format": "./format/index.js",
|
|
21
21
|
"./guard": "./guard/index.js",
|
|
22
22
|
"./hash": "./hash/index.js",
|
|
23
|
+
"./system": "./system/index.js",
|
|
23
24
|
"./value": "./value/index.js",
|
|
24
25
|
".": "./typebox.js"
|
|
25
26
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './system';
|
package/system/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
@sinclair/typebox/system
|
|
5
|
+
|
|
6
|
+
The MIT License (MIT)
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in
|
|
18
|
+
all copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
26
|
+
THE SOFTWARE.
|
|
27
|
+
|
|
28
|
+
---------------------------------------------------------------------------*/
|
|
29
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
32
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
33
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
34
|
+
}
|
|
35
|
+
Object.defineProperty(o, k2, desc);
|
|
36
|
+
}) : (function(o, m, k, k2) {
|
|
37
|
+
if (k2 === undefined) k2 = k;
|
|
38
|
+
o[k2] = m[k];
|
|
39
|
+
}));
|
|
40
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
41
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
__exportStar(require("./system"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare namespace TypeSystem {
|
|
2
|
+
/**
|
|
3
|
+
* Sets whether arrays should be treated as kinds of objects. The default is `false`
|
|
4
|
+
*/
|
|
5
|
+
let AllowArrayObjects: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Sets whether numeric checks should consider NaN a valid number type. The default is `false`
|
|
8
|
+
*/
|
|
9
|
+
let AllowNaN: boolean;
|
|
10
|
+
}
|
package/system/system.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
@sinclair/typebox/system
|
|
5
|
+
|
|
6
|
+
The MIT License (MIT)
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in
|
|
18
|
+
all copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
26
|
+
THE SOFTWARE.
|
|
27
|
+
|
|
28
|
+
---------------------------------------------------------------------------*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.TypeSystem = void 0;
|
|
31
|
+
var TypeSystem;
|
|
32
|
+
(function (TypeSystem) {
|
|
33
|
+
/**
|
|
34
|
+
* Sets whether arrays should be treated as kinds of objects. The default is `false`
|
|
35
|
+
*/
|
|
36
|
+
TypeSystem.AllowArrayObjects = false;
|
|
37
|
+
/**
|
|
38
|
+
* Sets whether numeric checks should consider NaN a valid number type. The default is `false`
|
|
39
|
+
*/
|
|
40
|
+
TypeSystem.AllowNaN = false;
|
|
41
|
+
})(TypeSystem = exports.TypeSystem || (exports.TypeSystem = {}));
|
package/value/cast.js
CHANGED
|
@@ -239,11 +239,11 @@ var ValueCast;
|
|
|
239
239
|
}
|
|
240
240
|
// additional schema properties
|
|
241
241
|
if (typeof schema.additionalProperties === 'object') {
|
|
242
|
-
const
|
|
243
|
-
for (const
|
|
244
|
-
if (
|
|
242
|
+
const propertyNames = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
243
|
+
for (const propertyName of globalThis.Object.getOwnPropertyNames(value)) {
|
|
244
|
+
if (propertyNames.includes(propertyName))
|
|
245
245
|
continue;
|
|
246
|
-
result[
|
|
246
|
+
result[propertyName] = Visit(schema.additionalProperties, references, value[propertyName]);
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
return result;
|
|
@@ -256,8 +256,8 @@ var ValueCast;
|
|
|
256
256
|
return clone_1.ValueClone.Clone(value);
|
|
257
257
|
if (value === null || typeof value !== 'object' || globalThis.Array.isArray(value) || value instanceof globalThis.Date)
|
|
258
258
|
return create_1.ValueCreate.Create(schema, references);
|
|
259
|
-
const
|
|
260
|
-
const subschema = schema.patternProperties[
|
|
259
|
+
const subschemaPropertyName = globalThis.Object.getOwnPropertyNames(schema.patternProperties)[0];
|
|
260
|
+
const subschema = schema.patternProperties[subschemaPropertyName];
|
|
261
261
|
const result = {};
|
|
262
262
|
for (const [propKey, propValue] of globalThis.Object.entries(value)) {
|
|
263
263
|
result[propKey] = Visit(subschema, references, propValue);
|
package/value/check.js
CHANGED
|
@@ -29,9 +29,10 @@ THE SOFTWARE.
|
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
30
|
exports.ValueCheck = exports.ValueCheckUnknownTypeError = void 0;
|
|
31
31
|
const Types = require("../typebox");
|
|
32
|
-
const index_1 = require("../
|
|
33
|
-
const index_2 = require("../
|
|
34
|
-
const index_3 = require("../
|
|
32
|
+
const index_1 = require("../system/index");
|
|
33
|
+
const index_2 = require("../format/index");
|
|
34
|
+
const index_3 = require("../custom/index");
|
|
35
|
+
const index_4 = require("../hash/index");
|
|
35
36
|
class ValueCheckUnknownTypeError extends Error {
|
|
36
37
|
constructor(schema) {
|
|
37
38
|
super(`ValueCheck: ${schema[Types.Kind] ? `Unknown type '${schema[Types.Kind]}'` : 'Unknown type'}`);
|
|
@@ -59,7 +60,7 @@ var ValueCheck;
|
|
|
59
60
|
}
|
|
60
61
|
// prettier-ignore
|
|
61
62
|
if (schema.uniqueItems === true && !((function () { const set = new Set(); for (const element of value) {
|
|
62
|
-
const hashed =
|
|
63
|
+
const hashed = index_4.ValueHash.Create(element);
|
|
63
64
|
if (set.has(hashed)) {
|
|
64
65
|
return false;
|
|
65
66
|
}
|
|
@@ -102,9 +103,6 @@ var ValueCheck;
|
|
|
102
103
|
if (!(typeof value === 'number' && globalThis.Number.isInteger(value))) {
|
|
103
104
|
return false;
|
|
104
105
|
}
|
|
105
|
-
if (!globalThis.Number.isInteger(value)) {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
106
|
if (IsNumber(schema.multipleOf) && !(value % schema.multipleOf === 0)) {
|
|
109
107
|
return false;
|
|
110
108
|
}
|
|
@@ -132,8 +130,15 @@ var ValueCheck;
|
|
|
132
130
|
return value === null;
|
|
133
131
|
}
|
|
134
132
|
function Number(schema, references, value) {
|
|
135
|
-
if (
|
|
136
|
-
|
|
133
|
+
if (index_1.TypeSystem.AllowNaN) {
|
|
134
|
+
if (!(typeof value === 'number')) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
if (!(typeof value === 'number' && !isNaN(value))) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
137
142
|
}
|
|
138
143
|
if (IsNumber(schema.multipleOf) && !(value % schema.multipleOf === 0)) {
|
|
139
144
|
return false;
|
|
@@ -153,32 +158,39 @@ var ValueCheck;
|
|
|
153
158
|
return true;
|
|
154
159
|
}
|
|
155
160
|
function Object(schema, references, value) {
|
|
156
|
-
if (
|
|
157
|
-
|
|
161
|
+
if (index_1.TypeSystem.AllowArrayObjects) {
|
|
162
|
+
if (!(typeof value === 'object' && value !== null)) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
158
165
|
}
|
|
159
|
-
|
|
166
|
+
else {
|
|
167
|
+
if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (IsNumber(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) {
|
|
160
172
|
return false;
|
|
161
173
|
}
|
|
162
|
-
if (IsNumber(schema.maxProperties) && !(globalThis.Object.
|
|
174
|
+
if (IsNumber(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) {
|
|
163
175
|
return false;
|
|
164
176
|
}
|
|
165
|
-
const propertyKeys = globalThis.Object.
|
|
177
|
+
const propertyKeys = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
166
178
|
if (schema.additionalProperties === false) {
|
|
167
179
|
// optimization: If the property key length matches the required keys length
|
|
168
180
|
// then we only need check that the values property key length matches that
|
|
169
181
|
// of the property key length. This is because exhaustive testing for values
|
|
170
182
|
// will occur in subsequent property tests.
|
|
171
|
-
if (schema.required && schema.required.length === propertyKeys.length && !(globalThis.Object.
|
|
183
|
+
if (schema.required && schema.required.length === propertyKeys.length && !(globalThis.Object.getOwnPropertyNames(value).length === propertyKeys.length)) {
|
|
172
184
|
return false;
|
|
173
185
|
}
|
|
174
186
|
else {
|
|
175
|
-
if (!globalThis.Object.
|
|
187
|
+
if (!globalThis.Object.getOwnPropertyNames(value).every((key) => propertyKeys.includes(key))) {
|
|
176
188
|
return false;
|
|
177
189
|
}
|
|
178
190
|
}
|
|
179
191
|
}
|
|
180
192
|
if (typeof schema.additionalProperties === 'object') {
|
|
181
|
-
for (const objectKey of globalThis.Object.
|
|
193
|
+
for (const objectKey of globalThis.Object.getOwnPropertyNames(value)) {
|
|
182
194
|
if (propertyKeys.includes(objectKey))
|
|
183
195
|
continue;
|
|
184
196
|
if (!Visit(schema.additionalProperties, references, value[objectKey])) {
|
|
@@ -207,12 +219,19 @@ var ValueCheck;
|
|
|
207
219
|
return typeof value === 'object' && typeof value.then === 'function';
|
|
208
220
|
}
|
|
209
221
|
function Record(schema, references, value) {
|
|
210
|
-
if (
|
|
211
|
-
|
|
222
|
+
if (index_1.TypeSystem.AllowArrayObjects) {
|
|
223
|
+
if (!(typeof value === 'object' && value !== null && !(value instanceof globalThis.Date))) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
if (!(typeof value === 'object' && value !== null && !(value instanceof globalThis.Date) && !globalThis.Array.isArray(value))) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
212
231
|
}
|
|
213
232
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
214
233
|
const regex = new RegExp(keyPattern);
|
|
215
|
-
if (!globalThis.Object.
|
|
234
|
+
if (!globalThis.Object.getOwnPropertyNames(value).every((key) => regex.test(key))) {
|
|
216
235
|
return false;
|
|
217
236
|
}
|
|
218
237
|
for (const propValue of globalThis.Object.values(value)) {
|
|
@@ -251,9 +270,9 @@ var ValueCheck;
|
|
|
251
270
|
return false;
|
|
252
271
|
}
|
|
253
272
|
if (schema.format !== undefined) {
|
|
254
|
-
if (!
|
|
273
|
+
if (!index_2.Format.Has(schema.format))
|
|
255
274
|
return false;
|
|
256
|
-
const func =
|
|
275
|
+
const func = index_2.Format.Get(schema.format);
|
|
257
276
|
return func(value);
|
|
258
277
|
}
|
|
259
278
|
return true;
|
|
@@ -302,9 +321,9 @@ var ValueCheck;
|
|
|
302
321
|
return value === null;
|
|
303
322
|
}
|
|
304
323
|
function UserDefined(schema, references, value) {
|
|
305
|
-
if (!
|
|
324
|
+
if (!index_3.Custom.Has(schema[Types.Kind]))
|
|
306
325
|
return false;
|
|
307
|
-
const func =
|
|
326
|
+
const func = index_3.Custom.Get(schema[Types.Kind]);
|
|
308
327
|
return func(schema, value);
|
|
309
328
|
}
|
|
310
329
|
function Visit(schema, references, value) {
|
|
@@ -358,7 +377,7 @@ var ValueCheck;
|
|
|
358
377
|
case 'Void':
|
|
359
378
|
return Void(anySchema, anyReferences, value);
|
|
360
379
|
default:
|
|
361
|
-
if (!
|
|
380
|
+
if (!index_3.Custom.Has(anySchema[Types.Kind]))
|
|
362
381
|
throw new ValueCheckUnknownTypeError(anySchema);
|
|
363
382
|
return UserDefined(anySchema, anyReferences, value);
|
|
364
383
|
}
|