@fgv/ts-json-base 5.0.1-9 → 5.0.2-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 (43) hide show
  1. package/dist/index.browser.js +31 -0
  2. package/dist/index.js +29 -0
  3. package/dist/packlets/converters/converters.js +187 -0
  4. package/dist/packlets/converters/index.js +23 -0
  5. package/dist/packlets/file-tree/directoryItem.js +67 -0
  6. package/dist/packlets/file-tree/fileItem.js +126 -0
  7. package/dist/packlets/file-tree/fileTree.js +85 -0
  8. package/dist/packlets/file-tree/fileTreeAccessors.js +23 -0
  9. package/dist/packlets/file-tree/fileTreeHelpers.inMemory.js +28 -0
  10. package/dist/packlets/file-tree/fileTreeHelpers.js +29 -0
  11. package/dist/packlets/file-tree/fsTree.js +122 -0
  12. package/dist/packlets/file-tree/in-memory/inMemoryTree.js +177 -0
  13. package/dist/packlets/file-tree/in-memory/index.js +23 -0
  14. package/dist/packlets/file-tree/in-memory/treeBuilder.js +173 -0
  15. package/dist/packlets/file-tree/index.browser.js +34 -0
  16. package/dist/packlets/file-tree/index.js +35 -0
  17. package/dist/packlets/json/common.js +145 -0
  18. package/dist/packlets/json/index.js +23 -0
  19. package/dist/packlets/json-compatible/common.js +23 -0
  20. package/dist/packlets/json-compatible/converters.js +90 -0
  21. package/dist/packlets/json-compatible/index.js +26 -0
  22. package/dist/packlets/json-compatible/validators.js +54 -0
  23. package/dist/packlets/json-file/file.js +74 -0
  24. package/dist/packlets/json-file/index.browser.js +30 -0
  25. package/dist/packlets/json-file/index.js +30 -0
  26. package/dist/packlets/json-file/jsonFsHelper.js +166 -0
  27. package/dist/packlets/json-file/jsonLike.js +26 -0
  28. package/dist/packlets/json-file/jsonTreeHelper.js +116 -0
  29. package/dist/packlets/validators/index.js +23 -0
  30. package/dist/packlets/validators/validators.js +179 -0
  31. package/dist/test/fixtures/file-tree/config.json +1 -0
  32. package/dist/test/fixtures/file-tree/data/items.json +1 -0
  33. package/dist/test/fixtures/file-tree/docs/api/reference.json +1 -0
  34. package/dist/test/unit/data/file/bad/bad3.json +3 -0
  35. package/dist/test/unit/data/file/bad/thing1.json +4 -0
  36. package/dist/test/unit/data/file/bad/thing2.json +3 -0
  37. package/dist/test/unit/data/file/good/thing1.json +4 -0
  38. package/dist/test/unit/data/file/good/thing2.json +3 -0
  39. package/dist/test/unit/json-compatible/helpers.js +32 -0
  40. package/dist/tsdoc-metadata.json +1 -1
  41. package/lib/packlets/json-file/index.browser.d.ts +1 -1
  42. package/lib/packlets/json-file/index.browser.js +2 -2
  43. package/package.json +11 -5
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright (c) 2023 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import * as Converters from './packlets/converters';
23
+ // eslint-disable-next-line @rushstack/packlets/mechanics
24
+ import * as FileTree from './packlets/file-tree/index.browser';
25
+ import * as JsonCompatible from './packlets/json-compatible';
26
+ // eslint-disable-next-line @rushstack/packlets/mechanics
27
+ import * as JsonFile from './packlets/json-file/index.browser';
28
+ import * as Validators from './packlets/validators';
29
+ export * from './packlets/json';
30
+ export { Converters, FileTree, JsonCompatible, JsonFile, Validators };
31
+ //# sourceMappingURL=index.browser.js.map
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (c) 2023 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import * as Converters from './packlets/converters';
23
+ import * as FileTree from './packlets/file-tree';
24
+ import * as JsonCompatible from './packlets/json-compatible';
25
+ import * as JsonFile from './packlets/json-file';
26
+ import * as Validators from './packlets/validators';
27
+ export * from './packlets/json';
28
+ export { Converters, FileTree, JsonCompatible, JsonFile, Validators };
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,187 @@
1
+ /*
2
+ * Copyright (c) 2023 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { Conversion, Converters as BaseConverters, StringConverter, fail, succeed } from '@fgv/ts-utils';
23
+ import { isJsonArray, isJsonObject } from '../json';
24
+ /**
25
+ * An converter which converts a supplied `unknown` value to a valid {@link JsonPrimitive | JsonPrimitive}.
26
+ * @public
27
+ */
28
+ export const jsonPrimitive = new Conversion.BaseConverter((from, __self, ctx) => {
29
+ if (from === null) {
30
+ return succeed(null);
31
+ }
32
+ switch (typeof from) {
33
+ case 'boolean':
34
+ case 'string':
35
+ return succeed(from);
36
+ case 'number':
37
+ if (!Number.isNaN(from)) {
38
+ return succeed(from);
39
+ }
40
+ break;
41
+ }
42
+ return fail(`"${String(from)}": invalid JSON primitive.`);
43
+ });
44
+ /**
45
+ * An copying converter which converts a supplied `unknown` value into
46
+ * a valid {@link JsonObject | JsonObject}. Fails by default if any properties or array elements
47
+ * are `undefined` - this default behavior can be overridden by supplying an appropriate
48
+ * {@link Converters.IJsonConverterContext | context} at runtime.
49
+ *
50
+ * Guaranteed to return a new object.
51
+ * @public
52
+ */
53
+ export const jsonObject = new Conversion.BaseConverter((from, __self, ctx) => {
54
+ if (!isJsonObject(from)) {
55
+ return fail('invalid JSON object.');
56
+ }
57
+ const obj = {};
58
+ const errors = [];
59
+ for (const [name, value] of Object.entries(from)) {
60
+ if (value === undefined && (ctx === null || ctx === void 0 ? void 0 : ctx.ignoreUndefinedProperties) === true) {
61
+ // optionally ignore undefined values
62
+ continue;
63
+ }
64
+ jsonValue
65
+ .convert(value, ctx)
66
+ .onSuccess((v) => {
67
+ obj[name] = v;
68
+ return succeed(v);
69
+ })
70
+ .onFailure((m) => {
71
+ errors.push(`${name}: ${m}`);
72
+ return fail(m);
73
+ });
74
+ }
75
+ if (errors.length > 0) {
76
+ return fail(`invalid JSON object:\n${errors.join('\n')}`);
77
+ }
78
+ return succeed(obj);
79
+ });
80
+ /**
81
+ * An copying converter which converts a supplied `unknown` value to
82
+ * a valid {@link JsonArray | JsonArray}. Fails by default if any properties or array elements
83
+ * are `undefined` - this default behavior can be overridden by supplying an appropriate
84
+ * {@link Converters.IJsonConverterContext | context} at runtime.
85
+ *
86
+ * Guaranteed to return a new array.
87
+ * @public
88
+ */
89
+ export const jsonArray = new Conversion.BaseConverter((from, __self, ctx) => {
90
+ if (!isJsonArray(from)) {
91
+ return fail('not an array');
92
+ }
93
+ const arr = [];
94
+ const errors = [];
95
+ for (let i = 0; i < from.length; i++) {
96
+ const value = from[i];
97
+ if (value === undefined && (ctx === null || ctx === void 0 ? void 0 : ctx.ignoreUndefinedProperties) === true) {
98
+ // convert undefined to 'null' for parity with JSON.stringify
99
+ arr.push(null);
100
+ continue;
101
+ }
102
+ jsonValue
103
+ .convert(value, ctx)
104
+ .onSuccess((v) => {
105
+ arr.push(v);
106
+ return succeed(v);
107
+ })
108
+ .onFailure((m) => {
109
+ errors.push(`${i}: ${m}`);
110
+ return fail(m);
111
+ });
112
+ }
113
+ if (errors.length > 0) {
114
+ return fail(`array contains non-json elements:\n${errors.join('\n')}`);
115
+ }
116
+ return succeed(arr);
117
+ });
118
+ /**
119
+ * An copying converter which converts a supplied `unknown` value to a
120
+ * valid {@link JsonValue | JsonValue}. Fails by default if any properties or array elements
121
+ * are `undefined` - this default behavior can be overridden by supplying an appropriate
122
+ * {@link Converters.IJsonConverterContext | context} at runtime.
123
+ * @public
124
+ */
125
+ export const jsonValue = new Conversion.BaseConverter((from, __self, ctx) => {
126
+ if (isJsonArray(from)) {
127
+ return jsonArray.convert(from, ctx);
128
+ }
129
+ else if (isJsonObject(from)) {
130
+ return jsonObject.convert(from, ctx);
131
+ }
132
+ return jsonPrimitive.convert(from, ctx);
133
+ });
134
+ /**
135
+ * A {@link Converter | Converter} which converts `unknown` to a `string`.
136
+ * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
137
+ * @public
138
+ */
139
+ export const string = new StringConverter();
140
+ /**
141
+ * A {@link Converter | Converter} which converts `unknown` to a `number`.
142
+ * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
143
+ * Mirrors the behavior of `@fgv/ts-utils`.
144
+ * @public
145
+ */
146
+ export const number = new Conversion.BaseConverter((from) => BaseConverters.number.convert(from));
147
+ /**
148
+ * A {@link Converter | Converter} which converts `unknown` to a `boolean`.
149
+ * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
150
+ * Mirrors the behavior of `@fgv/ts-utils`.
151
+ * @public
152
+ */
153
+ export const boolean = new Conversion.BaseConverter((from) => BaseConverters.boolean.convert(from));
154
+ /**
155
+ * Helper to create a converter for a literal value.
156
+ * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
157
+ * Mirrors the behavior of `@fgv/ts-utils`.
158
+ * @public
159
+ */
160
+ export function literal(value) {
161
+ return BaseConverters.literal(value);
162
+ }
163
+ /**
164
+ * Helper function to create a {@link Converter | Converter} which converts `unknown` to one of a set of
165
+ * supplied enumerated values. Anything else fails.
166
+ *
167
+ * @remarks
168
+ * This JSON variant accepts an {@link Converters.IJsonConverterContext | IJsonConverterContext} OR
169
+ * a `ReadonlyArray<T>` as its conversion context. If the context is an array, it is used to override the
170
+ * allowed values for that conversion; otherwise, the original `values` supplied at creation time are used.
171
+ *
172
+ * @param values - Array of allowed values.
173
+ * @param message - Optional custom failure message.
174
+ * @returns A new {@link Converter | Converter} returning `<T>`.
175
+ * @public
176
+ */
177
+ export function enumeratedValue(values, message) {
178
+ return new Conversion.BaseConverter((from, __self, context) => {
179
+ const effectiveValues = Array.isArray(context) ? context : values;
180
+ const index = effectiveValues.indexOf(from);
181
+ if (index >= 0) {
182
+ return succeed(effectiveValues[index]);
183
+ }
184
+ return fail(message !== null && message !== void 0 ? message : `Invalid enumerated value ${JSON.stringify(from)}`);
185
+ });
186
+ }
187
+ //# sourceMappingURL=converters.js.map
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) 2020 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ export * from './converters';
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,67 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { captureResult } from '@fgv/ts-utils';
23
+ /**
24
+ * Class representing a directory in a file tree.
25
+ * @public
26
+ */
27
+ export class DirectoryItem {
28
+ /**
29
+ * {@inheritdoc FileTree.IFileTreeDirectoryItem.name}
30
+ */
31
+ get name() {
32
+ return this._hal.getBaseName(this.absolutePath);
33
+ }
34
+ /**
35
+ * Protected constructor for derived classes.
36
+ * @param path - Relative path of the directory.
37
+ * @param hal - The {@link FileTree.IFileTreeAccessors | accessors} to use for
38
+ * file system operations.
39
+ * @public
40
+ */
41
+ constructor(path, hal) {
42
+ /**
43
+ * {@inheritdoc FileTree.IFileTreeDirectoryItem."type"}
44
+ */
45
+ this.type = 'directory';
46
+ this._hal = hal;
47
+ this.absolutePath = hal.resolveAbsolutePath(path);
48
+ }
49
+ /**
50
+ * Creates a new DirectoryItem instance.
51
+ * @param path - Relative path of the directory.
52
+ * @param hal - The {@link FileTree.IFileTreeAccessors | accessors} to use for
53
+ * file system operations.
54
+ * @returns `Success` with the new {@link FileTree.DirectoryItem | DirectoryItem} instance if successful,
55
+ * or `Failure` with an error message otherwise.
56
+ */
57
+ static create(path, hal) {
58
+ return captureResult(() => new DirectoryItem(path, hal));
59
+ }
60
+ /**
61
+ * {@inheritdoc FileTree.IFileTreeDirectoryItem.getChildren}
62
+ */
63
+ getChildren() {
64
+ return this._hal.getChildren(this.absolutePath);
65
+ }
66
+ }
67
+ //# sourceMappingURL=directoryItem.js.map
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { captureResult, succeed } from '@fgv/ts-utils';
23
+ /**
24
+ * Class representing a file in a file tree.
25
+ * @public
26
+ */
27
+ export class FileItem {
28
+ /**
29
+ * {@inheritdoc FileTree.IFileTreeFileItem.name}
30
+ */
31
+ get name() {
32
+ return this._hal.getBaseName(this.absolutePath);
33
+ }
34
+ /**
35
+ * {@inheritdoc FileTree.IFileTreeFileItem.baseName}
36
+ */
37
+ get baseName() {
38
+ return this._hal.getBaseName(this.absolutePath, this.extension);
39
+ }
40
+ /**
41
+ * {@inheritdoc FileTree.IFileTreeFileItem.extension}
42
+ */
43
+ get extension() {
44
+ return this._hal.getExtension(this.absolutePath);
45
+ }
46
+ /**
47
+ * {@inheritdoc FileTree.IFileTreeFileItem.contentType}
48
+ */
49
+ get contentType() {
50
+ return this._contentType;
51
+ }
52
+ /**
53
+ * Protected constructor for derived classes.
54
+ * @param path - Relative path of the file.
55
+ * @param hal - The {@link FileTree.IFileTreeAccessors | accessors} to use for
56
+ * file system operations.
57
+ * @public
58
+ */
59
+ constructor(path, hal) {
60
+ /**
61
+ * {@inheritdoc FileTree.IFileTreeFileItem."type"}
62
+ */
63
+ this.type = 'file';
64
+ this._hal = hal;
65
+ this.absolutePath = hal.resolveAbsolutePath(path);
66
+ this._contentType = hal.getFileContentType(this.absolutePath).orDefault();
67
+ }
68
+ /**
69
+ * Creates a new {@link FileTree.FileItem} instance.
70
+ * @param path - Relative path of the file.
71
+ * @param hal - The {@link FileTree.IFileTreeAccessors | accessors} to use for
72
+ * file system operations.
73
+ * @public
74
+ */
75
+ static create(path, hal) {
76
+ return captureResult(() => new FileItem(path, hal));
77
+ }
78
+ getContents(converter) {
79
+ return this._hal
80
+ .getFileContents(this.absolutePath)
81
+ .onSuccess((body) => captureResult(() => JSON.parse(body)).onFailure(() => succeed(body)))
82
+ .onSuccess((parsed) => {
83
+ if (converter !== undefined) {
84
+ return converter.convert(parsed);
85
+ }
86
+ return succeed(parsed);
87
+ });
88
+ }
89
+ /**
90
+ * {@inheritdoc FileTree.IFileTreeFileItem.getRawContents}
91
+ */
92
+ getRawContents() {
93
+ return this._hal.getFileContents(this.absolutePath);
94
+ }
95
+ /**
96
+ * Sets the content type of the file.
97
+ * @param contentType - The content type of the file.
98
+ */
99
+ setContentType(contentType) {
100
+ this._contentType = contentType;
101
+ }
102
+ /**
103
+ * Default function to infer the content type of a file.
104
+ * @param filePath - The path of the file.
105
+ * @returns `Success` with the content type of the file if successful, or
106
+ * `Failure` with an error message otherwise.
107
+ * @remarks This default implementation always returns `Success` with `undefined`.
108
+ * @public
109
+ */
110
+ static defaultInferContentType(__filePath, __provided) {
111
+ return succeed(undefined);
112
+ }
113
+ /**
114
+ * Default function to accept the content type of a file.
115
+ * @param filePath - The path of the file.
116
+ * @param provided - Optional supplied content type.
117
+ * @returns `Success` with the content type of the file if successful, or
118
+ * `Failure` with an error message otherwise.
119
+ * @remarks This default implementation always returns `Success` with `undefined`.
120
+ * @public
121
+ */
122
+ static defaultAcceptContentType(__filePath, provided) {
123
+ return succeed(provided);
124
+ }
125
+ }
126
+ //# sourceMappingURL=fileItem.js.map
@@ -0,0 +1,85 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { captureResult, fail, succeed } from '@fgv/ts-utils';
23
+ /**
24
+ * Represents a file tree.
25
+ * @public
26
+ */
27
+ export class FileTree {
28
+ /**
29
+ * Protected constructor for derived classes.
30
+ * @param hal - The {@link FileTree.IFileTreeAccessors | accessors} to use for
31
+ * file system operations.
32
+ * @public
33
+ */
34
+ constructor(hal) {
35
+ this.hal = hal;
36
+ }
37
+ /**
38
+ * Creates a new {@link FileTree} instance with the supplied
39
+ * accessors.
40
+ * @param hal - The {@link FileTree.IFileTreeAccessors | accessors} to use for
41
+ * file system operations.
42
+ */
43
+ static create(hal) {
44
+ return captureResult(() => new FileTree(hal));
45
+ }
46
+ /**
47
+ * Gets an item from the tree.
48
+ * @param itemPath - The path to the item.
49
+ * @returns `Success` with the item if successful,
50
+ * or `Failure` with an error message otherwise.
51
+ */
52
+ getItem(itemPath) {
53
+ const absolutePath = this.hal.resolveAbsolutePath(itemPath);
54
+ return this.hal.getItem(absolutePath);
55
+ }
56
+ /**
57
+ * Gets a file item from the tree.
58
+ * @param filePath - The path to the file.
59
+ * @returns `Success` with the {@link FileTree.IFileTreeFileItem | file item}
60
+ * if successful, or `Failure` with an error message otherwise.
61
+ */
62
+ getFile(filePath) {
63
+ return this.getItem(filePath).onSuccess((item) => {
64
+ if (item.type === 'file') {
65
+ return succeed(item);
66
+ }
67
+ return fail(`${filePath}: not a file`);
68
+ });
69
+ }
70
+ /**
71
+ * Gets a directory item from the tree.
72
+ * @param directoryPath - The path to the directory.
73
+ * @returns `Success` with the {@link FileTree.IFileTreeDirectoryItem | directory item}
74
+ * if successful, or `Failure` with an error message otherwise.
75
+ */
76
+ getDirectory(directoryPath) {
77
+ return this.getItem(directoryPath).onSuccess((item) => {
78
+ if (item.type === 'directory') {
79
+ return succeed(item);
80
+ }
81
+ return fail(`${directoryPath}: not a directory`);
82
+ });
83
+ }
84
+ }
85
+ //# sourceMappingURL=fileTree.js.map
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=fileTreeAccessors.js.map
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { FileTree } from './fileTree';
23
+ import { InMemoryTreeAccessors } from './in-memory';
24
+ export function inMemory(files, params) {
25
+ params = typeof params === 'string' ? { prefix: params } : params;
26
+ return InMemoryTreeAccessors.create(files, params).onSuccess((hal) => FileTree.create(hal));
27
+ }
28
+ //# sourceMappingURL=fileTreeHelpers.inMemory.js.map
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { captureResult } from '@fgv/ts-utils';
23
+ import { FileTree } from './fileTree';
24
+ import { FsFileTreeAccessors } from './fsTree';
25
+ export function forFilesystem(params) {
26
+ params = typeof params === 'string' ? { prefix: params } : params;
27
+ return captureResult(() => new FsFileTreeAccessors(params)).onSuccess((hal) => FileTree.create(hal));
28
+ }
29
+ //# sourceMappingURL=fileTreeHelpers.js.map