@brianbuie/node-kit 0.14.4 → 0.15.1

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/README.md CHANGED
@@ -100,15 +100,15 @@ export class Dir {
100
100
  #inputPath;
101
101
  #resolved?: string;
102
102
  isTemp;
103
- constructor(inputPath: string, options: DirOptions = {})
103
+ constructor(inputPath = Format.date("ymd"), options: DirOptions = {})
104
104
  get pathUnsafe()
105
105
  get path()
106
106
  get name()
107
- dir(subPath: string, options: DirOptions = { temp: this.isTemp })
108
- tempDir(subPath: string)
107
+ dir(subPath = Format.date("ymd"), options: DirOptions = { temp: this.isTemp })
108
+ tempDir(subPath?: string)
109
109
  sanitize(filename: string)
110
110
  filepath(base: string)
111
- file(base: string)
111
+ file(base = Format.date("ymd-hms"))
112
112
  get contents(): (Dir | File)[]
113
113
  get dirs()
114
114
  get files()
@@ -122,7 +122,7 @@ export class Dir {
122
122
  }
123
123
  ```
124
124
 
125
- See also: [DirOptions](#type-diroptions), [File](#class-file), [temp](#variable-temp)
125
+ See also: [DirOptions](#type-diroptions), [File](#class-file), [Format](#class-format), [temp](#variable-temp)
126
126
 
127
127
  <details>
128
128
 
@@ -131,9 +131,9 @@ See also: [DirOptions](#type-diroptions), [File](#class-file), [temp](#variable-
131
131
  ### Constructor
132
132
 
133
133
  ```ts
134
- constructor(inputPath: string, options: DirOptions = {})
134
+ constructor(inputPath = Format.date("ymd"), options: DirOptions = {})
135
135
  ```
136
- See also: [DirOptions](#type-diroptions)
136
+ See also: [DirOptions](#type-diroptions), [Format](#class-format)
137
137
 
138
138
  Argument Details
139
139
 
@@ -153,9 +153,9 @@ clear()
153
153
  Create a new Dir inside the current Dir
154
154
 
155
155
  ```ts
156
- dir(subPath: string, options: DirOptions = { temp: this.isTemp })
156
+ dir(subPath = Format.date("ymd"), options: DirOptions = { temp: this.isTemp })
157
157
  ```
158
- See also: [DirOptions](#type-diroptions), [temp](#variable-temp)
158
+ See also: [DirOptions](#type-diroptions), [Format](#class-format), [temp](#variable-temp)
159
159
 
160
160
  Argument Details
161
161
 
@@ -175,11 +175,12 @@ const child = folder.dir('path/to/dir');
175
175
 
176
176
  ### Method file
177
177
 
178
- Create a new file in this directory
178
+ Create a new file in this directory. Filename defaults to `YYYYMMDD-HHMMSS` if not provided
179
179
 
180
180
  ```ts
181
- file(base: string)
181
+ file(base = Format.date("ymd-hms"))
182
182
  ```
183
+ See also: [Format](#class-format)
183
184
 
184
185
  ### Method filepath
185
186
 
@@ -197,7 +198,7 @@ Example
197
198
  ```ts
198
199
  const folder = new Dir('example');
199
200
  const filepath = folder.resolve('file.json');
200
- // 'example/file.json'
201
+ // '/path/to/example/file.json'
201
202
  ```
202
203
 
203
204
  ### Method tempDir
@@ -205,7 +206,7 @@ const filepath = folder.resolve('file.json');
205
206
  Creates a new temp directory inside current Dir
206
207
 
207
208
  ```ts
208
- tempDir(subPath: string)
209
+ tempDir(subPath?: string)
209
210
  ```
210
211
 
211
212
  Argument Details
@@ -727,9 +728,11 @@ export class TypeWriter {
727
728
  moduleName;
728
729
  input = qt.jsonInputForTargetLanguage("typescript");
729
730
  outDir;
731
+ outFile;
730
732
  qtSettings;
731
733
  constructor(moduleName: string, settings: {
732
734
  outDir?: string;
735
+ outFile?: string;
733
736
  } & Partial<qt.Options> = {})
734
737
  async addMember(name: string, _samples: any[])
735
738
  async toString()
package/dist/index.d.mts CHANGED
@@ -148,7 +148,7 @@ type DirOptions = {
148
148
  /**
149
149
  * Reference to a specific directory with methods to create and list files.
150
150
  * @param inputPath
151
- * The path of the directory, created on file system the first time `.path` is read or any methods are used
151
+ * The path of the directory, created on file system the first time `.path` is read or any methods are used. Default: `./YYYYMMDD`
152
152
  * @param options
153
153
  * include `{ temp: true }` to enable the `.clear()` method
154
154
  */
@@ -158,7 +158,7 @@ declare class Dir {
158
158
  /**
159
159
  * @param path can be relative to workspace or absolute
160
160
  */
161
- constructor(inputPath: string, options?: DirOptions);
161
+ constructor(inputPath?: string, options?: DirOptions);
162
162
  /**
163
163
  * The path of the directory, which might not exist yet.
164
164
  */
@@ -187,25 +187,25 @@ declare class Dir {
187
187
  * const child = folder.dir('path/to/dir');
188
188
  * // child.path = '/path/to/cwd/example/path/to/dir'
189
189
  */
190
- dir(subPath: string, options?: DirOptions): this;
190
+ dir(subPath?: string, options?: DirOptions): this;
191
191
  /**
192
192
  * Creates a new temp directory inside current Dir
193
193
  * @param subPath joined with parent Dir's path to make new TempDir
194
194
  */
195
- tempDir(subPath: string): this;
195
+ tempDir(subPath?: string): this;
196
196
  sanitize(filename: string): string;
197
197
  /**
198
198
  * @param base - The file base (name and extension)
199
199
  * @example
200
200
  * const folder = new Dir('example');
201
201
  * const filepath = folder.resolve('file.json');
202
- * // 'example/file.json'
202
+ * // '/path/to/example/file.json'
203
203
  */
204
204
  filepath(base: string): string;
205
205
  /**
206
- * Create a new file in this directory
206
+ * Create a new file in this directory. Filename defaults to `YYYYMMDD-HHMMSS` if not provided
207
207
  */
208
- file(base: string): File;
208
+ file(base?: string): File;
209
209
  /**
210
210
  * All files and subdirectories in in this directory, returned as Dir and File instances
211
211
  */
@@ -448,6 +448,7 @@ declare class TypeWriter {
448
448
  moduleName: string;
449
449
  input: qt.JSONInput<string>;
450
450
  outDir: string;
451
+ outFile: string;
451
452
  qtSettings: {
452
453
  lang: string;
453
454
  rendererOptions: {
@@ -890,6 +891,7 @@ declare class TypeWriter {
890
891
  };
891
892
  constructor(moduleName: string, settings?: {
892
893
  outDir?: string;
894
+ outFile?: string;
893
895
  } & Partial<qt.Options>);
894
896
  addMember(name: string, _samples: any[]): Promise<void>;
895
897
  toString(): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/File.ts","../src/Dir.ts","../src/Cache.ts","../src/Fetcher.ts","../src/Format.ts","../src/Log.ts","../src/snapshot.ts","../src/timeout.ts","../src/TypeWriter.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/File.ts","../src/Dir.ts","../src/Cache.ts","../src/Fetcher.ts","../src/Format.ts","../src/Log.ts","../src/snapshot.ts","../src/timeout.ts","../src/TypeWriter.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -7,8 +7,8 @@ import mime from "mime-types";
7
7
  import { parseStream, writeToStream } from "fast-csv";
8
8
  import { isObjectLike, merge } from "lodash-es";
9
9
  import { add, format, formatISO, isAfter } from "date-fns";
10
- import extractDomain from "extract-domain";
11
10
  import formatDuration from "format-duration";
11
+ import extractDomain from "extract-domain";
12
12
  import { inspect } from "node:util";
13
13
  import chalk from "chalk";
14
14
  import * as qt from "quicktype-core";
@@ -287,12 +287,82 @@ var FileTypeCsv = class extends FileType {
287
287
  }
288
288
  };
289
289
 
290
+ //#endregion
291
+ //#region src/Format.ts
292
+ /**
293
+ * Helpers for formatting dates, times, and numbers as strings
294
+ */
295
+ var Format = class {
296
+ /**
297
+ * date-fns format() with some shortcuts
298
+ * @param formatStr the format to use
299
+ * @param date the date to format, default `new Date()`
300
+ * @example
301
+ * Format.date('iso') // '2026-04-08T13:56:45Z'
302
+ * Format.date('ymd') // '20260408'
303
+ * Format.date('ymd-hm') // '20260408-1356'
304
+ * Format.date('ymd-hms') // '20260408-135645'
305
+ * Format.date('h:m:s') // '13:56:45'
306
+ * @see more format options https://date-fns.org/v4.1.0/docs/format
307
+ */
308
+ static date(formatStr = "iso", d = /* @__PURE__ */ new Date()) {
309
+ if (formatStr === "iso") return formatISO(d);
310
+ if (formatStr === "ymd") return format(d, "yyyyMMdd");
311
+ if (formatStr === "ymd-hm") return format(d, "yyyyMMdd-HHmm");
312
+ if (formatStr === "ymd-hms") return format(d, "yyyyMMdd-HHmmss");
313
+ if (formatStr === "h:m:s") return format(d, "HH:mm:ss");
314
+ return format(d, formatStr);
315
+ }
316
+ /**
317
+ * Round a number to a specific set of places
318
+ */
319
+ static round(n, places = 0) {
320
+ return new Intl.NumberFormat("en-US", { maximumFractionDigits: places }).format(n);
321
+ }
322
+ static plural(amount, singular, multiple) {
323
+ return amount === 1 ? `${amount} ${singular}` : `${amount} ${multiple || singular + "s"}`;
324
+ }
325
+ /**
326
+ * Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")
327
+ * @param ms milliseconds
328
+ * @param style 'digital' to output as 'HH:MM:SS'
329
+ * @see details on 'digital' format https://github.com/ungoldman/format-duration
330
+ * @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608
331
+ */
332
+ static ms(ms, style) {
333
+ if (style === "digital") return formatDuration(ms, { leading: true });
334
+ if (ms < 1e3) return `${this.round(ms)}ms`;
335
+ const s = ms / 1e3;
336
+ if (s < 60) return `${this.round(s, 2)}s`;
337
+ const m = Math.floor(s / 60);
338
+ if (m < 60) return `${m}m ${Math.floor(s) % 60}s`;
339
+ const h = Math.floor(m / 60);
340
+ if (h < 24) return `${h}h ${m % 60}m`;
341
+ return `${Math.floor(h / 24)}d ${h % 24}h`;
342
+ }
343
+ static bytes(b) {
344
+ const labels = [
345
+ "b",
346
+ "KB",
347
+ "MB",
348
+ "GB",
349
+ "TB"
350
+ ];
351
+ let factor = 0;
352
+ while (b >= 1024 && labels[factor + 1]) {
353
+ b = b / 1024;
354
+ factor++;
355
+ }
356
+ return `${this.round(b, 2)} ${labels[factor]}`;
357
+ }
358
+ };
359
+
290
360
  //#endregion
291
361
  //#region src/Dir.ts
292
362
  /**
293
363
  * Reference to a specific directory with methods to create and list files.
294
364
  * @param inputPath
295
- * The path of the directory, created on file system the first time `.path` is read or any methods are used
365
+ * The path of the directory, created on file system the first time `.path` is read or any methods are used. Default: `./YYYYMMDD`
296
366
  * @param options
297
367
  * include `{ temp: true }` to enable the `.clear()` method
298
368
  */
@@ -303,7 +373,7 @@ var Dir = class Dir {
303
373
  /**
304
374
  * @param path can be relative to workspace or absolute
305
375
  */
306
- constructor(inputPath, options = {}) {
376
+ constructor(inputPath = Format.date("ymd"), options = {}) {
307
377
  this.#inputPath = inputPath;
308
378
  this.isTemp = Boolean(options.temp);
309
379
  }
@@ -348,7 +418,7 @@ var Dir = class Dir {
348
418
  * const child = folder.dir('path/to/dir');
349
419
  * // child.path = '/path/to/cwd/example/path/to/dir'
350
420
  */
351
- dir(subPath, options = { temp: this.isTemp }) {
421
+ dir(subPath = Format.date("ymd"), options = { temp: this.isTemp }) {
352
422
  return new this.constructor(path.join(this.path, subPath), options);
353
423
  }
354
424
  /**
@@ -366,15 +436,15 @@ var Dir = class Dir {
366
436
  * @example
367
437
  * const folder = new Dir('example');
368
438
  * const filepath = folder.resolve('file.json');
369
- * // 'example/file.json'
439
+ * // '/path/to/example/file.json'
370
440
  */
371
441
  filepath(base) {
372
442
  return path.resolve(this.path, this.sanitize(base));
373
443
  }
374
444
  /**
375
- * Create a new file in this directory
445
+ * Create a new file in this directory. Filename defaults to `YYYYMMDD-HHMMSS` if not provided
376
446
  */
377
- file(base) {
447
+ file(base = Format.date("ymd-hms")) {
378
448
  return new File(this.filepath(base));
379
449
  }
380
450
  /**
@@ -604,76 +674,6 @@ var Fetcher = class {
604
674
  }
605
675
  };
606
676
 
607
- //#endregion
608
- //#region src/Format.ts
609
- /**
610
- * Helpers for formatting dates, times, and numbers as strings
611
- */
612
- var Format = class {
613
- /**
614
- * date-fns format() with some shortcuts
615
- * @param formatStr the format to use
616
- * @param date the date to format, default `new Date()`
617
- * @example
618
- * Format.date('iso') // '2026-04-08T13:56:45Z'
619
- * Format.date('ymd') // '20260408'
620
- * Format.date('ymd-hm') // '20260408-1356'
621
- * Format.date('ymd-hms') // '20260408-135645'
622
- * Format.date('h:m:s') // '13:56:45'
623
- * @see more format options https://date-fns.org/v4.1.0/docs/format
624
- */
625
- static date(formatStr = "iso", d = /* @__PURE__ */ new Date()) {
626
- if (formatStr === "iso") return formatISO(d);
627
- if (formatStr === "ymd") return format(d, "yyyyMMdd");
628
- if (formatStr === "ymd-hm") return format(d, "yyyyMMdd-HHmm");
629
- if (formatStr === "ymd-hms") return format(d, "yyyyMMdd-HHmmss");
630
- if (formatStr === "h:m:s") return format(d, "HH:mm:ss");
631
- return format(d, formatStr);
632
- }
633
- /**
634
- * Round a number to a specific set of places
635
- */
636
- static round(n, places = 0) {
637
- return new Intl.NumberFormat("en-US", { maximumFractionDigits: places }).format(n);
638
- }
639
- static plural(amount, singular, multiple) {
640
- return amount === 1 ? `${amount} ${singular}` : `${amount} ${multiple || singular + "s"}`;
641
- }
642
- /**
643
- * Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")
644
- * @param ms milliseconds
645
- * @param style 'digital' to output as 'HH:MM:SS'
646
- * @see details on 'digital' format https://github.com/ungoldman/format-duration
647
- * @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608
648
- */
649
- static ms(ms, style) {
650
- if (style === "digital") return formatDuration(ms, { leading: true });
651
- if (ms < 1e3) return `${this.round(ms)}ms`;
652
- const s = ms / 1e3;
653
- if (s < 60) return `${this.round(s, 2)}s`;
654
- const m = Math.floor(s / 60);
655
- if (m < 60) return `${m}m ${Math.floor(s) % 60}s`;
656
- const h = Math.floor(m / 60);
657
- if (h < 24) return `${h}h ${m % 60}m`;
658
- return `${Math.floor(h / 24)}d ${h % 24}h`;
659
- }
660
- static bytes(b) {
661
- const labels = [
662
- "b",
663
- "KB",
664
- "MB",
665
- "GB",
666
- "TB"
667
- ];
668
- let factor = 0;
669
- while (b >= 1024 && labels[factor + 1]) {
670
- b = b / 1024;
671
- factor++;
672
- }
673
- return `${this.round(b, 2)} ${labels[factor]}`;
674
- }
675
- };
676
-
677
677
  //#endregion
678
678
  //#region src/Log.ts
679
679
  var Log = class Log {
@@ -807,11 +807,13 @@ var TypeWriter = class {
807
807
  moduleName;
808
808
  input = qt.jsonInputForTargetLanguage("typescript");
809
809
  outDir;
810
+ outFile;
810
811
  qtSettings;
811
812
  constructor(moduleName, settings = {}) {
812
813
  this.moduleName = moduleName;
813
- const { outDir, ...qtSettings } = settings;
814
+ const { outDir, outFile, ...qtSettings } = settings;
814
815
  this.outDir = outDir || "./types";
816
+ this.outFile = outFile || `${this.moduleName}.types.ts`;
815
817
  this.qtSettings = merge({
816
818
  lang: "typescript",
817
819
  rendererOptions: {
@@ -840,7 +842,7 @@ var TypeWriter = class {
840
842
  async toFile() {
841
843
  const result = await this.toString();
842
844
  fs.mkdirSync(this.outDir, { recursive: true });
843
- fs.writeFileSync(`${this.outDir}/${this.moduleName}.d.ts`, result);
845
+ fs.writeFileSync(`${this.outDir}/${this.outFile}`, result);
844
846
  }
845
847
  };
846
848
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["output: Record<string, any>","obj: Record<string, any>","#resolve","parsed: Row[]","#parseVal","#inputPath","#resolved","params: [string, string][]","timeout","#toGcloud","#toConsole","#log","entry: Entry"],"sources":["../src/snapshot.ts","../src/File.ts","../src/Dir.ts","../src/Cache.ts","../src/Fetcher.ts","../src/Format.ts","../src/Log.ts","../src/timeout.ts","../src/TypeWriter.ts"],"sourcesContent":["import { isObjectLike } from 'lodash-es';\n\n/**\n * Allows special objects (Error, Headers, Set) to be included in JSON.stringify output.\n * Functions are removed\n */\nexport function snapshot(i: unknown, max = 50, depth = 0): any {\n if (Array.isArray(i)) {\n if (depth === max) return [];\n return i.map(c => snapshot(c, max, depth + 1));\n }\n if (typeof i === 'function') return undefined;\n if (!isObjectLike(i)) return i;\n\n if (depth === max) return {};\n let output: Record<string, any> = {};\n // @ts-ignore If it has an 'entries' function, use that for looping (eg. Set, Map, Headers)\n if (typeof i.entries === 'function') {\n // @ts-ignore\n for (let [k, v] of i.entries()) {\n output[k] = snapshot(v, max, depth + 1);\n }\n return output;\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Enumerability_and_ownership_of_properties\n\n // Get Enumerable, inherited properties\n const obj: Record<string, any> = i!;\n for (let key in obj) {\n output[key] = snapshot(obj[key], max, depth + 1);\n }\n\n // Get Non-enumberable, own properties\n Object.getOwnPropertyNames(obj).forEach(key => {\n output[key] = snapshot(obj[key], max, depth + 1);\n });\n\n return output;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { finished } from 'node:stream/promises';\nimport mime from 'mime-types';\nimport { writeToStream, parseStream } from 'fast-csv';\nimport { snapshot } from './snapshot.ts';\n\n/**\n * Represents a file on the file system. If the file doesn't exist, it is created the first time it is written to.\n */\nexport class File {\n path;\n root;\n dir;\n base;\n name;\n ext;\n type;\n\n constructor(filepath: string) {\n this.path = this.#resolve(filepath);\n const { root, dir, base, ext, name } = path.parse(this.path);\n this.root = root;\n this.dir = dir;\n this.base = base;\n this.name = name;\n this.ext = ext;\n this.type = mime.lookup(ext) || undefined;\n }\n\n #resolve(filepath: string) {\n if (filepath[0] === '~') {\n if (process.env.HOME) {\n return path.join(process.env.HOME, filepath.slice(1));\n } else {\n console.warn('process.env.HOME does not exist! \"~\" will not resolve to home directory');\n }\n }\n return path.resolve(filepath);\n }\n\n get exists() {\n return fs.existsSync(this.path);\n }\n\n get stats(): Partial<fs.Stats> {\n return this.exists ? fs.statSync(this.path) : {};\n }\n\n /**\n * Deletes the file if it exists\n */\n delete() {\n fs.rmSync(this.path, { force: true });\n }\n\n /**\n * @returns the contents of the file as a string, or undefined if the file doesn't exist\n */\n read() {\n return this.exists ? fs.readFileSync(this.path, 'utf8') : undefined;\n }\n\n /**\n * @returns lines as strings, removes trailing '\\n'\n */\n lines() {\n const contents = (this.read() || '').split('\\n');\n return contents.at(-1)?.length ? contents : contents.slice(0, contents.length - 1);\n }\n\n get readStream() {\n return this.exists ? fs.createReadStream(this.path) : Readable.from([]);\n }\n\n get writeStream() {\n fs.mkdirSync(this.dir, { recursive: true });\n return fs.createWriteStream(this.path);\n }\n\n write(contents: string | ReadableStream) {\n fs.mkdirSync(this.dir, { recursive: true });\n if (typeof contents === 'string') return fs.writeFileSync(this.path, contents);\n if (contents instanceof ReadableStream) return finished(Readable.from(contents).pipe(this.writeStream));\n throw new Error(`Invalid content type: ${typeof contents}`);\n }\n\n /**\n * creates file if it doesn't exist, appends string or array of strings as new lines.\n * File always ends with '\\n', so contents don't need to be read before appending\n */\n append(lines: string | string[]) {\n if (!this.exists) this.write('');\n const contents = Array.isArray(lines) ? lines.join('\\n') : lines;\n fs.appendFileSync(this.path, contents + '\\n');\n }\n\n /**\n * @returns FileTypeJson adaptor for current File, adds '.json' extension if not present.\n * @example\n * const file = new File('./data').json({ key: 'val' }); // FileTypeJson<{ key: string; }>\n * console.log(file.path) // '/path/to/cwd/data.json'\n * file.write({ something: 'else' }) // ❌ property 'something' doesn't exist on type { key: string; }\n * @example\n * const file = new File('./data').json<object>({ key: 'val' }); // FileTypeJson<object>\n * file.write({ something: 'else' }) // ✅ data is typed as object\n */\n json<T>(contents?: T) {\n return new FileTypeJson<T>(this.path, contents);\n }\n\n /**\n * @example\n * const file = new File.json('data.json', { key: 'val' }); // FileTypeJson<{ key: string; }>\n */\n static get json() {\n return FileTypeJson;\n }\n\n /**\n * @returns FileTypeNdjson adaptor for current File, adds '.ndjson' extension if not present.\n */\n ndjson<T extends object>(lines?: T | T[]) {\n return new FileTypeNdjson<T>(this.path, lines);\n }\n /**\n * @example\n * const file = new File.ndjson('log', { key: 'val' }); // FileTypeNdjson<{ key: string; }>\n * console.log(file.path) // /path/to/cwd/log.ndjson\n */\n static get ndjson() {\n return FileTypeNdjson;\n }\n\n /**\n * @returns FileTypeCsv adaptor for current File, adds '.csv' extension if not present.\n * @example\n * const file = await new File('a').csv([{ col: 'val' }, { col: 'val2' }]); // FileTypeCsv<{ col: string; }>\n * await file.write([ { col2: 'val2' } ]); // ❌ 'col2' doesn't exist on type { col: string; }\n * await file.write({ col: 'val' }); // ✅ Writes one row\n * await file.write([{ col: 'val2' }, { col: 'val3' }]); // ✅ Writes multiple rows\n */\n async csv<T extends object>(rows?: T[], keys?: (keyof T)[]) {\n const csvFile = new FileTypeCsv<T>(this.path);\n if (rows) await csvFile.write(rows, keys);\n return csvFile;\n }\n\n static get csv() {\n return FileTypeCsv;\n }\n}\n\n/**\n * A generic file adaptor, extended by specific file type implementations\n */\nexport class FileType {\n file;\n\n constructor(filepath: string, contents?: string) {\n this.file = new File(filepath);\n if (contents) this.file.write(contents);\n }\n\n get path() {\n return this.file.path;\n }\n\n get root() {\n return this.file.root;\n }\n\n get dir() {\n return this.file.dir;\n }\n\n get base() {\n return this.file.base;\n }\n\n get name() {\n return this.file.name;\n }\n\n get ext() {\n return this.file.ext;\n }\n\n get type() {\n return this.file.type;\n }\n\n get exists() {\n return this.file.exists;\n }\n\n get stats() {\n return this.file.stats;\n }\n\n delete() {\n this.file.delete();\n }\n\n get readStream() {\n return this.file.readStream;\n }\n\n get writeStream() {\n return this.file.writeStream;\n }\n}\n\n/**\n * A .json file that maintains data type when reading/writing.\n * > ⚠️ This is mildly unsafe, important/foreign json files should be validated at runtime!\n * @example\n * const file = new FileTypeJson('./data', { key: 'val' }); // FileTypeJson<{ key: string; }>\n * console.log(file.path) // '/path/to/cwd/data.json'\n * file.write({ something: 'else' }) // ❌ property 'something' doesn't exist on type { key: string; }\n * @example\n * const file = new FileTypeJson<object>('./data', { key: 'val' }); // FileTypeJson<object>\n * file.write({ something: 'else' }) // ✅ data is typed as object\n */\nexport class FileTypeJson<T> extends FileType {\n constructor(filepath: string, contents?: T) {\n super(filepath.endsWith('.json') ? filepath : filepath + '.json');\n if (contents) this.write(contents);\n }\n\n read() {\n const contents = this.file.read();\n return contents ? (JSON.parse(contents) as T) : undefined;\n }\n\n write(contents: T) {\n this.file.write(JSON.stringify(snapshot(contents), null, 2));\n }\n}\n\n/**\n * New-line delimited json file (.ndjson)\n * @see https://jsonltools.com/ndjson-format-specification\n */\nexport class FileTypeNdjson<T extends object> extends FileType {\n constructor(filepath: string, lines?: T | T[]) {\n super(filepath.endsWith('.ndjson') ? filepath : filepath + '.ndjson');\n if (lines) this.append(lines);\n }\n\n append(lines: T | T[]) {\n this.file.append(\n Array.isArray(lines) ? lines.map(l => JSON.stringify(snapshot(l))) : JSON.stringify(snapshot(lines)),\n );\n }\n\n lines() {\n return this.file.lines().map(l => JSON.parse(l) as T);\n }\n}\n\ntype Key<T extends object> = keyof T;\n\n/**\n * Comma separated values (.csv).\n * Input rows as objects, keys are used as column headers\n */\nexport class FileTypeCsv<Row extends object> extends FileType {\n constructor(filepath: string) {\n super(filepath.endsWith('.csv') ? filepath : filepath + '.csv');\n }\n\n async write(rows: Row[], keys?: Key<Row>[]) {\n const headerSet = new Set<Key<Row>>();\n if (keys) {\n for (const key of keys) headerSet.add(key);\n } else {\n for (const row of rows) {\n for (const key in row) headerSet.add(key);\n }\n }\n const headers = Array.from(headerSet);\n const outRows = rows.map(row => headers.map(key => row[key]));\n return finished(writeToStream(this.file.writeStream, [headers, ...outRows]));\n }\n\n #parseVal(val: string) {\n if (val.toLowerCase() === 'false') return false;\n if (val.toLowerCase() === 'true') return true;\n if (val.length === 0) return null;\n if (/^[\\.0-9]+$/.test(val)) return Number(val);\n return val;\n }\n\n async read() {\n return new Promise<Row[]>((resolve, reject) => {\n const parsed: Row[] = [];\n parseStream(this.file.readStream, { headers: true })\n .on('data', (raw: Record<Key<Row>, string>) => {\n parsed.push(\n Object.entries(raw).reduce(\n (all, [key, val]) => ({\n ...all,\n [key]: this.#parseVal(val as string),\n }),\n {} as Row,\n ),\n );\n })\n .on('error', e => reject(e))\n .on('end', () => resolve(parsed));\n });\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport sanitizeFilename from 'sanitize-filename';\nimport { File } from './File.ts';\n\nexport type DirOptions = {\n temp?: boolean;\n};\n\n/**\n * Reference to a specific directory with methods to create and list files.\n * @param inputPath\n * The path of the directory, created on file system the first time `.path` is read or any methods are used\n * @param options\n * include `{ temp: true }` to enable the `.clear()` method\n */\nexport class Dir {\n #inputPath;\n #resolved?: string;\n isTemp;\n\n /**\n * @param path can be relative to workspace or absolute\n */\n constructor(inputPath: string, options: DirOptions = {}) {\n this.#inputPath = inputPath;\n this.isTemp = Boolean(options.temp);\n }\n\n /**\n * The path of the directory, which might not exist yet.\n */\n get pathUnsafe() {\n if (this.#resolved) return this.#resolved;\n if (this.#inputPath[0] === '~') {\n if (process.env.HOME) {\n return path.join(process.env.HOME, this.#inputPath.slice(1));\n } else {\n console.warn('process.env.HOME does not exist! \"~\" will not resolve to home directory');\n }\n }\n return path.resolve(this.#inputPath);\n }\n\n /**\n * The path of this Dir instance. Created on file system the first time this property is read/used.\n * Safe to use the directory immediately, without calling mkdir separately.\n */\n get path() {\n // avoids calling mkdir every time path is read\n if (!this.#resolved) {\n this.#resolved = this.pathUnsafe;\n fs.mkdirSync(this.#resolved, { recursive: true });\n }\n return this.#resolved;\n }\n\n /**\n * The last segment in the path. Doesn't read this.path, to avoid creating directory on file system before it's needed.\n * @example\n * const example = new Dir('/path/to/folder');\n * console.log(example.name); // \"folder\"\n */\n get name() {\n return this.pathUnsafe.split(path.sep).at(-1)!;\n }\n\n /**\n * Create a new Dir inside the current Dir\n * @param subPath\n * joined with parent Dir's path to make new Dir\n * @param options\n * include `{ temp: true }` to enable the `.clear()` method. If current Dir is temporary, child directories will also be temporary.\n * @example\n * const folder = new Dir('example');\n * // folder.path = '/path/to/cwd/example'\n * const child = folder.dir('path/to/dir');\n * // child.path = '/path/to/cwd/example/path/to/dir'\n */\n dir(subPath: string, options: DirOptions = { temp: this.isTemp }) {\n return new (this.constructor as typeof Dir)(path.join(this.path, subPath), options) as this;\n }\n\n /**\n * Creates a new temp directory inside current Dir\n * @param subPath joined with parent Dir's path to make new TempDir\n */\n tempDir(subPath: string) {\n return this.dir(subPath, { temp: true });\n }\n\n sanitize(filename: string) {\n const notUrl = filename.replace('https://', '').replace('www.', '');\n return sanitizeFilename(notUrl, { replacement: '_' }).slice(-200);\n }\n\n /**\n * @param base - The file base (name and extension)\n * @example\n * const folder = new Dir('example');\n * const filepath = folder.resolve('file.json');\n * // 'example/file.json'\n */\n filepath(base: string) {\n return path.resolve(this.path, this.sanitize(base));\n }\n\n /**\n * Create a new file in this directory\n */\n file(base: string) {\n return new File(this.filepath(base));\n }\n\n /**\n * All files and subdirectories in in this directory, returned as Dir and File instances\n */\n get contents(): (Dir | File)[] {\n return fs\n .readdirSync(this.path)\n .map(name => (fs.statSync(path.join(this.path, name)).isDirectory() ? this.dir(name) : this.file(name)));\n }\n\n /**\n * All subdirectories in this directory\n */\n get dirs() {\n return this.contents.filter(f => f instanceof Dir);\n }\n\n /**\n * All files in this directory\n */\n get files() {\n return this.contents.filter(f => f instanceof File);\n }\n\n /**\n * All files with MIME type that includes \"video\"\n */\n get videos() {\n return this.files.filter(f => f.type?.includes('video'));\n }\n\n /**\n * All files with MIME type that includes \"image\"\n */\n get images() {\n return this.files.filter(f => f.type?.includes('image'));\n }\n\n /**\n * All files with ext \".json\"\n * @example\n * // Directory of json files with the same shape\n * const dataFiles = dataDir.jsonFiles.map(f => f.json<ExampleType>());\n * // dataFiles: FileTypeJson<ExampleType>[]\n */\n get jsonFiles() {\n return this.files.filter(f => f.ext === '.json');\n }\n\n /**\n * All files with ext \".ndjson\"\n * @example\n * // Directory of ndjson files with the same shape\n * const dataFiles = dataDir.ndjsonFiles.map(f => f.ndjson<ExampleType>());\n * // dataFiles: FileTypeNdjson<ExampleType>[]\n */\n get ndjsonFiles() {\n return this.files.filter(f => f.ext === '.ndjson');\n }\n\n /**\n * All files with ext \".csv\"\n * @example\n * // Directory of csv files with the same shape\n * const dataFiles = dataDir.csvFile.map(f => f.csv<ExampleType>());\n * // dataFiles: FileTypeCsv<ExampleType>[]\n */\n get csvFiles() {\n return this.files.filter(f => f.ext === '.csv');\n }\n\n /**\n * All files with ext \".txt\"\n */\n get textFiles() {\n return this.files.filter(f => f.ext === '.txt');\n }\n\n /**\n * Deletes the contents of the directory. Only allowed if created with `temp` option set to `true` (or created with `dir.tempDir` method).\n */\n clear() {\n if (!this.isTemp) throw new Error('Dir is not temporary');\n fs.rmSync(this.path, { recursive: true, force: true });\n fs.mkdirSync(this.path, { recursive: true });\n }\n}\n\n/**\n * Current working directory\n */\nexport const cwd = new Dir('./');\n/**\n * ./.temp in current working directory\n */\nexport const temp = cwd.tempDir('.temp');\n","import { type Duration, isAfter, add } from 'date-fns';\nimport { Dir } from './Dir.ts';\n\n/**\n * Save data to a local file with an expiration.\n * Fresh/stale data is returned with a flag for if it's fresh or not,\n * so stale data can still be used if needed.\n */\nexport class Cache<T> {\n file;\n ttl;\n\n constructor(key: string, ttl: number | Duration, initialData?: T) {\n const dir = new Dir('.cache', { temp: true });\n this.file = dir.file(key).json<{ savedAt: string; data: T }>();\n this.ttl = typeof ttl === 'number' ? { minutes: ttl } : ttl;\n if (initialData) this.write(initialData);\n }\n\n write(data: T) {\n this.file.write({ savedAt: new Date().toUTCString(), data });\n }\n\n read(): [T | undefined, boolean] {\n const { savedAt, data } = this.file.read() || {};\n const isFresh = Boolean(savedAt && isAfter(add(savedAt, this.ttl), new Date()));\n return [data, isFresh];\n }\n}\n","import { merge } from 'lodash-es';\nimport extractDomain from 'extract-domain';\n\nexport type Route = string | URL;\n\ntype QueryVal = string | number | boolean | null | undefined;\nexport type Query = Record<string, QueryVal | QueryVal[]>;\n\nexport type FetchOptions = RequestInit & {\n base?: string;\n query?: Query;\n headers?: Record<string, string>;\n data?: any;\n timeout?: number;\n retries?: number;\n retryDelay?: number;\n};\n\n/**\n * Fetcher provides a quick way to set up a basic API connection\n * with options applied to every request.\n * Includes basic methods for requesting and parsing responses\n */\nexport class Fetcher {\n defaultOptions;\n\n constructor(opts: FetchOptions = {}) {\n this.defaultOptions = {\n timeout: 60000,\n retries: 0,\n retryDelay: 3000,\n ...opts,\n };\n }\n\n /**\n * Build URL with URLSearchParams if query is provided.\n * Also returns domain, to help with cookies.\n * Query params are merged in this order, last instance of key wins:\n * 1. defaultOptions.query\n * 2. route URLSearchParams\n * 3. options.query\n */\n buildUrl(route: Route, opts: FetchOptions = {}): [URL, string] {\n const routeUrl = route instanceof URL ? route : new URL(route, opts.base || this.defaultOptions.base);\n const routeQuery = Object.fromEntries(routeUrl.searchParams);\n const mergedOptions = merge({}, this.defaultOptions, { query: routeQuery }, opts);\n const params: [string, string][] = [];\n Object.entries(mergedOptions.query || {}).forEach(([key, val]) => {\n if (val === undefined) return;\n if (Array.isArray(val)) {\n val.forEach(v => {\n params.push([key, `${v}`]);\n });\n } else {\n params.push([key, `${val}`]);\n }\n });\n const search = params.length > 0 ? '?' + new URLSearchParams(params).toString() : '';\n const url = new URL(route + search, mergedOptions.base);\n const domain = extractDomain(url.href) as string;\n return [url, domain];\n }\n\n /**\n * Merges options to get headers. Useful when extending the Fetcher class to add custom auth.\n */\n buildHeaders(route: Route, opts: FetchOptions = {}) {\n const { headers } = merge({}, this.defaultOptions, opts);\n return headers || {};\n }\n\n /**\n * Builds request, merging defaultOptions and provided options.\n * Includes Abort signal for timeout\n */\n buildRequest(route: Route, opts: FetchOptions = {}): [Request, FetchOptions, string] {\n const mergedOptions = merge({}, this.defaultOptions, opts);\n const { query, data, timeout, retries, ...init } = mergedOptions;\n init.headers = this.buildHeaders(route, mergedOptions);\n if (data) {\n init.headers['content-type'] = init.headers['content-type'] || 'application/json';\n init.method = init.method || 'POST';\n init.body = JSON.stringify(data);\n }\n if (timeout) {\n init.signal = AbortSignal.timeout(timeout);\n }\n const [url, domain] = this.buildUrl(route, mergedOptions);\n const req = new Request(url, init);\n return [req, mergedOptions, domain];\n }\n\n /**\n * Builds and performs the request, merging provided options with defaultOptions.\n * If `opts.data` is provided, method is updated to POST, content-type json, data is stringified in the body.\n * Retries on local or network error, with increasing backoff.\n */\n async fetch(route: Route, opts: FetchOptions = {}): Promise<[Response, Request]> {\n const [_req, options] = this.buildRequest(route, opts);\n const maxAttempts = (options.retries || 0) + 1;\n let attempt = 0;\n while (attempt < maxAttempts) {\n attempt++;\n const [req] = this.buildRequest(route, opts);\n const res = await fetch(req)\n .then(r => {\n if (!r.ok) throw new Error(r.statusText);\n return r;\n })\n .catch(async error => {\n if (attempt < maxAttempts) {\n const wait = attempt * 3000;\n console.warn(`${req.method} ${req.url} (attempt ${attempt} of ${maxAttempts})`, error);\n await new Promise(resolve => setTimeout(resolve, wait));\n } else {\n throw new Error(error);\n }\n });\n if (res) return [res, req];\n }\n throw new Error(`Failed to fetch ${_req.url}`);\n }\n\n async fetchText(route: Route, opts: FetchOptions = {}): Promise<[string, Response, Request]> {\n return this.fetch(route, opts).then(async ([res, req]) => {\n const text = await res.text();\n return [text, res, req];\n });\n }\n\n async fetchJson<T>(route: Route, opts: FetchOptions = {}): Promise<[T, Response, Request]> {\n return this.fetchText(route, opts).then(([txt, res, req]) => [JSON.parse(txt) as T, res, req]);\n }\n}\n","import { format, formatISO, type DateArg, type Duration } from 'date-fns';\nimport formatDuration from 'format-duration';\n\n/**\n * Helpers for formatting dates, times, and numbers as strings\n */\nexport class Format {\n /**\n * date-fns format() with some shortcuts\n * @param formatStr the format to use\n * @param date the date to format, default `new Date()`\n * @example\n * Format.date('iso') // '2026-04-08T13:56:45Z'\n * Format.date('ymd') // '20260408'\n * Format.date('ymd-hm') // '20260408-1356'\n * Format.date('ymd-hms') // '20260408-135645'\n * Format.date('h:m:s') // '13:56:45'\n * @see more format options https://date-fns.org/v4.1.0/docs/format\n */\n static date(\n formatStr: 'iso' | 'ymd' | 'ymd-hm' | 'ymd-hms' | 'h:m:s' | string = 'iso',\n d: DateArg<Date> = new Date(),\n ) {\n if (formatStr === 'iso') return formatISO(d);\n if (formatStr === 'ymd') return format(d, 'yyyyMMdd');\n if (formatStr === 'ymd-hm') return format(d, 'yyyyMMdd-HHmm');\n if (formatStr === 'ymd-hms') return format(d, 'yyyyMMdd-HHmmss');\n if (formatStr === 'h:m:s') return format(d, 'HH:mm:ss');\n return format(d, formatStr);\n }\n\n /**\n * Round a number to a specific set of places\n */\n static round(n: number, places = 0) {\n return new Intl.NumberFormat('en-US', { maximumFractionDigits: places }).format(n);\n }\n\n static plural(amount: number, singular: string, multiple?: string) {\n return amount === 1 ? `${amount} ${singular}` : `${amount} ${multiple || singular + 's'}`;\n }\n\n /**\n * Make millisecond durations actually readable (eg \"123ms\", \"3.56s\", \"1m 34s\", \"3h 24m\", \"2d 4h\")\n * @param ms milliseconds\n * @param style 'digital' to output as 'HH:MM:SS'\n * @see details on 'digital' format https://github.com/ungoldman/format-duration\n * @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608\n */\n static ms(ms: number, style?: 'digital') {\n if (style === 'digital') return formatDuration(ms, { leading: true });\n if (ms < 1000) return `${this.round(ms)}ms`;\n const s = ms / 1000;\n if (s < 60) return `${this.round(s, 2)}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${Math.floor(s) % 60}s`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h}h ${m % 60}m`;\n const d = Math.floor(h / 24);\n return `${d}d ${h % 24}h`;\n }\n\n static bytes(b: number) {\n const labels = ['b', 'KB', 'MB', 'GB', 'TB'];\n let factor = 0;\n while (b >= 1024 && labels[factor + 1]) {\n b = b / 1024;\n factor++;\n }\n return `${this.round(b, 2)} ${labels[factor]}`;\n }\n}\n","import { inspect } from 'node:util';\nimport { isObjectLike } from 'lodash-es';\nimport chalk, { type ChalkInstance } from 'chalk';\nimport { snapshot } from './snapshot.ts';\nimport { Format } from './Format.ts';\n\n// https://docs.cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity\ntype Severity = 'DEFAULT' | 'DEBUG' | 'INFO' | 'NOTICE' | 'WARNING' | 'ERROR' | 'CRITICAL' | 'ALERT' | 'EMERGENCY';\n\ntype Options = {\n severity: Severity;\n color: ChalkInstance;\n};\n\ntype Entry = {\n message?: string;\n severity: Severity;\n stack?: string;\n details?: unknown[];\n};\n\nexport class Log {\n static getStack() {\n const details = { stack: '' };\n // replaces details.stack with current stack trace, excluding this Log.getStack call\n Error.captureStackTrace(details, Log.getStack);\n // remove 'Error' on first line\n return details.stack\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l !== 'Error');\n }\n\n /**\n * Gcloud parses JSON in stdout\n */\n static #toGcloud(entry: Entry) {\n const details = entry.details?.length === 1 ? entry.details[0] : entry.details;\n const output = { ...entry, details, stack: entry.stack || this.getStack() };\n console.log(JSON.stringify(snapshot(output)));\n }\n\n /**\n * Includes colors and better inspection for logging during dev\n */\n static #toConsole(entry: Entry, color: ChalkInstance) {\n if (entry.message) console.log(color(`${Format.date('h:m:s')} [${entry.severity}] ${entry.message}`));\n entry.details?.forEach(detail => {\n console.log(inspect(detail, { depth: 10, breakLength: 100, compact: true, colors: true }));\n });\n }\n\n static #log({ severity, color }: Options, ...input: unknown[]) {\n const { message, details } = this.prepare(...input);\n const entry: Entry = { message, severity, details };\n // https://cloud.google.com/run/docs/container-contract#env-vars\n const isGcloud = process.env.K_SERVICE !== undefined || process.env.CLOUD_RUN_JOB !== undefined;\n if (isGcloud) {\n this.#toGcloud(entry);\n } else {\n this.#toConsole(entry, color);\n }\n return entry;\n }\n\n /**\n * Handle first argument being a string or an object with a 'message' prop\n */\n static prepare(...input: unknown[]): { message?: string; details: unknown[] } {\n let [firstArg, ...rest] = input;\n // First argument is a string, use that as the message\n if (typeof firstArg === 'string') {\n return { message: firstArg, details: rest };\n }\n // First argument is an object with a `message` property\n // @ts-ignore\n if (isObjectLike(firstArg) && typeof firstArg['message'] === 'string') {\n const { message, ...firstDetails } = firstArg as { message: string };\n return { message, details: [firstDetails, ...rest] };\n }\n // No message found, log all args as details\n return { details: input };\n }\n\n /**\n * Events that require action or attention immediately\n */\n static alert(...input: unknown[]) {\n return this.#log({ severity: 'ALERT', color: chalk.bgRed }, ...input);\n }\n\n /**\n * Events that cause problems\n */\n static error(...input: unknown[]) {\n return this.#log({ severity: 'ERROR', color: chalk.red }, ...input);\n }\n\n /**\n * Events that might cause problems\n */\n static warn(...input: unknown[]) {\n return this.#log({ severity: 'WARNING', color: chalk.yellow }, ...input);\n }\n\n /**\n * Normal but significant events, such as start up, shut down, or a configuration change\n */\n static notice(...input: unknown[]) {\n return this.#log({ severity: 'NOTICE', color: chalk.cyan }, ...input);\n }\n\n /**\n * Routine information, such as ongoing status or performance\n */\n static info(...input: unknown[]) {\n return this.#log({ severity: 'INFO', color: chalk.white }, ...input);\n }\n\n /**\n * Debug or trace information\n */\n static debug(...input: unknown[]) {\n return this.#log({ severity: 'DEBUG', color: chalk.gray }, ...input);\n }\n}\n","export async function timeout(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","import * as fs from 'node:fs';\nimport { merge } from 'lodash-es';\nimport * as qt from 'quicktype-core';\n\nexport class TypeWriter {\n moduleName;\n input = qt.jsonInputForTargetLanguage('typescript');\n outDir;\n qtSettings;\n\n constructor(moduleName: string, settings: { outDir?: string } & Partial<qt.Options> = {}) {\n this.moduleName = moduleName;\n const { outDir, ...qtSettings } = settings;\n this.outDir = outDir || './types';\n const defaultSettings = {\n lang: 'typescript',\n rendererOptions: {\n 'just-types': true,\n 'prefer-types': true,\n },\n inferEnums: false,\n inferDateTimes: false,\n };\n this.qtSettings = merge(defaultSettings, qtSettings);\n }\n\n async addMember(name: string, _samples: any[]) {\n const samples = _samples.map(s => (typeof s === 'string' ? s : JSON.stringify(s)));\n await this.input.addSource({ name, samples });\n }\n\n async toString() {\n const inputData = new qt.InputData();\n inputData.addInput(this.input);\n const result = await qt.quicktype({\n inputData,\n ...this.qtSettings,\n });\n return result.lines.join('\\n');\n }\n\n async toFile() {\n const result = await this.toString();\n fs.mkdirSync(this.outDir, { recursive: true });\n fs.writeFileSync(`${this.outDir}/${this.moduleName}.d.ts`, result);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["output: Record<string, any>","obj: Record<string, any>","#resolve","parsed: Row[]","#parseVal","#inputPath","#resolved","params: [string, string][]","timeout","#toGcloud","#toConsole","#log","entry: Entry"],"sources":["../src/snapshot.ts","../src/File.ts","../src/Format.ts","../src/Dir.ts","../src/Cache.ts","../src/Fetcher.ts","../src/Log.ts","../src/timeout.ts","../src/TypeWriter.ts"],"sourcesContent":["import { isObjectLike } from 'lodash-es';\n\n/**\n * Allows special objects (Error, Headers, Set) to be included in JSON.stringify output.\n * Functions are removed\n */\nexport function snapshot(i: unknown, max = 50, depth = 0): any {\n if (Array.isArray(i)) {\n if (depth === max) return [];\n return i.map(c => snapshot(c, max, depth + 1));\n }\n if (typeof i === 'function') return undefined;\n if (!isObjectLike(i)) return i;\n\n if (depth === max) return {};\n let output: Record<string, any> = {};\n // @ts-ignore If it has an 'entries' function, use that for looping (eg. Set, Map, Headers)\n if (typeof i.entries === 'function') {\n // @ts-ignore\n for (let [k, v] of i.entries()) {\n output[k] = snapshot(v, max, depth + 1);\n }\n return output;\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Enumerability_and_ownership_of_properties\n\n // Get Enumerable, inherited properties\n const obj: Record<string, any> = i!;\n for (let key in obj) {\n output[key] = snapshot(obj[key], max, depth + 1);\n }\n\n // Get Non-enumberable, own properties\n Object.getOwnPropertyNames(obj).forEach(key => {\n output[key] = snapshot(obj[key], max, depth + 1);\n });\n\n return output;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { finished } from 'node:stream/promises';\nimport mime from 'mime-types';\nimport { writeToStream, parseStream } from 'fast-csv';\nimport { snapshot } from './snapshot.ts';\n\n/**\n * Represents a file on the file system. If the file doesn't exist, it is created the first time it is written to.\n */\nexport class File {\n path;\n root;\n dir;\n base;\n name;\n ext;\n type;\n\n constructor(filepath: string) {\n this.path = this.#resolve(filepath);\n const { root, dir, base, ext, name } = path.parse(this.path);\n this.root = root;\n this.dir = dir;\n this.base = base;\n this.name = name;\n this.ext = ext;\n this.type = mime.lookup(ext) || undefined;\n }\n\n #resolve(filepath: string) {\n if (filepath[0] === '~') {\n if (process.env.HOME) {\n return path.join(process.env.HOME, filepath.slice(1));\n } else {\n console.warn('process.env.HOME does not exist! \"~\" will not resolve to home directory');\n }\n }\n return path.resolve(filepath);\n }\n\n get exists() {\n return fs.existsSync(this.path);\n }\n\n get stats(): Partial<fs.Stats> {\n return this.exists ? fs.statSync(this.path) : {};\n }\n\n /**\n * Deletes the file if it exists\n */\n delete() {\n fs.rmSync(this.path, { force: true });\n }\n\n /**\n * @returns the contents of the file as a string, or undefined if the file doesn't exist\n */\n read() {\n return this.exists ? fs.readFileSync(this.path, 'utf8') : undefined;\n }\n\n /**\n * @returns lines as strings, removes trailing '\\n'\n */\n lines() {\n const contents = (this.read() || '').split('\\n');\n return contents.at(-1)?.length ? contents : contents.slice(0, contents.length - 1);\n }\n\n get readStream() {\n return this.exists ? fs.createReadStream(this.path) : Readable.from([]);\n }\n\n get writeStream() {\n fs.mkdirSync(this.dir, { recursive: true });\n return fs.createWriteStream(this.path);\n }\n\n write(contents: string | ReadableStream) {\n fs.mkdirSync(this.dir, { recursive: true });\n if (typeof contents === 'string') return fs.writeFileSync(this.path, contents);\n if (contents instanceof ReadableStream) return finished(Readable.from(contents).pipe(this.writeStream));\n throw new Error(`Invalid content type: ${typeof contents}`);\n }\n\n /**\n * creates file if it doesn't exist, appends string or array of strings as new lines.\n * File always ends with '\\n', so contents don't need to be read before appending\n */\n append(lines: string | string[]) {\n if (!this.exists) this.write('');\n const contents = Array.isArray(lines) ? lines.join('\\n') : lines;\n fs.appendFileSync(this.path, contents + '\\n');\n }\n\n /**\n * @returns FileTypeJson adaptor for current File, adds '.json' extension if not present.\n * @example\n * const file = new File('./data').json({ key: 'val' }); // FileTypeJson<{ key: string; }>\n * console.log(file.path) // '/path/to/cwd/data.json'\n * file.write({ something: 'else' }) // ❌ property 'something' doesn't exist on type { key: string; }\n * @example\n * const file = new File('./data').json<object>({ key: 'val' }); // FileTypeJson<object>\n * file.write({ something: 'else' }) // ✅ data is typed as object\n */\n json<T>(contents?: T) {\n return new FileTypeJson<T>(this.path, contents);\n }\n\n /**\n * @example\n * const file = new File.json('data.json', { key: 'val' }); // FileTypeJson<{ key: string; }>\n */\n static get json() {\n return FileTypeJson;\n }\n\n /**\n * @returns FileTypeNdjson adaptor for current File, adds '.ndjson' extension if not present.\n */\n ndjson<T extends object>(lines?: T | T[]) {\n return new FileTypeNdjson<T>(this.path, lines);\n }\n /**\n * @example\n * const file = new File.ndjson('log', { key: 'val' }); // FileTypeNdjson<{ key: string; }>\n * console.log(file.path) // /path/to/cwd/log.ndjson\n */\n static get ndjson() {\n return FileTypeNdjson;\n }\n\n /**\n * @returns FileTypeCsv adaptor for current File, adds '.csv' extension if not present.\n * @example\n * const file = await new File('a').csv([{ col: 'val' }, { col: 'val2' }]); // FileTypeCsv<{ col: string; }>\n * await file.write([ { col2: 'val2' } ]); // ❌ 'col2' doesn't exist on type { col: string; }\n * await file.write({ col: 'val' }); // ✅ Writes one row\n * await file.write([{ col: 'val2' }, { col: 'val3' }]); // ✅ Writes multiple rows\n */\n async csv<T extends object>(rows?: T[], keys?: (keyof T)[]) {\n const csvFile = new FileTypeCsv<T>(this.path);\n if (rows) await csvFile.write(rows, keys);\n return csvFile;\n }\n\n static get csv() {\n return FileTypeCsv;\n }\n}\n\n/**\n * A generic file adaptor, extended by specific file type implementations\n */\nexport class FileType {\n file;\n\n constructor(filepath: string, contents?: string) {\n this.file = new File(filepath);\n if (contents) this.file.write(contents);\n }\n\n get path() {\n return this.file.path;\n }\n\n get root() {\n return this.file.root;\n }\n\n get dir() {\n return this.file.dir;\n }\n\n get base() {\n return this.file.base;\n }\n\n get name() {\n return this.file.name;\n }\n\n get ext() {\n return this.file.ext;\n }\n\n get type() {\n return this.file.type;\n }\n\n get exists() {\n return this.file.exists;\n }\n\n get stats() {\n return this.file.stats;\n }\n\n delete() {\n this.file.delete();\n }\n\n get readStream() {\n return this.file.readStream;\n }\n\n get writeStream() {\n return this.file.writeStream;\n }\n}\n\n/**\n * A .json file that maintains data type when reading/writing.\n * > ⚠️ This is mildly unsafe, important/foreign json files should be validated at runtime!\n * @example\n * const file = new FileTypeJson('./data', { key: 'val' }); // FileTypeJson<{ key: string; }>\n * console.log(file.path) // '/path/to/cwd/data.json'\n * file.write({ something: 'else' }) // ❌ property 'something' doesn't exist on type { key: string; }\n * @example\n * const file = new FileTypeJson<object>('./data', { key: 'val' }); // FileTypeJson<object>\n * file.write({ something: 'else' }) // ✅ data is typed as object\n */\nexport class FileTypeJson<T> extends FileType {\n constructor(filepath: string, contents?: T) {\n super(filepath.endsWith('.json') ? filepath : filepath + '.json');\n if (contents) this.write(contents);\n }\n\n read() {\n const contents = this.file.read();\n return contents ? (JSON.parse(contents) as T) : undefined;\n }\n\n write(contents: T) {\n this.file.write(JSON.stringify(snapshot(contents), null, 2));\n }\n}\n\n/**\n * New-line delimited json file (.ndjson)\n * @see https://jsonltools.com/ndjson-format-specification\n */\nexport class FileTypeNdjson<T extends object> extends FileType {\n constructor(filepath: string, lines?: T | T[]) {\n super(filepath.endsWith('.ndjson') ? filepath : filepath + '.ndjson');\n if (lines) this.append(lines);\n }\n\n append(lines: T | T[]) {\n this.file.append(\n Array.isArray(lines) ? lines.map(l => JSON.stringify(snapshot(l))) : JSON.stringify(snapshot(lines)),\n );\n }\n\n lines() {\n return this.file.lines().map(l => JSON.parse(l) as T);\n }\n}\n\ntype Key<T extends object> = keyof T;\n\n/**\n * Comma separated values (.csv).\n * Input rows as objects, keys are used as column headers\n */\nexport class FileTypeCsv<Row extends object> extends FileType {\n constructor(filepath: string) {\n super(filepath.endsWith('.csv') ? filepath : filepath + '.csv');\n }\n\n async write(rows: Row[], keys?: Key<Row>[]) {\n const headerSet = new Set<Key<Row>>();\n if (keys) {\n for (const key of keys) headerSet.add(key);\n } else {\n for (const row of rows) {\n for (const key in row) headerSet.add(key);\n }\n }\n const headers = Array.from(headerSet);\n const outRows = rows.map(row => headers.map(key => row[key]));\n return finished(writeToStream(this.file.writeStream, [headers, ...outRows]));\n }\n\n #parseVal(val: string) {\n if (val.toLowerCase() === 'false') return false;\n if (val.toLowerCase() === 'true') return true;\n if (val.length === 0) return null;\n if (/^[\\.0-9]+$/.test(val)) return Number(val);\n return val;\n }\n\n async read() {\n return new Promise<Row[]>((resolve, reject) => {\n const parsed: Row[] = [];\n parseStream(this.file.readStream, { headers: true })\n .on('data', (raw: Record<Key<Row>, string>) => {\n parsed.push(\n Object.entries(raw).reduce(\n (all, [key, val]) => ({\n ...all,\n [key]: this.#parseVal(val as string),\n }),\n {} as Row,\n ),\n );\n })\n .on('error', e => reject(e))\n .on('end', () => resolve(parsed));\n });\n }\n}\n","import { format, formatISO, type DateArg, type Duration } from 'date-fns';\nimport formatDuration from 'format-duration';\n\n/**\n * Helpers for formatting dates, times, and numbers as strings\n */\nexport class Format {\n /**\n * date-fns format() with some shortcuts\n * @param formatStr the format to use\n * @param date the date to format, default `new Date()`\n * @example\n * Format.date('iso') // '2026-04-08T13:56:45Z'\n * Format.date('ymd') // '20260408'\n * Format.date('ymd-hm') // '20260408-1356'\n * Format.date('ymd-hms') // '20260408-135645'\n * Format.date('h:m:s') // '13:56:45'\n * @see more format options https://date-fns.org/v4.1.0/docs/format\n */\n static date(\n formatStr: 'iso' | 'ymd' | 'ymd-hm' | 'ymd-hms' | 'h:m:s' | string = 'iso',\n d: DateArg<Date> = new Date(),\n ) {\n if (formatStr === 'iso') return formatISO(d);\n if (formatStr === 'ymd') return format(d, 'yyyyMMdd');\n if (formatStr === 'ymd-hm') return format(d, 'yyyyMMdd-HHmm');\n if (formatStr === 'ymd-hms') return format(d, 'yyyyMMdd-HHmmss');\n if (formatStr === 'h:m:s') return format(d, 'HH:mm:ss');\n return format(d, formatStr);\n }\n\n /**\n * Round a number to a specific set of places\n */\n static round(n: number, places = 0) {\n return new Intl.NumberFormat('en-US', { maximumFractionDigits: places }).format(n);\n }\n\n static plural(amount: number, singular: string, multiple?: string) {\n return amount === 1 ? `${amount} ${singular}` : `${amount} ${multiple || singular + 's'}`;\n }\n\n /**\n * Make millisecond durations actually readable (eg \"123ms\", \"3.56s\", \"1m 34s\", \"3h 24m\", \"2d 4h\")\n * @param ms milliseconds\n * @param style 'digital' to output as 'HH:MM:SS'\n * @see details on 'digital' format https://github.com/ungoldman/format-duration\n * @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608\n */\n static ms(ms: number, style?: 'digital') {\n if (style === 'digital') return formatDuration(ms, { leading: true });\n if (ms < 1000) return `${this.round(ms)}ms`;\n const s = ms / 1000;\n if (s < 60) return `${this.round(s, 2)}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${Math.floor(s) % 60}s`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h}h ${m % 60}m`;\n const d = Math.floor(h / 24);\n return `${d}d ${h % 24}h`;\n }\n\n static bytes(b: number) {\n const labels = ['b', 'KB', 'MB', 'GB', 'TB'];\n let factor = 0;\n while (b >= 1024 && labels[factor + 1]) {\n b = b / 1024;\n factor++;\n }\n return `${this.round(b, 2)} ${labels[factor]}`;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport sanitizeFilename from 'sanitize-filename';\nimport { File } from './File.ts';\nimport { Format } from './Format.ts';\n\nexport type DirOptions = {\n temp?: boolean;\n};\n\n/**\n * Reference to a specific directory with methods to create and list files.\n * @param inputPath\n * The path of the directory, created on file system the first time `.path` is read or any methods are used. Default: `./YYYYMMDD`\n * @param options\n * include `{ temp: true }` to enable the `.clear()` method\n */\nexport class Dir {\n #inputPath;\n #resolved?: string;\n isTemp;\n\n /**\n * @param path can be relative to workspace or absolute\n */\n constructor(inputPath = Format.date('ymd'), options: DirOptions = {}) {\n this.#inputPath = inputPath;\n this.isTemp = Boolean(options.temp);\n }\n\n /**\n * The path of the directory, which might not exist yet.\n */\n get pathUnsafe() {\n if (this.#resolved) return this.#resolved;\n if (this.#inputPath[0] === '~') {\n if (process.env.HOME) {\n return path.join(process.env.HOME, this.#inputPath.slice(1));\n } else {\n console.warn('process.env.HOME does not exist! \"~\" will not resolve to home directory');\n }\n }\n return path.resolve(this.#inputPath);\n }\n\n /**\n * The path of this Dir instance. Created on file system the first time this property is read/used.\n * Safe to use the directory immediately, without calling mkdir separately.\n */\n get path() {\n // avoids calling mkdir every time path is read\n if (!this.#resolved) {\n this.#resolved = this.pathUnsafe;\n fs.mkdirSync(this.#resolved, { recursive: true });\n }\n return this.#resolved;\n }\n\n /**\n * The last segment in the path. Doesn't read this.path, to avoid creating directory on file system before it's needed.\n * @example\n * const example = new Dir('/path/to/folder');\n * console.log(example.name); // \"folder\"\n */\n get name() {\n return this.pathUnsafe.split(path.sep).at(-1)!;\n }\n\n /**\n * Create a new Dir inside the current Dir\n * @param subPath\n * joined with parent Dir's path to make new Dir\n * @param options\n * include `{ temp: true }` to enable the `.clear()` method. If current Dir is temporary, child directories will also be temporary.\n * @example\n * const folder = new Dir('example');\n * // folder.path = '/path/to/cwd/example'\n * const child = folder.dir('path/to/dir');\n * // child.path = '/path/to/cwd/example/path/to/dir'\n */\n dir(subPath = Format.date('ymd'), options: DirOptions = { temp: this.isTemp }) {\n return new (this.constructor as typeof Dir)(path.join(this.path, subPath), options) as this;\n }\n\n /**\n * Creates a new temp directory inside current Dir\n * @param subPath joined with parent Dir's path to make new TempDir\n */\n tempDir(subPath?: string) {\n return this.dir(subPath, { temp: true });\n }\n\n sanitize(filename: string) {\n const notUrl = filename.replace('https://', '').replace('www.', '');\n return sanitizeFilename(notUrl, { replacement: '_' }).slice(-200);\n }\n\n /**\n * @param base - The file base (name and extension)\n * @example\n * const folder = new Dir('example');\n * const filepath = folder.resolve('file.json');\n * // '/path/to/example/file.json'\n */\n filepath(base: string) {\n return path.resolve(this.path, this.sanitize(base));\n }\n\n /**\n * Create a new file in this directory. Filename defaults to `YYYYMMDD-HHMMSS` if not provided\n */\n file(base = Format.date('ymd-hms')) {\n return new File(this.filepath(base));\n }\n\n /**\n * All files and subdirectories in in this directory, returned as Dir and File instances\n */\n get contents(): (Dir | File)[] {\n return fs\n .readdirSync(this.path)\n .map(name => (fs.statSync(path.join(this.path, name)).isDirectory() ? this.dir(name) : this.file(name)));\n }\n\n /**\n * All subdirectories in this directory\n */\n get dirs() {\n return this.contents.filter(f => f instanceof Dir);\n }\n\n /**\n * All files in this directory\n */\n get files() {\n return this.contents.filter(f => f instanceof File);\n }\n\n /**\n * All files with MIME type that includes \"video\"\n */\n get videos() {\n return this.files.filter(f => f.type?.includes('video'));\n }\n\n /**\n * All files with MIME type that includes \"image\"\n */\n get images() {\n return this.files.filter(f => f.type?.includes('image'));\n }\n\n /**\n * All files with ext \".json\"\n * @example\n * // Directory of json files with the same shape\n * const dataFiles = dataDir.jsonFiles.map(f => f.json<ExampleType>());\n * // dataFiles: FileTypeJson<ExampleType>[]\n */\n get jsonFiles() {\n return this.files.filter(f => f.ext === '.json');\n }\n\n /**\n * All files with ext \".ndjson\"\n * @example\n * // Directory of ndjson files with the same shape\n * const dataFiles = dataDir.ndjsonFiles.map(f => f.ndjson<ExampleType>());\n * // dataFiles: FileTypeNdjson<ExampleType>[]\n */\n get ndjsonFiles() {\n return this.files.filter(f => f.ext === '.ndjson');\n }\n\n /**\n * All files with ext \".csv\"\n * @example\n * // Directory of csv files with the same shape\n * const dataFiles = dataDir.csvFile.map(f => f.csv<ExampleType>());\n * // dataFiles: FileTypeCsv<ExampleType>[]\n */\n get csvFiles() {\n return this.files.filter(f => f.ext === '.csv');\n }\n\n /**\n * All files with ext \".txt\"\n */\n get textFiles() {\n return this.files.filter(f => f.ext === '.txt');\n }\n\n /**\n * Deletes the contents of the directory. Only allowed if created with `temp` option set to `true` (or created with `dir.tempDir` method).\n */\n clear() {\n if (!this.isTemp) throw new Error('Dir is not temporary');\n fs.rmSync(this.path, { recursive: true, force: true });\n fs.mkdirSync(this.path, { recursive: true });\n }\n}\n\n/**\n * Current working directory\n */\nexport const cwd = new Dir('./');\n/**\n * ./.temp in current working directory\n */\nexport const temp = cwd.tempDir('.temp');\n","import { type Duration, isAfter, add } from 'date-fns';\nimport { Dir } from './Dir.ts';\n\n/**\n * Save data to a local file with an expiration.\n * Fresh/stale data is returned with a flag for if it's fresh or not,\n * so stale data can still be used if needed.\n */\nexport class Cache<T> {\n file;\n ttl;\n\n constructor(key: string, ttl: number | Duration, initialData?: T) {\n const dir = new Dir('.cache', { temp: true });\n this.file = dir.file(key).json<{ savedAt: string; data: T }>();\n this.ttl = typeof ttl === 'number' ? { minutes: ttl } : ttl;\n if (initialData) this.write(initialData);\n }\n\n write(data: T) {\n this.file.write({ savedAt: new Date().toUTCString(), data });\n }\n\n read(): [T | undefined, boolean] {\n const { savedAt, data } = this.file.read() || {};\n const isFresh = Boolean(savedAt && isAfter(add(savedAt, this.ttl), new Date()));\n return [data, isFresh];\n }\n}\n","import { merge } from 'lodash-es';\nimport extractDomain from 'extract-domain';\n\nexport type Route = string | URL;\n\ntype QueryVal = string | number | boolean | null | undefined;\nexport type Query = Record<string, QueryVal | QueryVal[]>;\n\nexport type FetchOptions = RequestInit & {\n base?: string;\n query?: Query;\n headers?: Record<string, string>;\n data?: any;\n timeout?: number;\n retries?: number;\n retryDelay?: number;\n};\n\n/**\n * Fetcher provides a quick way to set up a basic API connection\n * with options applied to every request.\n * Includes basic methods for requesting and parsing responses\n */\nexport class Fetcher {\n defaultOptions;\n\n constructor(opts: FetchOptions = {}) {\n this.defaultOptions = {\n timeout: 60000,\n retries: 0,\n retryDelay: 3000,\n ...opts,\n };\n }\n\n /**\n * Build URL with URLSearchParams if query is provided.\n * Also returns domain, to help with cookies.\n * Query params are merged in this order, last instance of key wins:\n * 1. defaultOptions.query\n * 2. route URLSearchParams\n * 3. options.query\n */\n buildUrl(route: Route, opts: FetchOptions = {}): [URL, string] {\n const routeUrl = route instanceof URL ? route : new URL(route, opts.base || this.defaultOptions.base);\n const routeQuery = Object.fromEntries(routeUrl.searchParams);\n const mergedOptions = merge({}, this.defaultOptions, { query: routeQuery }, opts);\n const params: [string, string][] = [];\n Object.entries(mergedOptions.query || {}).forEach(([key, val]) => {\n if (val === undefined) return;\n if (Array.isArray(val)) {\n val.forEach(v => {\n params.push([key, `${v}`]);\n });\n } else {\n params.push([key, `${val}`]);\n }\n });\n const search = params.length > 0 ? '?' + new URLSearchParams(params).toString() : '';\n const url = new URL(route + search, mergedOptions.base);\n const domain = extractDomain(url.href) as string;\n return [url, domain];\n }\n\n /**\n * Merges options to get headers. Useful when extending the Fetcher class to add custom auth.\n */\n buildHeaders(route: Route, opts: FetchOptions = {}) {\n const { headers } = merge({}, this.defaultOptions, opts);\n return headers || {};\n }\n\n /**\n * Builds request, merging defaultOptions and provided options.\n * Includes Abort signal for timeout\n */\n buildRequest(route: Route, opts: FetchOptions = {}): [Request, FetchOptions, string] {\n const mergedOptions = merge({}, this.defaultOptions, opts);\n const { query, data, timeout, retries, ...init } = mergedOptions;\n init.headers = this.buildHeaders(route, mergedOptions);\n if (data) {\n init.headers['content-type'] = init.headers['content-type'] || 'application/json';\n init.method = init.method || 'POST';\n init.body = JSON.stringify(data);\n }\n if (timeout) {\n init.signal = AbortSignal.timeout(timeout);\n }\n const [url, domain] = this.buildUrl(route, mergedOptions);\n const req = new Request(url, init);\n return [req, mergedOptions, domain];\n }\n\n /**\n * Builds and performs the request, merging provided options with defaultOptions.\n * If `opts.data` is provided, method is updated to POST, content-type json, data is stringified in the body.\n * Retries on local or network error, with increasing backoff.\n */\n async fetch(route: Route, opts: FetchOptions = {}): Promise<[Response, Request]> {\n const [_req, options] = this.buildRequest(route, opts);\n const maxAttempts = (options.retries || 0) + 1;\n let attempt = 0;\n while (attempt < maxAttempts) {\n attempt++;\n const [req] = this.buildRequest(route, opts);\n const res = await fetch(req)\n .then(r => {\n if (!r.ok) throw new Error(r.statusText);\n return r;\n })\n .catch(async error => {\n if (attempt < maxAttempts) {\n const wait = attempt * 3000;\n console.warn(`${req.method} ${req.url} (attempt ${attempt} of ${maxAttempts})`, error);\n await new Promise(resolve => setTimeout(resolve, wait));\n } else {\n throw new Error(error);\n }\n });\n if (res) return [res, req];\n }\n throw new Error(`Failed to fetch ${_req.url}`);\n }\n\n async fetchText(route: Route, opts: FetchOptions = {}): Promise<[string, Response, Request]> {\n return this.fetch(route, opts).then(async ([res, req]) => {\n const text = await res.text();\n return [text, res, req];\n });\n }\n\n async fetchJson<T>(route: Route, opts: FetchOptions = {}): Promise<[T, Response, Request]> {\n return this.fetchText(route, opts).then(([txt, res, req]) => [JSON.parse(txt) as T, res, req]);\n }\n}\n","import { inspect } from 'node:util';\nimport { isObjectLike } from 'lodash-es';\nimport chalk, { type ChalkInstance } from 'chalk';\nimport { snapshot } from './snapshot.ts';\nimport { Format } from './Format.ts';\n\n// https://docs.cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity\ntype Severity = 'DEFAULT' | 'DEBUG' | 'INFO' | 'NOTICE' | 'WARNING' | 'ERROR' | 'CRITICAL' | 'ALERT' | 'EMERGENCY';\n\ntype Options = {\n severity: Severity;\n color: ChalkInstance;\n};\n\ntype Entry = {\n message?: string;\n severity: Severity;\n stack?: string;\n details?: unknown[];\n};\n\nexport class Log {\n static getStack() {\n const details = { stack: '' };\n // replaces details.stack with current stack trace, excluding this Log.getStack call\n Error.captureStackTrace(details, Log.getStack);\n // remove 'Error' on first line\n return details.stack\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l !== 'Error');\n }\n\n /**\n * Gcloud parses JSON in stdout\n */\n static #toGcloud(entry: Entry) {\n const details = entry.details?.length === 1 ? entry.details[0] : entry.details;\n const output = { ...entry, details, stack: entry.stack || this.getStack() };\n console.log(JSON.stringify(snapshot(output)));\n }\n\n /**\n * Includes colors and better inspection for logging during dev\n */\n static #toConsole(entry: Entry, color: ChalkInstance) {\n if (entry.message) console.log(color(`${Format.date('h:m:s')} [${entry.severity}] ${entry.message}`));\n entry.details?.forEach(detail => {\n console.log(inspect(detail, { depth: 10, breakLength: 100, compact: true, colors: true }));\n });\n }\n\n static #log({ severity, color }: Options, ...input: unknown[]) {\n const { message, details } = this.prepare(...input);\n const entry: Entry = { message, severity, details };\n // https://cloud.google.com/run/docs/container-contract#env-vars\n const isGcloud = process.env.K_SERVICE !== undefined || process.env.CLOUD_RUN_JOB !== undefined;\n if (isGcloud) {\n this.#toGcloud(entry);\n } else {\n this.#toConsole(entry, color);\n }\n return entry;\n }\n\n /**\n * Handle first argument being a string or an object with a 'message' prop\n */\n static prepare(...input: unknown[]): { message?: string; details: unknown[] } {\n let [firstArg, ...rest] = input;\n // First argument is a string, use that as the message\n if (typeof firstArg === 'string') {\n return { message: firstArg, details: rest };\n }\n // First argument is an object with a `message` property\n // @ts-ignore\n if (isObjectLike(firstArg) && typeof firstArg['message'] === 'string') {\n const { message, ...firstDetails } = firstArg as { message: string };\n return { message, details: [firstDetails, ...rest] };\n }\n // No message found, log all args as details\n return { details: input };\n }\n\n /**\n * Events that require action or attention immediately\n */\n static alert(...input: unknown[]) {\n return this.#log({ severity: 'ALERT', color: chalk.bgRed }, ...input);\n }\n\n /**\n * Events that cause problems\n */\n static error(...input: unknown[]) {\n return this.#log({ severity: 'ERROR', color: chalk.red }, ...input);\n }\n\n /**\n * Events that might cause problems\n */\n static warn(...input: unknown[]) {\n return this.#log({ severity: 'WARNING', color: chalk.yellow }, ...input);\n }\n\n /**\n * Normal but significant events, such as start up, shut down, or a configuration change\n */\n static notice(...input: unknown[]) {\n return this.#log({ severity: 'NOTICE', color: chalk.cyan }, ...input);\n }\n\n /**\n * Routine information, such as ongoing status or performance\n */\n static info(...input: unknown[]) {\n return this.#log({ severity: 'INFO', color: chalk.white }, ...input);\n }\n\n /**\n * Debug or trace information\n */\n static debug(...input: unknown[]) {\n return this.#log({ severity: 'DEBUG', color: chalk.gray }, ...input);\n }\n}\n","export async function timeout(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","import * as fs from 'node:fs';\nimport { merge } from 'lodash-es';\nimport * as qt from 'quicktype-core';\n\nexport class TypeWriter {\n moduleName;\n input = qt.jsonInputForTargetLanguage('typescript');\n outDir;\n outFile;\n qtSettings;\n\n constructor(moduleName: string, settings: { outDir?: string; outFile?: string } & Partial<qt.Options> = {}) {\n this.moduleName = moduleName;\n const { outDir, outFile, ...qtSettings } = settings;\n this.outDir = outDir || './types';\n this.outFile = outFile || `${this.moduleName}.types.ts`;\n const defaultSettings = {\n lang: 'typescript',\n rendererOptions: {\n 'just-types': true,\n 'prefer-types': true,\n },\n inferEnums: false,\n inferDateTimes: false,\n };\n this.qtSettings = merge(defaultSettings, qtSettings);\n }\n\n async addMember(name: string, _samples: any[]) {\n const samples = _samples.map(s => (typeof s === 'string' ? s : JSON.stringify(s)));\n await this.input.addSource({ name, samples });\n }\n\n async toString() {\n const inputData = new qt.InputData();\n inputData.addInput(this.input);\n const result = await qt.quicktype({\n inputData,\n ...this.qtSettings,\n });\n return result.lines.join('\\n');\n }\n\n async toFile() {\n const result = await this.toString();\n fs.mkdirSync(this.outDir, { recursive: true });\n fs.writeFileSync(`${this.outDir}/${this.outFile}`, result);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brianbuie/node-kit",
3
- "version": "0.14.4",
3
+ "version": "0.15.1",
4
4
  "license": "Unlicense",
5
5
  "description": "Basic tools for quick node.js projects",
6
6
  "author": "Brian Buie <brian@buie.dev>",
package/src/Dir.test.ts CHANGED
@@ -20,6 +20,17 @@ describe('Dir', () => {
20
20
  assert(testDir.dirs.length > 0);
21
21
  });
22
22
 
23
+ it('Creates sub directory using date when no input provided', () => {
24
+ const sub = testDir.dir();
25
+ assert(sub.path.includes(testDir.path));
26
+ assert(/\d{8}/g.test(sub.path));
27
+ });
28
+
29
+ it('Creates files using date when no input provided', () => {
30
+ const f = testDir.file();
31
+ assert(/\d{8}-\d{6}/g.test(f.path));
32
+ });
33
+
23
34
  it('Handles ~ (home) input', () => {
24
35
  const homeDir = new Dir('~/example');
25
36
  if (process.env.HOME) assert(homeDir.pathUnsafe.includes(process.env.HOME));
package/src/Dir.ts CHANGED
@@ -2,6 +2,7 @@ import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import sanitizeFilename from 'sanitize-filename';
4
4
  import { File } from './File.ts';
5
+ import { Format } from './Format.ts';
5
6
 
6
7
  export type DirOptions = {
7
8
  temp?: boolean;
@@ -10,7 +11,7 @@ export type DirOptions = {
10
11
  /**
11
12
  * Reference to a specific directory with methods to create and list files.
12
13
  * @param inputPath
13
- * The path of the directory, created on file system the first time `.path` is read or any methods are used
14
+ * The path of the directory, created on file system the first time `.path` is read or any methods are used. Default: `./YYYYMMDD`
14
15
  * @param options
15
16
  * include `{ temp: true }` to enable the `.clear()` method
16
17
  */
@@ -22,7 +23,7 @@ export class Dir {
22
23
  /**
23
24
  * @param path can be relative to workspace or absolute
24
25
  */
25
- constructor(inputPath: string, options: DirOptions = {}) {
26
+ constructor(inputPath = Format.date('ymd'), options: DirOptions = {}) {
26
27
  this.#inputPath = inputPath;
27
28
  this.isTemp = Boolean(options.temp);
28
29
  }
@@ -77,7 +78,7 @@ export class Dir {
77
78
  * const child = folder.dir('path/to/dir');
78
79
  * // child.path = '/path/to/cwd/example/path/to/dir'
79
80
  */
80
- dir(subPath: string, options: DirOptions = { temp: this.isTemp }) {
81
+ dir(subPath = Format.date('ymd'), options: DirOptions = { temp: this.isTemp }) {
81
82
  return new (this.constructor as typeof Dir)(path.join(this.path, subPath), options) as this;
82
83
  }
83
84
 
@@ -85,7 +86,7 @@ export class Dir {
85
86
  * Creates a new temp directory inside current Dir
86
87
  * @param subPath joined with parent Dir's path to make new TempDir
87
88
  */
88
- tempDir(subPath: string) {
89
+ tempDir(subPath?: string) {
89
90
  return this.dir(subPath, { temp: true });
90
91
  }
91
92
 
@@ -99,16 +100,16 @@ export class Dir {
99
100
  * @example
100
101
  * const folder = new Dir('example');
101
102
  * const filepath = folder.resolve('file.json');
102
- * // 'example/file.json'
103
+ * // '/path/to/example/file.json'
103
104
  */
104
105
  filepath(base: string) {
105
106
  return path.resolve(this.path, this.sanitize(base));
106
107
  }
107
108
 
108
109
  /**
109
- * Create a new file in this directory
110
+ * Create a new file in this directory. Filename defaults to `YYYYMMDD-HHMMSS` if not provided
110
111
  */
111
- file(base: string) {
112
+ file(base = Format.date('ymd-hms')) {
112
113
  return new File(this.filepath(base));
113
114
  }
114
115
 
package/src/TypeWriter.ts CHANGED
@@ -6,12 +6,14 @@ export class TypeWriter {
6
6
  moduleName;
7
7
  input = qt.jsonInputForTargetLanguage('typescript');
8
8
  outDir;
9
+ outFile;
9
10
  qtSettings;
10
11
 
11
- constructor(moduleName: string, settings: { outDir?: string } & Partial<qt.Options> = {}) {
12
+ constructor(moduleName: string, settings: { outDir?: string; outFile?: string } & Partial<qt.Options> = {}) {
12
13
  this.moduleName = moduleName;
13
- const { outDir, ...qtSettings } = settings;
14
+ const { outDir, outFile, ...qtSettings } = settings;
14
15
  this.outDir = outDir || './types';
16
+ this.outFile = outFile || `${this.moduleName}.types.ts`;
15
17
  const defaultSettings = {
16
18
  lang: 'typescript',
17
19
  rendererOptions: {
@@ -42,6 +44,6 @@ export class TypeWriter {
42
44
  async toFile() {
43
45
  const result = await this.toString();
44
46
  fs.mkdirSync(this.outDir, { recursive: true });
45
- fs.writeFileSync(`${this.outDir}/${this.moduleName}.d.ts`, result);
47
+ fs.writeFileSync(`${this.outDir}/${this.outFile}`, result);
46
48
  }
47
49
  }