@sinclair/typebox 0.33.3 → 0.33.5

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 (60) hide show
  1. package/build/cjs/compiler/compiler.d.ts +2 -2
  2. package/build/cjs/compiler/compiler.js +1 -1
  3. package/build/cjs/system/policy.d.ts +5 -5
  4. package/build/cjs/system/policy.js +5 -5
  5. package/build/cjs/value/assert/assert.d.ts +15 -0
  6. package/build/cjs/value/assert/assert.js +55 -0
  7. package/build/cjs/value/assert/index.d.ts +1 -0
  8. package/build/cjs/value/assert/index.js +18 -0
  9. package/build/cjs/value/cast/cast.js +1 -1
  10. package/build/cjs/value/clean/clean.js +6 -6
  11. package/build/cjs/value/clone/clone.js +21 -11
  12. package/build/cjs/value/convert/convert.d.ts +2 -2
  13. package/build/cjs/value/convert/convert.js +17 -18
  14. package/build/cjs/value/create/create.js +5 -1
  15. package/build/cjs/value/default/default.js +14 -16
  16. package/build/cjs/value/equal/equal.js +3 -3
  17. package/build/cjs/value/hash/hash.js +1 -1
  18. package/build/cjs/value/index.d.ts +2 -0
  19. package/build/cjs/value/index.js +2 -0
  20. package/build/cjs/value/mutate/mutate.js +4 -4
  21. package/build/cjs/value/parse/index.d.ts +1 -0
  22. package/build/cjs/value/parse/index.js +18 -0
  23. package/build/cjs/value/parse/parse.d.ts +6 -0
  24. package/build/cjs/value/parse/parse.js +29 -0
  25. package/build/cjs/value/transform/decode.js +21 -8
  26. package/build/cjs/value/transform/encode.js +22 -9
  27. package/build/cjs/value/transform/has.js +5 -1
  28. package/build/cjs/value/value/value.d.ts +10 -2
  29. package/build/cjs/value/value/value.js +38 -26
  30. package/build/esm/compiler/compiler.d.mts +2 -2
  31. package/build/esm/compiler/compiler.mjs +1 -1
  32. package/build/esm/system/policy.d.mts +5 -5
  33. package/build/esm/system/policy.mjs +5 -5
  34. package/build/esm/value/assert/assert.d.mts +15 -0
  35. package/build/esm/value/assert/assert.mjs +49 -0
  36. package/build/esm/value/assert/index.d.mts +1 -0
  37. package/build/esm/value/assert/index.mjs +1 -0
  38. package/build/esm/value/cast/cast.mjs +2 -2
  39. package/build/esm/value/clean/clean.mjs +7 -7
  40. package/build/esm/value/clone/clone.mjs +22 -12
  41. package/build/esm/value/convert/convert.d.mts +2 -2
  42. package/build/esm/value/convert/convert.mjs +17 -18
  43. package/build/esm/value/create/create.mjs +5 -1
  44. package/build/esm/value/default/default.mjs +14 -16
  45. package/build/esm/value/equal/equal.mjs +4 -4
  46. package/build/esm/value/hash/hash.mjs +2 -2
  47. package/build/esm/value/index.d.mts +2 -0
  48. package/build/esm/value/index.mjs +2 -0
  49. package/build/esm/value/mutate/mutate.mjs +5 -5
  50. package/build/esm/value/parse/index.d.mts +1 -0
  51. package/build/esm/value/parse/index.mjs +1 -0
  52. package/build/esm/value/parse/parse.d.mts +6 -0
  53. package/build/esm/value/parse/parse.mjs +25 -0
  54. package/build/esm/value/transform/decode.mjs +23 -10
  55. package/build/esm/value/transform/encode.mjs +24 -11
  56. package/build/esm/value/transform/has.mjs +5 -1
  57. package/build/esm/value/value/value.d.mts +10 -2
  58. package/build/esm/value/value/value.mjs +11 -1
  59. package/package.json +1 -1
  60. package/readme.md +115 -130
@@ -56,7 +56,7 @@ function TryConvertLiteral(schema, value) {
56
56
  return (IsString(schema.const) ? TryConvertLiteralString(value, schema.const) :
57
57
  IsNumber(schema.const) ? TryConvertLiteralNumber(value, schema.const) :
58
58
  IsBoolean(schema.const) ? TryConvertLiteralBoolean(value, schema.const) :
59
- Clone(value));
59
+ value);
60
60
  }
61
61
  function TryConvertBoolean(value) {
62
62
  return IsValueTrue(value) ? true : IsValueFalse(value) ? false : value;
@@ -139,16 +139,14 @@ function FromNumber(schema, references, value) {
139
139
  }
140
140
  // prettier-ignore
141
141
  function FromObject(schema, references, value) {
142
- const isConvertable = IsObject(value);
143
- if (!isConvertable)
142
+ if (!IsObject(value))
144
143
  return value;
145
- const result = {};
146
- for (const key of Object.keys(value)) {
147
- result[key] = HasPropertyKey(schema.properties, key)
148
- ? Visit(schema.properties[key], references, value[key])
149
- : value[key];
144
+ for (const propertyKey of Object.getOwnPropertyNames(schema.properties)) {
145
+ if (!HasPropertyKey(value, propertyKey))
146
+ continue;
147
+ value[propertyKey] = Visit(schema.properties[propertyKey], references, value[propertyKey]);
150
148
  }
151
- return result;
149
+ return value;
152
150
  }
153
151
  function FromRecord(schema, references, value) {
154
152
  const isConvertable = IsObject(value);
@@ -156,11 +154,10 @@ function FromRecord(schema, references, value) {
156
154
  return value;
157
155
  const propertyKey = Object.getOwnPropertyNames(schema.patternProperties)[0];
158
156
  const property = schema.patternProperties[propertyKey];
159
- const result = {};
160
157
  for (const [propKey, propValue] of Object.entries(value)) {
161
- result[propKey] = Visit(property, references, propValue);
158
+ value[propKey] = Visit(property, references, propValue);
162
159
  }
163
- return result;
160
+ return value;
164
161
  }
165
162
  function FromRef(schema, references, value) {
166
163
  return Visit(Deref(schema, references), references, value);
@@ -190,15 +187,19 @@ function FromUndefined(schema, references, value) {
190
187
  }
191
188
  function FromUnion(schema, references, value) {
192
189
  for (const subschema of schema.anyOf) {
193
- const converted = Visit(subschema, references, value);
190
+ const converted = Visit(subschema, references, Clone(value));
194
191
  if (!Check(subschema, references, converted))
195
192
  continue;
196
193
  return converted;
197
194
  }
198
195
  return value;
199
196
  }
197
+ function AddReference(references, schema) {
198
+ references.push(schema);
199
+ return references;
200
+ }
200
201
  function Visit(schema, references, value) {
201
- const references_ = IsString(schema.$id) ? [...references, schema] : references;
202
+ const references_ = IsString(schema.$id) ? AddReference(references, schema) : references;
202
203
  const schema_ = schema;
203
204
  switch (schema[Kind]) {
204
205
  case 'Array':
@@ -241,10 +242,8 @@ function Visit(schema, references, value) {
241
242
  return Default(value);
242
243
  }
243
244
  }
244
- /** Converts any type mismatched values to their target type if a reasonable conversion is possible. */
245
+ /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */
245
246
  // prettier-ignore
246
247
  export function Convert(...args) {
247
- return args.length === 3
248
- ? Visit(args[0], args[1], args[2])
249
- : Visit(args[0], [], args[1]);
248
+ return args.length === 3 ? Visit(args[0], args[1], args[2]) : Visit(args[0], [], args[1]);
250
249
  }
@@ -380,8 +380,12 @@ function FromKind(schema, references) {
380
380
  throw new Error('User defined types must specify a default value');
381
381
  }
382
382
  }
383
+ function AddReference(references, schema) {
384
+ references.push(schema);
385
+ return references;
386
+ }
383
387
  function Visit(schema, references) {
384
- const references_ = IsString(schema.$id) ? [...references, schema] : references;
388
+ const references_ = IsString(schema.$id) ? AddReference(references, schema) : references;
385
389
  const schema_ = schema;
386
390
  switch (schema_[Kind]) {
387
391
  case 'Any':
@@ -9,7 +9,7 @@ import { IsString, IsObject, IsArray, IsUndefined } from '../guard/index.mjs';
9
9
  // ------------------------------------------------------------------
10
10
  // TypeGuard
11
11
  // ------------------------------------------------------------------
12
- import { IsSchema } from '../../type/guard/type.mjs';
12
+ import { IsKind } from '../../type/guard/kind.mjs';
13
13
  // ------------------------------------------------------------------
14
14
  // ValueOrDefault
15
15
  // ------------------------------------------------------------------
@@ -17,16 +17,10 @@ function ValueOrDefault(schema, value) {
17
17
  return value === undefined && 'default' in schema ? Clone(schema.default) : value;
18
18
  }
19
19
  // ------------------------------------------------------------------
20
- // IsCheckable
20
+ // HasDefaultProperty
21
21
  // ------------------------------------------------------------------
22
- function IsCheckable(schema) {
23
- return IsSchema(schema) && schema[Kind] !== 'Unsafe';
24
- }
25
- // ------------------------------------------------------------------
26
- // IsDefaultSchema
27
- // ------------------------------------------------------------------
28
- function IsDefaultSchema(value) {
29
- return IsSchema(value) && 'default' in value;
22
+ function HasDefaultProperty(schema) {
23
+ return IsKind(schema) && 'default' in schema;
30
24
  }
31
25
  // ------------------------------------------------------------------
32
26
  // Types
@@ -55,12 +49,12 @@ function FromObject(schema, references, value) {
55
49
  const knownPropertyKeys = Object.getOwnPropertyNames(schema.properties);
56
50
  // properties
57
51
  for (const key of knownPropertyKeys) {
58
- if (!IsDefaultSchema(schema.properties[key]))
52
+ if (!HasDefaultProperty(schema.properties[key]))
59
53
  continue;
60
54
  defaulted[key] = Visit(schema.properties[key], references, defaulted[key]);
61
55
  }
62
56
  // return if not additional properties
63
- if (!IsDefaultSchema(additionalPropertiesSchema))
57
+ if (!HasDefaultProperty(additionalPropertiesSchema))
64
58
  return defaulted;
65
59
  // additional properties
66
60
  for (const key of Object.getOwnPropertyNames(defaulted)) {
@@ -79,12 +73,12 @@ function FromRecord(schema, references, value) {
79
73
  const knownPropertyKey = new RegExp(propertyKeyPattern);
80
74
  // properties
81
75
  for (const key of Object.getOwnPropertyNames(defaulted)) {
82
- if (!(knownPropertyKey.test(key) && IsDefaultSchema(propertySchema)))
76
+ if (!(knownPropertyKey.test(key) && HasDefaultProperty(propertySchema)))
83
77
  continue;
84
78
  defaulted[key] = Visit(propertySchema, references, defaulted[key]);
85
79
  }
86
80
  // return if not additional properties
87
- if (!IsDefaultSchema(additionalPropertiesSchema))
81
+ if (!HasDefaultProperty(additionalPropertiesSchema))
88
82
  return defaulted;
89
83
  // additional properties
90
84
  for (const key of Object.getOwnPropertyNames(defaulted)) {
@@ -115,14 +109,18 @@ function FromUnion(schema, references, value) {
115
109
  const defaulted = ValueOrDefault(schema, value);
116
110
  for (const inner of schema.anyOf) {
117
111
  const result = Visit(inner, references, defaulted);
118
- if (IsCheckable(inner) && Check(inner, result)) {
112
+ if (Check(inner, result)) {
119
113
  return result;
120
114
  }
121
115
  }
122
116
  return defaulted;
123
117
  }
118
+ function AddReference(references, schema) {
119
+ references.push(schema);
120
+ return references;
121
+ }
124
122
  function Visit(schema, references, value) {
125
- const references_ = IsString(schema.$id) ? [...references, schema] : references;
123
+ const references_ = IsString(schema.$id) ? AddReference(references, schema) : references;
126
124
  const schema_ = schema;
127
125
  switch (schema_[Kind]) {
128
126
  case 'Array':
@@ -1,9 +1,9 @@
1
- import { IsStandardObject, IsDate, IsArray, IsTypedArray, IsValueType } from '../guard/index.mjs';
1
+ import { IsObject, IsDate, IsArray, IsTypedArray, IsValueType } from '../guard/index.mjs';
2
2
  // ------------------------------------------------------------------
3
3
  // Equality Checks
4
4
  // ------------------------------------------------------------------
5
5
  function ObjectType(left, right) {
6
- if (!IsStandardObject(right))
6
+ if (!IsObject(right))
7
7
  return false;
8
8
  const leftKeys = [...Object.keys(left), ...Object.getOwnPropertySymbols(left)];
9
9
  const rightKeys = [...Object.keys(right), ...Object.getOwnPropertySymbols(right)];
@@ -32,14 +32,14 @@ function ValueType(left, right) {
32
32
  // ------------------------------------------------------------------
33
33
  /** Returns true if the left value deep-equals the right */
34
34
  export function Equal(left, right) {
35
- if (IsStandardObject(left))
36
- return ObjectType(left, right);
37
35
  if (IsDate(left))
38
36
  return DateType(left, right);
39
37
  if (IsTypedArray(left))
40
38
  return TypedArrayType(left, right);
41
39
  if (IsArray(left))
42
40
  return ArrayType(left, right);
41
+ if (IsObject(left))
42
+ return ObjectType(left, right);
43
43
  if (IsValueType(left))
44
44
  return ValueType(left, right);
45
45
  throw new Error('ValueEquals: Unable to compare value');
@@ -1,4 +1,4 @@
1
- import { IsArray, IsBoolean, IsBigInt, IsDate, IsNull, IsNumber, IsStandardObject, IsString, IsSymbol, IsUint8Array, IsUndefined } from '../guard/index.mjs';
1
+ import { IsArray, IsBoolean, IsBigInt, IsDate, IsNull, IsNumber, IsObject, IsString, IsSymbol, IsUint8Array, IsUndefined } from '../guard/index.mjs';
2
2
  import { TypeBoxError } from '../../type/error/index.mjs';
3
3
  // ------------------------------------------------------------------
4
4
  // Errors
@@ -119,7 +119,7 @@ function Visit(value) {
119
119
  return NullType(value);
120
120
  if (IsNumber(value))
121
121
  return NumberType(value);
122
- if (IsStandardObject(value))
122
+ if (IsObject(value))
123
123
  return ObjectType(value);
124
124
  if (IsString(value))
125
125
  return StringType(value);
@@ -1,5 +1,6 @@
1
1
  export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index.mjs';
2
2
  export * from './guard/index.mjs';
3
+ export * from './assert/index.mjs';
3
4
  export * from './cast/index.mjs';
4
5
  export * from './check/index.mjs';
5
6
  export * from './clean/index.mjs';
@@ -11,6 +12,7 @@ export * from './delta/index.mjs';
11
12
  export * from './equal/index.mjs';
12
13
  export * from './hash/index.mjs';
13
14
  export * from './mutate/index.mjs';
15
+ export * from './parse/index.mjs';
14
16
  export * from './pointer/index.mjs';
15
17
  export * from './transform/index.mjs';
16
18
  export { Value } from './value/index.mjs';
@@ -9,6 +9,7 @@ export * from './guard/index.mjs';
9
9
  // ------------------------------------------------------------------
10
10
  // Operators
11
11
  // ------------------------------------------------------------------
12
+ export * from './assert/index.mjs';
12
13
  export * from './cast/index.mjs';
13
14
  export * from './check/index.mjs';
14
15
  export * from './clean/index.mjs';
@@ -20,6 +21,7 @@ export * from './delta/index.mjs';
20
21
  export * from './equal/index.mjs';
21
22
  export * from './hash/index.mjs';
22
23
  export * from './mutate/index.mjs';
24
+ export * from './parse/index.mjs';
23
25
  export * from './pointer/index.mjs';
24
26
  export * from './transform/index.mjs';
25
27
  // ------------------------------------------------------------------
@@ -1,4 +1,4 @@
1
- import { IsStandardObject, IsArray, IsTypedArray, IsValueType } from '../guard/index.mjs';
1
+ import { IsObject, IsArray, IsTypedArray, IsValueType } from '../guard/index.mjs';
2
2
  import { ValuePointer } from '../pointer/index.mjs';
3
3
  import { Clone } from '../clone/index.mjs';
4
4
  import { TypeBoxError } from '../../type/error/index.mjs';
@@ -11,7 +11,7 @@ export class ValueMutateError extends TypeBoxError {
11
11
  }
12
12
  }
13
13
  function ObjectType(root, path, current, next) {
14
- if (!IsStandardObject(current)) {
14
+ if (!IsObject(current)) {
15
15
  ValuePointer.Set(root, path, Clone(next));
16
16
  }
17
17
  else {
@@ -63,7 +63,7 @@ function Visit(root, path, current, next) {
63
63
  return ArrayType(root, path, current, next);
64
64
  if (IsTypedArray(next))
65
65
  return TypedArrayType(root, path, current, next);
66
- if (IsStandardObject(next))
66
+ if (IsObject(next))
67
67
  return ObjectType(root, path, current, next);
68
68
  if (IsValueType(next))
69
69
  return ValueType(root, path, current, next);
@@ -76,8 +76,8 @@ function IsNonMutableValue(value) {
76
76
  }
77
77
  function IsMismatchedValue(current, next) {
78
78
  // prettier-ignore
79
- return ((IsStandardObject(current) && IsArray(next)) ||
80
- (IsArray(current) && IsStandardObject(next)));
79
+ return ((IsObject(current) && IsArray(next)) ||
80
+ (IsArray(current) && IsObject(next)));
81
81
  }
82
82
  // ------------------------------------------------------------------
83
83
  // Mutate
@@ -0,0 +1 @@
1
+ export * from './parse.mjs';
@@ -0,0 +1 @@
1
+ export * from './parse.mjs';
@@ -0,0 +1,6 @@
1
+ import { TSchema } from '../../type/schema/index.mjs';
2
+ import { StaticDecode } from '../../type/static/index.mjs';
3
+ /** Parses a value or throws an `AssertError` if invalid. */
4
+ export declare function Parse<T extends TSchema, R = StaticDecode<T>>(schema: T, references: TSchema[], value: unknown): R;
5
+ /** Parses a value or throws an `AssertError` if invalid. */
6
+ export declare function Parse<T extends TSchema, R = StaticDecode<T>>(schema: T, value: unknown): R;
@@ -0,0 +1,25 @@
1
+ import { TransformDecode, HasTransform } from '../transform/index.mjs';
2
+ import { Assert } from '../assert/assert.mjs';
3
+ import { Default } from '../default/default.mjs';
4
+ import { Convert } from '../convert/convert.mjs';
5
+ import { Clean } from '../clean/clean.mjs';
6
+ import { Clone } from '../clone/index.mjs';
7
+ // prettier-ignore
8
+ const ParseReducer = [
9
+ (_schema, _references, value) => Clone(value),
10
+ (schema, references, value) => Default(schema, references, value),
11
+ (schema, references, value) => Clean(schema, references, value),
12
+ (schema, references, value) => Convert(schema, references, value),
13
+ (schema, references, value) => { Assert(schema, references, value); return value; },
14
+ (schema, references, value) => (HasTransform(schema, references) ? TransformDecode(schema, references, value) : value),
15
+ ];
16
+ // ------------------------------------------------------------------
17
+ // ParseValue
18
+ // ------------------------------------------------------------------
19
+ function ParseValue(schema, references, value) {
20
+ return ParseReducer.reduce((value, reducer) => reducer(schema, references, value), value);
21
+ }
22
+ /** Parses a value or throws an `AssertError` if invalid. */
23
+ export function Parse(...args) {
24
+ return args.length === 3 ? ParseValue(args[0], args[1], args[2]) : ParseValue(args[0], [], args[1]);
25
+ }
@@ -1,3 +1,4 @@
1
+ import { TypeSystemPolicy } from '../../system/policy.mjs';
1
2
  import { Kind, TransformKind } from '../../type/symbols/index.mjs';
2
3
  import { TypeBoxError } from '../../type/error/index.mjs';
3
4
  import { KeyOfPropertyKeys, KeyOfPropertyEntries } from '../../type/keyof/index.mjs';
@@ -6,11 +7,11 @@ import { Check } from '../check/index.mjs';
6
7
  // ------------------------------------------------------------------
7
8
  // ValueGuard
8
9
  // ------------------------------------------------------------------
9
- import { IsStandardObject, IsArray, IsValueType } from '../guard/index.mjs';
10
+ import { HasPropertyKey, IsObject, IsArray, IsValueType, IsUndefined as IsUndefinedValue } from '../guard/index.mjs';
10
11
  // ------------------------------------------------------------------
11
12
  // TypeGuard
12
13
  // ------------------------------------------------------------------
13
- import { IsTransform, IsSchema } from '../../type/guard/type.mjs';
14
+ import { IsTransform, IsSchema, IsUndefined } from '../../type/guard/type.mjs';
14
15
  // ------------------------------------------------------------------
15
16
  // Errors
16
17
  // ------------------------------------------------------------------
@@ -54,7 +55,7 @@ function FromArray(schema, references, path, value) {
54
55
  }
55
56
  // prettier-ignore
56
57
  function FromIntersect(schema, references, path, value) {
57
- if (!IsStandardObject(value) || IsValueType(value))
58
+ if (!IsObject(value) || IsValueType(value))
58
59
  return Default(schema, path, value);
59
60
  const knownEntries = KeyOfPropertyEntries(schema);
60
61
  const knownKeys = knownEntries.map(entry => entry[0]);
@@ -80,14 +81,22 @@ function FromNot(schema, references, path, value) {
80
81
  }
81
82
  // prettier-ignore
82
83
  function FromObject(schema, references, path, value) {
83
- if (!IsStandardObject(value))
84
+ if (!IsObject(value))
84
85
  return Default(schema, path, value);
85
86
  const knownKeys = KeyOfPropertyKeys(schema);
86
87
  const knownProperties = { ...value };
87
- for (const key of knownKeys)
88
- if (key in knownProperties) {
89
- knownProperties[key] = Visit(schema.properties[key], references, `${path}/${key}`, knownProperties[key]);
90
- }
88
+ for (const key of knownKeys) {
89
+ if (!HasPropertyKey(knownProperties, key))
90
+ continue;
91
+ // if the property value is undefined, but the target is not, nor does it satisfy exact optional
92
+ // property policy, then we need to continue. This is a special case for optional property handling
93
+ // where a transforms wrapped in a optional modifiers should not run.
94
+ if (IsUndefinedValue(knownProperties[key]) && (!IsUndefined(schema.properties[key]) ||
95
+ TypeSystemPolicy.IsExactOptionalProperty(knownProperties, key)))
96
+ continue;
97
+ // decode property
98
+ knownProperties[key] = Visit(schema.properties[key], references, `${path}/${key}`, knownProperties[key]);
99
+ }
91
100
  if (!IsSchema(schema.additionalProperties)) {
92
101
  return Default(schema, path, knownProperties);
93
102
  }
@@ -102,7 +111,7 @@ function FromObject(schema, references, path, value) {
102
111
  }
103
112
  // prettier-ignore
104
113
  function FromRecord(schema, references, path, value) {
105
- if (!IsStandardObject(value))
114
+ if (!IsObject(value))
106
115
  return Default(schema, path, value);
107
116
  const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0];
108
117
  const knownKeys = new RegExp(pattern);
@@ -150,9 +159,13 @@ function FromUnion(schema, references, path, value) {
150
159
  }
151
160
  return Default(schema, path, value);
152
161
  }
162
+ function AddReference(references, schema) {
163
+ references.push(schema);
164
+ return references;
165
+ }
153
166
  // prettier-ignore
154
167
  function Visit(schema, references, path, value) {
155
- const references_ = typeof schema.$id === 'string' ? [...references, schema] : references;
168
+ const references_ = typeof schema.$id === 'string' ? AddReference(references, schema) : references;
156
169
  const schema_ = schema;
157
170
  switch (schema[Kind]) {
158
171
  case 'Array':
@@ -1,3 +1,4 @@
1
+ import { TypeSystemPolicy } from '../../system/policy.mjs';
1
2
  import { Kind, TransformKind } from '../../type/symbols/index.mjs';
2
3
  import { TypeBoxError } from '../../type/error/index.mjs';
3
4
  import { KeyOfPropertyKeys, KeyOfPropertyEntries } from '../../type/keyof/index.mjs';
@@ -6,11 +7,11 @@ import { Check } from '../check/index.mjs';
6
7
  // ------------------------------------------------------------------
7
8
  // ValueGuard
8
9
  // ------------------------------------------------------------------
9
- import { IsStandardObject, IsArray, IsValueType } from '../guard/index.mjs';
10
+ import { HasPropertyKey, IsObject, IsArray, IsValueType, IsUndefined as IsUndefinedValue } from '../guard/index.mjs';
10
11
  // ------------------------------------------------------------------
11
12
  // TypeGuard
12
13
  // ------------------------------------------------------------------
13
- import { IsTransform, IsSchema } from '../../type/guard/type.mjs';
14
+ import { IsTransform, IsSchema, IsUndefined } from '../../type/guard/type.mjs';
14
15
  // ------------------------------------------------------------------
15
16
  // Errors
16
17
  // ------------------------------------------------------------------
@@ -55,7 +56,7 @@ function FromArray(schema, references, path, value) {
55
56
  // prettier-ignore
56
57
  function FromIntersect(schema, references, path, value) {
57
58
  const defaulted = Default(schema, path, value);
58
- if (!IsStandardObject(value) || IsValueType(value))
59
+ if (!IsObject(value) || IsValueType(value))
59
60
  return defaulted;
60
61
  const knownEntries = KeyOfPropertyEntries(schema);
61
62
  const knownKeys = knownEntries.map(entry => entry[0]);
@@ -83,14 +84,22 @@ function FromNot(schema, references, path, value) {
83
84
  // prettier-ignore
84
85
  function FromObject(schema, references, path, value) {
85
86
  const defaulted = Default(schema, path, value);
86
- if (!IsStandardObject(defaulted))
87
+ if (!IsObject(defaulted))
87
88
  return defaulted;
88
89
  const knownKeys = KeyOfPropertyKeys(schema);
89
90
  const knownProperties = { ...defaulted };
90
- for (const key of knownKeys)
91
- if (key in knownProperties) {
92
- knownProperties[key] = Visit(schema.properties[key], references, `${path}/${key}`, knownProperties[key]);
93
- }
91
+ for (const key of knownKeys) {
92
+ if (!HasPropertyKey(knownProperties, key))
93
+ continue;
94
+ // if the property value is undefined, but the target is not, nor does it satisfy exact optional
95
+ // property policy, then we need to continue. This is a special case for optional property handling
96
+ // where a transforms wrapped in a optional modifiers should not run.
97
+ if (IsUndefinedValue(knownProperties[key]) && (!IsUndefined(schema.properties[key]) ||
98
+ TypeSystemPolicy.IsExactOptionalProperty(knownProperties, key)))
99
+ continue;
100
+ // encode property
101
+ knownProperties[key] = Visit(schema.properties[key], references, `${path}/${key}`, knownProperties[key]);
102
+ }
94
103
  if (!IsSchema(schema.additionalProperties)) {
95
104
  return knownProperties;
96
105
  }
@@ -106,7 +115,7 @@ function FromObject(schema, references, path, value) {
106
115
  // prettier-ignore
107
116
  function FromRecord(schema, references, path, value) {
108
117
  const defaulted = Default(schema, path, value);
109
- if (!IsStandardObject(value))
118
+ if (!IsObject(value))
110
119
  return defaulted;
111
120
  const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0];
112
121
  const knownKeys = new RegExp(pattern);
@@ -116,7 +125,7 @@ function FromRecord(schema, references, path, value) {
116
125
  knownProperties[key] = Visit(schema.patternProperties[pattern], references, `${path}/${key}`, knownProperties[key]);
117
126
  }
118
127
  if (!IsSchema(schema.additionalProperties)) {
119
- return Default(schema, path, knownProperties);
128
+ return knownProperties;
120
129
  }
121
130
  const unknownKeys = Object.getOwnPropertyNames(knownProperties);
122
131
  const additionalProperties = schema.additionalProperties;
@@ -162,9 +171,13 @@ function FromUnion(schema, references, path, value) {
162
171
  }
163
172
  return Default(schema, path, value);
164
173
  }
174
+ function AddReference(references, schema) {
175
+ references.push(schema);
176
+ return references;
177
+ }
165
178
  // prettier-ignore
166
179
  function Visit(schema, references, path, value) {
167
- const references_ = typeof schema.$id === 'string' ? [...references, schema] : references;
180
+ const references_ = typeof schema.$id === 'string' ? AddReference(references, schema) : references;
168
181
  const schema_ = schema;
169
182
  switch (schema[Kind]) {
170
183
  case 'Array':
@@ -72,9 +72,13 @@ function FromTuple(schema, references) {
72
72
  function FromUnion(schema, references) {
73
73
  return IsTransform(schema) || schema.anyOf.some((schema) => Visit(schema, references));
74
74
  }
75
+ function AddReference(references, schema) {
76
+ references.push(schema);
77
+ return references;
78
+ }
75
79
  // prettier-ignore
76
80
  function Visit(schema, references) {
77
- const references_ = IsString(schema.$id) ? [...references, schema] : references;
81
+ const references_ = IsString(schema.$id) ? AddReference(references, schema) : references;
78
82
  const schema_ = schema;
79
83
  if (schema.$id && visited.has(schema.$id))
80
84
  return false;
@@ -3,6 +3,10 @@ import { Edit } from '../delta/index.mjs';
3
3
  import { ValueErrorIterator } from '../../errors/index.mjs';
4
4
  import type { TSchema } from '../../type/schema/index.mjs';
5
5
  import type { Static, StaticDecode, StaticEncode } from '../../type/static/index.mjs';
6
+ /** Asserts a value matches the given type or throws an `AssertError` if invalid. */
7
+ export declare function Assert<T extends TSchema, R = Static<T>>(schema: T, references: TSchema[], value: unknown): asserts value is R;
8
+ /** Asserts a value matches the given type or throws an `AssertError` if invalid. */
9
+ export declare function Assert<T extends TSchema, R = Static<T>>(schema: T, value: unknown): asserts value is R;
6
10
  /** Casts a value into a given type. The return value will retain as much information of the original value as possible. */
7
11
  export declare function Cast<T extends TSchema>(schema: T, references: TSchema[], value: unknown): Static<T>;
8
12
  /** Casts a value into a given type. The return value will retain as much information of the original value as possible. */
@@ -19,9 +23,9 @@ export declare function Check<T extends TSchema>(schema: T, value: unknown): val
19
23
  export declare function Clean(schema: TSchema, references: TSchema[], value: unknown): unknown;
20
24
  /** `[Mutable]` Removes excess properties from a value and returns the result. This function does not check the value and returns an unknown type. You should Check the result before use. Clean is a mutable operation. To avoid mutation, Clone the value first. */
21
25
  export declare function Clean(schema: TSchema, value: unknown): unknown;
22
- /** Converts any type mismatched values to their target type if a reasonable conversion is possible. */
26
+ /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */
23
27
  export declare function Convert(schema: TSchema, references: TSchema[], value: unknown): unknown;
24
- /** Converts any type mismatched values to their target type if a reasonable conversion is possible. */
28
+ /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */
25
29
  export declare function Convert(schema: TSchema, value: unknown): unknown;
26
30
  /** Returns a structural clone of the given value */
27
31
  export declare function Clone<T>(value: T): T;
@@ -37,6 +41,10 @@ export declare function Default(schema: TSchema, value: unknown): unknown;
37
41
  export declare function Encode<T extends TSchema, R = StaticEncode<T>>(schema: T, references: TSchema[], value: unknown): R;
38
42
  /** Encodes a value or throws if error */
39
43
  export declare function Encode<T extends TSchema, R = StaticEncode<T>>(schema: T, value: unknown): R;
44
+ /** Parses a value or throws an `AssertError` if invalid. */
45
+ export declare function Parse<T extends TSchema, R = StaticDecode<T>>(schema: T, references: TSchema[], value: unknown): R;
46
+ /** Parses a value or throws an `AssertError` if invalid. */
47
+ export declare function Parse<T extends TSchema, R = StaticDecode<T>>(schema: T, value: unknown): R;
40
48
  /** Returns an iterator for each error in this value. */
41
49
  export declare function Errors<T extends TSchema>(schema: T, references: TSchema[], value: unknown): ValueErrorIterator;
42
50
  /** Returns an iterator for each error in this value. */
@@ -1,4 +1,5 @@
1
1
  import { HasTransform, TransformDecode, TransformEncode, TransformDecodeCheckError, TransformEncodeCheckError } from '../transform/index.mjs';
2
+ import { Assert as AssertValue } from '../assert/index.mjs';
2
3
  import { Mutate as MutateValue } from '../mutate/index.mjs';
3
4
  import { Hash as HashValue } from '../hash/index.mjs';
4
5
  import { Equal as EqualValue } from '../equal/index.mjs';
@@ -8,9 +9,14 @@ import { Convert as ConvertValue } from '../convert/index.mjs';
8
9
  import { Create as CreateValue } from '../create/index.mjs';
9
10
  import { Clean as CleanValue } from '../clean/index.mjs';
10
11
  import { Check as CheckValue } from '../check/index.mjs';
12
+ import { Parse as ParseValue } from '../parse/index.mjs';
11
13
  import { Default as DefaultValue } from '../default/index.mjs';
12
14
  import { Diff as DiffValue, Patch as PatchValue } from '../delta/index.mjs';
13
15
  import { Errors as ValueErrors } from '../../errors/index.mjs';
16
+ /** Asserts a value matches the given type or throws an `AssertError` if invalid. */
17
+ export function Assert(...args) {
18
+ return AssertValue.apply(AssertValue, args);
19
+ }
14
20
  /** Casts a value into a given type. The return value will retain as much information of the original value as possible. */
15
21
  export function Cast(...args) {
16
22
  return CastValue.apply(CastValue, args);
@@ -27,7 +33,7 @@ export function Check(...args) {
27
33
  export function Clean(...args) {
28
34
  return CleanValue.apply(CleanValue, args);
29
35
  }
30
- /** Converts any type mismatched values to their target type if a reasonable conversion is possible. */
36
+ /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */
31
37
  export function Convert(...args) {
32
38
  return ConvertValue.apply(ConvertValue, args);
33
39
  }
@@ -54,6 +60,10 @@ export function Encode(...args) {
54
60
  throw new TransformEncodeCheckError(schema, encoded, Errors(schema, references, encoded).First());
55
61
  return encoded;
56
62
  }
63
+ /** Parses a value or throws an `AssertError` if invalid. */
64
+ export function Parse(...args) {
65
+ return ParseValue.apply(ParseValue, args);
66
+ }
57
67
  /** Returns an iterator for each error in this value. */
58
68
  export function Errors(...args) {
59
69
  return ValueErrors.apply(ValueErrors, args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.33.3",
3
+ "version": "0.33.5",
4
4
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",