@fgv/ts-extras 5.1.0-0 → 5.1.0-10

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.
@@ -60,8 +60,41 @@ export const isoDate = new Conversion.BaseConverter((from) => {
60
60
  else if (from instanceof Date) {
61
61
  return succeed(from);
62
62
  }
63
+ else if (from instanceof DateTime) {
64
+ if (from.isValid) {
65
+ return succeed(from.toJSDate());
66
+ }
67
+ return fail(`Invalid date: ${from.invalidExplanation}`);
68
+ }
63
69
  return fail(`Cannot convert ${JSON.stringify(from)} to Date`);
64
70
  });
71
+ /**
72
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
73
+ * a `DateTime` object.
74
+ * @public
75
+ */
76
+ export const isoDateTime = new Conversion.BaseConverter((from) => {
77
+ if (typeof from === 'string') {
78
+ const dt = DateTime.fromISO(from);
79
+ if (dt.isValid) {
80
+ return succeed(dt);
81
+ }
82
+ return fail(`Invalid date: ${dt.invalidExplanation}`);
83
+ }
84
+ else if (typeof from === 'number') {
85
+ return succeed(DateTime.fromMillis(from));
86
+ }
87
+ else if (from instanceof Date) {
88
+ return succeed(DateTime.fromJSDate(from));
89
+ }
90
+ else if (from instanceof DateTime) {
91
+ if (from.isValid) {
92
+ return succeed(from);
93
+ }
94
+ return fail(`Invalid date: ${from.invalidExplanation}`);
95
+ }
96
+ return fail(`Cannot convert ${JSON.stringify(from)} to DateTime`);
97
+ });
65
98
  /**
66
99
  * A helper function to create a `Converter` which converts `unknown` to {@link Experimental.ExtendedArray | ExtendedArray<T>}.
67
100
  * @remarks
@@ -20,9 +20,11 @@
20
20
  * SOFTWARE.
21
21
  */
22
22
  import { unzipSync, unzip } from 'fflate';
23
- import { succeed, fail, captureResult, failWithDetail, Success } from '@fgv/ts-utils';
23
+ import { succeed, fail, captureResult } from '@fgv/ts-utils';
24
24
  /**
25
25
  * Implementation of `FileTree.IFileTreeFileItem` for files in a ZIP archive.
26
+ * ZIP files are read-only, so this item does not support mutation.
27
+ * Use {@link FileTree.isMutableFileItem | isMutableFileItem} to check before attempting mutations.
26
28
  * @public
27
29
  */
28
30
  export class ZipFileItem {
@@ -58,30 +60,6 @@ export class ZipFileItem {
58
60
  this.extension = accessors.getExtension(zipFilePath);
59
61
  this.baseName = accessors.getBaseName(zipFilePath, this.extension);
60
62
  }
61
- /**
62
- * Returns a boolean indicating whether this file can be saved.
63
- */
64
- getIsMutable() {
65
- return this._accessors.fileIsMutable(this.absolutePath);
66
- }
67
- /**
68
- * Sets the contents of the file as parsed JSON.
69
- * @param json - The JSON to set as the contents of the file.
70
- * @returns A Result indicating success or failure.
71
- */
72
- setContents(json) {
73
- return captureResult(() => JSON.stringify(json, null, 2)).onSuccess((contents) => this.setRawContents(contents).onSuccess(() => Success.with(json)));
74
- }
75
- /**
76
- * Sets the contents of the file as a string.
77
- * @param contents - The string to set as the contents of the file.
78
- * @returns A Result indicating success or failure.
79
- */
80
- setRawContents(contents) {
81
- return this.getIsMutable().asResult.onSuccess(() =>
82
- /* c8 ignore next - unreachable: ZIP files are always read-only */
83
- this._accessors.saveFileContents(this.absolutePath, contents));
84
- }
85
63
  /**
86
64
  * Sets the content type of the file.
87
65
  * @param contentType - The content type of the file.
@@ -142,7 +120,9 @@ export class ZipDirectoryItem {
142
120
  }
143
121
  }
144
122
  /**
145
- * File tree accessors for ZIP archives.
123
+ * Read-only file tree accessors for ZIP archives.
124
+ * ZIP archives are read-only by design — use {@link FileTree.isMutableAccessors | isMutableAccessors}
125
+ * to check before attempting mutations.
146
126
  * @public
147
127
  */
148
128
  export class ZipFileTreeAccessors {
@@ -262,23 +242,6 @@ export class ZipFileTreeAccessors {
262
242
  this._itemCache.set(absolutePath, item);
263
243
  });
264
244
  }
265
- /**
266
- * Returns a boolean indicating whether this file can be saved.
267
- * @param path - The path of the file.
268
- * @returns A `DetailedResult` indicating success or failure.
269
- */
270
- fileIsMutable(__path) {
271
- return failWithDetail('ZIP files are read-only', 'not-supported');
272
- }
273
- /**
274
- * Saves the contents of a file.
275
- * @param path - The path of the file.
276
- * @param contents - The contents of the file.
277
- * @returns A `Result` indicating success or failure.
278
- */
279
- saveFileContents(__path, __contents) {
280
- return failWithDetail('ZIP files are read-only', 'not-supported');
281
- }
282
245
  /**
283
246
  * Resolves paths to an absolute path.
284
247
  */
@@ -1,6 +1,6 @@
1
1
  import { Conversion } from '@fgv/ts-utils';
2
2
  import { Converter } from '@fgv/ts-utils';
3
- import { DetailedResult } from '@fgv/ts-utils';
3
+ import { DateTime } from 'luxon';
4
4
  import { FileTree } from '@fgv/ts-json-base';
5
5
  import { Hash as Hash_2 } from '@fgv/ts-utils';
6
6
  import { JsonValue } from '@fgv/ts-json-base';
@@ -211,7 +211,8 @@ declare namespace Converters {
211
211
  extendedArrayOf,
212
212
  rangeTypeOf,
213
213
  rangeOf,
214
- isoDate
214
+ isoDate,
215
+ isoDateTime
215
216
  }
216
217
  }
217
218
  export { Converters }
@@ -1400,6 +1401,13 @@ declare function isKeyStoreFile(json: unknown): boolean;
1400
1401
  */
1401
1402
  declare const isoDate: Converter<Date, unknown>;
1402
1403
 
1404
+ /**
1405
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
1406
+ * a `DateTime` object.
1407
+ * @public
1408
+ */
1409
+ declare const isoDateTime: Converter<DateTime, unknown>;
1410
+
1403
1411
  /**
1404
1412
  * Represents a variable reference extracted from a Mustache template.
1405
1413
  * @public
@@ -2338,6 +2346,8 @@ declare class ZipDirectoryItem<TCT extends string = string> implements FileTree.
2338
2346
 
2339
2347
  /**
2340
2348
  * Implementation of `FileTree.IFileTreeFileItem` for files in a ZIP archive.
2349
+ * ZIP files are read-only, so this item does not support mutation.
2350
+ * Use {@link FileTree.isMutableFileItem | isMutableFileItem} to check before attempting mutations.
2341
2351
  * @public
2342
2352
  */
2343
2353
  declare class ZipFileItem<TCT extends string = string> implements FileTree.IFileTreeFileItem<TCT> {
@@ -2388,22 +2398,6 @@ declare class ZipFileItem<TCT extends string = string> implements FileTree.IFile
2388
2398
  * @param accessors - The ZIP file tree accessors.
2389
2399
  */
2390
2400
  constructor(zipFilePath: string, contents: string, accessors: ZipFileTreeAccessors<TCT>);
2391
- /**
2392
- * Returns a boolean indicating whether this file can be saved.
2393
- */
2394
- getIsMutable(): DetailedResult<boolean, FileTree.SaveDetail>;
2395
- /**
2396
- * Sets the contents of the file as parsed JSON.
2397
- * @param json - The JSON to set as the contents of the file.
2398
- * @returns A Result indicating success or failure.
2399
- */
2400
- setContents(json: JsonValue): Result<JsonValue>;
2401
- /**
2402
- * Sets the contents of the file as a string.
2403
- * @param contents - The string to set as the contents of the file.
2404
- * @returns A Result indicating success or failure.
2405
- */
2406
- setRawContents(contents: string): Result<string>;
2407
2401
  /**
2408
2402
  * Sets the content type of the file.
2409
2403
  * @param contentType - The content type of the file.
@@ -2434,10 +2428,12 @@ declare namespace ZipFileTree {
2434
2428
  export { ZipFileTree }
2435
2429
 
2436
2430
  /**
2437
- * File tree accessors for ZIP archives.
2431
+ * Read-only file tree accessors for ZIP archives.
2432
+ * ZIP archives are read-only by design — use {@link FileTree.isMutableAccessors | isMutableAccessors}
2433
+ * to check before attempting mutations.
2438
2434
  * @public
2439
2435
  */
2440
- declare class ZipFileTreeAccessors<TCT extends string = string> implements FileTree.IMutableFileTreeAccessors<TCT> {
2436
+ declare class ZipFileTreeAccessors<TCT extends string = string> implements FileTree.IFileTreeAccessors<TCT> {
2441
2437
  /**
2442
2438
  * The unzipped file data.
2443
2439
  */
@@ -2509,19 +2505,6 @@ declare class ZipFileTreeAccessors<TCT extends string = string> implements FileT
2509
2505
  * Builds the cache of all items in the ZIP archive.
2510
2506
  */
2511
2507
  private _buildItemCache;
2512
- /**
2513
- * Returns a boolean indicating whether this file can be saved.
2514
- * @param path - The path of the file.
2515
- * @returns A `DetailedResult` indicating success or failure.
2516
- */
2517
- fileIsMutable(__path: string): DetailedResult<boolean, FileTree.SaveDetail>;
2518
- /**
2519
- * Saves the contents of a file.
2520
- * @param path - The path of the file.
2521
- * @param contents - The contents of the file.
2522
- * @returns A `Result` indicating success or failure.
2523
- */
2524
- saveFileContents(__path: string, __contents: string): Result<string>;
2525
2508
  /**
2526
2509
  * Resolves paths to an absolute path.
2527
2510
  */
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.57.6"
8
+ "packageVersion": "7.57.7"
9
9
  }
10
10
  ]
11
11
  }
@@ -1,4 +1,5 @@
1
1
  import { Conversion, Converter, Result } from '@fgv/ts-utils';
2
+ import { DateTime } from 'luxon';
2
3
  import { ExtendedArray, RangeOf, RangeOfProperties } from '../experimental';
3
4
  /**
4
5
  * Helper function to create a `StringConverter` which converts
@@ -17,6 +18,12 @@ export declare function templateString(defaultContext?: unknown): Conversion.Str
17
18
  * @public
18
19
  */
19
20
  export declare const isoDate: Converter<Date, unknown>;
21
+ /**
22
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
23
+ * a `DateTime` object.
24
+ * @public
25
+ */
26
+ export declare const isoDateTime: Converter<DateTime, unknown>;
20
27
  /**
21
28
  * A helper function to create a `Converter` which converts `unknown` to {@link Experimental.ExtendedArray | ExtendedArray<T>}.
22
29
  * @remarks
@@ -24,7 +24,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
24
  return (mod && mod.__esModule) ? mod : { "default": mod };
25
25
  };
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.isoDate = void 0;
27
+ exports.isoDateTime = exports.isoDate = void 0;
28
28
  exports.templateString = templateString;
29
29
  exports.extendedArrayOf = extendedArrayOf;
30
30
  exports.rangeTypeOf = rangeTypeOf;
@@ -70,8 +70,41 @@ exports.isoDate = new ts_utils_1.Conversion.BaseConverter((from) => {
70
70
  else if (from instanceof Date) {
71
71
  return (0, ts_utils_1.succeed)(from);
72
72
  }
73
+ else if (from instanceof luxon_1.DateTime) {
74
+ if (from.isValid) {
75
+ return (0, ts_utils_1.succeed)(from.toJSDate());
76
+ }
77
+ return (0, ts_utils_1.fail)(`Invalid date: ${from.invalidExplanation}`);
78
+ }
73
79
  return (0, ts_utils_1.fail)(`Cannot convert ${JSON.stringify(from)} to Date`);
74
80
  });
81
+ /**
82
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
83
+ * a `DateTime` object.
84
+ * @public
85
+ */
86
+ exports.isoDateTime = new ts_utils_1.Conversion.BaseConverter((from) => {
87
+ if (typeof from === 'string') {
88
+ const dt = luxon_1.DateTime.fromISO(from);
89
+ if (dt.isValid) {
90
+ return (0, ts_utils_1.succeed)(dt);
91
+ }
92
+ return (0, ts_utils_1.fail)(`Invalid date: ${dt.invalidExplanation}`);
93
+ }
94
+ else if (typeof from === 'number') {
95
+ return (0, ts_utils_1.succeed)(luxon_1.DateTime.fromMillis(from));
96
+ }
97
+ else if (from instanceof Date) {
98
+ return (0, ts_utils_1.succeed)(luxon_1.DateTime.fromJSDate(from));
99
+ }
100
+ else if (from instanceof luxon_1.DateTime) {
101
+ if (from.isValid) {
102
+ return (0, ts_utils_1.succeed)(from);
103
+ }
104
+ return (0, ts_utils_1.fail)(`Invalid date: ${from.invalidExplanation}`);
105
+ }
106
+ return (0, ts_utils_1.fail)(`Cannot convert ${JSON.stringify(from)} to DateTime`);
107
+ });
75
108
  /**
76
109
  * A helper function to create a `Converter` which converts `unknown` to {@link Experimental.ExtendedArray | ExtendedArray<T>}.
77
110
  * @remarks
@@ -1,7 +1,9 @@
1
- import { Result, Converter, Validator, DetailedResult } from '@fgv/ts-utils';
1
+ import { Result, Converter, Validator } from '@fgv/ts-utils';
2
2
  import { FileTree, JsonValue } from '@fgv/ts-json-base';
3
3
  /**
4
4
  * Implementation of `FileTree.IFileTreeFileItem` for files in a ZIP archive.
5
+ * ZIP files are read-only, so this item does not support mutation.
6
+ * Use {@link FileTree.isMutableFileItem | isMutableFileItem} to check before attempting mutations.
5
7
  * @public
6
8
  */
7
9
  export declare class ZipFileItem<TCT extends string = string> implements FileTree.IFileTreeFileItem<TCT> {
@@ -52,22 +54,6 @@ export declare class ZipFileItem<TCT extends string = string> implements FileTre
52
54
  * @param accessors - The ZIP file tree accessors.
53
55
  */
54
56
  constructor(zipFilePath: string, contents: string, accessors: ZipFileTreeAccessors<TCT>);
55
- /**
56
- * Returns a boolean indicating whether this file can be saved.
57
- */
58
- getIsMutable(): DetailedResult<boolean, FileTree.SaveDetail>;
59
- /**
60
- * Sets the contents of the file as parsed JSON.
61
- * @param json - The JSON to set as the contents of the file.
62
- * @returns A Result indicating success or failure.
63
- */
64
- setContents(json: JsonValue): Result<JsonValue>;
65
- /**
66
- * Sets the contents of the file as a string.
67
- * @param contents - The string to set as the contents of the file.
68
- * @returns A Result indicating success or failure.
69
- */
70
- setRawContents(contents: string): Result<string>;
71
57
  /**
72
58
  * Sets the content type of the file.
73
59
  * @param contentType - The content type of the file.
@@ -116,10 +102,12 @@ export declare class ZipDirectoryItem<TCT extends string = string> implements Fi
116
102
  getChildren(): Result<ReadonlyArray<FileTree.FileTreeItem<TCT>>>;
117
103
  }
118
104
  /**
119
- * File tree accessors for ZIP archives.
105
+ * Read-only file tree accessors for ZIP archives.
106
+ * ZIP archives are read-only by design — use {@link FileTree.isMutableAccessors | isMutableAccessors}
107
+ * to check before attempting mutations.
120
108
  * @public
121
109
  */
122
- export declare class ZipFileTreeAccessors<TCT extends string = string> implements FileTree.IMutableFileTreeAccessors<TCT> {
110
+ export declare class ZipFileTreeAccessors<TCT extends string = string> implements FileTree.IFileTreeAccessors<TCT> {
123
111
  /**
124
112
  * The unzipped file data.
125
113
  */
@@ -191,19 +179,6 @@ export declare class ZipFileTreeAccessors<TCT extends string = string> implement
191
179
  * Builds the cache of all items in the ZIP archive.
192
180
  */
193
181
  private _buildItemCache;
194
- /**
195
- * Returns a boolean indicating whether this file can be saved.
196
- * @param path - The path of the file.
197
- * @returns A `DetailedResult` indicating success or failure.
198
- */
199
- fileIsMutable(__path: string): DetailedResult<boolean, FileTree.SaveDetail>;
200
- /**
201
- * Saves the contents of a file.
202
- * @param path - The path of the file.
203
- * @param contents - The contents of the file.
204
- * @returns A `Result` indicating success or failure.
205
- */
206
- saveFileContents(__path: string, __contents: string): Result<string>;
207
182
  /**
208
183
  * Resolves paths to an absolute path.
209
184
  */
@@ -26,6 +26,8 @@ const fflate_1 = require("fflate");
26
26
  const ts_utils_1 = require("@fgv/ts-utils");
27
27
  /**
28
28
  * Implementation of `FileTree.IFileTreeFileItem` for files in a ZIP archive.
29
+ * ZIP files are read-only, so this item does not support mutation.
30
+ * Use {@link FileTree.isMutableFileItem | isMutableFileItem} to check before attempting mutations.
29
31
  * @public
30
32
  */
31
33
  class ZipFileItem {
@@ -61,30 +63,6 @@ class ZipFileItem {
61
63
  this.extension = accessors.getExtension(zipFilePath);
62
64
  this.baseName = accessors.getBaseName(zipFilePath, this.extension);
63
65
  }
64
- /**
65
- * Returns a boolean indicating whether this file can be saved.
66
- */
67
- getIsMutable() {
68
- return this._accessors.fileIsMutable(this.absolutePath);
69
- }
70
- /**
71
- * Sets the contents of the file as parsed JSON.
72
- * @param json - The JSON to set as the contents of the file.
73
- * @returns A Result indicating success or failure.
74
- */
75
- setContents(json) {
76
- return (0, ts_utils_1.captureResult)(() => JSON.stringify(json, null, 2)).onSuccess((contents) => this.setRawContents(contents).onSuccess(() => ts_utils_1.Success.with(json)));
77
- }
78
- /**
79
- * Sets the contents of the file as a string.
80
- * @param contents - The string to set as the contents of the file.
81
- * @returns A Result indicating success or failure.
82
- */
83
- setRawContents(contents) {
84
- return this.getIsMutable().asResult.onSuccess(() =>
85
- /* c8 ignore next - unreachable: ZIP files are always read-only */
86
- this._accessors.saveFileContents(this.absolutePath, contents));
87
- }
88
66
  /**
89
67
  * Sets the content type of the file.
90
68
  * @param contentType - The content type of the file.
@@ -147,7 +125,9 @@ class ZipDirectoryItem {
147
125
  }
148
126
  exports.ZipDirectoryItem = ZipDirectoryItem;
149
127
  /**
150
- * File tree accessors for ZIP archives.
128
+ * Read-only file tree accessors for ZIP archives.
129
+ * ZIP archives are read-only by design — use {@link FileTree.isMutableAccessors | isMutableAccessors}
130
+ * to check before attempting mutations.
151
131
  * @public
152
132
  */
153
133
  class ZipFileTreeAccessors {
@@ -267,23 +247,6 @@ class ZipFileTreeAccessors {
267
247
  this._itemCache.set(absolutePath, item);
268
248
  });
269
249
  }
270
- /**
271
- * Returns a boolean indicating whether this file can be saved.
272
- * @param path - The path of the file.
273
- * @returns A `DetailedResult` indicating success or failure.
274
- */
275
- fileIsMutable(__path) {
276
- return (0, ts_utils_1.failWithDetail)('ZIP files are read-only', 'not-supported');
277
- }
278
- /**
279
- * Saves the contents of a file.
280
- * @param path - The path of the file.
281
- * @param contents - The contents of the file.
282
- * @returns A `Result` indicating success or failure.
283
- */
284
- saveFileContents(__path, __contents) {
285
- return (0, ts_utils_1.failWithDetail)('ZIP files are read-only', 'not-supported');
286
- }
287
250
  /**
288
251
  * Resolves paths to an absolute path.
289
252
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-extras",
3
- "version": "5.1.0-0",
3
+ "version": "5.1.0-10",
4
4
  "description": "Assorted Typescript Utilities",
5
5
  "main": "lib/index.js",
6
6
  "types": "dist/ts-extras.d.ts",
@@ -77,8 +77,8 @@
77
77
  "typescript": "5.9.3",
78
78
  "eslint-plugin-n": "^17.23.1",
79
79
  "jest-snapshot": "~29.7.0",
80
- "@rushstack/heft": "1.2.6",
81
- "@rushstack/heft-node-rig": "2.11.26",
80
+ "@rushstack/heft": "1.2.7",
81
+ "@rushstack/heft-node-rig": "2.11.27",
82
82
  "@rushstack/eslint-config": "4.6.4",
83
83
  "@types/heft-jest": "1.0.6",
84
84
  "@rushstack/heft-jest-plugin": "1.2.6",
@@ -86,9 +86,10 @@
86
86
  "@types/js-yaml": "~4.0.9",
87
87
  "typedoc": "~0.28.16",
88
88
  "typedoc-plugin-markdown": "~4.9.0",
89
- "@fgv/ts-utils-jest": "5.1.0-0",
90
- "@fgv/heft-dual-rig": "0.1.0",
91
- "@fgv/ts-utils": "5.1.0-0"
89
+ "@fgv/heft-dual-rig": "5.1.0-10",
90
+ "@fgv/ts-utils-jest": "5.1.0-10",
91
+ "@fgv/typedoc-compact-theme": "5.1.0-10",
92
+ "@fgv/ts-utils": "5.1.0-10"
92
93
  },
93
94
  "dependencies": {
94
95
  "luxon": "^3.7.2",
@@ -96,10 +97,10 @@
96
97
  "papaparse": "^5.4.1",
97
98
  "fflate": "~0.8.2",
98
99
  "js-yaml": "~4.1.1",
99
- "@fgv/ts-json-base": "5.1.0-0"
100
+ "@fgv/ts-json-base": "5.1.0-10"
100
101
  },
101
102
  "peerDependencies": {
102
- "@fgv/ts-utils": "5.1.0-0"
103
+ "@fgv/ts-utils": "5.1.0-10"
103
104
  },
104
105
  "repository": {
105
106
  "type": "git",