@sinclair/typebox 0.24.13 → 0.24.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/index.js +5 -1
- package/conditional/conditional.d.ts +17 -0
- package/conditional/conditional.js +91 -0
- package/conditional/index.d.ts +2 -0
- package/conditional/index.js +45 -0
- package/conditional/structural.d.ts +11 -0
- package/conditional/structural.js +654 -0
- package/guard/guard.d.ts +1 -1
- package/guard/guard.js +3 -3
- package/guard/index.js +5 -1
- package/package.json +2 -2
- package/readme.md +56 -4
- package/typebox.d.ts +16 -4
- package/typebox.js +16 -0
- package/value/cast.js +4 -3
- package/value/index.js +5 -1
package/compiler/index.js
CHANGED
|
@@ -28,7 +28,11 @@ THE SOFTWARE.
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
29
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
30
|
if (k2 === undefined) k2 = k;
|
|
31
|
-
Object.
|
|
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);
|
|
32
36
|
}) : (function(o, m, k, k2) {
|
|
33
37
|
if (k2 === undefined) k2 = k;
|
|
34
38
|
o[k2] = m[k];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as Types from '../typebox';
|
|
2
|
+
export declare type TExtends<L extends Types.TSchema, R extends Types.TSchema, T extends Types.TSchema, U extends Types.TSchema> = Types.Static<L> extends Types.Static<R> ? T : U;
|
|
3
|
+
export interface TExclude<T extends Types.TUnion, U extends Types.TUnion> extends Types.TUnion<any[]> {
|
|
4
|
+
static: Exclude<Types.Static<T, this['params']>, Types.Static<U, this['params']>>;
|
|
5
|
+
}
|
|
6
|
+
export interface TExtract<T extends Types.TSchema, U extends Types.TUnion> extends Types.TUnion<any[]> {
|
|
7
|
+
static: Extract<Types.Static<T, this['params']>, Types.Static<U, this['params']>>;
|
|
8
|
+
}
|
|
9
|
+
/** Provides Conditional Types */
|
|
10
|
+
export declare namespace Conditional {
|
|
11
|
+
/** (Experimental) Creates a conditional expression type */
|
|
12
|
+
function Extends<L extends Types.TSchema, R extends Types.TSchema, T extends Types.TSchema, U extends Types.TSchema>(left: L, right: R, ok: T, fail: U): TExtends<L, R, T, U>;
|
|
13
|
+
/** (Experimental) Constructs a type by excluding from UnionType all union members that are assignable to ExcludedMembers. */
|
|
14
|
+
function Exclude<T extends Types.TUnion, U extends Types.TUnion>(unionType: T, excludedMembers: U, options?: Types.SchemaOptions): TExclude<T, U>;
|
|
15
|
+
/** (Experimental) Constructs a type by extracting from Type all union members that are assignable to Union. */
|
|
16
|
+
function Extract<T extends Types.TSchema, U extends Types.TUnion>(type: T, union: U, options?: Types.SchemaOptions): TExtract<T, U>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
@sinclair/typebox/conditional
|
|
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.Conditional = void 0;
|
|
31
|
+
const Types = require("../typebox");
|
|
32
|
+
const structural_1 = require("./structural");
|
|
33
|
+
const guard_1 = require("../guard");
|
|
34
|
+
/** Provides Conditional Types */
|
|
35
|
+
var Conditional;
|
|
36
|
+
(function (Conditional) {
|
|
37
|
+
/** (Experimental) Creates a conditional expression type */
|
|
38
|
+
function Extends(left, right, ok, fail) {
|
|
39
|
+
switch (structural_1.Structural.Check(left, right)) {
|
|
40
|
+
case structural_1.StructuralResult.Union:
|
|
41
|
+
return Types.Type.Union([Clone(ok), Clone(fail)]);
|
|
42
|
+
case structural_1.StructuralResult.True:
|
|
43
|
+
return Clone(ok);
|
|
44
|
+
case structural_1.StructuralResult.False:
|
|
45
|
+
return Clone(fail);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
Conditional.Extends = Extends;
|
|
49
|
+
/** (Experimental) Constructs a type by excluding from UnionType all union members that are assignable to ExcludedMembers. */
|
|
50
|
+
function Exclude(unionType, excludedMembers, options = {}) {
|
|
51
|
+
const anyOf = unionType.anyOf
|
|
52
|
+
.filter((schema) => {
|
|
53
|
+
const check = structural_1.Structural.Check(schema, excludedMembers);
|
|
54
|
+
return !(check === structural_1.StructuralResult.True || check === structural_1.StructuralResult.Union);
|
|
55
|
+
})
|
|
56
|
+
.map((schema) => Clone(schema));
|
|
57
|
+
return { ...options, [Types.Kind]: 'Union', anyOf };
|
|
58
|
+
}
|
|
59
|
+
Conditional.Exclude = Exclude;
|
|
60
|
+
/** (Experimental) Constructs a type by extracting from Type all union members that are assignable to Union. */
|
|
61
|
+
function Extract(type, union, options = {}) {
|
|
62
|
+
if (guard_1.TypeGuard.TUnion(type)) {
|
|
63
|
+
const anyOf = type.anyOf.filter((schema) => structural_1.Structural.Check(schema, union) === structural_1.StructuralResult.True).map((schema) => Clone(schema));
|
|
64
|
+
return { ...options, [Types.Kind]: 'Union', anyOf };
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const anyOf = union.anyOf.filter((schema) => structural_1.Structural.Check(type, schema) === structural_1.StructuralResult.True).map((schema) => Clone(schema));
|
|
68
|
+
return { ...options, [Types.Kind]: 'Union', anyOf };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
Conditional.Extract = Extract;
|
|
72
|
+
function Clone(value) {
|
|
73
|
+
const isObject = (object) => typeof object === 'object' && object !== null && !Array.isArray(object);
|
|
74
|
+
const isArray = (object) => typeof object === 'object' && object !== null && Array.isArray(object);
|
|
75
|
+
if (isObject(value)) {
|
|
76
|
+
return Object.keys(value).reduce((acc, key) => ({
|
|
77
|
+
...acc,
|
|
78
|
+
[key]: Clone(value[key]),
|
|
79
|
+
}), Object.getOwnPropertySymbols(value).reduce((acc, key) => ({
|
|
80
|
+
...acc,
|
|
81
|
+
[key]: Clone(value[key]),
|
|
82
|
+
}), {}));
|
|
83
|
+
}
|
|
84
|
+
else if (isArray(value)) {
|
|
85
|
+
return value.map((item) => Clone(item));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
})(Conditional = exports.Conditional || (exports.Conditional = {}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
@sinclair/typebox/conditional
|
|
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("./conditional"), exports);
|
|
45
|
+
__exportStar(require("./structural"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as Types from '../typebox';
|
|
2
|
+
export declare enum StructuralResult {
|
|
3
|
+
Union = 0,
|
|
4
|
+
True = 1,
|
|
5
|
+
False = 2
|
|
6
|
+
}
|
|
7
|
+
/** Performs structural equivalence checks against TypeBox types. */
|
|
8
|
+
export declare namespace Structural {
|
|
9
|
+
/** Structurally tests if the left schema extends the right. */
|
|
10
|
+
function Check(left: Types.TSchema, right: Types.TSchema): StructuralResult;
|
|
11
|
+
}
|
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
@sinclair/typebox/conditional
|
|
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.Structural = exports.StructuralResult = void 0;
|
|
31
|
+
const Types = require("../typebox");
|
|
32
|
+
const guard_1 = require("../guard");
|
|
33
|
+
// --------------------------------------------------------------------------
|
|
34
|
+
// StructuralResult
|
|
35
|
+
// --------------------------------------------------------------------------
|
|
36
|
+
var StructuralResult;
|
|
37
|
+
(function (StructuralResult) {
|
|
38
|
+
StructuralResult[StructuralResult["Union"] = 0] = "Union";
|
|
39
|
+
StructuralResult[StructuralResult["True"] = 1] = "True";
|
|
40
|
+
StructuralResult[StructuralResult["False"] = 2] = "False";
|
|
41
|
+
})(StructuralResult = exports.StructuralResult || (exports.StructuralResult = {}));
|
|
42
|
+
// --------------------------------------------------------------------------
|
|
43
|
+
// Structural
|
|
44
|
+
// --------------------------------------------------------------------------
|
|
45
|
+
/** Performs structural equivalence checks against TypeBox types. */
|
|
46
|
+
var Structural;
|
|
47
|
+
(function (Structural) {
|
|
48
|
+
const referenceMap = new Map();
|
|
49
|
+
// ------------------------------------------------------------------------
|
|
50
|
+
// Rules
|
|
51
|
+
// ------------------------------------------------------------------------
|
|
52
|
+
function AnyOrUnknownRule(right) {
|
|
53
|
+
// https://github.com/microsoft/TypeScript/issues/40049
|
|
54
|
+
if (right[Types.Kind] === 'Union' && right.anyOf.some((schema) => schema[Types.Kind] === 'Any' || schema[Types.Kind] === 'Unknown'))
|
|
55
|
+
return true;
|
|
56
|
+
if (right[Types.Kind] === 'Unknown')
|
|
57
|
+
return true;
|
|
58
|
+
if (right[Types.Kind] === 'Any')
|
|
59
|
+
return true;
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
function ObjectRightRule(left, right) {
|
|
63
|
+
// type A = boolean extends {} ? 1 : 2 // additionalProperties: false
|
|
64
|
+
// type B = boolean extends object ? 1 : 2 // additionalProperties: true
|
|
65
|
+
const additionalProperties = right.additionalProperties;
|
|
66
|
+
const propertyLength = globalThis.Object.keys(right.properties).length;
|
|
67
|
+
return additionalProperties === false && propertyLength === 0;
|
|
68
|
+
}
|
|
69
|
+
function UnionRightRule(left, right) {
|
|
70
|
+
const result = right.anyOf.some((right) => Visit(left, right) !== StructuralResult.False);
|
|
71
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
72
|
+
}
|
|
73
|
+
// ------------------------------------------------------------------------
|
|
74
|
+
// Records
|
|
75
|
+
// ------------------------------------------------------------------------
|
|
76
|
+
function RecordPattern(schema) {
|
|
77
|
+
return globalThis.Object.keys(schema.patternProperties)[0];
|
|
78
|
+
}
|
|
79
|
+
function RecordNumberOrStringKey(schema) {
|
|
80
|
+
const pattern = RecordPattern(schema);
|
|
81
|
+
return pattern === '^.*$' || pattern === '^(0|[1-9][0-9]*)$';
|
|
82
|
+
}
|
|
83
|
+
function RecordValue(schema) {
|
|
84
|
+
const pattern = RecordPattern(schema);
|
|
85
|
+
return schema.patternProperties[pattern];
|
|
86
|
+
}
|
|
87
|
+
function RecordKey(schema) {
|
|
88
|
+
const pattern = RecordPattern(schema);
|
|
89
|
+
if (pattern === '^.*$') {
|
|
90
|
+
return Types.Type.String();
|
|
91
|
+
}
|
|
92
|
+
else if (pattern === '^(0|[1-9][0-9]*)$') {
|
|
93
|
+
return Types.Type.Number();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const keys = pattern.slice(1, pattern.length - 1).split('|');
|
|
97
|
+
const schemas = keys.map((key) => (isNaN(+key) ? Types.Type.Literal(key) : Types.Type.Literal(parseFloat(key))));
|
|
98
|
+
return Types.Type.Union(schemas);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function PropertyMap(schema) {
|
|
102
|
+
const comparable = new Map();
|
|
103
|
+
if (guard_1.TypeGuard.TRecord(schema)) {
|
|
104
|
+
const propertyPattern = RecordPattern(schema);
|
|
105
|
+
if (propertyPattern === '^.*$' || propertyPattern === '^(0|[1-9][0-9]*)$')
|
|
106
|
+
throw Error('Cannot extract record properties without property constraints');
|
|
107
|
+
const propertySchema = schema.patternProperties[propertyPattern];
|
|
108
|
+
const propertyKeys = propertyPattern.slice(1, propertyPattern.length - 1).split('|');
|
|
109
|
+
propertyKeys.forEach((propertyKey) => {
|
|
110
|
+
comparable.set(propertyKey, propertySchema);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
globalThis.Object.entries(schema.properties).forEach(([propertyKey, propertySchema]) => {
|
|
115
|
+
comparable.set(propertyKey, propertySchema);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return comparable;
|
|
119
|
+
}
|
|
120
|
+
// ------------------------------------------------------------------------
|
|
121
|
+
// Indexable
|
|
122
|
+
// ------------------------------------------------------------------------
|
|
123
|
+
function Indexable(left, right) {
|
|
124
|
+
if (guard_1.TypeGuard.TUnion(right)) {
|
|
125
|
+
return StructuralResult.False;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
return Visit(left, right);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ------------------------------------------------------------------------
|
|
132
|
+
// Checks
|
|
133
|
+
// ------------------------------------------------------------------------
|
|
134
|
+
function Any(left, right) {
|
|
135
|
+
return AnyOrUnknownRule(right) ? StructuralResult.True : StructuralResult.Union;
|
|
136
|
+
}
|
|
137
|
+
function Array(left, right) {
|
|
138
|
+
if (AnyOrUnknownRule(right)) {
|
|
139
|
+
return StructuralResult.True;
|
|
140
|
+
}
|
|
141
|
+
else if (guard_1.TypeGuard.TObject(right)) {
|
|
142
|
+
if (right.properties['length'] !== undefined && right.properties['length'][Types.Kind] === 'Number')
|
|
143
|
+
return StructuralResult.True;
|
|
144
|
+
if (globalThis.Object.keys(right.properties).length === 0)
|
|
145
|
+
return StructuralResult.True;
|
|
146
|
+
return StructuralResult.False;
|
|
147
|
+
}
|
|
148
|
+
else if (!guard_1.TypeGuard.TArray(right)) {
|
|
149
|
+
return StructuralResult.False;
|
|
150
|
+
}
|
|
151
|
+
else if (left.items === undefined && right.items !== undefined) {
|
|
152
|
+
return StructuralResult.False;
|
|
153
|
+
}
|
|
154
|
+
else if (left.items !== undefined && right.items === undefined) {
|
|
155
|
+
return StructuralResult.False;
|
|
156
|
+
}
|
|
157
|
+
else if (left.items === undefined && right.items === undefined) {
|
|
158
|
+
return StructuralResult.False;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const result = Visit(left.items, right.items) !== StructuralResult.False;
|
|
162
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function Boolean(left, right) {
|
|
166
|
+
if (AnyOrUnknownRule(right)) {
|
|
167
|
+
return StructuralResult.True;
|
|
168
|
+
}
|
|
169
|
+
else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
|
|
170
|
+
return StructuralResult.True;
|
|
171
|
+
}
|
|
172
|
+
else if (guard_1.TypeGuard.TBoolean(right)) {
|
|
173
|
+
return StructuralResult.True;
|
|
174
|
+
}
|
|
175
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
176
|
+
return UnionRightRule(left, right);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
return StructuralResult.False;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function Constructor(left, right) {
|
|
183
|
+
if (AnyOrUnknownRule(right)) {
|
|
184
|
+
return StructuralResult.True;
|
|
185
|
+
}
|
|
186
|
+
else if (!guard_1.TypeGuard.TConstructor(right)) {
|
|
187
|
+
return StructuralResult.False;
|
|
188
|
+
}
|
|
189
|
+
else if (right.parameters.length < left.parameters.length) {
|
|
190
|
+
return StructuralResult.False;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
if (Visit(left.returns, right.returns) === StructuralResult.False) {
|
|
194
|
+
return StructuralResult.False;
|
|
195
|
+
}
|
|
196
|
+
for (let i = 0; i < left.parameters.length; i++) {
|
|
197
|
+
const result = Visit(right.parameters[i], left.parameters[i]);
|
|
198
|
+
if (result === StructuralResult.False)
|
|
199
|
+
return StructuralResult.False;
|
|
200
|
+
}
|
|
201
|
+
return StructuralResult.True;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function Function(left, right) {
|
|
205
|
+
if (AnyOrUnknownRule(right)) {
|
|
206
|
+
return StructuralResult.True;
|
|
207
|
+
}
|
|
208
|
+
else if (guard_1.TypeGuard.TObject(right)) {
|
|
209
|
+
if (right.properties['length'] !== undefined && right.properties['length'][Types.Kind] === 'Number')
|
|
210
|
+
return StructuralResult.True;
|
|
211
|
+
if (globalThis.Object.keys(right.properties).length === 0)
|
|
212
|
+
return StructuralResult.True;
|
|
213
|
+
return StructuralResult.False;
|
|
214
|
+
}
|
|
215
|
+
else if (!guard_1.TypeGuard.TFunction(right)) {
|
|
216
|
+
return StructuralResult.False;
|
|
217
|
+
}
|
|
218
|
+
else if (right.parameters.length < left.parameters.length) {
|
|
219
|
+
return StructuralResult.False;
|
|
220
|
+
}
|
|
221
|
+
else if (Visit(left.returns, right.returns) === StructuralResult.False) {
|
|
222
|
+
return StructuralResult.False;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
for (let i = 0; i < left.parameters.length; i++) {
|
|
226
|
+
const result = Visit(right.parameters[i], left.parameters[i]);
|
|
227
|
+
if (result === StructuralResult.False)
|
|
228
|
+
return StructuralResult.False;
|
|
229
|
+
}
|
|
230
|
+
return StructuralResult.True;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function Integer(left, right) {
|
|
234
|
+
if (AnyOrUnknownRule(right)) {
|
|
235
|
+
return StructuralResult.True;
|
|
236
|
+
}
|
|
237
|
+
else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
|
|
238
|
+
return StructuralResult.True;
|
|
239
|
+
}
|
|
240
|
+
else if (guard_1.TypeGuard.TInteger(right) || guard_1.TypeGuard.TNumber(right)) {
|
|
241
|
+
return StructuralResult.True;
|
|
242
|
+
}
|
|
243
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
244
|
+
return UnionRightRule(left, right);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
return StructuralResult.False;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function Literal(left, right) {
|
|
251
|
+
if (AnyOrUnknownRule(right)) {
|
|
252
|
+
return StructuralResult.True;
|
|
253
|
+
}
|
|
254
|
+
else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
|
|
255
|
+
return StructuralResult.True;
|
|
256
|
+
}
|
|
257
|
+
else if (guard_1.TypeGuard.TRecord(right)) {
|
|
258
|
+
if (typeof left.const === 'string') {
|
|
259
|
+
return Indexable(left, RecordValue(right));
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
return StructuralResult.False;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else if (guard_1.TypeGuard.TLiteral(right) && left.const === right.const) {
|
|
266
|
+
return StructuralResult.True;
|
|
267
|
+
}
|
|
268
|
+
else if (guard_1.TypeGuard.TString(right) && typeof left.const === 'string') {
|
|
269
|
+
return StructuralResult.True;
|
|
270
|
+
}
|
|
271
|
+
else if (guard_1.TypeGuard.TNumber(right) && typeof left.const === 'number') {
|
|
272
|
+
return StructuralResult.True;
|
|
273
|
+
}
|
|
274
|
+
else if (guard_1.TypeGuard.TInteger(right) && typeof left.const === 'number') {
|
|
275
|
+
return StructuralResult.True;
|
|
276
|
+
}
|
|
277
|
+
else if (guard_1.TypeGuard.TBoolean(right) && typeof left.const === 'boolean') {
|
|
278
|
+
return StructuralResult.True;
|
|
279
|
+
}
|
|
280
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
281
|
+
return UnionRightRule(left, right);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
return StructuralResult.False;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function Number(left, right) {
|
|
288
|
+
if (AnyOrUnknownRule(right)) {
|
|
289
|
+
return StructuralResult.True;
|
|
290
|
+
}
|
|
291
|
+
else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
|
|
292
|
+
return StructuralResult.True;
|
|
293
|
+
}
|
|
294
|
+
else if (guard_1.TypeGuard.TNumber(right)) {
|
|
295
|
+
return StructuralResult.True;
|
|
296
|
+
}
|
|
297
|
+
else if (guard_1.TypeGuard.TInteger(right)) {
|
|
298
|
+
return StructuralResult.True;
|
|
299
|
+
}
|
|
300
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
301
|
+
return UnionRightRule(left, right);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
return StructuralResult.False;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function Null(left, right) {
|
|
308
|
+
if (AnyOrUnknownRule(right)) {
|
|
309
|
+
return StructuralResult.True;
|
|
310
|
+
}
|
|
311
|
+
else if (guard_1.TypeGuard.TNull(right)) {
|
|
312
|
+
return StructuralResult.True;
|
|
313
|
+
}
|
|
314
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
315
|
+
return UnionRightRule(left, right);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
return StructuralResult.False;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function Properties(left, right) {
|
|
322
|
+
if (right.size > left.size)
|
|
323
|
+
return StructuralResult.False;
|
|
324
|
+
if (![...right.keys()].every((rightKey) => left.has(rightKey)))
|
|
325
|
+
return StructuralResult.False;
|
|
326
|
+
for (const rightKey of right.keys()) {
|
|
327
|
+
const leftProp = left.get(rightKey);
|
|
328
|
+
const rightProp = right.get(rightKey);
|
|
329
|
+
if (Visit(leftProp, rightProp) === StructuralResult.False) {
|
|
330
|
+
return StructuralResult.False;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return StructuralResult.True;
|
|
334
|
+
}
|
|
335
|
+
function Object(left, right) {
|
|
336
|
+
if (AnyOrUnknownRule(right)) {
|
|
337
|
+
return StructuralResult.True;
|
|
338
|
+
}
|
|
339
|
+
else if (guard_1.TypeGuard.TObject(right)) {
|
|
340
|
+
return Properties(PropertyMap(left), PropertyMap(right));
|
|
341
|
+
}
|
|
342
|
+
else if (guard_1.TypeGuard.TRecord(right)) {
|
|
343
|
+
if (!RecordNumberOrStringKey(right)) {
|
|
344
|
+
return Properties(PropertyMap(left), PropertyMap(right));
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
return StructuralResult.True;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
return StructuralResult.False;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function Promise(left, right) {
|
|
355
|
+
if (AnyOrUnknownRule(right)) {
|
|
356
|
+
return StructuralResult.True;
|
|
357
|
+
}
|
|
358
|
+
else if (guard_1.TypeGuard.TObject(right)) {
|
|
359
|
+
if (ObjectRightRule(left, right) || globalThis.Object.keys(right.properties).length === 0) {
|
|
360
|
+
return StructuralResult.True;
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
return StructuralResult.False;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
else if (!guard_1.TypeGuard.TPromise(right)) {
|
|
367
|
+
return StructuralResult.False;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
const result = Visit(left.item, right.item) !== StructuralResult.False;
|
|
371
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function Record(left, right) {
|
|
375
|
+
if (AnyOrUnknownRule(right)) {
|
|
376
|
+
return StructuralResult.True;
|
|
377
|
+
}
|
|
378
|
+
else if (guard_1.TypeGuard.TObject(right)) {
|
|
379
|
+
if (!RecordNumberOrStringKey(left)) {
|
|
380
|
+
return Properties(PropertyMap(left), PropertyMap(right));
|
|
381
|
+
}
|
|
382
|
+
else if (RecordPattern(left) === '^.*$') {
|
|
383
|
+
return StructuralResult.False;
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
return globalThis.Object.keys(right.properties).length === 0 ? StructuralResult.True : StructuralResult.False;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
else if (guard_1.TypeGuard.TRecord(right)) {
|
|
390
|
+
if (!RecordNumberOrStringKey(left) && !RecordNumberOrStringKey(right)) {
|
|
391
|
+
return Properties(PropertyMap(left), PropertyMap(right));
|
|
392
|
+
}
|
|
393
|
+
else if (RecordNumberOrStringKey(left) && !RecordNumberOrStringKey(right)) {
|
|
394
|
+
const leftKey = RecordKey(left);
|
|
395
|
+
const rightKey = RecordKey(right);
|
|
396
|
+
if (Visit(rightKey, leftKey) === StructuralResult.False) {
|
|
397
|
+
return StructuralResult.False;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
return StructuralResult.True;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
return StructuralResult.True;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
return StructuralResult.False;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function Ref(left, right) {
|
|
412
|
+
if (!referenceMap.has(left.$ref))
|
|
413
|
+
throw Error(`Cannot locate referenced $id '${left.$ref}'`);
|
|
414
|
+
const resolved = referenceMap.get(left.$ref);
|
|
415
|
+
return Visit(resolved, right);
|
|
416
|
+
}
|
|
417
|
+
function Self(left, right) {
|
|
418
|
+
if (!referenceMap.has(left.$ref))
|
|
419
|
+
throw Error(`Cannot locate referenced self $id '${left.$ref}'`);
|
|
420
|
+
const resolved = referenceMap.get(left.$ref);
|
|
421
|
+
return Visit(resolved, right);
|
|
422
|
+
}
|
|
423
|
+
function String(left, right) {
|
|
424
|
+
if (AnyOrUnknownRule(right)) {
|
|
425
|
+
return StructuralResult.True;
|
|
426
|
+
}
|
|
427
|
+
else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
|
|
428
|
+
return StructuralResult.True;
|
|
429
|
+
}
|
|
430
|
+
else if (guard_1.TypeGuard.TRecord(right)) {
|
|
431
|
+
return Indexable(left, RecordValue(right));
|
|
432
|
+
}
|
|
433
|
+
else if (guard_1.TypeGuard.TString(right)) {
|
|
434
|
+
return StructuralResult.True;
|
|
435
|
+
}
|
|
436
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
437
|
+
return UnionRightRule(left, right);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
return StructuralResult.False;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
function Tuple(left, right) {
|
|
444
|
+
if (AnyOrUnknownRule(right)) {
|
|
445
|
+
return StructuralResult.True;
|
|
446
|
+
}
|
|
447
|
+
else if (guard_1.TypeGuard.TObject(right)) {
|
|
448
|
+
const result = ObjectRightRule(left, right) || globalThis.Object.keys(right.properties).length === 0;
|
|
449
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
450
|
+
}
|
|
451
|
+
else if (guard_1.TypeGuard.TRecord(right)) {
|
|
452
|
+
return Indexable(left, RecordValue(right));
|
|
453
|
+
}
|
|
454
|
+
else if (guard_1.TypeGuard.TArray(right)) {
|
|
455
|
+
if (right.items === undefined) {
|
|
456
|
+
return StructuralResult.False;
|
|
457
|
+
}
|
|
458
|
+
else if (guard_1.TypeGuard.TUnion(right.items) && left.items) {
|
|
459
|
+
const result = left.items.every((left) => UnionRightRule(left, right.items) !== StructuralResult.False);
|
|
460
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
461
|
+
}
|
|
462
|
+
else if (guard_1.TypeGuard.TAny(right.items)) {
|
|
463
|
+
return StructuralResult.True;
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
return StructuralResult.False;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (!guard_1.TypeGuard.TTuple(right))
|
|
470
|
+
return StructuralResult.False;
|
|
471
|
+
if (left.items === undefined && right.items === undefined)
|
|
472
|
+
return StructuralResult.True;
|
|
473
|
+
if (left.items === undefined && right.items !== undefined)
|
|
474
|
+
return StructuralResult.False;
|
|
475
|
+
if (left.items !== undefined && right.items === undefined)
|
|
476
|
+
return StructuralResult.False;
|
|
477
|
+
if (left.items === undefined && right.items === undefined)
|
|
478
|
+
return StructuralResult.True;
|
|
479
|
+
if (left.minItems !== right.minItems || left.maxItems !== right.maxItems)
|
|
480
|
+
return StructuralResult.False;
|
|
481
|
+
for (let i = 0; i < left.items.length; i++) {
|
|
482
|
+
if (Visit(left.items[i], right.items[i]) === StructuralResult.False)
|
|
483
|
+
return StructuralResult.False;
|
|
484
|
+
}
|
|
485
|
+
return StructuralResult.True;
|
|
486
|
+
}
|
|
487
|
+
function Uint8Array(left, right) {
|
|
488
|
+
if (AnyOrUnknownRule(right)) {
|
|
489
|
+
return StructuralResult.True;
|
|
490
|
+
}
|
|
491
|
+
else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
|
|
492
|
+
return StructuralResult.True;
|
|
493
|
+
}
|
|
494
|
+
else if (guard_1.TypeGuard.TRecord(right)) {
|
|
495
|
+
return Indexable(left, RecordValue(right));
|
|
496
|
+
}
|
|
497
|
+
else if (guard_1.TypeGuard.TUint8Array(right)) {
|
|
498
|
+
return StructuralResult.True;
|
|
499
|
+
}
|
|
500
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
501
|
+
return UnionRightRule(left, right);
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
return StructuralResult.False;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function Undefined(left, right) {
|
|
508
|
+
if (AnyOrUnknownRule(right)) {
|
|
509
|
+
return StructuralResult.True;
|
|
510
|
+
}
|
|
511
|
+
else if (guard_1.TypeGuard.TUndefined(right)) {
|
|
512
|
+
return StructuralResult.True;
|
|
513
|
+
}
|
|
514
|
+
else if (guard_1.TypeGuard.TVoid(right)) {
|
|
515
|
+
return StructuralResult.True;
|
|
516
|
+
}
|
|
517
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
518
|
+
return UnionRightRule(left, right);
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
return StructuralResult.False;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
function Union(left, right) {
|
|
525
|
+
if (left.anyOf.some((left) => guard_1.TypeGuard.TAny(left))) {
|
|
526
|
+
return StructuralResult.Union;
|
|
527
|
+
}
|
|
528
|
+
else if (guard_1.TypeGuard.TUnion(right)) {
|
|
529
|
+
const result = left.anyOf.every((left) => right.anyOf.some((right) => Visit(left, right) !== StructuralResult.False));
|
|
530
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
const result = left.anyOf.every((left) => Visit(left, right) !== StructuralResult.False);
|
|
534
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
function Unknown(left, right) {
|
|
538
|
+
if (guard_1.TypeGuard.TUnion(right)) {
|
|
539
|
+
const result = right.anyOf.some((right) => guard_1.TypeGuard.TAny(right) || guard_1.TypeGuard.TUnknown(right));
|
|
540
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
541
|
+
}
|
|
542
|
+
else if (guard_1.TypeGuard.TAny(right)) {
|
|
543
|
+
return StructuralResult.True;
|
|
544
|
+
}
|
|
545
|
+
else if (guard_1.TypeGuard.TUnknown(right)) {
|
|
546
|
+
return StructuralResult.True;
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
return StructuralResult.False;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
function Void(left, right) {
|
|
553
|
+
if (guard_1.TypeGuard.TUnion(right)) {
|
|
554
|
+
const result = right.anyOf.some((right) => guard_1.TypeGuard.TAny(right) || guard_1.TypeGuard.TUnknown(right));
|
|
555
|
+
return result ? StructuralResult.True : StructuralResult.False;
|
|
556
|
+
}
|
|
557
|
+
else if (guard_1.TypeGuard.TAny(right)) {
|
|
558
|
+
return StructuralResult.True;
|
|
559
|
+
}
|
|
560
|
+
else if (guard_1.TypeGuard.TUnknown(right)) {
|
|
561
|
+
return StructuralResult.True;
|
|
562
|
+
}
|
|
563
|
+
else if (guard_1.TypeGuard.TVoid(right)) {
|
|
564
|
+
return StructuralResult.True;
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
return StructuralResult.False;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
let recursionDepth = 0;
|
|
571
|
+
function Visit(left, right) {
|
|
572
|
+
recursionDepth += 1;
|
|
573
|
+
if (recursionDepth >= 1000)
|
|
574
|
+
return StructuralResult.True;
|
|
575
|
+
if (left.$id !== undefined)
|
|
576
|
+
referenceMap.set(left.$id, left);
|
|
577
|
+
if (right.$id !== undefined)
|
|
578
|
+
referenceMap.set(right.$id, right);
|
|
579
|
+
const resolvedRight = right[Types.Kind] === 'Self' ? referenceMap.get(right.$ref) : right;
|
|
580
|
+
if (guard_1.TypeGuard.TAny(left)) {
|
|
581
|
+
return Any(left, resolvedRight);
|
|
582
|
+
}
|
|
583
|
+
else if (guard_1.TypeGuard.TArray(left)) {
|
|
584
|
+
return Array(left, resolvedRight);
|
|
585
|
+
}
|
|
586
|
+
else if (guard_1.TypeGuard.TBoolean(left)) {
|
|
587
|
+
return Boolean(left, resolvedRight);
|
|
588
|
+
}
|
|
589
|
+
else if (guard_1.TypeGuard.TConstructor(left)) {
|
|
590
|
+
return Constructor(left, resolvedRight);
|
|
591
|
+
}
|
|
592
|
+
else if (guard_1.TypeGuard.TFunction(left)) {
|
|
593
|
+
return Function(left, resolvedRight);
|
|
594
|
+
}
|
|
595
|
+
else if (guard_1.TypeGuard.TInteger(left)) {
|
|
596
|
+
return Integer(left, resolvedRight);
|
|
597
|
+
}
|
|
598
|
+
else if (guard_1.TypeGuard.TLiteral(left)) {
|
|
599
|
+
return Literal(left, resolvedRight);
|
|
600
|
+
}
|
|
601
|
+
else if (guard_1.TypeGuard.TNull(left)) {
|
|
602
|
+
return Null(left, resolvedRight);
|
|
603
|
+
}
|
|
604
|
+
else if (guard_1.TypeGuard.TNumber(left)) {
|
|
605
|
+
return Number(left, resolvedRight);
|
|
606
|
+
}
|
|
607
|
+
else if (guard_1.TypeGuard.TObject(left)) {
|
|
608
|
+
return Object(left, resolvedRight);
|
|
609
|
+
}
|
|
610
|
+
else if (guard_1.TypeGuard.TPromise(left)) {
|
|
611
|
+
return Promise(left, resolvedRight);
|
|
612
|
+
}
|
|
613
|
+
else if (guard_1.TypeGuard.TRecord(left)) {
|
|
614
|
+
return Record(left, resolvedRight);
|
|
615
|
+
}
|
|
616
|
+
else if (guard_1.TypeGuard.TRef(left)) {
|
|
617
|
+
return Ref(left, resolvedRight);
|
|
618
|
+
}
|
|
619
|
+
else if (guard_1.TypeGuard.TSelf(left)) {
|
|
620
|
+
return Self(left, resolvedRight);
|
|
621
|
+
}
|
|
622
|
+
else if (guard_1.TypeGuard.TString(left)) {
|
|
623
|
+
return String(left, resolvedRight);
|
|
624
|
+
}
|
|
625
|
+
else if (guard_1.TypeGuard.TTuple(left)) {
|
|
626
|
+
return Tuple(left, resolvedRight);
|
|
627
|
+
}
|
|
628
|
+
else if (guard_1.TypeGuard.TUndefined(left)) {
|
|
629
|
+
return Undefined(left, resolvedRight);
|
|
630
|
+
}
|
|
631
|
+
else if (guard_1.TypeGuard.TUint8Array(left)) {
|
|
632
|
+
return Uint8Array(left, resolvedRight);
|
|
633
|
+
}
|
|
634
|
+
else if (guard_1.TypeGuard.TUnion(left)) {
|
|
635
|
+
return Union(left, resolvedRight);
|
|
636
|
+
}
|
|
637
|
+
else if (guard_1.TypeGuard.TUnknown(left)) {
|
|
638
|
+
return Unknown(left, resolvedRight);
|
|
639
|
+
}
|
|
640
|
+
else if (guard_1.TypeGuard.TVoid(left)) {
|
|
641
|
+
return Void(left, resolvedRight);
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
throw Error(`Structural: Unknown left operand '${left[Types.Kind]}'`);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
/** Structurally tests if the left schema extends the right. */
|
|
648
|
+
function Check(left, right) {
|
|
649
|
+
referenceMap.clear();
|
|
650
|
+
recursionDepth = 0;
|
|
651
|
+
return Visit(left, right);
|
|
652
|
+
}
|
|
653
|
+
Structural.Check = Check;
|
|
654
|
+
})(Structural = exports.Structural || (exports.Structural = {}));
|
package/guard/guard.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Types from '../typebox';
|
|
2
|
-
/**
|
|
2
|
+
/** TypeGuard tests that values conform to a known TypeBox type specification */
|
|
3
3
|
export declare namespace TypeGuard {
|
|
4
4
|
/** Returns true if the given schema is TAny */
|
|
5
5
|
function TAny(schema: any): schema is Types.TAny;
|
package/guard/guard.js
CHANGED
|
@@ -29,7 +29,7 @@ THE SOFTWARE.
|
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
30
|
exports.TypeGuard = void 0;
|
|
31
31
|
const Types = require("../typebox");
|
|
32
|
-
/**
|
|
32
|
+
/** TypeGuard tests that values conform to a known TypeBox type specification */
|
|
33
33
|
var TypeGuard;
|
|
34
34
|
(function (TypeGuard) {
|
|
35
35
|
function IsObject(schema) {
|
|
@@ -146,10 +146,10 @@ var TypeGuard;
|
|
|
146
146
|
TypeGuard.TString = TString;
|
|
147
147
|
/** Returns true if the given schema is TTuple */
|
|
148
148
|
function TTuple(schema) {
|
|
149
|
-
if (!(IsObject(schema) && schema[Types.Kind] === 'Tuple' && schema.type === 'array' &&
|
|
149
|
+
if (!(IsObject(schema) && schema[Types.Kind] === 'Tuple' && schema.type === 'array' && typeof schema.minItems === 'number' && typeof schema.maxItems === 'number' && schema.minItems === schema.maxItems)) {
|
|
150
150
|
return false;
|
|
151
151
|
}
|
|
152
|
-
if (schema.items === undefined && schema.minItems === 0) {
|
|
152
|
+
if (schema.items === undefined && schema.additionalItems === undefined && schema.minItems === 0) {
|
|
153
153
|
return true;
|
|
154
154
|
}
|
|
155
155
|
if (!IsArray(schema.items)) {
|
package/guard/index.js
CHANGED
|
@@ -28,7 +28,11 @@ THE SOFTWARE.
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
29
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
30
|
if (k2 === undefined) k2 = k;
|
|
31
|
-
Object.
|
|
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);
|
|
32
36
|
}) : (function(o, m, k, k2) {
|
|
33
37
|
if (k2 === undefined) k2 = k;
|
|
34
38
|
o[k2] = m[k];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinclair/typebox",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.16",
|
|
4
4
|
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"json-schema",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"mocha": "^9.2.0",
|
|
37
37
|
"prettier": "^2.7.1",
|
|
38
38
|
"tsd": "^0.19.1",
|
|
39
|
-
"typescript": "^4.
|
|
39
|
+
"typescript": "^4.7.4"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/readme.md
CHANGED
|
@@ -63,6 +63,7 @@ License MIT
|
|
|
63
63
|
- [Recursive Types](#Recursive-Types)
|
|
64
64
|
- [Generic Types](#Generic-Types)
|
|
65
65
|
- [Unsafe Types](#Unsafe-Types)
|
|
66
|
+
- [Conditional Types](#Conditional-Types)
|
|
66
67
|
- [Values](#Values)
|
|
67
68
|
- [Guards](#Guards)
|
|
68
69
|
- [Strict](#Strict)
|
|
@@ -413,12 +414,12 @@ In addition to JSON schema types, TypeBox provides several extended types that a
|
|
|
413
414
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
414
415
|
│ const T = Type.Constructor([ │ type T = new ( │ const T = { │
|
|
415
416
|
│ Type.String(), │ arg0: string, │ type: 'constructor' │
|
|
416
|
-
│ Type.Number() │ arg1: number │
|
|
417
|
+
│ Type.Number() │ arg1: number │ parameters: [{ │
|
|
417
418
|
│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │
|
|
418
419
|
│ │ │ }, { │
|
|
419
420
|
│ │ │ type: 'number' │
|
|
420
421
|
│ │ │ }], │
|
|
421
|
-
│ │ │
|
|
422
|
+
│ │ │ return: { │
|
|
422
423
|
│ │ │ type: 'boolean' │
|
|
423
424
|
│ │ │ } │
|
|
424
425
|
│ │ │ } │
|
|
@@ -426,12 +427,12 @@ In addition to JSON schema types, TypeBox provides several extended types that a
|
|
|
426
427
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
427
428
|
│ const T = Type.Function([ │ type T = ( │ const T = { │
|
|
428
429
|
| Type.String(), │ arg0: string, │ type : 'function', │
|
|
429
|
-
│ Type.Number() │ arg1: number │
|
|
430
|
+
│ Type.Number() │ arg1: number │ parameters: [{ │
|
|
430
431
|
│ ], Type.Boolean()) │ ) => boolean │ type: 'string' │
|
|
431
432
|
│ │ │ }, { │
|
|
432
433
|
│ │ │ type: 'number' │
|
|
433
434
|
│ │ │ }], │
|
|
434
|
-
│ │ │
|
|
435
|
+
│ │ │ return: { │
|
|
435
436
|
│ │ │ type: 'boolean' │
|
|
436
437
|
│ │ │ } │
|
|
437
438
|
│ │ │ } │
|
|
@@ -606,6 +607,57 @@ const T = StringEnum(['A', 'B', 'C']) // const T = {
|
|
|
606
607
|
type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
|
|
607
608
|
```
|
|
608
609
|
|
|
610
|
+
<a name="Conditional-Types"></a>
|
|
611
|
+
|
|
612
|
+
## Conditional Types
|
|
613
|
+
|
|
614
|
+
Use `Conditional.Extends(...)` to create conditional mapped types.
|
|
615
|
+
|
|
616
|
+
```typescript
|
|
617
|
+
import { Conditional } from '@sinclair/typebox/conditional'
|
|
618
|
+
```
|
|
619
|
+
The following table shows the TypeBox mappings between TypeScript and JSON schema.
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────┐
|
|
623
|
+
│ TypeBox │ TypeScript │ Extended Schema │
|
|
624
|
+
│ │ │ │
|
|
625
|
+
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
626
|
+
│ const T = Conditional.Extends( │ type T = │ const T = { │
|
|
627
|
+
│ Type.String(), │ string extends number │ const: false │
|
|
628
|
+
│ Type.Number(), │ true : false │ type: 'boolean' │
|
|
629
|
+
│ Type.Literal(true) │ │ } │
|
|
630
|
+
│ Type.Literal(false) │ │ │
|
|
631
|
+
│ ) │ │ │
|
|
632
|
+
│ │ │ │
|
|
633
|
+
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
634
|
+
│ const T = Conditional.Exclude( │ type T = Exclude< │ const T = { │
|
|
635
|
+
│ Type.Union([ │ 'a' | 'b' | 'c', │ anyOf: [{ │
|
|
636
|
+
│ Type.Literal('a') │ 'a' │ const: 'b' │
|
|
637
|
+
│ Type.Literal('b') │ > │ type: 'string' │
|
|
638
|
+
│ Type.Literal('c') │ │ }, { │
|
|
639
|
+
│ ]), │ │ const: 'c' │
|
|
640
|
+
│ Type.Union([ │ │ type: 'string' │
|
|
641
|
+
│ Type.Literal('a') │ │ }] │
|
|
642
|
+
│ ]) │ │ } │
|
|
643
|
+
│ ) │ │ │
|
|
644
|
+
│ │ │ │
|
|
645
|
+
└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
|
|
646
|
+
│ const T = Conditional.Extract( │ type T = Extract< │ const T = { │
|
|
647
|
+
│ Type.Union([ │ 'a' | 'b' | 'c', │ anyOf: [{ │
|
|
648
|
+
│ Type.Literal('a') │ 'a' | 'f' │ const: 'a' │
|
|
649
|
+
│ Type.Literal('b') │ > │ type: 'string' │
|
|
650
|
+
│ Type.Literal('c') │ │ }] │
|
|
651
|
+
│ ]), │ │ } │
|
|
652
|
+
│ Type.Union([ │ │ │
|
|
653
|
+
│ Type.Literal('a') │ │ │
|
|
654
|
+
│ Type.Literal('f') │ │ │
|
|
655
|
+
│ ]) │ │ │
|
|
656
|
+
│ ) │ │ │
|
|
657
|
+
│ │ │ │
|
|
658
|
+
└────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
|
|
659
|
+
```
|
|
660
|
+
|
|
609
661
|
<a name="Values"></a>
|
|
610
662
|
|
|
611
663
|
## Values
|
package/typebox.d.ts
CHANGED
|
@@ -63,12 +63,14 @@ export interface TBoolean extends TSchema {
|
|
|
63
63
|
static: boolean;
|
|
64
64
|
type: 'boolean';
|
|
65
65
|
}
|
|
66
|
-
export declare type
|
|
66
|
+
export declare type TConstructorParameters<T extends TConstructor<TSchema[], TSchema>> = TTuple<T['parameters']>;
|
|
67
|
+
export declare type TInstanceType<T extends TConstructor<TSchema[], TSchema>> = T['returns'];
|
|
68
|
+
export declare type StaticContructorParameters<T extends readonly TSchema[], P extends unknown[]> = [...{
|
|
67
69
|
[K in keyof T]: T[K] extends TSchema ? Static<T[K], P> : never;
|
|
68
70
|
}];
|
|
69
71
|
export interface TConstructor<T extends TSchema[] = TSchema[], U extends TSchema = TSchema> extends TSchema {
|
|
70
72
|
[Kind]: 'Constructor';
|
|
71
|
-
static: new (...param:
|
|
73
|
+
static: new (...param: StaticContructorParameters<T, this['params']>) => Static<U, this['params']>;
|
|
72
74
|
type: 'constructor';
|
|
73
75
|
parameters: T;
|
|
74
76
|
returns: U;
|
|
@@ -82,12 +84,14 @@ export interface TEnum<T extends Record<string, string | number> = Record<string
|
|
|
82
84
|
static: T[keyof T];
|
|
83
85
|
anyOf: TLiteral<string | number>[];
|
|
84
86
|
}
|
|
85
|
-
export declare type
|
|
87
|
+
export declare type TParameters<T extends TFunction> = TTuple<T['parameters']>;
|
|
88
|
+
export declare type TReturnType<T extends TFunction> = T['returns'];
|
|
89
|
+
export declare type StaticFunctionParameters<T extends readonly TSchema[], P extends unknown[]> = [...{
|
|
86
90
|
[K in keyof T]: T[K] extends TSchema ? Static<T[K], P> : never;
|
|
87
91
|
}];
|
|
88
92
|
export interface TFunction<T extends readonly TSchema[] = TSchema[], U extends TSchema = TSchema> extends TSchema {
|
|
89
93
|
[Kind]: 'Function';
|
|
90
|
-
static: (...param:
|
|
94
|
+
static: (...param: StaticFunctionParameters<T, this['params']>) => Static<U, this['params']>;
|
|
91
95
|
type: 'function';
|
|
92
96
|
parameters: T;
|
|
93
97
|
returns: U;
|
|
@@ -293,12 +297,16 @@ export declare class TypeBuilder {
|
|
|
293
297
|
Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<T>;
|
|
294
298
|
/** Creates a boolean type */
|
|
295
299
|
Boolean(options?: SchemaOptions): TBoolean;
|
|
300
|
+
/** Creates a tuple type from this constructors parameters */
|
|
301
|
+
ConstructorParameters<T extends TConstructor<any[], any>>(schema: T, options?: SchemaOptions): TConstructorParameters<T>;
|
|
296
302
|
/** Creates a constructor type */
|
|
297
303
|
Constructor<T extends TSchema[], U extends TSchema>(parameters: [...T], returns: U, options?: SchemaOptions): TConstructor<T, U>;
|
|
298
304
|
/** Creates a enum type */
|
|
299
305
|
Enum<T extends Record<string, string | number>>(item: T, options?: SchemaOptions): TEnum<T>;
|
|
300
306
|
/** Creates a function type */
|
|
301
307
|
Function<T extends readonly TSchema[], U extends TSchema>(parameters: [...T], returns: U, options?: SchemaOptions): TFunction<T, U>;
|
|
308
|
+
/** Creates a type from this constructors instance type */
|
|
309
|
+
InstanceType<T extends TConstructor<any[], any>>(schema: T, options?: SchemaOptions): TInstanceType<T>;
|
|
302
310
|
/** Creates a integer type */
|
|
303
311
|
Integer(options?: NumericOptions): TInteger;
|
|
304
312
|
/** Creates a intersect type. */
|
|
@@ -315,6 +323,8 @@ export declare class TypeBuilder {
|
|
|
315
323
|
Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<T>;
|
|
316
324
|
/** Creates a new object whose properties are omitted from the given object */
|
|
317
325
|
Omit<T extends TObject, Properties extends Array<ObjectPropertyKeys<T>>>(schema: T, keys: [...Properties], options?: ObjectOptions): TOmit<T, Properties>;
|
|
326
|
+
/** Creates a tuple type from this functions parameters */
|
|
327
|
+
Parameters<T extends TFunction<any[], any>>(schema: T, options?: SchemaOptions): TParameters<T>;
|
|
318
328
|
/** Creates an object type whose properties are all optional */
|
|
319
329
|
Partial<T extends TObject>(schema: T, options?: ObjectOptions): TPartial<T>;
|
|
320
330
|
/** Creates a new object whose properties are picked from the given object */
|
|
@@ -333,6 +343,8 @@ export declare class TypeBuilder {
|
|
|
333
343
|
RegEx(regex: RegExp, options?: SchemaOptions): TString;
|
|
334
344
|
/** Creates an object type whose properties are all required */
|
|
335
345
|
Required<T extends TObject>(schema: T, options?: SchemaOptions): TRequired<T>;
|
|
346
|
+
/** Creates a type from this functions return type */
|
|
347
|
+
ReturnType<T extends TFunction<any[], any>>(schema: T, options?: SchemaOptions): TReturnType<T>;
|
|
336
348
|
/** Removes Kind and Modifier symbol property keys from this schema */
|
|
337
349
|
Strict<T extends TSchema>(schema: T): T;
|
|
338
350
|
/** Creates a string type */
|
package/typebox.js
CHANGED
|
@@ -68,6 +68,10 @@ class TypeBuilder {
|
|
|
68
68
|
Boolean(options = {}) {
|
|
69
69
|
return this.Create({ ...options, [exports.Kind]: 'Boolean', type: 'boolean' });
|
|
70
70
|
}
|
|
71
|
+
/** Creates a tuple type from this constructors parameters */
|
|
72
|
+
ConstructorParameters(schema, options = {}) {
|
|
73
|
+
return this.Tuple([...schema.parameters], { ...options });
|
|
74
|
+
}
|
|
71
75
|
/** Creates a constructor type */
|
|
72
76
|
Constructor(parameters, returns, options = {}) {
|
|
73
77
|
return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'constructor', parameters, returns });
|
|
@@ -84,6 +88,10 @@ class TypeBuilder {
|
|
|
84
88
|
Function(parameters, returns, options = {}) {
|
|
85
89
|
return this.Create({ ...options, [exports.Kind]: 'Function', type: 'function', parameters, returns });
|
|
86
90
|
}
|
|
91
|
+
/** Creates a type from this constructors instance type */
|
|
92
|
+
InstanceType(schema, options = {}) {
|
|
93
|
+
return { ...options, ...this.Clone(schema.returns) };
|
|
94
|
+
}
|
|
87
95
|
/** Creates a integer type */
|
|
88
96
|
Integer(options = {}) {
|
|
89
97
|
return this.Create({ ...options, [exports.Kind]: 'Integer', type: 'integer' });
|
|
@@ -160,6 +168,10 @@ class TypeBuilder {
|
|
|
160
168
|
}
|
|
161
169
|
return this.Create(next);
|
|
162
170
|
}
|
|
171
|
+
/** Creates a tuple type from this functions parameters */
|
|
172
|
+
Parameters(schema, options = {}) {
|
|
173
|
+
return exports.Type.Tuple(schema.parameters, { ...options });
|
|
174
|
+
}
|
|
163
175
|
/** Creates an object type whose properties are all optional */
|
|
164
176
|
Partial(schema, options = {}) {
|
|
165
177
|
const next = { ...this.Clone(schema), ...options };
|
|
@@ -258,6 +270,10 @@ class TypeBuilder {
|
|
|
258
270
|
}
|
|
259
271
|
return this.Create(next);
|
|
260
272
|
}
|
|
273
|
+
/** Creates a type from this functions return type */
|
|
274
|
+
ReturnType(schema, options = {}) {
|
|
275
|
+
return { ...options, ...this.Clone(schema.returns) };
|
|
276
|
+
}
|
|
261
277
|
/** Removes Kind and Modifier symbol property keys from this schema */
|
|
262
278
|
Strict(schema) {
|
|
263
279
|
return JSON.parse(JSON.stringify(schema));
|
package/value/cast.js
CHANGED
|
@@ -32,9 +32,10 @@ const Types = require("../typebox");
|
|
|
32
32
|
const create_1 = require("./create");
|
|
33
33
|
const check_1 = require("./check");
|
|
34
34
|
// --------------------------------------------------------------------------
|
|
35
|
-
// Specialized Union
|
|
36
|
-
//
|
|
37
|
-
//
|
|
35
|
+
// Specialized Union Cast. Because a union can be one of many varying types
|
|
36
|
+
// with properties potentially overlapping, we need a strategy to determine
|
|
37
|
+
// which of those types we should cast into. This strategy needs to factor
|
|
38
|
+
// the value provided by the user to make this decision.
|
|
38
39
|
//
|
|
39
40
|
// The following will score each union type found within the types anyOf
|
|
40
41
|
// array. Typically this is executed for objects only, so the score is a
|
package/value/index.js
CHANGED
|
@@ -28,7 +28,11 @@ THE SOFTWARE.
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
29
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
30
|
if (k2 === undefined) k2 = k;
|
|
31
|
-
Object.
|
|
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);
|
|
32
36
|
}) : (function(o, m, k, k2) {
|
|
33
37
|
if (k2 === undefined) k2 = k;
|
|
34
38
|
o[k2] = m[k];
|