typebox 1.0.41 → 1.0.42

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.
Files changed (39) hide show
  1. package/build/guard/emit.mjs +1 -1
  2. package/build/schema/engine/index.d.mts +1 -0
  3. package/build/schema/engine/index.mjs +1 -0
  4. package/build/schema/engine/recursiveRef.d.mts +5 -0
  5. package/build/schema/engine/recursiveRef.mjs +36 -0
  6. package/build/schema/engine/ref.mjs +3 -3
  7. package/build/schema/engine/schema.mjs +5 -0
  8. package/build/schema/pointer/index.d.mts +1 -0
  9. package/build/schema/pointer/index.mjs +1 -0
  10. package/build/schema/pointer/pointer.d.mts +10 -0
  11. package/build/schema/pointer/pointer.mjs +88 -0
  12. package/build/schema/resolver/index.d.mts +1 -0
  13. package/build/schema/resolver/index.mjs +1 -0
  14. package/build/schema/resolver/recursiveRef.d.mts +2 -0
  15. package/build/schema/resolver/recursiveRef.mjs +47 -0
  16. package/build/schema/resolver/ref.d.mts +1 -0
  17. package/build/schema/resolver/ref.mjs +98 -0
  18. package/build/schema/resolver/resolver.d.mts +2 -0
  19. package/build/schema/resolver/resolver.mjs +2 -0
  20. package/build/schema/schema.d.mts +2 -0
  21. package/build/schema/schema.mjs +2 -0
  22. package/build/schema/types/index.d.mts +2 -0
  23. package/build/schema/types/index.mjs +2 -0
  24. package/build/schema/types/recursiveAnchor.d.mts +8 -0
  25. package/build/schema/types/recursiveAnchor.mjs +12 -0
  26. package/build/schema/types/recursiveRef.d.mts +8 -0
  27. package/build/schema/types/recursiveRef.mjs +12 -0
  28. package/build/system/system.d.mts +1 -1
  29. package/build/system/system.mjs +1 -1
  30. package/build/value/pointer/index.d.mts +1 -1
  31. package/build/value/pointer/index.mjs +1 -1
  32. package/package.json +27 -27
  33. package/readme.md +24 -0
  34. package/build/schema/deref/deref.d.mts +0 -4
  35. package/build/schema/deref/deref.mjs +0 -77
  36. package/build/schema/deref/index.d.mts +0 -1
  37. package/build/schema/deref/index.mjs +0 -1
  38. package/build/value/pointer/pointer.d.mts +0 -17
  39. package/build/value/pointer/pointer.mjs +0 -137
@@ -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 `${condition} ? ${true_} : ${false_}`;
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 { Deref } from '../deref/index.mjs';
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
- // inline referential schema
20
- const dereferenced = Deref(schemaRoot, { $ref: schema.$ref });
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,88 @@
1
+ // deno-fmt-ignore-file
2
+ import { Guard } from '../../guard/index.mjs';
3
+ // ------------------------------------------------------------------
4
+ // Indices
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 TakeIndexRight(indices) {
18
+ return [
19
+ indices.slice(0, indices.length - 1),
20
+ indices.slice(indices.length - 1)[0]
21
+ ];
22
+ }
23
+ function HasIndex(index, value) {
24
+ return Guard.IsObject(value) && Guard.HasPropertyKey(value, index);
25
+ }
26
+ function GetIndex(index, value) {
27
+ return Guard.IsObject(value) ? value[index] : undefined;
28
+ }
29
+ function GetIndices(indices, value) {
30
+ return indices.reduce((value, index) => GetIndex(index, value), value);
31
+ }
32
+ // ------------------------------------------------------------------
33
+ // Indices
34
+ // ------------------------------------------------------------------
35
+ /** Returns an array of path indices for the given pointer */
36
+ export function Indices(pointer) {
37
+ if (Guard.IsEqual(pointer.length, 0))
38
+ return [];
39
+ const indices = pointer.split("/").map(index => index.replace(/~1/g, "/").replace(/~0/g, "~"));
40
+ return (indices.length > 0 && indices[0] === '') ? indices.slice(1) : indices;
41
+ }
42
+ // ------------------------------------------------------------------
43
+ // Has
44
+ // ------------------------------------------------------------------
45
+ /** Returns true if a value exists at the current pointer */
46
+ export function Has(value, pointer) {
47
+ let current = value;
48
+ return Indices(pointer).every(index => {
49
+ if (!HasIndex(index, current))
50
+ return false;
51
+ current = current[index];
52
+ return true;
53
+ });
54
+ }
55
+ // ------------------------------------------------------------------
56
+ // Get
57
+ // ------------------------------------------------------------------
58
+ /** Gets a value at the pointer, or undefined if not exists */
59
+ export function Get(value, pointer) {
60
+ const indices = Indices(pointer);
61
+ return GetIndices(indices, value);
62
+ }
63
+ // ------------------------------------------------------------------
64
+ // Set
65
+ // ------------------------------------------------------------------
66
+ /** Sets a value at the given pointer. May throw if the target value is not indexable */
67
+ export function Set(value, pointer, next) {
68
+ const indices = Indices(pointer);
69
+ AssertNotRoot(indices);
70
+ const [head, index] = TakeIndexRight(indices);
71
+ const parent = GetIndices(head, value);
72
+ AssertCanSet(parent);
73
+ parent[index] = next;
74
+ return value;
75
+ }
76
+ // ------------------------------------------------------------------
77
+ // Delete
78
+ // ------------------------------------------------------------------
79
+ /** Deletes the value at the given pointer. May throw if the target value is not indexable */
80
+ export function Delete(value, pointer) {
81
+ const indices = Indices(pointer);
82
+ AssertNotRoot(indices);
83
+ const [head, index] = TakeIndexRight(indices);
84
+ const parent = GetIndices(head, value);
85
+ AssertCanSet(parent);
86
+ delete parent[index];
87
+ return value;
88
+ }
@@ -0,0 +1 @@
1
+ export * as Resolver from './resolver.mjs';
@@ -0,0 +1 @@
1
+ export * as Resolver from './resolver.mjs';
@@ -0,0 +1,2 @@
1
+ import * as S from '../types/index.mjs';
2
+ export declare function RecursiveRef(schema: unknown, ref: S.XRecursiveRef): unknown;
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ export * from './recursiveRef.mjs';
2
+ export * from './ref.mjs';
@@ -0,0 +1,2 @@
1
+ export * from './recursiveRef.mjs';
2
+ export * from './ref.mjs';
@@ -1,4 +1,6 @@
1
1
  export * from './engine/index.mjs';
2
+ export * from './pointer/index.mjs';
3
+ export * from './resolver/index.mjs';
2
4
  export * from './static/index.mjs';
3
5
  export * from './types/index.mjs';
4
6
  export * from './build.mjs';
@@ -1,4 +1,6 @@
1
1
  export * from './engine/index.mjs';
2
+ export * from './pointer/index.mjs';
3
+ export * from './resolver/index.mjs';
2
4
  export * from './static/index.mjs';
3
5
  export * from './types/index.mjs';
4
6
  export * from './build.mjs';
@@ -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';
@@ -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 * as Pointer from './pointer.mjs';
1
+ export * from '../../schema/pointer/index.mjs';
@@ -1 +1 @@
1
- export * as Pointer from './pointer.mjs';
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.41",
4
+ "version": "1.0.42",
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
- "./error": {
20
- "import": "./build/error/index.mjs",
21
- "default": "./build/error/index.mjs"
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
- "error": [
59
- "./build/error/index.d.mts"
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,4 +0,0 @@
1
- import * as S from '../types/index.mjs';
2
- export declare function Rebase(baseUri: string, schema: S.XSchemaObject): string;
3
- /** Deferences a schema with the given Ref */
4
- export declare function Deref(schema: object, ref: S.XRef): unknown | undefined;
@@ -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
- }