@sinclair/typebox 0.25.13 → 0.25.15
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 +32 -21
- package/errors/errors.js +40 -25
- package/package.json +2 -1
- package/readme.md +17 -17
- package/system/index.d.ts +1 -0
- package/system/index.js +44 -0
- package/system/system.d.ts +18 -0
- package/system/system.js +57 -0
- package/value/cast.js +6 -6
- package/value/check.js +35 -20
- package/value/create.js +24 -4
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
|
|
@@ -187,29 +188,34 @@ var TypeCompiler;
|
|
|
187
188
|
yield `(${value} <= ${schema.maximum})`;
|
|
188
189
|
}
|
|
189
190
|
function* Object(schema, value) {
|
|
190
|
-
|
|
191
|
+
if (index_2.TypeSystem.Kind === 'json-schema') {
|
|
192
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
|
|
193
|
+
}
|
|
194
|
+
else if (index_2.TypeSystem.Kind === 'structural') {
|
|
195
|
+
yield `(typeof ${value} === 'object' && ${value} !== null)`;
|
|
196
|
+
}
|
|
191
197
|
if (IsNumber(schema.minProperties))
|
|
192
|
-
yield `(Object.
|
|
198
|
+
yield `(Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties})`;
|
|
193
199
|
if (IsNumber(schema.maxProperties))
|
|
194
|
-
yield `(Object.
|
|
195
|
-
const propertyKeys = globalThis.Object.
|
|
200
|
+
yield `(Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties})`;
|
|
201
|
+
const propertyKeys = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
196
202
|
if (schema.additionalProperties === false) {
|
|
197
203
|
// Optimization: If the property key length matches the required keys length
|
|
198
204
|
// then we only need check that the values property key length matches that
|
|
199
205
|
// of the property key length. This is because exhaustive testing for values
|
|
200
206
|
// will occur in subsequent property tests.
|
|
201
207
|
if (schema.required && schema.required.length === propertyKeys.length) {
|
|
202
|
-
yield `(Object.
|
|
208
|
+
yield `(Object.getOwnPropertyNames(${value}).length === ${propertyKeys.length})`;
|
|
203
209
|
}
|
|
204
210
|
else {
|
|
205
211
|
const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
|
|
206
|
-
yield `(Object.
|
|
212
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key)))`;
|
|
207
213
|
}
|
|
208
214
|
}
|
|
209
|
-
if (
|
|
215
|
+
if (index_3.TypeGuard.TSchema(schema.additionalProperties)) {
|
|
210
216
|
const expression = CreateExpression(schema.additionalProperties, 'value[key]');
|
|
211
217
|
const keys = `[${propertyKeys.map((key) => `'${key}'`).join(', ')}]`;
|
|
212
|
-
yield `(Object.
|
|
218
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
|
|
213
219
|
}
|
|
214
220
|
for (const propertyKey of propertyKeys) {
|
|
215
221
|
const memberExpression = Property.Check(propertyKey) ? `${value}.${propertyKey}` : `${value}['${propertyKey}']`;
|
|
@@ -227,10 +233,15 @@ var TypeCompiler;
|
|
|
227
233
|
yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
|
|
228
234
|
}
|
|
229
235
|
function* Record(schema, value) {
|
|
230
|
-
|
|
236
|
+
if (index_2.TypeSystem.Kind === 'json-schema') {
|
|
237
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date))`;
|
|
238
|
+
}
|
|
239
|
+
else if (index_2.TypeSystem.Kind === 'structural') {
|
|
240
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date))`;
|
|
241
|
+
}
|
|
231
242
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
232
243
|
const local = PushLocal(`new RegExp(/${keyPattern}/)`);
|
|
233
|
-
yield `(Object.
|
|
244
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${local}.test(key)))`;
|
|
234
245
|
const expression = CreateExpression(valueSchema, 'value');
|
|
235
246
|
yield `(Object.values(${value}).every(value => ${expression}))`;
|
|
236
247
|
}
|
|
@@ -359,7 +370,7 @@ var TypeCompiler;
|
|
|
359
370
|
case 'Void':
|
|
360
371
|
return yield* Void(anySchema, value);
|
|
361
372
|
default:
|
|
362
|
-
if (!
|
|
373
|
+
if (!index_5.Custom.Has(anySchema[Types.Kind]))
|
|
363
374
|
throw new TypeCompilerUnknownTypeError(schema);
|
|
364
375
|
return yield* UserDefined(anySchema, value);
|
|
365
376
|
}
|
|
@@ -419,23 +430,23 @@ var TypeCompiler;
|
|
|
419
430
|
}
|
|
420
431
|
/** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
|
|
421
432
|
function Compile(schema, references = []) {
|
|
422
|
-
|
|
433
|
+
index_3.TypeGuard.Assert(schema, references);
|
|
423
434
|
const code = Build(schema, references);
|
|
424
435
|
const custom_schemas = new Map(state_remote_custom_types);
|
|
425
436
|
const compiledFunction = globalThis.Function('custom', 'format', 'hash', code);
|
|
426
437
|
const checkFunction = compiledFunction((kind, schema_key, value) => {
|
|
427
|
-
if (!
|
|
438
|
+
if (!index_5.Custom.Has(kind) || !custom_schemas.has(schema_key))
|
|
428
439
|
return false;
|
|
429
440
|
const schema = custom_schemas.get(schema_key);
|
|
430
|
-
const func =
|
|
441
|
+
const func = index_5.Custom.Get(kind);
|
|
431
442
|
return func(schema, value);
|
|
432
443
|
}, (format, value) => {
|
|
433
|
-
if (!
|
|
444
|
+
if (!index_4.Format.Has(format))
|
|
434
445
|
return false;
|
|
435
|
-
const func =
|
|
446
|
+
const func = index_4.Format.Get(format);
|
|
436
447
|
return func(value);
|
|
437
448
|
}, (value) => {
|
|
438
|
-
return
|
|
449
|
+
return index_6.ValueHash.Create(value);
|
|
439
450
|
});
|
|
440
451
|
return new TypeCheck(schema, references, checkFunction, code);
|
|
441
452
|
}
|
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
|
}
|
|
@@ -218,39 +219,46 @@ var ValueErrors;
|
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
221
|
function* Object(schema, references, path, value) {
|
|
221
|
-
if (
|
|
222
|
-
|
|
222
|
+
if (index_1.TypeSystem.Kind === 'json-schema') {
|
|
223
|
+
if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
|
|
224
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else if (index_1.TypeSystem.Kind === 'structural') {
|
|
228
|
+
if (!(typeof value === 'object' && value !== null)) {
|
|
229
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
230
|
+
}
|
|
223
231
|
}
|
|
224
|
-
if (IsNumber(schema.minProperties) && !(globalThis.Object.
|
|
232
|
+
if (IsNumber(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) {
|
|
225
233
|
yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` };
|
|
226
234
|
}
|
|
227
|
-
if (IsNumber(schema.maxProperties) && !(globalThis.Object.
|
|
235
|
+
if (IsNumber(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) {
|
|
228
236
|
yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` };
|
|
229
237
|
}
|
|
230
|
-
const
|
|
238
|
+
const propertyNames = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
231
239
|
if (schema.additionalProperties === false) {
|
|
232
|
-
for (const
|
|
233
|
-
if (!
|
|
234
|
-
yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${
|
|
240
|
+
for (const propertyName of globalThis.Object.getOwnPropertyNames(value)) {
|
|
241
|
+
if (!propertyNames.includes(propertyName)) {
|
|
242
|
+
yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${propertyName}`, value: value[propertyName], message: `Unexpected property` };
|
|
235
243
|
}
|
|
236
244
|
}
|
|
237
245
|
}
|
|
238
246
|
if (schema.required && schema.required.length > 0) {
|
|
239
|
-
const
|
|
247
|
+
const propertyNames = globalThis.Object.getOwnPropertyNames(value);
|
|
240
248
|
for (const requiredKey of schema.required) {
|
|
241
|
-
if (
|
|
249
|
+
if (propertyNames.includes(requiredKey))
|
|
242
250
|
continue;
|
|
243
251
|
yield { type: ValueErrorType.ObjectRequiredProperties, schema: schema.properties[requiredKey], path: `${path}/${requiredKey}`, value: undefined, message: `Expected required property` };
|
|
244
252
|
}
|
|
245
253
|
}
|
|
246
254
|
if (typeof schema.additionalProperties === 'object') {
|
|
247
|
-
for (const
|
|
248
|
-
if (
|
|
255
|
+
for (const propertyName of globalThis.Object.getOwnPropertyNames(value)) {
|
|
256
|
+
if (propertyNames.includes(propertyName))
|
|
249
257
|
continue;
|
|
250
|
-
yield* Visit(schema.additionalProperties, references, `${path}/${
|
|
258
|
+
yield* Visit(schema.additionalProperties, references, `${path}/${propertyName}`, value[propertyName]);
|
|
251
259
|
}
|
|
252
260
|
}
|
|
253
|
-
for (const propertyKey of
|
|
261
|
+
for (const propertyKey of propertyNames) {
|
|
254
262
|
const propertySchema = schema.properties[propertyKey];
|
|
255
263
|
if (schema.required && schema.required.includes(propertyKey)) {
|
|
256
264
|
yield* Visit(propertySchema, references, `${path}/${propertyKey}`, value[propertyKey]);
|
|
@@ -268,12 +276,19 @@ var ValueErrors;
|
|
|
268
276
|
}
|
|
269
277
|
}
|
|
270
278
|
function* Record(schema, references, path, value) {
|
|
271
|
-
if (
|
|
272
|
-
|
|
279
|
+
if (index_1.TypeSystem.Kind === 'json-schema') {
|
|
280
|
+
if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value) && !(value instanceof globalThis.Date))) {
|
|
281
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else if (index_1.TypeSystem.Kind === 'structural') {
|
|
285
|
+
if (!(typeof value === 'object' && value !== null && !(value instanceof globalThis.Date))) {
|
|
286
|
+
return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
|
|
287
|
+
}
|
|
273
288
|
}
|
|
274
289
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
275
290
|
const regex = new RegExp(keyPattern);
|
|
276
|
-
if (!globalThis.Object.
|
|
291
|
+
if (!globalThis.Object.getOwnPropertyNames(value).every((key) => regex.test(key))) {
|
|
277
292
|
const numeric = keyPattern === '^(0|[1-9][0-9]*)$';
|
|
278
293
|
const type = numeric ? ValueErrorType.RecordKeyNumeric : ValueErrorType.RecordKeyString;
|
|
279
294
|
const message = numeric ? 'Expected all object property keys to be numeric' : 'Expected all object property keys to be strings';
|
|
@@ -312,11 +327,11 @@ var ValueErrors;
|
|
|
312
327
|
}
|
|
313
328
|
}
|
|
314
329
|
if (schema.format !== undefined) {
|
|
315
|
-
if (!
|
|
330
|
+
if (!index_2.Format.Has(schema.format)) {
|
|
316
331
|
yield { type: ValueErrorType.StringFormatUnknown, schema, path, value, message: `Unknown string format '${schema.format}'` };
|
|
317
332
|
}
|
|
318
333
|
else {
|
|
319
|
-
const format =
|
|
334
|
+
const format = index_2.Format.Get(schema.format);
|
|
320
335
|
if (!format(value)) {
|
|
321
336
|
yield { type: ValueErrorType.StringFormat, schema, path, value, message: `Expected string to match format '${schema.format}'` };
|
|
322
337
|
}
|
|
@@ -378,7 +393,7 @@ var ValueErrors;
|
|
|
378
393
|
}
|
|
379
394
|
}
|
|
380
395
|
function* UserDefined(schema, references, path, value) {
|
|
381
|
-
const func =
|
|
396
|
+
const func = index_3.Custom.Get(schema[Types.Kind]);
|
|
382
397
|
if (!func(schema, value)) {
|
|
383
398
|
return yield { type: ValueErrorType.Custom, schema, path, value, message: `Expected kind ${schema[Types.Kind]}` };
|
|
384
399
|
}
|
|
@@ -434,7 +449,7 @@ var ValueErrors;
|
|
|
434
449
|
case 'Void':
|
|
435
450
|
return yield* Void(anySchema, anyReferences, path, value);
|
|
436
451
|
default:
|
|
437
|
-
if (!
|
|
452
|
+
if (!index_3.Custom.Has(anySchema[Types.Kind]))
|
|
438
453
|
throw new ValueErrorsUnknownTypeError(schema);
|
|
439
454
|
return yield* UserDefined(anySchema, anyReferences, path, value);
|
|
440
455
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinclair/typebox",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.15",
|
|
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
|
},
|
package/readme.md
CHANGED
|
@@ -1143,27 +1143,28 @@ The custom module is an optional import.
|
|
|
1143
1143
|
import { Custom } from '@sinclair/typebox/custom'
|
|
1144
1144
|
```
|
|
1145
1145
|
|
|
1146
|
-
The following creates a `
|
|
1146
|
+
The following creates a `bigint` type.
|
|
1147
1147
|
|
|
1148
1148
|
```typescript
|
|
1149
1149
|
import { Type, Kind } from '@sinclair/typebox'
|
|
1150
1150
|
|
|
1151
|
-
Custom.Set('
|
|
1151
|
+
Custom.Set('bigint', (schema, value) => typeof value === 'bigint')
|
|
1152
|
+
// ▲
|
|
1152
1153
|
// │
|
|
1153
|
-
// └────────────────────────────┐
|
|
1154
|
+
// └────────────────────────────┐
|
|
1154
1155
|
// │
|
|
1155
|
-
const T = Type.Unsafe<bigint>({ [Kind]: '
|
|
1156
|
+
const T = Type.Unsafe<bigint>({ [Kind]: 'bigint' }) // const T = { [Kind]: 'BigInt' }
|
|
1156
1157
|
|
|
1157
|
-
const A = TypeCompiler.Compile(T).Check(
|
|
1158
|
+
const A = TypeCompiler.Compile(T).Check(1n) // const A = true
|
|
1158
1159
|
|
|
1159
|
-
const B = Value.Check(T,
|
|
1160
|
+
const B = Value.Check(T, 1) // const B = false
|
|
1160
1161
|
```
|
|
1161
1162
|
|
|
1162
1163
|
<a name='typecheck-custom-formats'></a>
|
|
1163
1164
|
|
|
1164
1165
|
### Custom Formats
|
|
1165
1166
|
|
|
1166
|
-
Use the format module to create user defined string formats. If using Ajv, please refer to the official Ajv format documentation located [here](https://ajv.js.org/guide/formats.html).
|
|
1167
|
+
Use the format module to create user defined string formats. The format module is specific to TypeBox can only be used with the TypeCompiler and Value modules. If using Ajv, please refer to the official Ajv format documentation located [here](https://ajv.js.org/guide/formats.html).
|
|
1167
1168
|
|
|
1168
1169
|
The format module is an optional import.
|
|
1169
1170
|
|
|
@@ -1171,20 +1172,19 @@ The format module is an optional import.
|
|
|
1171
1172
|
import { Format } from '@sinclair/typebox/format'
|
|
1172
1173
|
```
|
|
1173
1174
|
|
|
1174
|
-
The following creates a
|
|
1175
|
+
The following creates a custom string format that checks for lowercase.
|
|
1175
1176
|
|
|
1176
1177
|
```typescript
|
|
1177
|
-
Format.Set('
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
const T = Type.String({ format: 'palindrome' })
|
|
1178
|
+
Format.Set('lowercase', value => value === value.toLowerCase())
|
|
1179
|
+
// ▲
|
|
1180
|
+
// │
|
|
1181
|
+
// └────────────────────┐
|
|
1182
|
+
// │
|
|
1183
|
+
const T = Type.String({ format: 'lowercase' })
|
|
1184
1184
|
|
|
1185
|
-
const A = TypeCompiler.Compile(T).Check('
|
|
1185
|
+
const A = TypeCompiler.Compile(T).Check('action') // const A = true
|
|
1186
1186
|
|
|
1187
|
-
const B = Value.Check(T, '
|
|
1187
|
+
const B = Value.Check(T, 'Action') // const B = false
|
|
1188
1188
|
```
|
|
1189
1189
|
|
|
1190
1190
|
<a name='benchmark'></a>
|
|
@@ -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,18 @@
|
|
|
1
|
+
export declare class InvalidTypeSystemError extends Error {
|
|
2
|
+
constructor(typeSystem: string);
|
|
3
|
+
}
|
|
4
|
+
export type TypeSystemKind = 'json-schema' | 'structural';
|
|
5
|
+
declare class TypeSystemSettings {
|
|
6
|
+
private kind;
|
|
7
|
+
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* `Experimental` Sets the type system kind used by TypeBox. By default TypeBox uses `json-schema` assertion
|
|
10
|
+
* rules to verify JavaScript values. If setting the type system to `structural`, TypeBox will use TypeScript
|
|
11
|
+
* structural checking rules enabling Arrays to be validated as Objects.
|
|
12
|
+
*/
|
|
13
|
+
get Kind(): TypeSystemKind;
|
|
14
|
+
set Kind(value: TypeSystemKind);
|
|
15
|
+
}
|
|
16
|
+
/** TypeBox TypeSystem Settings */
|
|
17
|
+
export declare const TypeSystem: TypeSystemSettings;
|
|
18
|
+
export {};
|
package/system/system.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
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 = exports.InvalidTypeSystemError = void 0;
|
|
31
|
+
class InvalidTypeSystemError extends Error {
|
|
32
|
+
constructor(typeSystem) {
|
|
33
|
+
super(`TypeSystemSettings: Unknown TypeSystem '${typeSystem}'`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.InvalidTypeSystemError = InvalidTypeSystemError;
|
|
37
|
+
class TypeSystemSettings {
|
|
38
|
+
constructor() {
|
|
39
|
+
this.kind = 'json-schema';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `Experimental` Sets the type system kind used by TypeBox. By default TypeBox uses `json-schema` assertion
|
|
43
|
+
* rules to verify JavaScript values. If setting the type system to `structural`, TypeBox will use TypeScript
|
|
44
|
+
* structural checking rules enabling Arrays to be validated as Objects.
|
|
45
|
+
*/
|
|
46
|
+
get Kind() {
|
|
47
|
+
return this.kind;
|
|
48
|
+
}
|
|
49
|
+
set Kind(value) {
|
|
50
|
+
if (!(value === 'json-schema' || value === 'structural')) {
|
|
51
|
+
throw new InvalidTypeSystemError(value);
|
|
52
|
+
}
|
|
53
|
+
this.kind = value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** TypeBox TypeSystem Settings */
|
|
57
|
+
exports.TypeSystem = new TypeSystemSettings();
|
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
|
}
|
|
@@ -153,32 +154,39 @@ var ValueCheck;
|
|
|
153
154
|
return true;
|
|
154
155
|
}
|
|
155
156
|
function Object(schema, references, value) {
|
|
156
|
-
if (
|
|
157
|
-
|
|
157
|
+
if (index_1.TypeSystem.Kind === 'json-schema') {
|
|
158
|
+
if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (index_1.TypeSystem.Kind === 'structural') {
|
|
163
|
+
if (!(typeof value === 'object' && value !== null)) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
158
166
|
}
|
|
159
|
-
if (IsNumber(schema.minProperties) && !(globalThis.Object.
|
|
167
|
+
if (IsNumber(schema.minProperties) && !(globalThis.Object.getOwnPropertyNames(value).length >= schema.minProperties)) {
|
|
160
168
|
return false;
|
|
161
169
|
}
|
|
162
|
-
if (IsNumber(schema.maxProperties) && !(globalThis.Object.
|
|
170
|
+
if (IsNumber(schema.maxProperties) && !(globalThis.Object.getOwnPropertyNames(value).length <= schema.maxProperties)) {
|
|
163
171
|
return false;
|
|
164
172
|
}
|
|
165
|
-
const propertyKeys = globalThis.Object.
|
|
173
|
+
const propertyKeys = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
166
174
|
if (schema.additionalProperties === false) {
|
|
167
175
|
// optimization: If the property key length matches the required keys length
|
|
168
176
|
// then we only need check that the values property key length matches that
|
|
169
177
|
// of the property key length. This is because exhaustive testing for values
|
|
170
178
|
// will occur in subsequent property tests.
|
|
171
|
-
if (schema.required && schema.required.length === propertyKeys.length && !(globalThis.Object.
|
|
179
|
+
if (schema.required && schema.required.length === propertyKeys.length && !(globalThis.Object.getOwnPropertyNames(value).length === propertyKeys.length)) {
|
|
172
180
|
return false;
|
|
173
181
|
}
|
|
174
182
|
else {
|
|
175
|
-
if (!globalThis.Object.
|
|
183
|
+
if (!globalThis.Object.getOwnPropertyNames(value).every((key) => propertyKeys.includes(key))) {
|
|
176
184
|
return false;
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
187
|
}
|
|
180
188
|
if (typeof schema.additionalProperties === 'object') {
|
|
181
|
-
for (const objectKey of globalThis.Object.
|
|
189
|
+
for (const objectKey of globalThis.Object.getOwnPropertyNames(value)) {
|
|
182
190
|
if (propertyKeys.includes(objectKey))
|
|
183
191
|
continue;
|
|
184
192
|
if (!Visit(schema.additionalProperties, references, value[objectKey])) {
|
|
@@ -207,12 +215,19 @@ var ValueCheck;
|
|
|
207
215
|
return typeof value === 'object' && typeof value.then === 'function';
|
|
208
216
|
}
|
|
209
217
|
function Record(schema, references, value) {
|
|
210
|
-
if (
|
|
211
|
-
|
|
218
|
+
if (index_1.TypeSystem.Kind === 'json-schema') {
|
|
219
|
+
if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value) && !(value instanceof globalThis.Date))) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (index_1.TypeSystem.Kind === 'structural') {
|
|
224
|
+
if (!(typeof value === 'object' && value !== null && !(value instanceof globalThis.Date))) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
212
227
|
}
|
|
213
228
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
214
229
|
const regex = new RegExp(keyPattern);
|
|
215
|
-
if (!globalThis.Object.
|
|
230
|
+
if (!globalThis.Object.getOwnPropertyNames(value).every((key) => regex.test(key))) {
|
|
216
231
|
return false;
|
|
217
232
|
}
|
|
218
233
|
for (const propValue of globalThis.Object.values(value)) {
|
|
@@ -251,9 +266,9 @@ var ValueCheck;
|
|
|
251
266
|
return false;
|
|
252
267
|
}
|
|
253
268
|
if (schema.format !== undefined) {
|
|
254
|
-
if (!
|
|
269
|
+
if (!index_2.Format.Has(schema.format))
|
|
255
270
|
return false;
|
|
256
|
-
const func =
|
|
271
|
+
const func = index_2.Format.Get(schema.format);
|
|
257
272
|
return func(value);
|
|
258
273
|
}
|
|
259
274
|
return true;
|
|
@@ -302,9 +317,9 @@ var ValueCheck;
|
|
|
302
317
|
return value === null;
|
|
303
318
|
}
|
|
304
319
|
function UserDefined(schema, references, value) {
|
|
305
|
-
if (!
|
|
320
|
+
if (!index_3.Custom.Has(schema[Types.Kind]))
|
|
306
321
|
return false;
|
|
307
|
-
const func =
|
|
322
|
+
const func = index_3.Custom.Get(schema[Types.Kind]);
|
|
308
323
|
return func(schema, value);
|
|
309
324
|
}
|
|
310
325
|
function Visit(schema, references, value) {
|
|
@@ -358,7 +373,7 @@ var ValueCheck;
|
|
|
358
373
|
case 'Void':
|
|
359
374
|
return Void(anySchema, anyReferences, value);
|
|
360
375
|
default:
|
|
361
|
-
if (!
|
|
376
|
+
if (!index_3.Custom.Has(anySchema[Types.Kind]))
|
|
362
377
|
throw new ValueCheckUnknownTypeError(anySchema);
|
|
363
378
|
return UserDefined(anySchema, anyReferences, value);
|
|
364
379
|
}
|
package/value/create.js
CHANGED
|
@@ -131,13 +131,23 @@ var ValueCreate;
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
function Literal(schema, references) {
|
|
134
|
-
|
|
134
|
+
if (schema.default !== undefined) {
|
|
135
|
+
return schema.default;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
return schema.const;
|
|
139
|
+
}
|
|
135
140
|
}
|
|
136
141
|
function Never(schema, references) {
|
|
137
142
|
throw new ValueCreateNeverTypeError(schema);
|
|
138
143
|
}
|
|
139
144
|
function Null(schema, references) {
|
|
140
|
-
|
|
145
|
+
if (schema.default !== undefined) {
|
|
146
|
+
return schema.default;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
141
151
|
}
|
|
142
152
|
function Number(schema, references) {
|
|
143
153
|
if (schema.default !== undefined) {
|
|
@@ -258,7 +268,12 @@ var ValueCreate;
|
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
270
|
function Undefined(schema, references) {
|
|
261
|
-
|
|
271
|
+
if (schema.default !== undefined) {
|
|
272
|
+
return schema.default;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
262
277
|
}
|
|
263
278
|
function Union(schema, references) {
|
|
264
279
|
if (schema.default !== undefined) {
|
|
@@ -291,7 +306,12 @@ var ValueCreate;
|
|
|
291
306
|
}
|
|
292
307
|
}
|
|
293
308
|
function Void(schema, references) {
|
|
294
|
-
|
|
309
|
+
if (schema.default !== undefined) {
|
|
310
|
+
return schema.default;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
295
315
|
}
|
|
296
316
|
function UserDefined(schema, references) {
|
|
297
317
|
if (schema.default !== undefined) {
|