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