@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
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.54.0"
8
+ "packageVersion": "7.57.6"
9
9
  }
10
10
  ]
11
11
  }
@@ -16,7 +16,7 @@ export declare const jsonPrimitive: Converter<JsonPrimitive, IJsonConverterConte
16
16
  * An copying converter which converts a supplied `unknown` value into
17
17
  * a valid {@link JsonObject | JsonObject}. Fails by default if any properties or array elements
18
18
  * are `undefined` - this default behavior can be overridden by supplying an appropriate
19
- * {@link Converters.IJsonConverterContext | context} at runtime.
19
+ * `IJsonConverterContext` at runtime.
20
20
  *
21
21
  * Guaranteed to return a new object.
22
22
  * @public
@@ -26,7 +26,7 @@ export declare const jsonObject: Converter<JsonObject, IJsonConverterContext>;
26
26
  * An copying converter which converts a supplied `unknown` value to
27
27
  * a valid {@link JsonArray | JsonArray}. Fails by default if any properties or array elements
28
28
  * are `undefined` - this default behavior can be overridden by supplying an appropriate
29
- * {@link Converters.IJsonConverterContext | context} at runtime.
29
+ * `IJsonConverterContext` at runtime.
30
30
  *
31
31
  * Guaranteed to return a new array.
32
32
  * @public
@@ -36,50 +36,57 @@ export declare const jsonArray: Converter<JsonArray, IJsonConverterContext>;
36
36
  * An copying converter which converts a supplied `unknown` value to a
37
37
  * valid {@link JsonValue | JsonValue}. Fails by default if any properties or array elements
38
38
  * are `undefined` - this default behavior can be overridden by supplying an appropriate
39
- * {@link Converters.IJsonConverterContext | context} at runtime.
39
+ * `IJsonConverterContext` at runtime.
40
40
  * @public
41
41
  */
42
42
  export declare const jsonValue: Converter<JsonValue, IJsonConverterContext>;
43
43
  /**
44
- * A {@link Converter | Converter} which converts `unknown` to a `string`.
45
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
44
+ * A `StringConverter` which converts `unknown` to a `string`.
45
+ * Accepts `IJsonConverterContext` but ignores it.
46
46
  * @public
47
47
  */
48
48
  export declare const string: StringConverter<string, IJsonConverterContext>;
49
49
  /**
50
- * A {@link Converter | Converter} which converts `unknown` to a `number`.
51
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
50
+ * A `Converter` which converts `unknown` to a `number`.
51
+ * Accepts `IJsonConverterContext` but ignores it.
52
52
  * Mirrors the behavior of `@fgv/ts-utils`.
53
53
  * @public
54
54
  */
55
55
  export declare const number: Converter<number, IJsonConverterContext>;
56
56
  /**
57
- * A {@link Converter | Converter} which converts `unknown` to a `boolean`.
58
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
57
+ * A `Converter` which converts `unknown` to a `boolean`.
58
+ * Accepts `IJsonConverterContext` but ignores it.
59
59
  * Mirrors the behavior of `@fgv/ts-utils`.
60
60
  * @public
61
61
  */
62
62
  export declare const boolean: Converter<boolean, IJsonConverterContext>;
63
63
  /**
64
64
  * Helper to create a converter for a literal value.
65
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
65
+ * Accepts `IJsonConverterContext` but ignores it.
66
66
  * Mirrors the behavior of `@fgv/ts-utils`.
67
67
  * @public
68
68
  */
69
69
  export declare function literal<T>(value: T): Converter<T, IJsonConverterContext>;
70
70
  /**
71
- * Helper function to create a {@link Converter | Converter} which converts `unknown` to one of a set of
71
+ * Helper function to create a `Converter` which converts `unknown` to one of a set of
72
72
  * supplied enumerated values. Anything else fails.
73
73
  *
74
74
  * @remarks
75
- * This JSON variant accepts an {@link Converters.IJsonConverterContext | IJsonConverterContext} OR
75
+ * This JSON variant accepts an `IJsonConverterContext` OR
76
76
  * a `ReadonlyArray<T>` as its conversion context. If the context is an array, it is used to override the
77
77
  * allowed values for that conversion; otherwise, the original `values` supplied at creation time are used.
78
78
  *
79
79
  * @param values - Array of allowed values.
80
80
  * @param message - Optional custom failure message.
81
- * @returns A new {@link Converter | Converter} returning `<T>`.
81
+ * @returns A new `Converter` returning `<T>`.
82
82
  * @public
83
83
  */
84
84
  export declare function enumeratedValue<T>(values: ReadonlyArray<T>, message?: string): Converter<T, IJsonConverterContext | ReadonlyArray<T>>;
85
+ /**
86
+ * Creates a converter that parses JSON string content and then applies the supplied converter.
87
+ * @param converter - Converter to apply to the parsed JSON
88
+ * @returns Converter that parses JSON then validates
89
+ * @public
90
+ */
91
+ export declare function jsonConverter<T>(converter: Converter<T>): Converter<T>;
85
92
  //# sourceMappingURL=converters.d.ts.map
@@ -24,6 +24,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.boolean = exports.number = exports.string = exports.jsonValue = exports.jsonArray = exports.jsonObject = exports.jsonPrimitive = void 0;
25
25
  exports.literal = literal;
26
26
  exports.enumeratedValue = enumeratedValue;
27
+ exports.jsonConverter = jsonConverter;
27
28
  const ts_utils_1 = require("@fgv/ts-utils");
28
29
  const json_1 = require("../json");
29
30
  /**
@@ -50,7 +51,7 @@ exports.jsonPrimitive = new ts_utils_1.Conversion.BaseConverter((from, __self, c
50
51
  * An copying converter which converts a supplied `unknown` value into
51
52
  * a valid {@link JsonObject | JsonObject}. Fails by default if any properties or array elements
52
53
  * are `undefined` - this default behavior can be overridden by supplying an appropriate
53
- * {@link Converters.IJsonConverterContext | context} at runtime.
54
+ * `IJsonConverterContext` at runtime.
54
55
  *
55
56
  * Guaranteed to return a new object.
56
57
  * @public
@@ -86,7 +87,7 @@ exports.jsonObject = new ts_utils_1.Conversion.BaseConverter((from, __self, ctx)
86
87
  * An copying converter which converts a supplied `unknown` value to
87
88
  * a valid {@link JsonArray | JsonArray}. Fails by default if any properties or array elements
88
89
  * are `undefined` - this default behavior can be overridden by supplying an appropriate
89
- * {@link Converters.IJsonConverterContext | context} at runtime.
90
+ * `IJsonConverterContext` at runtime.
90
91
  *
91
92
  * Guaranteed to return a new array.
92
93
  * @public
@@ -124,7 +125,7 @@ exports.jsonArray = new ts_utils_1.Conversion.BaseConverter((from, __self, ctx)
124
125
  * An copying converter which converts a supplied `unknown` value to a
125
126
  * valid {@link JsonValue | JsonValue}. Fails by default if any properties or array elements
126
127
  * are `undefined` - this default behavior can be overridden by supplying an appropriate
127
- * {@link Converters.IJsonConverterContext | context} at runtime.
128
+ * `IJsonConverterContext` at runtime.
128
129
  * @public
129
130
  */
130
131
  exports.jsonValue = new ts_utils_1.Conversion.BaseConverter((from, __self, ctx) => {
@@ -137,28 +138,28 @@ exports.jsonValue = new ts_utils_1.Conversion.BaseConverter((from, __self, ctx)
137
138
  return exports.jsonPrimitive.convert(from, ctx);
138
139
  });
139
140
  /**
140
- * A {@link Converter | Converter} which converts `unknown` to a `string`.
141
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
141
+ * A `StringConverter` which converts `unknown` to a `string`.
142
+ * Accepts `IJsonConverterContext` but ignores it.
142
143
  * @public
143
144
  */
144
145
  exports.string = new ts_utils_1.StringConverter();
145
146
  /**
146
- * A {@link Converter | Converter} which converts `unknown` to a `number`.
147
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
147
+ * A `Converter` which converts `unknown` to a `number`.
148
+ * Accepts `IJsonConverterContext` but ignores it.
148
149
  * Mirrors the behavior of `@fgv/ts-utils`.
149
150
  * @public
150
151
  */
151
152
  exports.number = new ts_utils_1.Conversion.BaseConverter((from) => ts_utils_1.Converters.number.convert(from));
152
153
  /**
153
- * A {@link Converter | Converter} which converts `unknown` to a `boolean`.
154
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
154
+ * A `Converter` which converts `unknown` to a `boolean`.
155
+ * Accepts `IJsonConverterContext` but ignores it.
155
156
  * Mirrors the behavior of `@fgv/ts-utils`.
156
157
  * @public
157
158
  */
158
159
  exports.boolean = new ts_utils_1.Conversion.BaseConverter((from) => ts_utils_1.Converters.boolean.convert(from));
159
160
  /**
160
161
  * Helper to create a converter for a literal value.
161
- * Accepts {@link Converters.IJsonConverterContext | IJsonConverterContext} but ignores it.
162
+ * Accepts `IJsonConverterContext` but ignores it.
162
163
  * Mirrors the behavior of `@fgv/ts-utils`.
163
164
  * @public
164
165
  */
@@ -166,17 +167,17 @@ function literal(value) {
166
167
  return ts_utils_1.Converters.literal(value);
167
168
  }
168
169
  /**
169
- * Helper function to create a {@link Converter | Converter} which converts `unknown` to one of a set of
170
+ * Helper function to create a `Converter` which converts `unknown` to one of a set of
170
171
  * supplied enumerated values. Anything else fails.
171
172
  *
172
173
  * @remarks
173
- * This JSON variant accepts an {@link Converters.IJsonConverterContext | IJsonConverterContext} OR
174
+ * This JSON variant accepts an `IJsonConverterContext` OR
174
175
  * a `ReadonlyArray<T>` as its conversion context. If the context is an array, it is used to override the
175
176
  * allowed values for that conversion; otherwise, the original `values` supplied at creation time are used.
176
177
  *
177
178
  * @param values - Array of allowed values.
178
179
  * @param message - Optional custom failure message.
179
- * @returns A new {@link Converter | Converter} returning `<T>`.
180
+ * @returns A new `Converter` returning `<T>`.
180
181
  * @public
181
182
  */
182
183
  function enumeratedValue(values, message) {
@@ -189,4 +190,26 @@ function enumeratedValue(values, message) {
189
190
  return (0, ts_utils_1.fail)(message !== null && message !== void 0 ? message : `Invalid enumerated value ${JSON.stringify(from)}`);
190
191
  });
191
192
  }
193
+ /**
194
+ * Creates a converter that parses JSON string content and then applies the supplied converter.
195
+ * @param converter - Converter to apply to the parsed JSON
196
+ * @returns Converter that parses JSON then validates
197
+ * @public
198
+ */
199
+ function jsonConverter(converter) {
200
+ return new ts_utils_1.Conversion.BaseConverter((from) => {
201
+ if (typeof from !== 'string') {
202
+ return (0, ts_utils_1.fail)('Input must be a string');
203
+ }
204
+ const parseResult = (0, ts_utils_1.captureResult)(() => JSON.parse(from));
205
+ if (parseResult.isFailure()) {
206
+ return (0, ts_utils_1.fail)(`Failed to parse JSON: ${parseResult.message}`);
207
+ }
208
+ const parsed = parseResult.value;
209
+ if (typeof parsed !== 'object' || parsed === null) {
210
+ return (0, ts_utils_1.fail)('Failed to parse JSON: JSON content must be an object');
211
+ }
212
+ return converter.convert(parsed);
213
+ });
214
+ }
192
215
  //# sourceMappingURL=converters.js.map
@@ -1,20 +1,20 @@
1
1
  import { Result } from '@fgv/ts-utils';
2
- import { FileTreeItem, IFileTreeAccessors, IFileTreeDirectoryItem } from './fileTreeAccessors';
2
+ import { FileTreeItem, IFileTreeAccessors, IFileTreeDirectoryItem, IFileTreeFileItem } from './fileTreeAccessors';
3
3
  /**
4
4
  * Class representing a directory in a file tree.
5
5
  * @public
6
6
  */
7
7
  export declare class DirectoryItem<TCT extends string = string> implements IFileTreeDirectoryItem<TCT> {
8
8
  /**
9
- * {@inheritdoc FileTree.IFileTreeDirectoryItem."type"}
9
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem."type"}
10
10
  */
11
11
  readonly type: 'directory';
12
12
  /**
13
- * {@inheritdoc FileTree.IFileTreeDirectoryItem.absolutePath}
13
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.absolutePath}
14
14
  */
15
15
  readonly absolutePath: string;
16
16
  /**
17
- * {@inheritdoc FileTree.IFileTreeDirectoryItem.name}
17
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.name}
18
18
  */
19
19
  get name(): string;
20
20
  /**
@@ -40,8 +40,16 @@ export declare class DirectoryItem<TCT extends string = string> implements IFile
40
40
  */
41
41
  static create<TCT extends string = string>(path: string, hal: IFileTreeAccessors<TCT>): Result<DirectoryItem<TCT>>;
42
42
  /**
43
- * {@inheritdoc FileTree.IFileTreeDirectoryItem.getChildren}
43
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.getChildren}
44
44
  */
45
45
  getChildren(): Result<ReadonlyArray<FileTreeItem<TCT>>>;
46
+ /**
47
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.createChildFile}
48
+ */
49
+ createChildFile(name: string, contents: string): Result<IFileTreeFileItem<TCT>>;
50
+ /**
51
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.createChildDirectory}
52
+ */
53
+ createChildDirectory(name: string): Result<IFileTreeDirectoryItem<TCT>>;
46
54
  }
47
55
  //# sourceMappingURL=directoryItem.d.ts.map
@@ -23,13 +23,14 @@
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.DirectoryItem = void 0;
25
25
  const ts_utils_1 = require("@fgv/ts-utils");
26
+ const fileTreeAccessors_1 = require("./fileTreeAccessors");
26
27
  /**
27
28
  * Class representing a directory in a file tree.
28
29
  * @public
29
30
  */
30
31
  class DirectoryItem {
31
32
  /**
32
- * {@inheritdoc FileTree.IFileTreeDirectoryItem.name}
33
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.name}
33
34
  */
34
35
  get name() {
35
36
  return this._hal.getBaseName(this.absolutePath);
@@ -43,7 +44,7 @@ class DirectoryItem {
43
44
  */
44
45
  constructor(path, hal) {
45
46
  /**
46
- * {@inheritdoc FileTree.IFileTreeDirectoryItem."type"}
47
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem."type"}
47
48
  */
48
49
  this.type = 'directory';
49
50
  this._hal = hal;
@@ -61,11 +62,41 @@ class DirectoryItem {
61
62
  return (0, ts_utils_1.captureResult)(() => new DirectoryItem(path, hal));
62
63
  }
63
64
  /**
64
- * {@inheritdoc FileTree.IFileTreeDirectoryItem.getChildren}
65
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.getChildren}
65
66
  */
66
67
  getChildren() {
67
68
  return this._hal.getChildren(this.absolutePath);
68
69
  }
70
+ /**
71
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.createChildFile}
72
+ */
73
+ createChildFile(name, contents) {
74
+ if (!(0, fileTreeAccessors_1.isMutableAccessors)(this._hal)) {
75
+ return (0, ts_utils_1.fail)(`${this.absolutePath}: mutation not supported`);
76
+ }
77
+ const filePath = this._hal.joinPaths(this.absolutePath, name);
78
+ return this._hal.saveFileContents(filePath, contents).onSuccess(() => this._hal.getItem(filePath).onSuccess((item) => {
79
+ /* c8 ignore next 3 - defensive: verifies accessor returned correct item type after save */
80
+ if (item.type !== 'file') {
81
+ return (0, ts_utils_1.fail)(`${filePath}: expected file but got ${item.type}`);
82
+ }
83
+ return (0, ts_utils_1.succeed)(item);
84
+ }));
85
+ }
86
+ /**
87
+ * {@inheritDoc FileTree.IFileTreeDirectoryItem.createChildDirectory}
88
+ */
89
+ createChildDirectory(name) {
90
+ if (!(0, fileTreeAccessors_1.isMutableAccessors)(this._hal)) {
91
+ return (0, ts_utils_1.fail)(`${this.absolutePath}: mutation not supported`);
92
+ }
93
+ /* c8 ignore next 3 - defensive: createDirectory should always exist if isMutableAccessors is true */
94
+ if (this._hal.createDirectory === undefined) {
95
+ return (0, ts_utils_1.fail)(`${this.absolutePath}: directory creation not supported`);
96
+ }
97
+ const dirPath = this._hal.joinPaths(this.absolutePath, name);
98
+ return this._hal.createDirectory(dirPath).onSuccess(() => DirectoryItem.create(dirPath, this._hal));
99
+ }
69
100
  }
70
101
  exports.DirectoryItem = DirectoryItem;
71
102
  //# sourceMappingURL=directoryItem.js.map
@@ -1,34 +1,34 @@
1
- import { Result } from '@fgv/ts-utils';
1
+ import { DetailedResult, Result } from '@fgv/ts-utils';
2
2
  import { Converter, Validator } from '@fgv/ts-utils';
3
3
  import { JsonValue } from '../json';
4
- import { IFileTreeAccessors, IFileTreeFileItem } from './fileTreeAccessors';
4
+ import { IFileTreeAccessors, IFileTreeFileItem, SaveDetail } from './fileTreeAccessors';
5
5
  /**
6
6
  * Class representing a file in a file tree.
7
7
  * @public
8
8
  */
9
9
  export declare class FileItem<TCT extends string = string> implements IFileTreeFileItem<TCT> {
10
10
  /**
11
- * {@inheritdoc FileTree.IFileTreeFileItem."type"}
11
+ * {@inheritDoc FileTree.IFileTreeFileItem."type"}
12
12
  */
13
13
  readonly type: 'file';
14
14
  /**
15
- * {@inheritdoc FileTree.IFileTreeFileItem.absolutePath}
15
+ * {@inheritDoc FileTree.IFileTreeFileItem.absolutePath}
16
16
  */
17
17
  readonly absolutePath: string;
18
18
  /**
19
- * {@inheritdoc FileTree.IFileTreeFileItem.name}
19
+ * {@inheritDoc FileTree.IFileTreeFileItem.name}
20
20
  */
21
21
  get name(): string;
22
22
  /**
23
- * {@inheritdoc FileTree.IFileTreeFileItem.baseName}
23
+ * {@inheritDoc FileTree.IFileTreeFileItem.baseName}
24
24
  */
25
25
  get baseName(): string;
26
26
  /**
27
- * {@inheritdoc FileTree.IFileTreeFileItem.extension}
27
+ * {@inheritDoc FileTree.IFileTreeFileItem.extension}
28
28
  */
29
29
  get extension(): string;
30
30
  /**
31
- * {@inheritdoc FileTree.IFileTreeFileItem.contentType}
31
+ * {@inheritDoc FileTree.IFileTreeFileItem.contentType}
32
32
  */
33
33
  get contentType(): TCT | undefined;
34
34
  /**
@@ -58,15 +58,19 @@ export declare class FileItem<TCT extends string = string> implements IFileTreeF
58
58
  */
59
59
  static create<TCT extends string = string>(path: string, hal: IFileTreeAccessors<TCT>): Result<FileItem<TCT>>;
60
60
  /**
61
- * {@inheritdoc FileTree.IFileTreeFileItem.(getContents:1)}
61
+ * {@inheritDoc FileTree.IFileTreeFileItem.getIsMutable}
62
+ */
63
+ getIsMutable(): DetailedResult<boolean, SaveDetail>;
64
+ /**
65
+ * {@inheritDoc FileTree.IFileTreeFileItem.getContents}
62
66
  */
63
67
  getContents(): Result<JsonValue>;
64
68
  /**
65
- * {@inheritdoc FileTree.IFileTreeFileItem.(getContents:2)}
69
+ * {@inheritDoc FileTree.IFileTreeFileItem.getContents}
66
70
  */
67
71
  getContents<T>(converter: Validator<T> | Converter<T>): Result<T>;
68
72
  /**
69
- * {@inheritdoc FileTree.IFileTreeFileItem.getRawContents}
73
+ * {@inheritDoc FileTree.IFileTreeFileItem.getRawContents}
70
74
  */
71
75
  getRawContents(): Result<string>;
72
76
  /**
@@ -74,15 +78,24 @@ export declare class FileItem<TCT extends string = string> implements IFileTreeF
74
78
  * @param contentType - The content type of the file.
75
79
  */
76
80
  setContentType(contentType: TCT | undefined): void;
81
+ /**
82
+ * {@inheritDoc FileTree.IFileTreeFileItem.setContents}
83
+ */
84
+ setContents(json: JsonValue): Result<JsonValue>;
85
+ /**
86
+ * {@inheritDoc FileTree.IFileTreeFileItem.setRawContents}
87
+ */
88
+ setRawContents(contents: string): Result<string>;
77
89
  /**
78
90
  * Default function to infer the content type of a file.
79
91
  * @param filePath - The path of the file.
92
+ * @param provided - Optional supplied content type.
80
93
  * @returns `Success` with the content type of the file if successful, or
81
94
  * `Failure` with an error message otherwise.
82
95
  * @remarks This default implementation always returns `Success` with `undefined`.
83
96
  * @public
84
97
  */
85
- static defaultInferContentType<TCT extends string = string>(__filePath: string, __provided?: string): Result<TCT | undefined>;
98
+ static defaultInferContentType<TCT extends string = string>(filePath: string, provided?: string): Result<TCT | undefined>;
86
99
  /**
87
100
  * Default function to accept the content type of a file.
88
101
  * @param filePath - The path of the file.
@@ -92,6 +105,6 @@ export declare class FileItem<TCT extends string = string> implements IFileTreeF
92
105
  * @remarks This default implementation always returns `Success` with `undefined`.
93
106
  * @public
94
107
  */
95
- static defaultAcceptContentType<TCT extends string = string>(__filePath: string, provided?: TCT): Result<TCT | undefined>;
108
+ static defaultAcceptContentType<TCT extends string = string>(filePath: string, provided?: TCT): Result<TCT | undefined>;
96
109
  }
97
110
  //# sourceMappingURL=fileItem.d.ts.map
@@ -23,31 +23,32 @@
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.FileItem = void 0;
25
25
  const ts_utils_1 = require("@fgv/ts-utils");
26
+ const fileTreeAccessors_1 = require("./fileTreeAccessors");
26
27
  /**
27
28
  * Class representing a file in a file tree.
28
29
  * @public
29
30
  */
30
31
  class FileItem {
31
32
  /**
32
- * {@inheritdoc FileTree.IFileTreeFileItem.name}
33
+ * {@inheritDoc FileTree.IFileTreeFileItem.name}
33
34
  */
34
35
  get name() {
35
36
  return this._hal.getBaseName(this.absolutePath);
36
37
  }
37
38
  /**
38
- * {@inheritdoc FileTree.IFileTreeFileItem.baseName}
39
+ * {@inheritDoc FileTree.IFileTreeFileItem.baseName}
39
40
  */
40
41
  get baseName() {
41
42
  return this._hal.getBaseName(this.absolutePath, this.extension);
42
43
  }
43
44
  /**
44
- * {@inheritdoc FileTree.IFileTreeFileItem.extension}
45
+ * {@inheritDoc FileTree.IFileTreeFileItem.extension}
45
46
  */
46
47
  get extension() {
47
48
  return this._hal.getExtension(this.absolutePath);
48
49
  }
49
50
  /**
50
- * {@inheritdoc FileTree.IFileTreeFileItem.contentType}
51
+ * {@inheritDoc FileTree.IFileTreeFileItem.contentType}
51
52
  */
52
53
  get contentType() {
53
54
  return this._contentType;
@@ -61,7 +62,7 @@ class FileItem {
61
62
  */
62
63
  constructor(path, hal) {
63
64
  /**
64
- * {@inheritdoc FileTree.IFileTreeFileItem."type"}
65
+ * {@inheritDoc FileTree.IFileTreeFileItem."type"}
65
66
  */
66
67
  this.type = 'file';
67
68
  this._hal = hal;
@@ -78,6 +79,16 @@ class FileItem {
78
79
  static create(path, hal) {
79
80
  return (0, ts_utils_1.captureResult)(() => new FileItem(path, hal));
80
81
  }
82
+ /**
83
+ * {@inheritDoc FileTree.IFileTreeFileItem.getIsMutable}
84
+ */
85
+ getIsMutable() {
86
+ if ((0, fileTreeAccessors_1.isMutableAccessors)(this._hal)) {
87
+ return this._hal.fileIsMutable(this.absolutePath);
88
+ }
89
+ /* c8 ignore next 2 - defensive: all current accessor implementations support mutation interface */
90
+ return (0, ts_utils_1.failWithDetail)(`${this.absolutePath}: mutation not supported`, 'not-supported');
91
+ }
81
92
  getContents(converter) {
82
93
  return this._hal
83
94
  .getFileContents(this.absolutePath)
@@ -90,7 +101,7 @@ class FileItem {
90
101
  });
91
102
  }
92
103
  /**
93
- * {@inheritdoc FileTree.IFileTreeFileItem.getRawContents}
104
+ * {@inheritDoc FileTree.IFileTreeFileItem.getRawContents}
94
105
  */
95
106
  getRawContents() {
96
107
  return this._hal.getFileContents(this.absolutePath);
@@ -102,15 +113,32 @@ class FileItem {
102
113
  setContentType(contentType) {
103
114
  this._contentType = contentType;
104
115
  }
116
+ /**
117
+ * {@inheritDoc FileTree.IFileTreeFileItem.setContents}
118
+ */
119
+ setContents(json) {
120
+ return (0, ts_utils_1.captureResult)(() => JSON.stringify(json, null, 2)).onSuccess((contents) => this.setRawContents(contents).onSuccess(() => ts_utils_1.Success.with(json)));
121
+ }
122
+ /**
123
+ * {@inheritDoc FileTree.IFileTreeFileItem.setRawContents}
124
+ */
125
+ setRawContents(contents) {
126
+ if ((0, fileTreeAccessors_1.isMutableAccessors)(this._hal)) {
127
+ return this._hal.saveFileContents(this.absolutePath, contents);
128
+ }
129
+ /* c8 ignore next 2 - defensive: all current accessor implementations support mutation interface */
130
+ return (0, ts_utils_1.fail)(`${this.absolutePath}: mutation not supported`);
131
+ }
105
132
  /**
106
133
  * Default function to infer the content type of a file.
107
134
  * @param filePath - The path of the file.
135
+ * @param provided - Optional supplied content type.
108
136
  * @returns `Success` with the content type of the file if successful, or
109
137
  * `Failure` with an error message otherwise.
110
138
  * @remarks This default implementation always returns `Success` with `undefined`.
111
139
  * @public
112
140
  */
113
- static defaultInferContentType(__filePath, __provided) {
141
+ static defaultInferContentType(filePath, provided) {
114
142
  return (0, ts_utils_1.succeed)(undefined);
115
143
  }
116
144
  /**
@@ -122,7 +150,7 @@ class FileItem {
122
150
  * @remarks This default implementation always returns `Success` with `undefined`.
123
151
  * @public
124
152
  */
125
- static defaultAcceptContentType(__filePath, provided) {
153
+ static defaultAcceptContentType(filePath, provided) {
126
154
  return (0, ts_utils_1.succeed)(provided);
127
155
  }
128
156
  }