@sinclair/typebox 0.24.41 → 0.24.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/guard/guard.js +4 -4
- package/package.json +1 -1
- package/readme.md +73 -57
- package/typebox.d.ts +8 -6
- package/typebox.js +12 -4
- package/value/pointer.d.ts +10 -8
- package/value/pointer.js +63 -69
package/guard/guard.js
CHANGED
|
@@ -161,12 +161,12 @@ var TypeGuard;
|
|
|
161
161
|
schema.allOf.length === 2 &&
|
|
162
162
|
IsObject(schema.allOf[0]) &&
|
|
163
163
|
IsString(schema.allOf[0].type) &&
|
|
164
|
-
schema.allOf[0].type === '
|
|
165
|
-
schema.allOf[0].const ===
|
|
164
|
+
schema.allOf[0].type === 'boolean' &&
|
|
165
|
+
schema.allOf[0].const === false &&
|
|
166
166
|
IsObject(schema.allOf[1]) &&
|
|
167
167
|
IsString(schema.allOf[1].type) &&
|
|
168
|
-
schema.allOf[1].type === '
|
|
169
|
-
schema.allOf[1].const ===
|
|
168
|
+
schema.allOf[1].type === 'boolean' &&
|
|
169
|
+
schema.allOf[1].const === true);
|
|
170
170
|
}
|
|
171
171
|
TypeGuard.TNever = TNever;
|
|
172
172
|
/** Returns true if the given schema is TNull */
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -76,6 +76,7 @@ License MIT
|
|
|
76
76
|
- [Diff](#values-diff)
|
|
77
77
|
- [Patch](#values-patch)
|
|
78
78
|
- [Errors](#values-errors)
|
|
79
|
+
- [Pointer](#values-pointer)
|
|
79
80
|
- [TypeCheck](#typecheck)
|
|
80
81
|
- [Ajv](#typecheck-ajv)
|
|
81
82
|
- [Compiler](#typecheck-compiler)
|
|
@@ -304,11 +305,11 @@ The following table lists the standard TypeBox types.
|
|
|
304
305
|
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
|
|
305
306
|
│ const T = Type.Never() │ type T = never │ const T = { │
|
|
306
307
|
│ │ │ allOf: [{ │
|
|
307
|
-
│ │ │ type: '
|
|
308
|
-
│ │ │ const:
|
|
308
|
+
│ │ │ type: 'boolean', │
|
|
309
|
+
│ │ │ const: false │
|
|
309
310
|
│ │ │ }, { │
|
|
310
|
-
│ │ │ type: '
|
|
311
|
-
│ │ │ const:
|
|
311
|
+
│ │ │ type: 'boolean', │
|
|
312
|
+
│ │ │ const: true │
|
|
312
313
|
│ │ │ }] │
|
|
313
314
|
│ │ │ } │
|
|
314
315
|
│ │ │ │
|
|
@@ -870,6 +871,21 @@ const R = [...Value.Errors(T, { x: '42' })] // const R = [{
|
|
|
870
871
|
// }]
|
|
871
872
|
```
|
|
872
873
|
|
|
874
|
+
<a name='values-pointer'></a>
|
|
875
|
+
|
|
876
|
+
### Pointer
|
|
877
|
+
|
|
878
|
+
Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) Json Pointers.
|
|
879
|
+
|
|
880
|
+
```typescript
|
|
881
|
+
import { ValuePointer } from '@sinclair/typebox/value'
|
|
882
|
+
|
|
883
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
884
|
+
|
|
885
|
+
ValuePointer.Set(A, '/x', 1) // const A = { x: 1, y: 0, z: 0 }
|
|
886
|
+
ValuePointer.Set(A, '/y', 1) // const A = { x: 1, y: 1, z: 0 }
|
|
887
|
+
ValuePointer.Set(A, '/z', 1) // const A = { x: 1, y: 1, z: 1 }
|
|
888
|
+
```
|
|
873
889
|
<a name='typecheck'></a>
|
|
874
890
|
|
|
875
891
|
## TypeCheck
|
|
@@ -1046,29 +1062,29 @@ This benchmark measures compilation performance for varying types. You can revie
|
|
|
1046
1062
|
┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
|
|
1047
1063
|
│ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
|
|
1048
1064
|
├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
|
|
1049
|
-
│ Number │ 2000 │ '
|
|
1050
|
-
│ String │ 2000 │ '
|
|
1051
|
-
│ Boolean │ 2000 │ '
|
|
1052
|
-
│ Null │ 2000 │ '
|
|
1053
|
-
│ RegEx │ 2000 │ '
|
|
1054
|
-
│ ObjectA │ 2000 │ '
|
|
1055
|
-
│ ObjectB │ 2000 │ '
|
|
1056
|
-
│ Tuple │ 2000 │ '
|
|
1057
|
-
│ Union │ 2000 │ '
|
|
1058
|
-
│ Vector4 │ 2000 │ '
|
|
1059
|
-
│ Matrix4 │ 2000 │ '
|
|
1060
|
-
│ Literal_String │ 2000 │ '
|
|
1061
|
-
│ Literal_Number │ 2000 │ '
|
|
1062
|
-
│ Literal_Boolean │ 2000 │ '
|
|
1063
|
-
│ Array_Number │ 2000 │ '
|
|
1064
|
-
│ Array_String │ 2000 │ '
|
|
1065
|
-
│ Array_Boolean │ 2000 │ '
|
|
1066
|
-
│ Array_ObjectA │ 2000 │ '
|
|
1067
|
-
│ Array_ObjectB │ 2000 │ '
|
|
1068
|
-
│ Array_Tuple │ 2000 │ '
|
|
1069
|
-
│ Array_Union │ 2000 │ '
|
|
1070
|
-
│ Array_Vector4 │ 2000 │ '
|
|
1071
|
-
│ Array_Matrix4 │ 2000 │ '
|
|
1065
|
+
│ Number │ 2000 │ ' 384 ms' │ ' 9 ms' │ ' 42.67 x' │
|
|
1066
|
+
│ String │ 2000 │ ' 322 ms' │ ' 8 ms' │ ' 40.25 x' │
|
|
1067
|
+
│ Boolean │ 2000 │ ' 310 ms' │ ' 6 ms' │ ' 51.67 x' │
|
|
1068
|
+
│ Null │ 2000 │ ' 271 ms' │ ' 6 ms' │ ' 45.17 x' │
|
|
1069
|
+
│ RegEx │ 2000 │ ' 491 ms' │ ' 12 ms' │ ' 40.92 x' │
|
|
1070
|
+
│ ObjectA │ 2000 │ ' 2935 ms' │ ' 44 ms' │ ' 66.70 x' │
|
|
1071
|
+
│ ObjectB │ 2000 │ ' 3076 ms' │ ' 30 ms' │ ' 102.53 x' │
|
|
1072
|
+
│ Tuple │ 2000 │ ' 1274 ms' │ ' 22 ms' │ ' 57.91 x' │
|
|
1073
|
+
│ Union │ 2000 │ ' 1281 ms' │ ' 22 ms' │ ' 58.23 x' │
|
|
1074
|
+
│ Vector4 │ 2000 │ ' 1602 ms' │ ' 17 ms' │ ' 94.24 x' │
|
|
1075
|
+
│ Matrix4 │ 2000 │ ' 959 ms' │ ' 10 ms' │ ' 95.90 x' │
|
|
1076
|
+
│ Literal_String │ 2000 │ ' 337 ms' │ ' 6 ms' │ ' 56.17 x' │
|
|
1077
|
+
│ Literal_Number │ 2000 │ ' 376 ms' │ ' 5 ms' │ ' 75.20 x' │
|
|
1078
|
+
│ Literal_Boolean │ 2000 │ ' 370 ms' │ ' 5 ms' │ ' 74.00 x' │
|
|
1079
|
+
│ Array_Number │ 2000 │ ' 733 ms' │ ' 9 ms' │ ' 81.44 x' │
|
|
1080
|
+
│ Array_String │ 2000 │ ' 764 ms' │ ' 10 ms' │ ' 76.40 x' │
|
|
1081
|
+
│ Array_Boolean │ 2000 │ ' 818 ms' │ ' 6 ms' │ ' 136.33 x' │
|
|
1082
|
+
│ Array_ObjectA │ 2000 │ ' 3744 ms' │ ' 35 ms' │ ' 106.97 x' │
|
|
1083
|
+
│ Array_ObjectB │ 2000 │ ' 3893 ms' │ ' 34 ms' │ ' 114.50 x' │
|
|
1084
|
+
│ Array_Tuple │ 2000 │ ' 2229 ms' │ ' 16 ms' │ ' 139.31 x' │
|
|
1085
|
+
│ Array_Union │ 2000 │ ' 1705 ms' │ ' 18 ms' │ ' 94.72 x' │
|
|
1086
|
+
│ Array_Vector4 │ 2000 │ ' 2261 ms' │ ' 17 ms' │ ' 133.00 x' │
|
|
1087
|
+
│ Array_Matrix4 │ 2000 │ ' 1574 ms' │ ' 14 ms' │ ' 112.43 x' │
|
|
1072
1088
|
└──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
|
|
1073
1089
|
```
|
|
1074
1090
|
|
|
@@ -1082,31 +1098,31 @@ This benchmark measures validation performance for varying types. You can review
|
|
|
1082
1098
|
┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
|
|
1083
1099
|
│ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
|
|
1084
1100
|
├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
|
|
1085
|
-
│ Number │ 1000000 │ '
|
|
1086
|
-
│ String │ 1000000 │ '
|
|
1087
|
-
│ Boolean │ 1000000 │ '
|
|
1088
|
-
│ Null │ 1000000 │ '
|
|
1089
|
-
│ RegEx │ 1000000 │ '
|
|
1090
|
-
│ ObjectA │ 1000000 │ '
|
|
1091
|
-
│ ObjectB │ 1000000 │ '
|
|
1092
|
-
│ Tuple │ 1000000 │ '
|
|
1093
|
-
│ Union │ 1000000 │ '
|
|
1094
|
-
│ Recursive │ 1000000 │ '
|
|
1095
|
-
│ Vector4 │ 1000000 │ '
|
|
1096
|
-
│ Matrix4 │ 1000000 │ '
|
|
1097
|
-
│ Literal_String │ 1000000 │ '
|
|
1098
|
-
│ Literal_Number │ 1000000 │ '
|
|
1099
|
-
│ Literal_Boolean │ 1000000 │ '
|
|
1100
|
-
│ Array_Number │ 1000000 │ '
|
|
1101
|
-
│ Array_String │ 1000000 │ '
|
|
1102
|
-
│ Array_Boolean │ 1000000 │ '
|
|
1103
|
-
│ Array_ObjectA │ 1000000 │ '
|
|
1104
|
-
│ Array_ObjectB │ 1000000 │ '
|
|
1105
|
-
│ Array_Tuple │ 1000000 │ '
|
|
1106
|
-
│ Array_Union │ 1000000 │ '
|
|
1107
|
-
│ Array_Recursive │ 1000000 │ '
|
|
1108
|
-
│ Array_Vector4 │ 1000000 │ '
|
|
1109
|
-
│ Array_Matrix4 │ 1000000 │ '
|
|
1101
|
+
│ Number │ 1000000 │ ' 37 ms' │ ' 5 ms' │ ' 5 ms' │ ' 1.00 x' │
|
|
1102
|
+
│ String │ 1000000 │ ' 31 ms' │ ' 24 ms' │ ' 13 ms' │ ' 1.85 x' │
|
|
1103
|
+
│ Boolean │ 1000000 │ ' 25 ms' │ ' 25 ms' │ ' 11 ms' │ ' 2.27 x' │
|
|
1104
|
+
│ Null │ 1000000 │ ' 32 ms' │ ' 26 ms' │ ' 10 ms' │ ' 2.60 x' │
|
|
1105
|
+
│ RegEx │ 1000000 │ ' 170 ms' │ ' 48 ms' │ ' 35 ms' │ ' 1.37 x' │
|
|
1106
|
+
│ ObjectA │ 1000000 │ ' 564 ms' │ ' 36 ms' │ ' 23 ms' │ ' 1.57 x' │
|
|
1107
|
+
│ ObjectB │ 1000000 │ ' 1000 ms' │ ' 56 ms' │ ' 40 ms' │ ' 1.40 x' │
|
|
1108
|
+
│ Tuple │ 1000000 │ ' 125 ms' │ ' 27 ms' │ ' 13 ms' │ ' 2.08 x' │
|
|
1109
|
+
│ Union │ 1000000 │ ' 316 ms' │ ' 27 ms' │ ' 14 ms' │ ' 1.93 x' │
|
|
1110
|
+
│ Recursive │ 1000000 │ ' 3308 ms' │ ' 415 ms' │ ' 183 ms' │ ' 2.27 x' │
|
|
1111
|
+
│ Vector4 │ 1000000 │ ' 135 ms' │ ' 27 ms' │ ' 12 ms' │ ' 2.25 x' │
|
|
1112
|
+
│ Matrix4 │ 1000000 │ ' 658 ms' │ ' 44 ms' │ ' 30 ms' │ ' 1.47 x' │
|
|
1113
|
+
│ Literal_String │ 1000000 │ ' 48 ms' │ ' 26 ms' │ ' 10 ms' │ ' 2.60 x' │
|
|
1114
|
+
│ Literal_Number │ 1000000 │ ' 49 ms' │ ' 31 ms' │ ' 9 ms' │ ' 3.44 x' │
|
|
1115
|
+
│ Literal_Boolean │ 1000000 │ ' 47 ms' │ ' 28 ms' │ ' 10 ms' │ ' 2.80 x' │
|
|
1116
|
+
│ Array_Number │ 1000000 │ ' 418 ms' │ ' 38 ms' │ ' 17 ms' │ ' 2.24 x' │
|
|
1117
|
+
│ Array_String │ 1000000 │ ' 466 ms' │ ' 35 ms' │ ' 22 ms' │ ' 1.59 x' │
|
|
1118
|
+
│ Array_Boolean │ 1000000 │ ' 403 ms' │ ' 41 ms' │ ' 24 ms' │ ' 1.71 x' │
|
|
1119
|
+
│ Array_ObjectA │ 1000000 │ ' 13596 ms' │ ' 2861 ms' │ ' 1759 ms' │ ' 1.63 x' │
|
|
1120
|
+
│ Array_ObjectB │ 1000000 │ ' 15767 ms' │ ' 2798 ms' │ ' 1991 ms' │ ' 1.41 x' │
|
|
1121
|
+
│ Array_Tuple │ 1000000 │ ' 1666 ms' │ ' 103 ms' │ ' 73 ms' │ ' 1.41 x' │
|
|
1122
|
+
│ Array_Union │ 1000000 │ ' 4738 ms' │ ' 229 ms' │ ' 87 ms' │ ' 2.63 x' │
|
|
1123
|
+
│ Array_Recursive │ 1000000 │ ' 56371 ms' │ ' 7315 ms' │ ' 2813 ms' │ ' 2.60 x' │
|
|
1124
|
+
│ Array_Vector4 │ 1000000 │ ' 2180 ms' │ ' 106 ms' │ ' 53 ms' │ ' 2.00 x' │
|
|
1125
|
+
│ Array_Matrix4 │ 1000000 │ ' 11795 ms' │ ' 384 ms' │ ' 313 ms' │ ' 1.23 x' │
|
|
1110
1126
|
└──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
|
|
1111
1127
|
```
|
|
1112
1128
|
|
|
@@ -1120,12 +1136,12 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
|
|
|
1120
1136
|
┌──────────────────────┬────────────┬────────────┬─────────────┐
|
|
1121
1137
|
│ (index) │ Compiled │ Minified │ Compression │
|
|
1122
1138
|
├──────────────────────┼────────────┼────────────┼─────────────┤
|
|
1123
|
-
│ typebox/compiler │ '
|
|
1124
|
-
│ typebox/conditional │ '
|
|
1139
|
+
│ typebox/compiler │ ' 49 kb' │ ' 24 kb' │ '2.00 x' │
|
|
1140
|
+
│ typebox/conditional │ ' 42 kb' │ ' 17 kb' │ '2.46 x' │
|
|
1125
1141
|
│ typebox/format │ ' 0 kb' │ ' 0 kb' │ '2.66 x' │
|
|
1126
|
-
│ typebox/guard │ '
|
|
1127
|
-
│ typebox/value │ '
|
|
1128
|
-
│ typebox │ ' 11 kb' │ '
|
|
1142
|
+
│ typebox/guard │ ' 21 kb' │ ' 10 kb' │ '2.07 x' │
|
|
1143
|
+
│ typebox/value │ ' 72 kb' │ ' 33 kb' │ '2.16 x' │
|
|
1144
|
+
│ typebox │ ' 11 kb' │ ' 6 kb' │ '1.91 x' │
|
|
1129
1145
|
└──────────────────────┴────────────┴────────────┴─────────────┘
|
|
1130
1146
|
```
|
|
1131
1147
|
|
package/typebox.d.ts
CHANGED
|
@@ -131,9 +131,11 @@ export interface TNever extends TSchema {
|
|
|
131
131
|
[Kind]: 'Never';
|
|
132
132
|
static: never;
|
|
133
133
|
allOf: [{
|
|
134
|
-
|
|
134
|
+
type: 'boolean';
|
|
135
|
+
const: false;
|
|
135
136
|
}, {
|
|
136
|
-
|
|
137
|
+
type: 'boolean';
|
|
138
|
+
const: true;
|
|
137
139
|
}];
|
|
138
140
|
}
|
|
139
141
|
export interface TNull extends TSchema {
|
|
@@ -231,15 +233,15 @@ export interface TRequired<T extends TObject | TRef<TObject>> extends TObject {
|
|
|
231
233
|
static: Required<Static<T, this['params']>>;
|
|
232
234
|
}
|
|
233
235
|
export declare type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex';
|
|
234
|
-
export interface StringOptions<
|
|
236
|
+
export interface StringOptions<Format extends string> extends SchemaOptions {
|
|
235
237
|
minLength?: number;
|
|
236
238
|
maxLength?: number;
|
|
237
239
|
pattern?: string;
|
|
238
|
-
format?:
|
|
240
|
+
format?: Format;
|
|
239
241
|
contentEncoding?: '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64';
|
|
240
242
|
contentMediaType?: string;
|
|
241
243
|
}
|
|
242
|
-
export interface TString extends TSchema, StringOptions<
|
|
244
|
+
export interface TString<Format extends string = string> extends TSchema, StringOptions<Format> {
|
|
243
245
|
[Kind]: 'String';
|
|
244
246
|
static: string;
|
|
245
247
|
type: 'string';
|
|
@@ -373,7 +375,7 @@ export declare class TypeBuilder {
|
|
|
373
375
|
/** Removes Kind and Modifier symbol property keys from this schema */
|
|
374
376
|
Strict<T extends TSchema>(schema: T): T;
|
|
375
377
|
/** Creates a string type */
|
|
376
|
-
String<
|
|
378
|
+
String<Format extends string>(options?: StringOptions<StringFormatOption | Format>): TString<Format>;
|
|
377
379
|
/** Creates a tuple type */
|
|
378
380
|
Tuple<T extends TSchema[]>(items: [...T], options?: SchemaOptions): TTuple<T>;
|
|
379
381
|
/** Creates a undefined type */
|
package/typebox.js
CHANGED
|
@@ -159,8 +159,8 @@ class TypeBuilder {
|
|
|
159
159
|
...options,
|
|
160
160
|
[exports.Kind]: 'Never',
|
|
161
161
|
allOf: [
|
|
162
|
-
{ type: '
|
|
163
|
-
{ type: '
|
|
162
|
+
{ type: 'boolean', const: false },
|
|
163
|
+
{ type: 'boolean', const: true },
|
|
164
164
|
],
|
|
165
165
|
});
|
|
166
166
|
}
|
|
@@ -192,7 +192,11 @@ class TypeBuilder {
|
|
|
192
192
|
Omit(schema, keys, options = {}) {
|
|
193
193
|
const select = keys[exports.Kind] === 'Union' ? keys.anyOf.map((schema) => schema.const) : keys;
|
|
194
194
|
const next = { ...this.Clone(schema), ...options, [exports.Hint]: 'Omit' };
|
|
195
|
-
|
|
195
|
+
if (next.required) {
|
|
196
|
+
next.required = next.required.filter((key) => !select.includes(key));
|
|
197
|
+
if (next.required.length === 0)
|
|
198
|
+
delete next.required;
|
|
199
|
+
}
|
|
196
200
|
for (const key of Object.keys(next.properties)) {
|
|
197
201
|
if (select.includes(key))
|
|
198
202
|
delete next.properties[key];
|
|
@@ -231,7 +235,11 @@ class TypeBuilder {
|
|
|
231
235
|
Pick(schema, keys, options = {}) {
|
|
232
236
|
const select = keys[exports.Kind] === 'Union' ? keys.anyOf.map((schema) => schema.const) : keys;
|
|
233
237
|
const next = { ...this.Clone(schema), ...options, [exports.Hint]: 'Pick' };
|
|
234
|
-
|
|
238
|
+
if (next.required) {
|
|
239
|
+
next.required = next.required.filter((key) => select.includes(key));
|
|
240
|
+
if (next.required.length === 0)
|
|
241
|
+
delete next.required;
|
|
242
|
+
}
|
|
235
243
|
for (const key of Object.keys(next.properties)) {
|
|
236
244
|
if (!select.includes(key))
|
|
237
245
|
delete next.properties[key];
|
package/value/pointer.d.ts
CHANGED
|
@@ -11,12 +11,14 @@ export declare class ValuePointerRootDeleteError extends Error {
|
|
|
11
11
|
}
|
|
12
12
|
/** ValuePointer performs mutable operations on values using RFC6901 Json Pointers */
|
|
13
13
|
export declare namespace ValuePointer {
|
|
14
|
-
/**
|
|
15
|
-
function
|
|
16
|
-
/**
|
|
17
|
-
function
|
|
18
|
-
/**
|
|
19
|
-
function
|
|
20
|
-
/**
|
|
21
|
-
function
|
|
14
|
+
/** Formats the given pointer into navigable key components */
|
|
15
|
+
function Format(pointer: string): IterableIterator<string>;
|
|
16
|
+
/** Sets the value at the given pointer. If the value at the pointer does not exist it is created */
|
|
17
|
+
function Set(value: any, pointer: string, update: unknown): void;
|
|
18
|
+
/** Deletes a value at the given pointer */
|
|
19
|
+
function Delete(value: any, pointer: string): void;
|
|
20
|
+
/** Returns true if a value exists at the given pointer */
|
|
21
|
+
function Has(value: any, pointer: string): boolean;
|
|
22
|
+
/** Gets the value at the given pointer */
|
|
23
|
+
function Get(value: any, pointer: string): any;
|
|
22
24
|
}
|
package/value/pointer.js
CHANGED
|
@@ -48,101 +48,95 @@ exports.ValuePointerRootDeleteError = ValuePointerRootDeleteError;
|
|
|
48
48
|
/** ValuePointer performs mutable operations on values using RFC6901 Json Pointers */
|
|
49
49
|
var ValuePointer;
|
|
50
50
|
(function (ValuePointer) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
function Escape(component) {
|
|
52
|
+
return component.indexOf('~') === -1 ? component : component.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
53
|
+
}
|
|
54
|
+
/** Formats the given pointer into navigable key components */
|
|
55
|
+
function* Format(pointer) {
|
|
56
|
+
if (pointer === '')
|
|
57
|
+
return;
|
|
58
|
+
let [start, end] = [0, 0];
|
|
59
|
+
for (let i = 0; i < pointer.length; i++) {
|
|
60
|
+
const char = pointer.charAt(i);
|
|
60
61
|
if (char === '/') {
|
|
61
|
-
if (i
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
if (i === 0) {
|
|
63
|
+
start = i + 1;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
end = i;
|
|
67
|
+
yield Escape(pointer.slice(start, end));
|
|
68
|
+
start = i + 1;
|
|
64
69
|
}
|
|
65
|
-
}
|
|
66
|
-
else if (char === '~' && path.charAt(i + 1) === '0' && (path.charAt(i + 2) === '/' || i !== path.length - 1)) {
|
|
67
|
-
chars.push('~');
|
|
68
|
-
i += 1;
|
|
69
|
-
}
|
|
70
|
-
else if (char === '~' && path.charAt(i + 1) === '1' && (path.charAt(i + 2) === '/' || i !== path.length - 1)) {
|
|
71
|
-
chars.push('/');
|
|
72
|
-
i += 1;
|
|
73
70
|
}
|
|
74
71
|
else {
|
|
75
|
-
|
|
72
|
+
end = i;
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
|
-
yield
|
|
79
|
-
clear(chars);
|
|
75
|
+
yield Escape(pointer.slice(start));
|
|
80
76
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
ValuePointer.Format = Format;
|
|
78
|
+
/** Sets the value at the given pointer. If the value at the pointer does not exist it is created */
|
|
79
|
+
function Set(value, pointer, update) {
|
|
80
|
+
if (pointer === '')
|
|
81
|
+
throw new ValuePointerRootSetError(value, pointer, update);
|
|
82
|
+
let [owner, next, key] = [null, value, ''];
|
|
83
|
+
for (const component of Format(pointer)) {
|
|
84
|
+
if (next[component] === undefined)
|
|
85
|
+
next[component] = {};
|
|
86
|
+
owner = next;
|
|
87
|
+
next = next[component];
|
|
88
|
+
key = component;
|
|
92
89
|
}
|
|
93
|
-
|
|
90
|
+
owner[key] = update;
|
|
94
91
|
}
|
|
95
92
|
ValuePointer.Set = Set;
|
|
96
|
-
/** Deletes a value at the given
|
|
97
|
-
function Delete(value,
|
|
98
|
-
if (
|
|
99
|
-
throw new ValuePointerRootDeleteError(value,
|
|
100
|
-
let
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
const next = pointer.shift();
|
|
104
|
-
if (current[next] === undefined)
|
|
93
|
+
/** Deletes a value at the given pointer */
|
|
94
|
+
function Delete(value, pointer) {
|
|
95
|
+
if (pointer === '')
|
|
96
|
+
throw new ValuePointerRootDeleteError(value, pointer);
|
|
97
|
+
let [owner, next, key] = [null, value, ''];
|
|
98
|
+
for (const component of Format(pointer)) {
|
|
99
|
+
if (next[component] === undefined || next[component] === null)
|
|
105
100
|
return;
|
|
106
|
-
|
|
101
|
+
owner = next;
|
|
102
|
+
next = next[component];
|
|
103
|
+
key = component;
|
|
107
104
|
}
|
|
108
|
-
if (globalThis.Array.isArray(
|
|
109
|
-
const index = parseInt(
|
|
110
|
-
|
|
105
|
+
if (globalThis.Array.isArray(owner)) {
|
|
106
|
+
const index = parseInt(key);
|
|
107
|
+
owner.splice(index, 1);
|
|
111
108
|
}
|
|
112
109
|
else {
|
|
113
|
-
|
|
114
|
-
delete current[key];
|
|
110
|
+
delete owner[key];
|
|
115
111
|
}
|
|
116
112
|
}
|
|
117
113
|
ValuePointer.Delete = Delete;
|
|
118
|
-
/**
|
|
119
|
-
function Has(value,
|
|
120
|
-
if (
|
|
114
|
+
/** Returns true if a value exists at the given pointer */
|
|
115
|
+
function Has(value, pointer) {
|
|
116
|
+
if (pointer === '')
|
|
121
117
|
return true;
|
|
122
|
-
let
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
const next = pointer.shift();
|
|
126
|
-
if (current[next] === undefined)
|
|
118
|
+
let [owner, next, key] = [null, value, ''];
|
|
119
|
+
for (const component of Format(pointer)) {
|
|
120
|
+
if (next[component] === undefined)
|
|
127
121
|
return false;
|
|
128
|
-
|
|
122
|
+
owner = next;
|
|
123
|
+
next = next[component];
|
|
124
|
+
key = component;
|
|
129
125
|
}
|
|
130
|
-
return
|
|
126
|
+
return globalThis.Object.getOwnPropertyNames(owner).includes(key);
|
|
131
127
|
}
|
|
132
128
|
ValuePointer.Has = Has;
|
|
133
|
-
/** Gets the value at the given
|
|
134
|
-
function Get(value,
|
|
135
|
-
if (
|
|
129
|
+
/** Gets the value at the given pointer */
|
|
130
|
+
function Get(value, pointer) {
|
|
131
|
+
if (pointer === '')
|
|
136
132
|
return value;
|
|
137
133
|
let current = value;
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
const next = pointer.shift();
|
|
141
|
-
if (current[next] === undefined)
|
|
134
|
+
for (const component of Format(pointer)) {
|
|
135
|
+
if (current[component] === undefined)
|
|
142
136
|
return undefined;
|
|
143
|
-
current = current[
|
|
137
|
+
current = current[component];
|
|
144
138
|
}
|
|
145
|
-
return current
|
|
139
|
+
return current;
|
|
146
140
|
}
|
|
147
141
|
ValuePointer.Get = Get;
|
|
148
142
|
})(ValuePointer = exports.ValuePointer || (exports.ValuePointer = {}));
|