@sinclair/typebox 0.24.41 → 0.24.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.41",
3
+ "version": "0.24.42",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
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)
@@ -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
package/typebox.d.ts CHANGED
@@ -231,15 +231,15 @@ export interface TRequired<T extends TObject | TRef<TObject>> extends TObject {
231
231
  static: Required<Static<T, this['params']>>;
232
232
  }
233
233
  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<TFormat extends string> extends SchemaOptions {
234
+ export interface StringOptions<Format extends string> extends SchemaOptions {
235
235
  minLength?: number;
236
236
  maxLength?: number;
237
237
  pattern?: string;
238
- format?: TFormat;
238
+ format?: Format;
239
239
  contentEncoding?: '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64';
240
240
  contentMediaType?: string;
241
241
  }
242
- export interface TString extends TSchema, StringOptions<string> {
242
+ export interface TString<Format extends string = string> extends TSchema, StringOptions<Format> {
243
243
  [Kind]: 'String';
244
244
  static: string;
245
245
  type: 'string';
@@ -373,7 +373,7 @@ export declare class TypeBuilder {
373
373
  /** Removes Kind and Modifier symbol property keys from this schema */
374
374
  Strict<T extends TSchema>(schema: T): T;
375
375
  /** Creates a string type */
376
- String<TCustomFormatOption extends string>(options?: StringOptions<StringFormatOption | TCustomFormatOption>): TString;
376
+ String<Format extends string>(options?: StringOptions<StringFormatOption | Format>): TString<Format>;
377
377
  /** Creates a tuple type */
378
378
  Tuple<T extends TSchema[]>(items: [...T], options?: SchemaOptions): TTuple<T>;
379
379
  /** Creates a undefined type */
@@ -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
- /** Sets the value at the given pointer. If the value at the pointer does not exist it is created. */
15
- function Set(value: unknown, path: string, update: unknown): void;
16
- /** Deletes a value at the given path. */
17
- function Delete(value: any, path: string): any[] | undefined;
18
- /** True if a value exists at the given path */
19
- function Has(value: any, path: string): boolean;
20
- /** Gets the value at the given path */
21
- function Get(value: any, path: string): any;
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
- /** Formats the path into navigable components */
52
- function* Format(path) {
53
- function clear(chars) {
54
- while (chars.length > 0)
55
- chars.shift();
56
- }
57
- const chars = [];
58
- for (let i = 0; i < path.length; i++) {
59
- const char = path.charAt(i);
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 !== 0) {
62
- yield chars.join('');
63
- clear(chars);
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
- chars.push(char);
72
+ end = i;
76
73
  }
77
74
  }
78
- yield chars.join('');
79
- clear(chars);
75
+ yield Escape(pointer.slice(start));
80
76
  }
81
- /** Sets the value at the given pointer. If the value at the pointer does not exist it is created. */
82
- function Set(value, path, update) {
83
- if (path === '')
84
- throw new ValuePointerRootSetError(value, path, update);
85
- const pointer = [...Format(path)];
86
- let current = value;
87
- while (pointer.length > 1) {
88
- const next = pointer.shift();
89
- if (current[next] === undefined)
90
- current[next] = {};
91
- current = current[next];
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
- current[pointer.shift()] = update;
90
+ owner[key] = update;
94
91
  }
95
92
  ValuePointer.Set = Set;
96
- /** Deletes a value at the given path. */
97
- function Delete(value, path) {
98
- if (path === '')
99
- throw new ValuePointerRootDeleteError(value, path);
100
- let current = value;
101
- const pointer = [...Format(path)];
102
- while (pointer.length > 1) {
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
- current = current[next];
101
+ owner = next;
102
+ next = next[component];
103
+ key = component;
107
104
  }
108
- if (globalThis.Array.isArray(current)) {
109
- const index = parseInt(pointer.shift());
110
- return current.splice(index, 1);
105
+ if (globalThis.Array.isArray(owner)) {
106
+ const index = parseInt(key);
107
+ owner.splice(index, 1);
111
108
  }
112
109
  else {
113
- const key = pointer.shift();
114
- delete current[key];
110
+ delete owner[key];
115
111
  }
116
112
  }
117
113
  ValuePointer.Delete = Delete;
118
- /** True if a value exists at the given path */
119
- function Has(value, path) {
120
- if (path === '')
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 current = value;
123
- const pointer = [...Format(path)];
124
- while (pointer.length > 1) {
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
- current = current[next];
122
+ owner = next;
123
+ next = next[component];
124
+ key = component;
129
125
  }
130
- return current[pointer.shift()] !== undefined;
126
+ return globalThis.Object.getOwnPropertyNames(owner).includes(key);
131
127
  }
132
128
  ValuePointer.Has = Has;
133
- /** Gets the value at the given path */
134
- function Get(value, path) {
135
- if (path === '')
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 pointer = [...Format(path)];
139
- while (pointer.length > 1) {
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[next];
137
+ current = current[component];
144
138
  }
145
- return current[pointer.shift()];
139
+ return current;
146
140
  }
147
141
  ValuePointer.Get = Get;
148
142
  })(ValuePointer = exports.ValuePointer || (exports.ValuePointer = {}));