@fgv/ts-json-base 5.0.2 → 5.1.0-0

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 (42) hide show
  1. package/dist/packlets/converters/converters.js +36 -14
  2. package/dist/packlets/file-tree/directoryItem.js +35 -4
  3. package/dist/packlets/file-tree/fileItem.js +37 -9
  4. package/dist/packlets/file-tree/fileTreeAccessors.js +24 -1
  5. package/dist/packlets/file-tree/filterSpec.js +74 -0
  6. package/dist/packlets/file-tree/fsTree.js +73 -12
  7. package/dist/packlets/file-tree/in-memory/inMemoryTree.js +204 -21
  8. package/dist/packlets/file-tree/in-memory/treeBuilder.js +23 -0
  9. package/dist/packlets/file-tree/index.browser.js +1 -0
  10. package/dist/packlets/file-tree/index.js +1 -0
  11. package/dist/packlets/json-file/file.js +1 -1
  12. package/dist/packlets/json-file/jsonFsHelper.js +1 -1
  13. package/dist/packlets/validators/validators.js +8 -8
  14. package/dist/ts-json-base.d.ts +290 -61
  15. package/dist/tsdoc-metadata.json +1 -1
  16. package/lib/packlets/converters/converters.d.ts +20 -13
  17. package/lib/packlets/converters/converters.js +36 -13
  18. package/lib/packlets/file-tree/directoryItem.d.ts +13 -5
  19. package/lib/packlets/file-tree/directoryItem.js +34 -3
  20. package/lib/packlets/file-tree/fileItem.d.ts +26 -13
  21. package/lib/packlets/file-tree/fileItem.js +36 -8
  22. package/lib/packlets/file-tree/fileTreeAccessors.d.ts +141 -1
  23. package/lib/packlets/file-tree/fileTreeAccessors.js +26 -0
  24. package/lib/packlets/file-tree/filterSpec.d.ts +10 -0
  25. package/lib/packlets/file-tree/filterSpec.js +77 -0
  26. package/lib/packlets/file-tree/fsTree.d.ts +29 -13
  27. package/lib/packlets/file-tree/fsTree.js +72 -11
  28. package/lib/packlets/file-tree/in-memory/inMemoryTree.d.ts +29 -13
  29. package/lib/packlets/file-tree/in-memory/inMemoryTree.js +203 -20
  30. package/lib/packlets/file-tree/in-memory/treeBuilder.d.ts +9 -0
  31. package/lib/packlets/file-tree/in-memory/treeBuilder.js +23 -0
  32. package/lib/packlets/file-tree/index.browser.d.ts +1 -0
  33. package/lib/packlets/file-tree/index.browser.js +1 -0
  34. package/lib/packlets/file-tree/index.d.ts +1 -0
  35. package/lib/packlets/file-tree/index.js +1 -0
  36. package/lib/packlets/json-file/file.d.ts +1 -1
  37. package/lib/packlets/json-file/file.js +1 -1
  38. package/lib/packlets/json-file/jsonFsHelper.d.ts +1 -1
  39. package/lib/packlets/json-file/jsonFsHelper.js +1 -1
  40. package/lib/packlets/validators/validators.d.ts +9 -9
  41. package/lib/packlets/validators/validators.js +8 -8
  42. package/package.json +18 -18
@@ -26,9 +26,79 @@ const ts_utils_1 = require("@fgv/ts-utils");
26
26
  const directoryItem_1 = require("../directoryItem");
27
27
  const fileItem_1 = require("../fileItem");
28
28
  const treeBuilder_1 = require("./treeBuilder");
29
+ const filterSpec_1 = require("../filterSpec");
29
30
  /**
30
- * Implementation of {@link FileTree.IFileTreeAccessors} that uses an in-memory
31
- * tree to access files and directories.
31
+ * A mutable in-memory file that allows updating contents.
32
+ * @internal
33
+ */
34
+ class MutableInMemoryFile {
35
+ constructor(absolutePath, contents, contentType) {
36
+ this.absolutePath = absolutePath;
37
+ this._contents = contents;
38
+ this.contentType = contentType;
39
+ }
40
+ get contents() {
41
+ return this._contents;
42
+ }
43
+ setContents(contents) {
44
+ this._contents = contents;
45
+ }
46
+ }
47
+ /**
48
+ * A mutable in-memory directory that creates mutable files.
49
+ * @internal
50
+ */
51
+ class MutableInMemoryDirectory {
52
+ /* c8 ignore next 3 - internal getter used by tree traversal */
53
+ get children() {
54
+ return this._children;
55
+ }
56
+ constructor(absolutePath) {
57
+ this.absolutePath = absolutePath;
58
+ this._children = new Map();
59
+ }
60
+ getChildPath(name) {
61
+ if (this.absolutePath === '/') {
62
+ return `/${name}`;
63
+ }
64
+ return [this.absolutePath, name].join('/');
65
+ }
66
+ addFile(name, contents, contentType) {
67
+ /* c8 ignore next 3 - defensive: duplicate detection during construction */
68
+ if (this._children.has(name)) {
69
+ return (0, ts_utils_1.fail)(`${name}: already exists`);
70
+ }
71
+ const child = new MutableInMemoryFile(this.getChildPath(name), contents, contentType);
72
+ this._children.set(name, child);
73
+ return (0, ts_utils_1.succeed)(child);
74
+ }
75
+ getOrAddDirectory(name) {
76
+ const existing = this._children.get(name);
77
+ if (existing) {
78
+ if (existing instanceof MutableInMemoryDirectory) {
79
+ return (0, ts_utils_1.succeed)(existing);
80
+ }
81
+ return (0, ts_utils_1.fail)(`${name}: not a directory`);
82
+ }
83
+ const child = new MutableInMemoryDirectory(this.getChildPath(name));
84
+ this._children.set(name, child);
85
+ return (0, ts_utils_1.succeed)(child);
86
+ }
87
+ updateOrAddFile(name, contents, contentType) {
88
+ const existing = this._children.get(name);
89
+ if (existing) {
90
+ if (existing instanceof MutableInMemoryFile) {
91
+ existing.setContents(contents);
92
+ return (0, ts_utils_1.succeed)(existing);
93
+ }
94
+ return (0, ts_utils_1.fail)(`${name}: not a file`);
95
+ }
96
+ return this.addFile(name, contents, contentType);
97
+ }
98
+ }
99
+ /**
100
+ * Implementation of {@link FileTree.IMutableFileTreeAccessors} that uses an in-memory
101
+ * tree to access and modify files and directories.
32
102
  * @public
33
103
  */
34
104
  class InMemoryTreeAccessors {
@@ -39,12 +109,18 @@ class InMemoryTreeAccessors {
39
109
  * @public
40
110
  */
41
111
  constructor(files, params) {
42
- var _a, _b;
112
+ var _a, _b, _c, _d;
43
113
  this._tree = treeBuilder_1.TreeBuilder.create(params === null || params === void 0 ? void 0 : params.prefix).orThrow();
44
114
  this._inferContentType = (_a = params === null || params === void 0 ? void 0 : params.inferContentType) !== null && _a !== void 0 ? _a : fileItem_1.FileItem.defaultInferContentType;
115
+ this._mutable = (_b = params === null || params === void 0 ? void 0 : params.mutable) !== null && _b !== void 0 ? _b : false;
116
+ this._mutableByPath = new Map();
117
+ const prefix = (_c = params === null || params === void 0 ? void 0 : params.prefix) !== null && _c !== void 0 ? _c : '/';
118
+ this._mutableRoot = new MutableInMemoryDirectory(prefix.endsWith('/') ? prefix.slice(0, -1) || '/' : prefix);
119
+ this._mutableByPath.set(this._mutableRoot.absolutePath, this._mutableRoot);
45
120
  for (const file of files) {
46
- const contentType = (_b = file.contentType) !== null && _b !== void 0 ? _b : this._inferContentType(file.path).orDefault();
121
+ const contentType = (_d = file.contentType) !== null && _d !== void 0 ? _d : this._inferContentType(file.path).orDefault();
47
122
  this._tree.addFile(file.path, file.contents, contentType).orThrow();
123
+ this._addMutableFile(file.path, file.contents, contentType);
48
124
  }
49
125
  }
50
126
  /**
@@ -59,7 +135,7 @@ class InMemoryTreeAccessors {
59
135
  return (0, ts_utils_1.captureResult)(() => new InMemoryTreeAccessors(files, params));
60
136
  }
61
137
  /**
62
- * {@inheritdoc FileTree.IFileTreeAccessors.resolveAbsolutePath}
138
+ * {@inheritDoc FileTree.IFileTreeAccessors.resolveAbsolutePath}
63
139
  */
64
140
  resolveAbsolutePath(...paths) {
65
141
  const parts = paths[0].startsWith('/') ? paths : [this._tree.prefix, ...paths];
@@ -67,7 +143,7 @@ class InMemoryTreeAccessors {
67
143
  return `/${joined}`;
68
144
  }
69
145
  /**
70
- * {@inheritdoc FileTree.IFileTreeAccessors.getExtension}
146
+ * {@inheritDoc FileTree.IFileTreeAccessors.getExtension}
71
147
  */
72
148
  getExtension(path) {
73
149
  const parts = path.split('.');
@@ -77,7 +153,7 @@ class InMemoryTreeAccessors {
77
153
  return `.${parts.pop()}`;
78
154
  }
79
155
  /**
80
- * {@inheritdoc FileTree.IFileTreeAccessors.getBaseName}
156
+ * {@inheritDoc FileTree.IFileTreeAccessors.getBaseName}
81
157
  */
82
158
  getBaseName(path, suffix) {
83
159
  var _a;
@@ -89,13 +165,15 @@ class InMemoryTreeAccessors {
89
165
  return base;
90
166
  }
91
167
  /**
92
- * {@inheritdoc FileTree.IFileTreeAccessors.joinPaths}
168
+ * {@inheritDoc FileTree.IFileTreeAccessors.joinPaths}
93
169
  */
94
170
  joinPaths(...paths) {
95
- return paths.join('/');
171
+ var _a;
172
+ const joined = paths.flatMap((p) => p.split('/').filter((s) => s.length > 0)).join('/');
173
+ return ((_a = paths[0]) === null || _a === void 0 ? void 0 : _a.startsWith('/')) ? `/${joined}` : joined;
96
174
  }
97
175
  /**
98
- * {@inheritdoc FileTree.IFileTreeAccessors.getItem}
176
+ * {@inheritDoc FileTree.IFileTreeAccessors.getItem}
99
177
  */
100
178
  getItem(itemPath) {
101
179
  const existing = this._tree.byAbsolutePath.get(itemPath);
@@ -110,26 +188,24 @@ class InMemoryTreeAccessors {
110
188
  return (0, ts_utils_1.fail)(`${itemPath}: not found`);
111
189
  }
112
190
  /**
113
- * {@inheritdoc FileTree.IFileTreeAccessors.getFileContents}
191
+ * {@inheritDoc FileTree.IFileTreeAccessors.getFileContents}
114
192
  */
115
193
  getFileContents(path) {
116
- const item = this._tree.byAbsolutePath.get(path);
194
+ const absolutePath = this.resolveAbsolutePath(path);
195
+ const item = this._mutableByPath.get(absolutePath);
117
196
  if (item === undefined) {
118
- return (0, ts_utils_1.fail)(`${path}: not found`);
197
+ return (0, ts_utils_1.fail)(`${absolutePath}: not found`);
119
198
  }
120
- /* c8 ignore next 3 - local coverage is 100% but build coverage has intermittent issues */
121
- if (!(item instanceof treeBuilder_1.InMemoryFile)) {
122
- return (0, ts_utils_1.fail)(`${path}: not a file`);
199
+ if (!(item instanceof MutableInMemoryFile)) {
200
+ return (0, ts_utils_1.fail)(`${absolutePath}: not a file`);
123
201
  }
124
- // if the body is a string we don't want to add quotes
125
202
  if (typeof item.contents === 'string') {
126
203
  return (0, ts_utils_1.succeed)(item.contents);
127
204
  }
128
- /* c8 ignore next 2 - local coverage is 100% but build coverage has intermittent issues */
129
205
  return (0, ts_utils_1.captureResult)(() => JSON.stringify(item.contents));
130
206
  }
131
207
  /**
132
- * {@inheritdoc FileTree.IFileTreeAccessors.getFileContentType}
208
+ * {@inheritDoc FileTree.IFileTreeAccessors.getFileContentType}
133
209
  */
134
210
  getFileContentType(path, provided) {
135
211
  // If provided contentType is given, use it directly (highest priority)
@@ -152,7 +228,7 @@ class InMemoryTreeAccessors {
152
228
  return this._inferContentType(path);
153
229
  }
154
230
  /**
155
- * {@inheritdoc FileTree.IFileTreeAccessors.getChildren}
231
+ * {@inheritDoc FileTree.IFileTreeAccessors.getChildren}
156
232
  */
157
233
  getChildren(path) {
158
234
  const item = this._tree.byAbsolutePath.get(path);
@@ -176,6 +252,113 @@ class InMemoryTreeAccessors {
176
252
  return children;
177
253
  });
178
254
  }
255
+ _addMutableFile(path, contents, contentType) {
256
+ const absolutePath = this.resolveAbsolutePath(path);
257
+ const parts = absolutePath.split('/').filter((p) => p.length > 0);
258
+ /* c8 ignore next 3 - defensive: invalid path detection */
259
+ if (parts.length === 0) {
260
+ return (0, ts_utils_1.fail)(`${absolutePath}: invalid file path`);
261
+ }
262
+ let dir = this._mutableRoot;
263
+ while (parts.length > 1) {
264
+ const part = parts.shift();
265
+ const result = dir.getOrAddDirectory(part);
266
+ /* c8 ignore next 3 - defensive: directory conflict during construction */
267
+ if (result.isFailure()) {
268
+ return (0, ts_utils_1.fail)(result.message);
269
+ }
270
+ dir = result.value;
271
+ if (!this._mutableByPath.has(dir.absolutePath)) {
272
+ this._mutableByPath.set(dir.absolutePath, dir);
273
+ }
274
+ }
275
+ return dir.addFile(parts[0], contents, contentType).onSuccess((file) => {
276
+ this._mutableByPath.set(file.absolutePath, file);
277
+ return (0, ts_utils_1.succeed)(file);
278
+ });
279
+ }
280
+ /**
281
+ * {@inheritDoc FileTree.IMutableFileTreeAccessors.createDirectory}
282
+ */
283
+ createDirectory(dirPath) {
284
+ const absolutePath = this.resolveAbsolutePath(dirPath);
285
+ // Check if mutability is disabled
286
+ if (this._mutable === false) {
287
+ return (0, ts_utils_1.fail)(`${absolutePath}: mutability is disabled`);
288
+ }
289
+ // Add to the TreeBuilder (read layer)
290
+ const treeResult = this._tree.addDirectory(absolutePath);
291
+ /* c8 ignore next 3 - defensive: read layer failure would indicate internal inconsistency */
292
+ if (treeResult.isFailure()) {
293
+ return (0, ts_utils_1.fail)(treeResult.message);
294
+ }
295
+ // Add to the mutable layer
296
+ const parts = absolutePath.split('/').filter((p) => p.length > 0);
297
+ let dir = this._mutableRoot;
298
+ for (const part of parts) {
299
+ const result = dir.getOrAddDirectory(part);
300
+ /* c8 ignore next 3 - defensive: mutable layer should match read layer state */
301
+ if (result.isFailure()) {
302
+ return (0, ts_utils_1.fail)(result.message);
303
+ }
304
+ dir = result.value;
305
+ if (!this._mutableByPath.has(dir.absolutePath)) {
306
+ this._mutableByPath.set(dir.absolutePath, dir);
307
+ }
308
+ }
309
+ return (0, ts_utils_1.succeed)(absolutePath);
310
+ }
311
+ /**
312
+ * {@inheritDoc FileTree.IMutableFileTreeAccessors.fileIsMutable}
313
+ */
314
+ fileIsMutable(path) {
315
+ const absolutePath = this.resolveAbsolutePath(path);
316
+ // Check if mutability is disabled
317
+ if (this._mutable === false) {
318
+ return (0, ts_utils_1.failWithDetail)(`${absolutePath}: mutability is disabled`, 'not-mutable');
319
+ }
320
+ // Check if path is excluded by filter
321
+ if (!(0, filterSpec_1.isPathMutable)(absolutePath, this._mutable)) {
322
+ return (0, ts_utils_1.failWithDetail)(`${absolutePath}: path is excluded by filter`, 'path-excluded');
323
+ }
324
+ return (0, ts_utils_1.succeedWithDetail)(true, 'transient');
325
+ }
326
+ /**
327
+ * {@inheritDoc FileTree.IMutableFileTreeAccessors.saveFileContents}
328
+ */
329
+ saveFileContents(path, contents) {
330
+ const isMutable = this.fileIsMutable(path);
331
+ if (isMutable.isFailure()) {
332
+ return (0, ts_utils_1.fail)(isMutable.message);
333
+ }
334
+ const absolutePath = this.resolveAbsolutePath(path);
335
+ const parts = absolutePath.split('/').filter((p) => p.length > 0);
336
+ if (parts.length === 0) {
337
+ return (0, ts_utils_1.fail)(`${absolutePath}: invalid file path`);
338
+ }
339
+ // Navigate to parent directory, creating directories as needed
340
+ let dir = this._mutableRoot;
341
+ while (parts.length > 1) {
342
+ const part = parts.shift();
343
+ const result = dir.getOrAddDirectory(part);
344
+ if (result.isFailure()) {
345
+ return (0, ts_utils_1.fail)(result.message);
346
+ }
347
+ dir = result.value;
348
+ if (!this._mutableByPath.has(dir.absolutePath)) {
349
+ this._mutableByPath.set(dir.absolutePath, dir);
350
+ }
351
+ }
352
+ // Update or add the file in the mutable layer
353
+ return dir.updateOrAddFile(parts[0], contents).onSuccess((file) => {
354
+ this._mutableByPath.set(file.absolutePath, file);
355
+ // Also register in the read layer so getItem/getChildren can find it
356
+ if (!this._tree.byAbsolutePath.has(file.absolutePath)) {
357
+ this._tree.addFile(file.absolutePath, contents);
358
+ }
359
+ return (0, ts_utils_1.succeed)(contents);
360
+ });
361
+ }
179
362
  }
180
363
  exports.InMemoryTreeAccessors = InMemoryTreeAccessors;
181
364
  //# sourceMappingURL=inMemoryTree.js.map
@@ -109,5 +109,14 @@ export declare class TreeBuilder<TCT extends string = string> {
109
109
  * @public
110
110
  */
111
111
  addFile(absolutePath: string, contents: unknown, contentType?: TCT): Result<InMemoryFile<TCT>>;
112
+ /**
113
+ * Ensures a directory exists at the given absolute path, creating
114
+ * intermediate directories as needed.
115
+ * @param absolutePath - The absolute path of the directory.
116
+ * @returns `Success` with the directory if successful, or
117
+ * `Failure` with an error message otherwise.
118
+ * @public
119
+ */
120
+ addDirectory(absolutePath: string): Result<InMemoryDirectory<TCT>>;
112
121
  }
113
122
  //# sourceMappingURL=treeBuilder.d.ts.map
@@ -174,6 +174,29 @@ class TreeBuilder {
174
174
  return (0, ts_utils_1.succeed)(file);
175
175
  });
176
176
  }
177
+ /**
178
+ * Ensures a directory exists at the given absolute path, creating
179
+ * intermediate directories as needed.
180
+ * @param absolutePath - The absolute path of the directory.
181
+ * @returns `Success` with the directory if successful, or
182
+ * `Failure` with an error message otherwise.
183
+ * @public
184
+ */
185
+ addDirectory(absolutePath) {
186
+ const parts = absolutePath.split('/').filter((p) => p.length > 0);
187
+ let dir = this.root;
188
+ for (const part of parts) {
189
+ const result = dir.getOrAddDirectory(part);
190
+ if (result.isFailure()) {
191
+ return (0, ts_utils_1.fail)(result.message);
192
+ }
193
+ dir = result.value;
194
+ if (!this.byAbsolutePath.has(dir.absolutePath)) {
195
+ this.byAbsolutePath.set(dir.absolutePath, dir);
196
+ }
197
+ }
198
+ return (0, ts_utils_1.succeed)(dir);
199
+ }
177
200
  }
178
201
  exports.TreeBuilder = TreeBuilder;
179
202
  //# sourceMappingURL=treeBuilder.js.map
@@ -2,6 +2,7 @@ export * from './fileTreeAccessors';
2
2
  export * from './fileTree';
3
3
  export * from './directoryItem';
4
4
  export * from './fileItem';
5
+ export * from './filterSpec';
5
6
  export * from './in-memory';
6
7
  export { inMemory } from './fileTreeHelpers.inMemory';
7
8
  //# sourceMappingURL=index.browser.d.ts.map
@@ -42,6 +42,7 @@ __exportStar(require("./fileTreeAccessors"), exports);
42
42
  __exportStar(require("./fileTree"), exports);
43
43
  __exportStar(require("./directoryItem"), exports);
44
44
  __exportStar(require("./fileItem"), exports);
45
+ __exportStar(require("./filterSpec"), exports);
45
46
  // Export in-memory implementations for web compatibility
46
47
  __exportStar(require("./in-memory"), exports);
47
48
  var fileTreeHelpers_inMemory_1 = require("./fileTreeHelpers.inMemory");
@@ -2,6 +2,7 @@ export * from './fileTreeAccessors';
2
2
  export * from './fileTree';
3
3
  export * from './directoryItem';
4
4
  export * from './fileItem';
5
+ export * from './filterSpec';
5
6
  export * from './fileTreeHelpers';
6
7
  export { inMemory } from './fileTreeHelpers.inMemory';
7
8
  export * from './in-memory';
@@ -41,6 +41,7 @@ __exportStar(require("./fileTreeAccessors"), exports);
41
41
  __exportStar(require("./fileTree"), exports);
42
42
  __exportStar(require("./directoryItem"), exports);
43
43
  __exportStar(require("./fileItem"), exports);
44
+ __exportStar(require("./filterSpec"), exports);
44
45
  // Export tree-shakeable helpers (filesystem ones will be shaken out if not used)
45
46
  __exportStar(require("./fileTreeHelpers"), exports);
46
47
  var fileTreeHelpers_inMemory_1 = require("./fileTreeHelpers.inMemory");
@@ -2,7 +2,7 @@ import { Converter, Result } from '@fgv/ts-utils';
2
2
  import { JsonValue } from '../json';
3
3
  import { IJsonFsDirectoryOptions, IJsonFsDirectoryToMapOptions, IReadDirectoryItem } from './jsonFsHelper';
4
4
  /**
5
- * {@inheritdoc JsonFile.JsonFsHelper.readJsonFileSync}
5
+ * {@inheritDoc JsonFile.JsonFsHelper.readJsonFileSync}
6
6
  * @public
7
7
  */
8
8
  export declare function readJsonFileSync(srcPath: string): Result<JsonValue>;
@@ -29,7 +29,7 @@ exports.writeJsonFileSync = writeJsonFileSync;
29
29
  const jsonFsHelper_1 = require("./jsonFsHelper");
30
30
  const jsonLike_1 = require("./jsonLike");
31
31
  /**
32
- * {@inheritdoc JsonFile.JsonFsHelper.readJsonFileSync}
32
+ * {@inheritDoc JsonFile.JsonFsHelper.readJsonFileSync}
33
33
  * @public
34
34
  */
35
35
  function readJsonFileSync(srcPath) {
@@ -74,7 +74,7 @@ export declare class JsonFsHelper {
74
74
  readonly config: IJsonFsHelperConfig;
75
75
  /**
76
76
  * Construct a new {@link JsonFile.JsonFsHelper | JsonFsHelper}.
77
- * @param json - Optional {@link JsonFile.IJsonLike | IJsonLike} used to process strings
77
+ * @param init - Optional {@link JsonFile.JsonFsHelperInitOptions | init options} to construct
78
78
  * and JSON values.
79
79
  */
80
80
  constructor(init?: JsonFsHelperInitOptions);
@@ -54,7 +54,7 @@ exports.DefaultJsonFsHelperConfig = {
54
54
  class JsonFsHelper {
55
55
  /**
56
56
  * Construct a new {@link JsonFile.JsonFsHelper | JsonFsHelper}.
57
- * @param json - Optional {@link JsonFile.IJsonLike | IJsonLike} used to process strings
57
+ * @param init - Optional {@link JsonFile.JsonFsHelperInitOptions | init options} to construct
58
58
  * and JSON values.
59
59
  */
60
60
  constructor(init) {
@@ -38,42 +38,42 @@ export declare const jsonArray: Validator<JsonArray, IJsonValidatorContext>;
38
38
  */
39
39
  export declare const jsonValue: Validator<JsonValue, IJsonValidatorContext>;
40
40
  /**
41
- * A {@link Validation.Classes.StringValidator | StringValidator} which validates a string in place.
41
+ * A `StringValidator` which validates a string in place.
42
42
  * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
43
43
  * @public
44
44
  */
45
45
  export declare const string: Validation.Classes.StringValidator<string, IJsonValidatorContext>;
46
46
  /**
47
- * A {@link Validation.Classes.NumberValidator | NumberValidator} which validates a number in place.
47
+ * A `NumberValidator` which validates a number in place.
48
48
  * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
49
49
  * @public
50
50
  */
51
- export declare const number: Validator<number, IJsonValidatorContext>;
51
+ export declare const number: Validation.Classes.NumberValidator<number, IJsonValidatorContext>;
52
52
  /**
53
- * A {@link Validation.Classes.BooleanValidator | BooleanValidator} which validates a boolean in place.
54
- * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
53
+ * A `BooleanValidator` which validates a boolean in place.
54
+ * Accepts `IJsonValidatorContext` but ignores it.
55
55
  * @public
56
56
  */
57
57
  export declare const boolean: Validator<boolean, IJsonValidatorContext>;
58
58
  /**
59
59
  * Helper to create a validator for a literal value.
60
- * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
60
+ * Accepts `IJsonValidatorContext` but ignores it.
61
61
  * Mirrors the behavior of `@fgv/ts-utils`.
62
62
  * @public
63
63
  */
64
64
  export declare function literal<T>(value: T): Validator<T, IJsonValidatorContext>;
65
65
  /**
66
- * Helper function to create a {@link Validator | Validator} which validates `unknown` to one of a set of
66
+ * Helper function to create a `Validator` which validates `unknown` to one of a set of
67
67
  * supplied enumerated values. Anything else fails.
68
68
  *
69
69
  * @remarks
70
- * This JSON variant accepts an {@link Validators.IJsonValidatorContext | IJsonValidatorContext} OR
70
+ * This JSON variant accepts an `IJsonValidatorContext` OR
71
71
  * a `ReadonlyArray<T>` as its validation context. If the context is an array, it is used to override the
72
72
  * allowed values for that validation; otherwise, the original `values` supplied at creation time are used.
73
73
  *
74
74
  * @param values - Array of allowed values.
75
75
  * @param message - Optional custom failure message.
76
- * @returns A new {@link Validator | Validator} returning `<T>`.
76
+ * @returns A new `Validator` returning `<T>`.
77
77
  * @public
78
78
  */
79
79
  export declare function enumeratedValue<T>(values: ReadonlyArray<T>, message?: string): Validator<T, IJsonValidatorContext | ReadonlyArray<T>>;
@@ -125,26 +125,26 @@ exports.jsonValue = new ts_utils_1.Validation.Base.GenericValidator({
125
125
  }
126
126
  });
127
127
  /**
128
- * A {@link Validation.Classes.StringValidator | StringValidator} which validates a string in place.
128
+ * A `StringValidator` which validates a string in place.
129
129
  * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
130
130
  * @public
131
131
  */
132
132
  exports.string = new ts_utils_1.Validation.Classes.StringValidator();
133
133
  /**
134
- * A {@link Validation.Classes.NumberValidator | NumberValidator} which validates a number in place.
134
+ * A `NumberValidator` which validates a number in place.
135
135
  * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
136
136
  * @public
137
137
  */
138
138
  exports.number = new ts_utils_1.Validation.Classes.NumberValidator();
139
139
  /**
140
- * A {@link Validation.Classes.BooleanValidator | BooleanValidator} which validates a boolean in place.
141
- * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
140
+ * A `BooleanValidator` which validates a boolean in place.
141
+ * Accepts `IJsonValidatorContext` but ignores it.
142
142
  * @public
143
143
  */
144
144
  exports.boolean = new ts_utils_1.Validation.Classes.BooleanValidator();
145
145
  /**
146
146
  * Helper to create a validator for a literal value.
147
- * Accepts {@link Validators.IJsonValidatorContext | IJsonValidatorContext} but ignores it.
147
+ * Accepts `IJsonValidatorContext` but ignores it.
148
148
  * Mirrors the behavior of `@fgv/ts-utils`.
149
149
  * @public
150
150
  */
@@ -156,17 +156,17 @@ function literal(value) {
156
156
  });
157
157
  }
158
158
  /**
159
- * Helper function to create a {@link Validator | Validator} which validates `unknown` to one of a set of
159
+ * Helper function to create a `Validator` which validates `unknown` to one of a set of
160
160
  * supplied enumerated values. Anything else fails.
161
161
  *
162
162
  * @remarks
163
- * This JSON variant accepts an {@link Validators.IJsonValidatorContext | IJsonValidatorContext} OR
163
+ * This JSON variant accepts an `IJsonValidatorContext` OR
164
164
  * a `ReadonlyArray<T>` as its validation context. If the context is an array, it is used to override the
165
165
  * allowed values for that validation; otherwise, the original `values` supplied at creation time are used.
166
166
  *
167
167
  * @param values - Array of allowed values.
168
168
  * @param message - Optional custom failure message.
169
- * @returns A new {@link Validator | Validator} returning `<T>`.
169
+ * @returns A new `Validator` returning `<T>`.
170
170
  * @public
171
171
  */
172
172
  function enumeratedValue(values, message) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-json-base",
3
- "version": "5.0.2",
3
+ "version": "5.1.0-0",
4
4
  "description": "Typescript types and basic functions for working with json",
5
5
  "main": "lib/index.js",
6
6
  "types": "dist/ts-json-base.d.ts",
@@ -31,35 +31,35 @@
31
31
  "devDependencies": {
32
32
  "@types/jest": "^29.5.14",
33
33
  "@types/node": "^20.14.9",
34
- "@typescript-eslint/eslint-plugin": "^8.46.2",
35
- "@typescript-eslint/parser": "^8.46.2",
36
- "eslint": "^9.39.0",
34
+ "@typescript-eslint/eslint-plugin": "^8.52.0",
35
+ "@typescript-eslint/parser": "^8.52.0",
36
+ "eslint": "^9.39.2",
37
37
  "eslint-plugin-import": "^2.32.0",
38
38
  "eslint-plugin-node": "^11.1.0",
39
39
  "eslint-plugin-promise": "^7.2.1",
40
40
  "jest": "^29.7.0",
41
41
  "jest-extended": "^4.0.2",
42
- "rimraf": "^6.1.0",
43
- "ts-jest": "^29.4.5",
42
+ "rimraf": "^6.1.2",
43
+ "ts-jest": "^29.4.6",
44
44
  "ts-node": "^10.9.2",
45
45
  "typescript": "5.9.3",
46
46
  "eslint-plugin-n": "^17.23.1",
47
- "@rushstack/heft": "1.1.3",
48
- "@rushstack/heft-jest-plugin": "1.1.3",
47
+ "@rushstack/heft": "1.2.6",
48
+ "@rushstack/heft-jest-plugin": "1.2.6",
49
49
  "@types/heft-jest": "1.0.6",
50
- "@microsoft/api-documenter": "^7.27.3",
50
+ "@microsoft/api-documenter": "^7.28.2",
51
51
  "@rushstack/eslint-patch": "1.14.1",
52
- "@rushstack/eslint-config": "4.5.3",
53
- "eslint-plugin-tsdoc": "~0.4.0",
52
+ "@rushstack/eslint-config": "4.6.4",
53
+ "eslint-plugin-tsdoc": "~0.5.2",
54
54
  "@types/luxon": "^3.7.1",
55
- "@rushstack/heft-node-rig": "2.11.4",
56
- "@microsoft/api-extractor": "^7.53.3",
57
- "@fgv/ts-utils": "5.0.2",
58
- "@fgv/heft-dual-rig": "0.1.0",
59
- "@fgv/ts-utils-jest": "5.0.2"
55
+ "@rushstack/heft-node-rig": "2.11.26",
56
+ "@microsoft/api-extractor": "^7.55.2",
57
+ "@fgv/ts-utils": "5.1.0-0",
58
+ "@fgv/ts-utils-jest": "5.1.0-0",
59
+ "@fgv/heft-dual-rig": "0.1.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@fgv/ts-utils": "5.0.2"
62
+ "@fgv/ts-utils": "5.1.0-0"
63
63
  },
64
64
  "dependencies": {
65
65
  "luxon": "^3.7.2"
@@ -72,7 +72,7 @@
72
72
  "build": "heft build --clean",
73
73
  "clean": "heft clean",
74
74
  "test": "heft test --clean",
75
- "build-docs": "api-documenter markdown --input-folder ./temp --output-folder docs",
75
+ "build-docs": "typedoc --options ./config/typedoc.json",
76
76
  "build-all": "rushx build; rushx build-docs",
77
77
  "test-handles": "jest --runInBand --detectOpenHandles",
78
78
  "clean-jest": "jest --clear-cache",