typebox 1.0.41 → 1.0.43
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/build/guard/emit.mjs +1 -1
- package/build/schema/engine/index.d.mts +1 -0
- package/build/schema/engine/index.mjs +1 -0
- package/build/schema/engine/recursiveRef.d.mts +5 -0
- package/build/schema/engine/recursiveRef.mjs +36 -0
- package/build/schema/engine/ref.mjs +3 -3
- package/build/schema/engine/schema.mjs +5 -0
- package/build/schema/pointer/index.d.mts +1 -0
- package/build/schema/pointer/index.mjs +1 -0
- package/build/schema/pointer/pointer.d.mts +10 -0
- package/build/schema/pointer/pointer.mjs +96 -0
- package/build/schema/resolver/index.d.mts +1 -0
- package/build/schema/resolver/index.mjs +1 -0
- package/build/schema/resolver/recursiveRef.d.mts +2 -0
- package/build/schema/resolver/recursiveRef.mjs +47 -0
- package/build/schema/resolver/ref.d.mts +1 -0
- package/build/schema/resolver/ref.mjs +98 -0
- package/build/schema/resolver/resolver.d.mts +2 -0
- package/build/schema/resolver/resolver.mjs +2 -0
- package/build/schema/schema.d.mts +2 -0
- package/build/schema/schema.mjs +2 -0
- package/build/schema/types/index.d.mts +2 -0
- package/build/schema/types/index.mjs +2 -0
- package/build/schema/types/recursiveAnchor.d.mts +8 -0
- package/build/schema/types/recursiveAnchor.mjs +12 -0
- package/build/schema/types/recursiveRef.d.mts +8 -0
- package/build/schema/types/recursiveRef.mjs +12 -0
- package/build/system/system.d.mts +1 -1
- package/build/system/system.mjs +1 -1
- package/build/value/pointer/index.d.mts +1 -1
- package/build/value/pointer/index.mjs +1 -1
- package/package.json +27 -27
- package/readme.md +24 -0
- package/build/schema/deref/deref.d.mts +0 -4
- package/build/schema/deref/deref.mjs +0 -77
- package/build/schema/deref/index.d.mts +0 -1
- package/build/schema/deref/index.mjs +0 -1
- package/build/value/pointer/pointer.d.mts +0 -17
- package/build/value/pointer/pointer.mjs +0 -137
package/build/guard/emit.mjs
CHANGED
|
@@ -153,7 +153,7 @@ export function Constant(value) {
|
|
|
153
153
|
return G.IsString(value) ? JSON.stringify(value) : `${value}`;
|
|
154
154
|
}
|
|
155
155
|
export function Ternary(condition, true_, false_) {
|
|
156
|
-
return
|
|
156
|
+
return `(${condition} ? ${true_} : ${false_})`;
|
|
157
157
|
}
|
|
158
158
|
// ------------------------------------------------------------------
|
|
159
159
|
// Statements
|
|
@@ -34,6 +34,7 @@ export * from './patternProperties.mjs';
|
|
|
34
34
|
export * from './prefixItems.mjs';
|
|
35
35
|
export * from './properties.mjs';
|
|
36
36
|
export * from './propertyNames.mjs';
|
|
37
|
+
export * from './recursiveRef.mjs';
|
|
37
38
|
export * from './ref.mjs';
|
|
38
39
|
export * from './required.mjs';
|
|
39
40
|
export * from './type.mjs';
|
|
@@ -40,6 +40,7 @@ export * from './patternProperties.mjs';
|
|
|
40
40
|
export * from './prefixItems.mjs';
|
|
41
41
|
export * from './properties.mjs';
|
|
42
42
|
export * from './propertyNames.mjs';
|
|
43
|
+
export * from './recursiveRef.mjs';
|
|
43
44
|
export * from './ref.mjs';
|
|
44
45
|
export * from './required.mjs';
|
|
45
46
|
export * from './type.mjs';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as S from '../types/index.mjs';
|
|
2
|
+
import { BuildContext, CheckContext, ErrorContext } from './_context.mjs';
|
|
3
|
+
export declare function BuildRecursiveRef(context: BuildContext, schema: S.XRecursiveRef, value: string): string;
|
|
4
|
+
export declare function CheckRecursiveRef(context: CheckContext, schema: S.XRecursiveRef, value: unknown): boolean;
|
|
5
|
+
export declare function ErrorRecursiveRef(context: ErrorContext, schemaPath: string, instancePath: string, schema: S.XRecursiveRef, value: unknown): boolean;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import * as F from './_functions.mjs';
|
|
3
|
+
import * as S from '../types/index.mjs';
|
|
4
|
+
import { CheckSchema, ErrorSchema } from './schema.mjs';
|
|
5
|
+
import { Resolver } from '../resolver/index.mjs';
|
|
6
|
+
// ------------------------------------------------------------------
|
|
7
|
+
// Resolve
|
|
8
|
+
// ------------------------------------------------------------------
|
|
9
|
+
function Resolve(context, schema) {
|
|
10
|
+
// note: it is safe to coerce to XSchema here as it wouldn't be possible
|
|
11
|
+
// to enter a ref resolution if the root schema was boolean.
|
|
12
|
+
const schemaRoot = context.GetSchema();
|
|
13
|
+
const dereferenced = Resolver.RecursiveRef(schemaRoot, schema);
|
|
14
|
+
return S.IsSchema(dereferenced) ? dereferenced : false;
|
|
15
|
+
}
|
|
16
|
+
// ------------------------------------------------------------------
|
|
17
|
+
// Build
|
|
18
|
+
// ------------------------------------------------------------------
|
|
19
|
+
export function BuildRecursiveRef(context, schema, value) {
|
|
20
|
+
const target = Resolve(context, schema);
|
|
21
|
+
return F.CreateFunction(context, target, value);
|
|
22
|
+
}
|
|
23
|
+
// ------------------------------------------------------------------
|
|
24
|
+
// Check
|
|
25
|
+
// ------------------------------------------------------------------
|
|
26
|
+
export function CheckRecursiveRef(context, schema, value) {
|
|
27
|
+
const target = Resolve(context, schema);
|
|
28
|
+
return (S.IsSchema(target) && CheckSchema(context, target, value));
|
|
29
|
+
}
|
|
30
|
+
// ------------------------------------------------------------------
|
|
31
|
+
// Error
|
|
32
|
+
// ------------------------------------------------------------------
|
|
33
|
+
export function ErrorRecursiveRef(context, schemaPath, instancePath, schema, value) {
|
|
34
|
+
const target = Resolve(context, schema);
|
|
35
|
+
return (S.IsSchema(target) && ErrorSchema(context, '#', instancePath, target, value));
|
|
36
|
+
}
|
|
@@ -3,7 +3,7 @@ import * as F from './_functions.mjs';
|
|
|
3
3
|
import * as S from '../types/index.mjs';
|
|
4
4
|
import { Guard as G } from '../../guard/index.mjs';
|
|
5
5
|
import { CheckSchema, ErrorSchema } from './schema.mjs';
|
|
6
|
-
import {
|
|
6
|
+
import { Resolver } from '../resolver/index.mjs';
|
|
7
7
|
// ------------------------------------------------------------------
|
|
8
8
|
// Resolve
|
|
9
9
|
// ------------------------------------------------------------------
|
|
@@ -16,8 +16,8 @@ function Resolve(context, schema) {
|
|
|
16
16
|
if (G.HasPropertyKey(schemaContext, schema.$ref)) {
|
|
17
17
|
return schemaContext[schema.$ref];
|
|
18
18
|
}
|
|
19
|
-
//
|
|
20
|
-
const dereferenced =
|
|
19
|
+
// referential schema
|
|
20
|
+
const dereferenced = Resolver.Ref(schemaRoot, schema.$ref);
|
|
21
21
|
return S.IsSchema(dereferenced) ? dereferenced : false;
|
|
22
22
|
}
|
|
23
23
|
// ------------------------------------------------------------------
|
|
@@ -37,6 +37,7 @@ import { BuildPatternProperties, CheckPatternProperties, ErrorPatternProperties
|
|
|
37
37
|
import { BuildPrefixItems, CheckPrefixItems, ErrorPrefixItems } from './prefixItems.mjs';
|
|
38
38
|
import { BuildProperties, CheckProperties, ErrorProperties } from './properties.mjs';
|
|
39
39
|
import { BuildPropertyNames, CheckPropertyNames, ErrorPropertyNames } from './propertyNames.mjs';
|
|
40
|
+
import { BuildRecursiveRef, CheckRecursiveRef, ErrorRecursiveRef } from './recursiveRef.mjs';
|
|
40
41
|
import { BuildRef, CheckRef, ErrorRef } from './ref.mjs';
|
|
41
42
|
import { BuildRequired, CheckRequired, ErrorRequired } from './required.mjs';
|
|
42
43
|
import { BuildType, CheckType, ErrorType } from './type.mjs';
|
|
@@ -202,6 +203,8 @@ export function BuildSchema(context, schema, value) {
|
|
|
202
203
|
const guarded = E.Or(E.Not(E.Or(E.IsNumber(value), E.IsBigInt(value))), reduced);
|
|
203
204
|
conditions.push(HasNumberType(schema) ? reduced : guarded);
|
|
204
205
|
}
|
|
206
|
+
if (S.IsRecursiveRef(schema))
|
|
207
|
+
conditions.push(BuildRecursiveRef(context, schema, value));
|
|
205
208
|
if (S.IsRef(schema))
|
|
206
209
|
conditions.push(BuildRef(context, schema, value));
|
|
207
210
|
if (S.IsGuard(schema))
|
|
@@ -261,6 +264,7 @@ export function CheckSchema(context, schema, value) {
|
|
|
261
264
|
(!S.IsMaximum(schema) || CheckMaximum(context, schema, value)) &&
|
|
262
265
|
(!S.IsMinimum(schema) || CheckMinimum(context, schema, value)) &&
|
|
263
266
|
(!S.IsMultipleOf(schema) || CheckMultipleOf(context, schema, value)))) &&
|
|
267
|
+
(!S.IsRecursiveRef(schema) || CheckRecursiveRef(context, schema, value)) &&
|
|
264
268
|
(!S.IsRef(schema) || CheckRef(context, schema, value)) &&
|
|
265
269
|
(!S.IsGuard(schema) || CheckGuard(context, schema, value)) &&
|
|
266
270
|
(!S.IsConst(schema) || CheckConst(context, schema, value)) &&
|
|
@@ -307,6 +311,7 @@ export function ErrorSchema(context, schemaPath, instancePath, schema, value) {
|
|
|
307
311
|
+(!S.IsMaximum(schema) || ErrorMaximum(context, schemaPath, instancePath, schema, value)) &
|
|
308
312
|
+(!S.IsMinimum(schema) || ErrorMinimum(context, schemaPath, instancePath, schema, value)) &
|
|
309
313
|
+(!S.IsMultipleOf(schema) || ErrorMultipleOf(context, schemaPath, instancePath, schema, value)))) &
|
|
314
|
+
+(!S.IsRecursiveRef(schema) || ErrorRecursiveRef(context, schemaPath, instancePath, schema, value)) &
|
|
310
315
|
+(!S.IsRef(schema) || ErrorRef(context, schemaPath, instancePath, schema, value)) &
|
|
311
316
|
+(!S.IsGuard(schema) || ErrorGuard(context, schemaPath, instancePath, schema, value)) &
|
|
312
317
|
+(!S.IsConst(schema) || ErrorConst(context, schemaPath, instancePath, schema, value)) &
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Pointer from './pointer.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Pointer from './pointer.mjs';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Returns an array of path indices for the given pointer */
|
|
2
|
+
export declare function Indices(pointer: string): string[];
|
|
3
|
+
/** Returns true if a value exists at the current pointer */
|
|
4
|
+
export declare function Has(value: unknown, pointer: string): unknown;
|
|
5
|
+
/** Gets a value at the pointer, or undefined if not exists */
|
|
6
|
+
export declare function Get(value: unknown, pointer: string): unknown;
|
|
7
|
+
/** Sets a value at the given pointer. May throw if the target value is not indexable */
|
|
8
|
+
export declare function Set(value: unknown, pointer: string, next: unknown): unknown;
|
|
9
|
+
/** Deletes the value at the given pointer. May throw if the target value is not indexable */
|
|
10
|
+
export declare function Delete(value: unknown, pointer: string): unknown;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import { Guard } from '../../guard/index.mjs';
|
|
3
|
+
// ------------------------------------------------------------------
|
|
4
|
+
// Asserts
|
|
5
|
+
// ------------------------------------------------------------------
|
|
6
|
+
function AssertNotRoot(indices) {
|
|
7
|
+
if (indices.length === 0)
|
|
8
|
+
throw Error('Cannot set root');
|
|
9
|
+
}
|
|
10
|
+
function AssertCanSet(value) {
|
|
11
|
+
if (!Guard.IsObject(value))
|
|
12
|
+
throw Error('Cannot set value');
|
|
13
|
+
}
|
|
14
|
+
// ------------------------------------------------------------------
|
|
15
|
+
// Indices
|
|
16
|
+
// ------------------------------------------------------------------
|
|
17
|
+
function IsNumericIndex(index) {
|
|
18
|
+
return /^(0|[1-9]\d*)$/.test(index);
|
|
19
|
+
}
|
|
20
|
+
function TakeIndexRight(indices) {
|
|
21
|
+
return [
|
|
22
|
+
indices.slice(0, indices.length - 1),
|
|
23
|
+
indices.slice(indices.length - 1)[0]
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
function HasIndex(index, value) {
|
|
27
|
+
return Guard.IsObject(value) && Guard.HasPropertyKey(value, index);
|
|
28
|
+
}
|
|
29
|
+
function GetIndex(index, value) {
|
|
30
|
+
return Guard.IsObject(value) ? value[index] : undefined;
|
|
31
|
+
}
|
|
32
|
+
function GetIndices(indices, value) {
|
|
33
|
+
return indices.reduce((value, index) => GetIndex(index, value), value);
|
|
34
|
+
}
|
|
35
|
+
// ------------------------------------------------------------------
|
|
36
|
+
// Indices
|
|
37
|
+
// ------------------------------------------------------------------
|
|
38
|
+
/** Returns an array of path indices for the given pointer */
|
|
39
|
+
export function Indices(pointer) {
|
|
40
|
+
if (Guard.IsEqual(pointer.length, 0))
|
|
41
|
+
return [];
|
|
42
|
+
const indices = pointer.split("/").map(index => index.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
43
|
+
return (indices.length > 0 && indices[0] === '') ? indices.slice(1) : indices;
|
|
44
|
+
}
|
|
45
|
+
// ------------------------------------------------------------------
|
|
46
|
+
// Has
|
|
47
|
+
// ------------------------------------------------------------------
|
|
48
|
+
/** Returns true if a value exists at the current pointer */
|
|
49
|
+
export function Has(value, pointer) {
|
|
50
|
+
let current = value;
|
|
51
|
+
return Indices(pointer).every(index => {
|
|
52
|
+
if (!HasIndex(index, current))
|
|
53
|
+
return false;
|
|
54
|
+
current = current[index];
|
|
55
|
+
return true;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// ------------------------------------------------------------------
|
|
59
|
+
// Get
|
|
60
|
+
// ------------------------------------------------------------------
|
|
61
|
+
/** Gets a value at the pointer, or undefined if not exists */
|
|
62
|
+
export function Get(value, pointer) {
|
|
63
|
+
const indices = Indices(pointer);
|
|
64
|
+
return GetIndices(indices, value);
|
|
65
|
+
}
|
|
66
|
+
// ------------------------------------------------------------------
|
|
67
|
+
// Set
|
|
68
|
+
// ------------------------------------------------------------------
|
|
69
|
+
/** Sets a value at the given pointer. May throw if the target value is not indexable */
|
|
70
|
+
export function Set(value, pointer, next) {
|
|
71
|
+
const indices = Indices(pointer);
|
|
72
|
+
AssertNotRoot(indices);
|
|
73
|
+
const [head, index] = TakeIndexRight(indices);
|
|
74
|
+
const parent = GetIndices(head, value);
|
|
75
|
+
AssertCanSet(parent);
|
|
76
|
+
parent[index] = next;
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
// ------------------------------------------------------------------
|
|
80
|
+
// Delete
|
|
81
|
+
// ------------------------------------------------------------------
|
|
82
|
+
/** Deletes the value at the given pointer. May throw if the target value is not indexable */
|
|
83
|
+
export function Delete(value, pointer) {
|
|
84
|
+
const indices = Indices(pointer);
|
|
85
|
+
AssertNotRoot(indices);
|
|
86
|
+
const [head, index] = TakeIndexRight(indices);
|
|
87
|
+
const parent = GetIndices(head, value);
|
|
88
|
+
AssertCanSet(parent);
|
|
89
|
+
if (Guard.IsArray(parent) && IsNumericIndex(index)) {
|
|
90
|
+
parent.splice(+index, 1);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
delete parent[index];
|
|
94
|
+
}
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Resolver from './resolver.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Resolver from './resolver.mjs';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Guard } from '../../guard/index.mjs';
|
|
2
|
+
import * as S from '../types/index.mjs';
|
|
3
|
+
import { Ref } from './ref.mjs';
|
|
4
|
+
// ------------------------------------------------------------------
|
|
5
|
+
// FromArray
|
|
6
|
+
// ------------------------------------------------------------------
|
|
7
|
+
function FromArray(value, anchor, ref) {
|
|
8
|
+
for (const item of value) {
|
|
9
|
+
const resolved = FromValue(item, anchor, ref);
|
|
10
|
+
if (!Guard.IsUndefined(resolved))
|
|
11
|
+
return resolved;
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
// ------------------------------------------------------------------
|
|
16
|
+
// FromObject
|
|
17
|
+
// ------------------------------------------------------------------
|
|
18
|
+
function FromObject(value, anchor, ref) {
|
|
19
|
+
for (const key of Guard.Keys(value)) {
|
|
20
|
+
const resolved = FromValue(value[key], anchor, ref);
|
|
21
|
+
if (!Guard.IsUndefined(resolved))
|
|
22
|
+
return resolved;
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
// ------------------------------------------------------------------
|
|
27
|
+
// FromValue
|
|
28
|
+
// ------------------------------------------------------------------
|
|
29
|
+
function FromValue(value, anchor, ref) {
|
|
30
|
+
if (Guard.IsObjectNotArray(value) && S.IsRecursiveAnchor(value)) {
|
|
31
|
+
anchor = value;
|
|
32
|
+
}
|
|
33
|
+
if (value === ref)
|
|
34
|
+
return Ref(anchor, ref.$recursiveRef);
|
|
35
|
+
if (Guard.IsArray(value))
|
|
36
|
+
return FromArray(value, anchor, ref);
|
|
37
|
+
if (Guard.IsObject(value))
|
|
38
|
+
return FromObject(value, anchor, ref);
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
// ------------------------------------------------------------------
|
|
42
|
+
// RecursiveRef
|
|
43
|
+
// ------------------------------------------------------------------
|
|
44
|
+
export function RecursiveRef(schema, ref) {
|
|
45
|
+
const anchor = schema;
|
|
46
|
+
return FromValue(schema, anchor, ref);
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Ref(schema: unknown, ref: string): unknown;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import { Guard } from '../../guard/index.mjs';
|
|
3
|
+
import { Pointer } from '../pointer/index.mjs';
|
|
4
|
+
import * as S from '../types/index.mjs';
|
|
5
|
+
// ------------------------------------------------------------------
|
|
6
|
+
// MatchId
|
|
7
|
+
// ------------------------------------------------------------------
|
|
8
|
+
function MatchId(value, base, ref) {
|
|
9
|
+
if (value.$id === ref.hash)
|
|
10
|
+
return value;
|
|
11
|
+
const absoluteId = new URL(value.$id, base.href);
|
|
12
|
+
const absoluteRef = new URL(ref.href, base.href);
|
|
13
|
+
if (Guard.IsEqual(absoluteId.pathname, absoluteRef.pathname)) {
|
|
14
|
+
return ref.hash.startsWith('#') ? MatchHash(value, base, ref) : value;
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
// ------------------------------------------------------------------
|
|
19
|
+
// MatchAnchor
|
|
20
|
+
// ------------------------------------------------------------------
|
|
21
|
+
function MatchAnchor(value, base, ref) {
|
|
22
|
+
const absoluteAnchor = new URL(`#${value.$anchor}`, base.href);
|
|
23
|
+
const absoluteRef = new URL(ref.href, base.href);
|
|
24
|
+
if (Guard.IsEqual(absoluteAnchor.href, absoluteRef.href))
|
|
25
|
+
return value;
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
// ------------------------------------------------------------------
|
|
29
|
+
// MatchHash
|
|
30
|
+
// ------------------------------------------------------------------
|
|
31
|
+
function MatchHash(value, base, ref) {
|
|
32
|
+
if (ref.href.endsWith('#'))
|
|
33
|
+
return value;
|
|
34
|
+
return ref.hash.startsWith('#')
|
|
35
|
+
? Pointer.Get(value, decodeURIComponent(ref.hash.slice(1)))
|
|
36
|
+
: undefined;
|
|
37
|
+
}
|
|
38
|
+
// ------------------------------------------------------------------
|
|
39
|
+
// Match
|
|
40
|
+
// ------------------------------------------------------------------
|
|
41
|
+
function Match(value, base, ref) {
|
|
42
|
+
if (S.IsId(value)) {
|
|
43
|
+
const result = MatchId(value, base, ref);
|
|
44
|
+
if (!Guard.IsUndefined(result))
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
if (S.IsAnchor(value)) {
|
|
48
|
+
const result = MatchAnchor(value, base, ref);
|
|
49
|
+
if (!Guard.IsUndefined(result))
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
return MatchHash(value, base, ref);
|
|
53
|
+
}
|
|
54
|
+
// ------------------------------------------------------------------
|
|
55
|
+
// FromArray
|
|
56
|
+
// ------------------------------------------------------------------
|
|
57
|
+
function FromArray(value, base, ref) {
|
|
58
|
+
for (const item of value) {
|
|
59
|
+
const result = FromValue(item, base, ref);
|
|
60
|
+
if (!Guard.IsUndefined(result))
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
// ------------------------------------------------------------------
|
|
66
|
+
// FromObject
|
|
67
|
+
// ------------------------------------------------------------------
|
|
68
|
+
function FromObject(value, base, ref) {
|
|
69
|
+
for (const key of Guard.Keys(value)) {
|
|
70
|
+
const result = FromValue(value[key], base, ref);
|
|
71
|
+
if (!Guard.IsUndefined(result))
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
// ------------------------------------------------------------------
|
|
77
|
+
// FromValue
|
|
78
|
+
// ------------------------------------------------------------------
|
|
79
|
+
function FromValue(value, base, ref) {
|
|
80
|
+
const newbase = S.IsSchemaObject(value) && S.IsId(value) ? new URL(value.$id, ref.href) : base;
|
|
81
|
+
if (S.IsSchemaObject(value)) {
|
|
82
|
+
const result = Match(value, newbase, ref);
|
|
83
|
+
if (!Guard.IsUndefined(result))
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
if (Guard.IsArray(value))
|
|
87
|
+
return FromArray(value, newbase, ref);
|
|
88
|
+
if (Guard.IsObject(value))
|
|
89
|
+
return FromObject(value, newbase, ref);
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
// ------------------------------------------------------------------
|
|
93
|
+
// Ref
|
|
94
|
+
// ------------------------------------------------------------------
|
|
95
|
+
export function Ref(schema, ref) {
|
|
96
|
+
const base = new URL('', 'http://domain.com');
|
|
97
|
+
return FromValue(schema, base, new URL(ref, 'http://domain.com'));
|
|
98
|
+
}
|
package/build/schema/schema.mjs
CHANGED
|
@@ -42,6 +42,8 @@ export * from './patternProperties.mjs';
|
|
|
42
42
|
export * from './prefixItems.mjs';
|
|
43
43
|
export * from './properties.mjs';
|
|
44
44
|
export * from './propertyNames.mjs';
|
|
45
|
+
export * from './recursiveAnchor.mjs';
|
|
46
|
+
export * from './recursiveRef.mjs';
|
|
45
47
|
export * from './ref.mjs';
|
|
46
48
|
export * from './required.mjs';
|
|
47
49
|
export * from './schema.mjs';
|
|
@@ -48,6 +48,8 @@ export * from './patternProperties.mjs';
|
|
|
48
48
|
export * from './prefixItems.mjs';
|
|
49
49
|
export * from './properties.mjs';
|
|
50
50
|
export * from './propertyNames.mjs';
|
|
51
|
+
export * from './recursiveAnchor.mjs';
|
|
52
|
+
export * from './recursiveRef.mjs';
|
|
51
53
|
export * from './ref.mjs';
|
|
52
54
|
export * from './required.mjs';
|
|
53
55
|
export * from './schema.mjs';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type XSchemaObject } from './schema.mjs';
|
|
2
|
+
export interface XRecursiveAnchor<Anchor extends string = string> {
|
|
3
|
+
$recursiveAnchor: Anchor;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Returns true if the schema contains a valid $recursiveAnchor property
|
|
7
|
+
*/
|
|
8
|
+
export declare function IsRecursiveAnchor(schema: XSchemaObject): schema is XRecursiveAnchor;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import { Guard } from '../../guard/index.mjs';
|
|
3
|
+
// ------------------------------------------------------------------
|
|
4
|
+
// Guard
|
|
5
|
+
// ------------------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Returns true if the schema contains a valid $recursiveAnchor property
|
|
8
|
+
*/
|
|
9
|
+
export function IsRecursiveAnchor(schema) {
|
|
10
|
+
return Guard.HasPropertyKey(schema, '$recursiveAnchor')
|
|
11
|
+
&& Guard.IsBoolean(schema.$recursiveAnchor);
|
|
12
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type XSchemaObject } from './schema.mjs';
|
|
2
|
+
export interface XRecursiveRef<Ref extends string = string> {
|
|
3
|
+
$recursiveRef: Ref;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Returns true if the schema contains a valid $recursiveRef property
|
|
7
|
+
*/
|
|
8
|
+
export declare function IsRecursiveRef(schema: XSchemaObject): schema is XRecursiveRef;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import { Guard } from '../../guard/index.mjs';
|
|
3
|
+
// ------------------------------------------------------------------
|
|
4
|
+
// Guard
|
|
5
|
+
// ------------------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Returns true if the schema contains a valid $recursiveRef property
|
|
8
|
+
*/
|
|
9
|
+
export function IsRecursiveRef(schema) {
|
|
10
|
+
return Guard.HasPropertyKey(schema, '$recursiveRef')
|
|
11
|
+
&& Guard.IsString(schema.$recursiveRef);
|
|
12
|
+
}
|
|
@@ -2,5 +2,5 @@ export * from './arguments/index.mjs';
|
|
|
2
2
|
export * from './environment/index.mjs';
|
|
3
3
|
export * from './hashing/index.mjs';
|
|
4
4
|
export * from './locale/index.mjs';
|
|
5
|
-
export * from './settings/index.mjs';
|
|
6
5
|
export * from './memory/index.mjs';
|
|
6
|
+
export * from './settings/index.mjs';
|
package/build/system/system.mjs
CHANGED
|
@@ -2,5 +2,5 @@ export * from './arguments/index.mjs';
|
|
|
2
2
|
export * from './environment/index.mjs';
|
|
3
3
|
export * from './hashing/index.mjs';
|
|
4
4
|
export * from './locale/index.mjs';
|
|
5
|
-
export * from './settings/index.mjs';
|
|
6
5
|
export * from './memory/index.mjs';
|
|
6
|
+
export * from './settings/index.mjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export *
|
|
1
|
+
export * from '../../schema/pointer/index.mjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export *
|
|
1
|
+
export * from '../../schema/pointer/index.mjs';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typebox",
|
|
3
3
|
"description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.43",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
7
7
|
"jsonschema"
|
|
@@ -16,38 +16,38 @@
|
|
|
16
16
|
"types": "./build/index.d.mts",
|
|
17
17
|
"module": "./build/index.mjs",
|
|
18
18
|
"exports": {
|
|
19
|
-
"./
|
|
20
|
-
"import": "./build/
|
|
21
|
-
"default": "./build/
|
|
19
|
+
"./guard": {
|
|
20
|
+
"import": "./build/guard/index.mjs",
|
|
21
|
+
"default": "./build/guard/index.mjs"
|
|
22
22
|
},
|
|
23
23
|
"./schema": {
|
|
24
24
|
"import": "./build/schema/index.mjs",
|
|
25
25
|
"default": "./build/schema/index.mjs"
|
|
26
26
|
},
|
|
27
|
-
"./format": {
|
|
28
|
-
"import": "./build/format/index.mjs",
|
|
29
|
-
"default": "./build/format/index.mjs"
|
|
30
|
-
},
|
|
31
|
-
"./compile": {
|
|
32
|
-
"import": "./build/compile/index.mjs",
|
|
33
|
-
"default": "./build/compile/index.mjs"
|
|
34
|
-
},
|
|
35
|
-
"./guard": {
|
|
36
|
-
"import": "./build/guard/index.mjs",
|
|
37
|
-
"default": "./build/guard/index.mjs"
|
|
38
|
-
},
|
|
39
27
|
"./value": {
|
|
40
28
|
"import": "./build/value/index.mjs",
|
|
41
29
|
"default": "./build/value/index.mjs"
|
|
42
30
|
},
|
|
31
|
+
"./format": {
|
|
32
|
+
"import": "./build/format/index.mjs",
|
|
33
|
+
"default": "./build/format/index.mjs"
|
|
34
|
+
},
|
|
43
35
|
"./type": {
|
|
44
36
|
"import": "./build/type/index.mjs",
|
|
45
37
|
"default": "./build/type/index.mjs"
|
|
46
38
|
},
|
|
39
|
+
"./error": {
|
|
40
|
+
"import": "./build/error/index.mjs",
|
|
41
|
+
"default": "./build/error/index.mjs"
|
|
42
|
+
},
|
|
47
43
|
"./system": {
|
|
48
44
|
"import": "./build/system/index.mjs",
|
|
49
45
|
"default": "./build/system/index.mjs"
|
|
50
46
|
},
|
|
47
|
+
"./compile": {
|
|
48
|
+
"import": "./build/compile/index.mjs",
|
|
49
|
+
"default": "./build/compile/index.mjs"
|
|
50
|
+
},
|
|
51
51
|
".": {
|
|
52
52
|
"import": "./build/index.mjs",
|
|
53
53
|
"default": "./build/index.mjs"
|
|
@@ -55,30 +55,30 @@
|
|
|
55
55
|
},
|
|
56
56
|
"typesVersions": {
|
|
57
57
|
"*": {
|
|
58
|
-
"
|
|
59
|
-
"./build/
|
|
58
|
+
"guard": [
|
|
59
|
+
"./build/guard/index.d.mts"
|
|
60
60
|
],
|
|
61
61
|
"schema": [
|
|
62
62
|
"./build/schema/index.d.mts"
|
|
63
63
|
],
|
|
64
|
-
"format": [
|
|
65
|
-
"./build/format/index.d.mts"
|
|
66
|
-
],
|
|
67
|
-
"compile": [
|
|
68
|
-
"./build/compile/index.d.mts"
|
|
69
|
-
],
|
|
70
|
-
"guard": [
|
|
71
|
-
"./build/guard/index.d.mts"
|
|
72
|
-
],
|
|
73
64
|
"value": [
|
|
74
65
|
"./build/value/index.d.mts"
|
|
75
66
|
],
|
|
67
|
+
"format": [
|
|
68
|
+
"./build/format/index.d.mts"
|
|
69
|
+
],
|
|
76
70
|
"type": [
|
|
77
71
|
"./build/type/index.d.mts"
|
|
78
72
|
],
|
|
73
|
+
"error": [
|
|
74
|
+
"./build/error/index.d.mts"
|
|
75
|
+
],
|
|
79
76
|
"system": [
|
|
80
77
|
"./build/system/index.d.mts"
|
|
81
78
|
],
|
|
79
|
+
"compile": [
|
|
80
|
+
"./build/compile/index.d.mts"
|
|
81
|
+
],
|
|
82
82
|
".": [
|
|
83
83
|
"./build/index.d.mts"
|
|
84
84
|
]
|
package/readme.md
CHANGED
|
@@ -102,6 +102,30 @@ type T = Type.Static<typeof T> // type T = {
|
|
|
102
102
|
// }
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
Constraints and metadata can be passed on the last argument of any given type.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const T = Type.Number({ // const T = {
|
|
109
|
+
minimum: 0, // type: 'number',
|
|
110
|
+
maximum: 100 // minimum: 0,
|
|
111
|
+
}) // maximum: 100
|
|
112
|
+
// }
|
|
113
|
+
|
|
114
|
+
const S = Type.String({ // const S = {
|
|
115
|
+
format: 'email' // type: 'string',
|
|
116
|
+
}) // format: 'email'
|
|
117
|
+
// }
|
|
118
|
+
|
|
119
|
+
const M = Type.Object({ // const M = {
|
|
120
|
+
id: Type.String(), // type: 'object',
|
|
121
|
+
message: Type.String() // required: ['id', 'message'],
|
|
122
|
+
}, { // properties: {
|
|
123
|
+
description: 'A protocol message' // id: { type: 'string' },
|
|
124
|
+
}) // message: { type: 'string' }
|
|
125
|
+
// },
|
|
126
|
+
// description: 'A protocol message'
|
|
127
|
+
// }
|
|
128
|
+
```
|
|
105
129
|
|
|
106
130
|
|
|
107
131
|
<a name="Script"></a>
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { Guard } from '../../guard/index.mjs';
|
|
2
|
-
import { IsJsonPointer, IsUri } from '../../format/index.mjs';
|
|
3
|
-
import { Pointer } from '../../value/pointer/index.mjs';
|
|
4
|
-
import * as S from '../types/index.mjs';
|
|
5
|
-
// ------------------------------------------------------------------
|
|
6
|
-
// Rebase
|
|
7
|
-
// ------------------------------------------------------------------
|
|
8
|
-
export function Rebase(baseUri, schema) {
|
|
9
|
-
if (!S.IsId(schema))
|
|
10
|
-
return baseUri;
|
|
11
|
-
if (IsUri(schema.$id))
|
|
12
|
-
return schema.$id;
|
|
13
|
-
if (!IsUri(schema.$id) && IsUri(baseUri)) {
|
|
14
|
-
return new URL(schema.$id, baseUri).href;
|
|
15
|
-
}
|
|
16
|
-
return baseUri;
|
|
17
|
-
}
|
|
18
|
-
// ------------------------------------------------------------------
|
|
19
|
-
// Select
|
|
20
|
-
// ------------------------------------------------------------------
|
|
21
|
-
function IsHashPointer(value) {
|
|
22
|
-
return IsHash(value) && IsJsonPointer(value.slice(1));
|
|
23
|
-
}
|
|
24
|
-
function IsHash(value) {
|
|
25
|
-
return value.length > 0 && value[0] === '#';
|
|
26
|
-
}
|
|
27
|
-
function Select(schema, baseUri, $ref) {
|
|
28
|
-
if (IsUri(baseUri)) {
|
|
29
|
-
const [base, ref] = [new URL(baseUri), new URL($ref, baseUri)];
|
|
30
|
-
const matched = base.pathname === ref.pathname;
|
|
31
|
-
const withHash = IsHash(ref.hash);
|
|
32
|
-
if (matched && !withHash) {
|
|
33
|
-
return schema;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (IsHashPointer($ref)) {
|
|
37
|
-
const target = Pointer.Get(schema, $ref.slice(1));
|
|
38
|
-
if (S.IsSchema(target))
|
|
39
|
-
return target;
|
|
40
|
-
}
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
// ------------------------------------------------------------------
|
|
44
|
-
// Traversal
|
|
45
|
-
// ------------------------------------------------------------------
|
|
46
|
-
function FromObject(schema, baseUrl, ref) {
|
|
47
|
-
// ----------------------------------------------------------------
|
|
48
|
-
// TypeBox: Fast TCyclic Deref
|
|
49
|
-
// ----------------------------------------------------------------
|
|
50
|
-
if (S.IsDefs(schema) && Guard.HasPropertyKey(schema.$defs, ref.$ref)) {
|
|
51
|
-
return schema.$defs[ref.$ref];
|
|
52
|
-
}
|
|
53
|
-
// ----------------------------------------------------------------
|
|
54
|
-
// Json Schema
|
|
55
|
-
// ----------------------------------------------------------------
|
|
56
|
-
const rebase = Rebase(baseUrl, schema);
|
|
57
|
-
const target = Select(schema, rebase, ref.$ref);
|
|
58
|
-
if (S.IsSchema(target))
|
|
59
|
-
return target;
|
|
60
|
-
// Keep searching ...
|
|
61
|
-
return Object.values(schema).reduce((result, subschema) => result || FromValue(subschema, rebase, ref), undefined);
|
|
62
|
-
}
|
|
63
|
-
function FromArray(schema, baseUri, ref) {
|
|
64
|
-
return schema.reduce((result, value) => result || FromValue(value, baseUri, ref), undefined);
|
|
65
|
-
}
|
|
66
|
-
function FromValue(schema, base, ref) {
|
|
67
|
-
return ((Guard.IsObject(schema) && FromObject(schema, base, ref)) ||
|
|
68
|
-
(Guard.IsArray(schema) && FromArray(schema, base, ref)) ||
|
|
69
|
-
undefined);
|
|
70
|
-
}
|
|
71
|
-
// ------------------------------------------------------------------
|
|
72
|
-
// Deref
|
|
73
|
-
// ------------------------------------------------------------------
|
|
74
|
-
/** Deferences a schema with the given Ref */
|
|
75
|
-
export function Deref(schema, ref) {
|
|
76
|
-
return FromValue(schema, '', ref);
|
|
77
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Deref } from './deref.mjs';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Deref } from './deref.mjs';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
type ObjectLike = Record<PropertyKey, any>;
|
|
2
|
-
/** Transforms a pointer into navigable key components */
|
|
3
|
-
export declare function Format(pointer: string): IterableIterator<string>;
|
|
4
|
-
/**
|
|
5
|
-
* Sets the value at the given pointer and returns the updated value. If the pointer
|
|
6
|
-
* path does not exist, the path will be created.
|
|
7
|
-
*/
|
|
8
|
-
export declare function Set(value: ObjectLike, pointer: string, update: unknown): ObjectLike;
|
|
9
|
-
/**
|
|
10
|
-
* Deletes a value at the given pointer and returns the updated value.
|
|
11
|
-
*/
|
|
12
|
-
export declare function Delete(value: ObjectLike, pointer: string): ObjectLike;
|
|
13
|
-
/** Returns true if a property or element exists at the given pointer */
|
|
14
|
-
export declare function Has(value: ObjectLike, pointer: string): boolean;
|
|
15
|
-
/** Gets the value at the given pointer or undefined if not exists. */
|
|
16
|
-
export declare function Get(value: ObjectLike, pointer: string): unknown | undefined;
|
|
17
|
-
export {};
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
// deno-fmt-ignore-file
|
|
2
|
-
import { Guard } from '../../guard/index.mjs';
|
|
3
|
-
// ------------------------------------------------------------------
|
|
4
|
-
// Errors
|
|
5
|
-
// ------------------------------------------------------------------
|
|
6
|
-
class ValuePointerRootSetError extends Error {
|
|
7
|
-
constructor(value, path, update) {
|
|
8
|
-
super('Cannot set root value');
|
|
9
|
-
this.value = value;
|
|
10
|
-
this.path = path;
|
|
11
|
-
this.update = update;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
class ValuePointerRootDeleteError extends Error {
|
|
15
|
-
constructor(value, path) {
|
|
16
|
-
super('Cannot delete root value');
|
|
17
|
-
this.value = value;
|
|
18
|
-
this.path = path;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// ------------------------------------------------------------------
|
|
22
|
-
// ValuePointer
|
|
23
|
-
// ------------------------------------------------------------------
|
|
24
|
-
/** Provides functionality to update values through RFC6901 string pointers */
|
|
25
|
-
function Escape(component) {
|
|
26
|
-
const decoded = decodeURIComponent(component);
|
|
27
|
-
return decoded.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
28
|
-
}
|
|
29
|
-
// ------------------------------------------------------------------
|
|
30
|
-
// Format
|
|
31
|
-
// ------------------------------------------------------------------
|
|
32
|
-
/** Transforms a pointer into navigable key components */
|
|
33
|
-
export function* Format(pointer) {
|
|
34
|
-
if (pointer === '')
|
|
35
|
-
return;
|
|
36
|
-
let [start, end] = [0, 0];
|
|
37
|
-
for (let i = 0; i < pointer.length; i++) {
|
|
38
|
-
const char = pointer.charAt(i);
|
|
39
|
-
if (char === '/') {
|
|
40
|
-
if (i === 0) {
|
|
41
|
-
start = i + 1;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
end = i;
|
|
45
|
-
yield Escape(pointer.slice(start, end));
|
|
46
|
-
start = i + 1;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
end = i;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
yield Escape(pointer.slice(start));
|
|
54
|
-
}
|
|
55
|
-
// ------------------------------------------------------------------
|
|
56
|
-
// Set
|
|
57
|
-
// ------------------------------------------------------------------
|
|
58
|
-
/**
|
|
59
|
-
* Sets the value at the given pointer and returns the updated value. If the pointer
|
|
60
|
-
* path does not exist, the path will be created.
|
|
61
|
-
*/
|
|
62
|
-
export function Set(value, pointer, update) {
|
|
63
|
-
if (pointer === '')
|
|
64
|
-
throw new ValuePointerRootSetError(value, pointer, update);
|
|
65
|
-
let [owner, next, key] = [null, value, ''];
|
|
66
|
-
for (const component of Format(pointer)) {
|
|
67
|
-
if (Guard.IsUndefined(next[component]))
|
|
68
|
-
next[component] = {};
|
|
69
|
-
owner = next;
|
|
70
|
-
next = next[component];
|
|
71
|
-
key = component;
|
|
72
|
-
}
|
|
73
|
-
if (Guard.IsObject(owner)) {
|
|
74
|
-
owner[key] = update;
|
|
75
|
-
}
|
|
76
|
-
return value;
|
|
77
|
-
}
|
|
78
|
-
// ------------------------------------------------------------------
|
|
79
|
-
// Delete
|
|
80
|
-
// ------------------------------------------------------------------
|
|
81
|
-
/**
|
|
82
|
-
* Deletes a value at the given pointer and returns the updated value.
|
|
83
|
-
*/
|
|
84
|
-
export function Delete(value, pointer) {
|
|
85
|
-
if (pointer === '')
|
|
86
|
-
throw new ValuePointerRootDeleteError(value, pointer);
|
|
87
|
-
let [owner, next, key] = [null, value, ''];
|
|
88
|
-
for (const component of Format(pointer)) {
|
|
89
|
-
if (Guard.IsUndefined(next[component]) || Guard.IsNull(next[component])) {
|
|
90
|
-
return value;
|
|
91
|
-
}
|
|
92
|
-
owner = next;
|
|
93
|
-
next = next[component];
|
|
94
|
-
key = component;
|
|
95
|
-
}
|
|
96
|
-
if (Guard.IsArray(owner)) {
|
|
97
|
-
const index = parseInt(key);
|
|
98
|
-
owner.splice(index, 1);
|
|
99
|
-
}
|
|
100
|
-
else if (Guard.IsObject(owner)) {
|
|
101
|
-
delete owner[key];
|
|
102
|
-
}
|
|
103
|
-
return value;
|
|
104
|
-
}
|
|
105
|
-
// ------------------------------------------------------------------
|
|
106
|
-
// Has
|
|
107
|
-
// ------------------------------------------------------------------
|
|
108
|
-
/** Returns true if a property or element exists at the given pointer */
|
|
109
|
-
export function Has(value, pointer) {
|
|
110
|
-
if (pointer === '')
|
|
111
|
-
return true;
|
|
112
|
-
let [owner, next, key] = [null, value, ''];
|
|
113
|
-
for (const component of Format(pointer)) {
|
|
114
|
-
if (Guard.IsUndefined(next[component]) || Guard.IsNull(next[component])) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
owner = next;
|
|
118
|
-
next = next[component];
|
|
119
|
-
key = component;
|
|
120
|
-
}
|
|
121
|
-
return Object.getOwnPropertyNames(owner).includes(key);
|
|
122
|
-
}
|
|
123
|
-
// ------------------------------------------------------------------
|
|
124
|
-
// Get
|
|
125
|
-
// ------------------------------------------------------------------
|
|
126
|
-
/** Gets the value at the given pointer or undefined if not exists. */
|
|
127
|
-
export function Get(value, pointer) {
|
|
128
|
-
if (pointer === '')
|
|
129
|
-
return value;
|
|
130
|
-
let current = value;
|
|
131
|
-
for (const component of Format(pointer)) {
|
|
132
|
-
if (current[component] === undefined)
|
|
133
|
-
return undefined;
|
|
134
|
-
current = current[component];
|
|
135
|
-
}
|
|
136
|
-
return current;
|
|
137
|
-
}
|