@brianbuie/node-kit 0.15.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
@@ -5,41 +5,13 @@ import { Readable } from "node:stream";
5
5
  import { finished } from "node:stream/promises";
6
6
  import mime from "mime-types";
7
7
  import { parseStream, writeToStream } from "fast-csv";
8
- import { isObjectLike, merge } from "lodash-es";
9
8
  import { add, format, formatISO, isAfter } from "date-fns";
10
9
  import formatDuration from "format-duration";
10
+ import { isObjectLike, merge } from "lodash-es";
11
11
  import extractDomain from "extract-domain";
12
- import { inspect } from "node:util";
13
- import chalk from "chalk";
12
+ import pino from "pino";
14
13
  import * as qt from "quicktype-core";
15
14
 
16
- //#region src/snapshot.ts
17
- /**
18
- * Allows special objects (Error, Headers, Set) to be included in JSON.stringify output.
19
- * Functions are removed
20
- */
21
- function snapshot(i, max = 50, depth = 0) {
22
- if (Array.isArray(i)) {
23
- if (depth === max) return [];
24
- return i.map((c) => snapshot(c, max, depth + 1));
25
- }
26
- if (typeof i === "function") return void 0;
27
- if (!isObjectLike(i)) return i;
28
- if (depth === max) return {};
29
- let output = {};
30
- if (typeof i.entries === "function") {
31
- for (let [k, v] of i.entries()) output[k] = snapshot(v, max, depth + 1);
32
- return output;
33
- }
34
- const obj = i;
35
- for (let key in obj) output[key] = snapshot(obj[key], max, depth + 1);
36
- Object.getOwnPropertyNames(obj).forEach((key) => {
37
- output[key] = snapshot(obj[key], max, depth + 1);
38
- });
39
- return output;
40
- }
41
-
42
- //#endregion
43
15
  //#region src/File.ts
44
16
  /**
45
17
  * Represents a file on the file system. If the file doesn't exist, it is created the first time it is written to.
@@ -156,9 +128,9 @@ var File = class {
156
128
  * await file.write({ col: 'val' }); // ✅ Writes one row
157
129
  * await file.write([{ col: 'val2' }, { col: 'val3' }]); // ✅ Writes multiple rows
158
130
  */
159
- async csv(rows, keys) {
160
- const csvFile = new FileTypeCsv(this.path);
161
- if (rows) await csvFile.write(rows, keys);
131
+ async csv(rows, options) {
132
+ const csvFile = new FileTypeCsv(this.path, options);
133
+ if (rows) await csvFile.write(rows);
162
134
  return csvFile;
163
135
  }
164
136
  static get csv() {
@@ -213,7 +185,7 @@ var FileType = class {
213
185
  };
214
186
  /**
215
187
  * A .json file that maintains data type when reading/writing.
216
- * > ⚠️ This is mildly unsafe, important/foreign json files should be validated at runtime!
188
+ * > ⚠️ This is mildly unsafe, json files should be validated at runtime!
217
189
  * @example
218
190
  * const file = new FileTypeJson('./data', { key: 'val' }); // FileTypeJson<{ key: string; }>
219
191
  * console.log(file.path) // '/path/to/cwd/data.json'
@@ -232,7 +204,7 @@ var FileTypeJson = class extends FileType {
232
204
  return contents ? JSON.parse(contents) : void 0;
233
205
  }
234
206
  write(contents) {
235
- this.file.write(JSON.stringify(snapshot(contents), null, 2));
207
+ this.file.write(JSON.stringify(contents, null, 2));
236
208
  }
237
209
  };
238
210
  /**
@@ -245,7 +217,7 @@ var FileTypeNdjson = class extends FileType {
245
217
  if (lines) this.append(lines);
246
218
  }
247
219
  append(lines) {
248
- this.file.append(Array.isArray(lines) ? lines.map((l) => JSON.stringify(snapshot(l))) : JSON.stringify(snapshot(lines)));
220
+ this.file.append(Array.isArray(lines) ? lines.map((l) => JSON.stringify(l)) : JSON.stringify(lines));
249
221
  }
250
222
  lines() {
251
223
  return this.file.lines().map((l) => JSON.parse(l));
@@ -256,22 +228,30 @@ var FileTypeNdjson = class extends FileType {
256
228
  * Input rows as objects, keys are used as column headers
257
229
  */
258
230
  var FileTypeCsv = class extends FileType {
259
- constructor(filepath) {
231
+ options;
232
+ constructor(filepath, options = {}) {
260
233
  super(filepath.endsWith(".csv") ? filepath : filepath + ".csv");
234
+ this.options = {
235
+ parseNumbers: true,
236
+ parseBooleans: true,
237
+ parseNulls: true,
238
+ ...options
239
+ };
261
240
  }
262
- async write(rows, keys) {
241
+ async write(rows) {
263
242
  const headerSet = /* @__PURE__ */ new Set();
264
- if (keys) for (const key of keys) headerSet.add(key);
243
+ if (this.options.keys) for (const key of this.options.keys) headerSet.add(key);
265
244
  else for (const row of rows) for (const key in row) headerSet.add(key);
266
245
  const headers = Array.from(headerSet);
267
246
  const outRows = rows.map((row) => headers.map((key) => row[key]));
268
247
  return finished(writeToStream(this.file.writeStream, [headers, ...outRows]));
269
248
  }
270
249
  #parseVal(val) {
271
- if (val.toLowerCase() === "false") return false;
272
- if (val.toLowerCase() === "true") return true;
273
- if (val.length === 0) return null;
274
- if (/^[\.0-9]+$/.test(val)) return Number(val);
250
+ const { parseNumbers, parseBooleans, parseNulls } = this.options;
251
+ if (parseBooleans && val.toLowerCase() === "false") return false;
252
+ if (parseBooleans && val.toLowerCase() === "true") return true;
253
+ if (parseNulls && (val.length === 0 || val.toLowerCase() === "null")) return null;
254
+ if (parseNumbers && /^[\.0-9]+$/.test(val)) return Number(val);
275
255
  return val;
276
256
  }
277
257
  async read() {
@@ -510,7 +490,7 @@ var Dir = class Dir {
510
490
  /**
511
491
  * All files with ext ".txt"
512
492
  */
513
- get textFiles() {
493
+ get txtFiles() {
514
494
  return this.files.filter((f) => f.ext === ".txt");
515
495
  }
516
496
  /**
@@ -676,122 +656,91 @@ var Fetcher = class {
676
656
 
677
657
  //#endregion
678
658
  //#region src/Log.ts
659
+ /**
660
+ * Wrapper for [pino](https://github.com/pinojs/pino)
661
+ * Levels: fatal, error, warn, info, debug, trace
662
+ * Use `LOG_LEVL=info` to limit what's printed to console
663
+ * Use `Log.configure` to customize the pino instance
664
+ */
679
665
  var Log = class Log {
680
- static getStack() {
681
- const details = { stack: "" };
682
- Error.captureStackTrace(details, Log.getStack);
683
- return details.stack.split("\n").map((l) => l.trim()).filter((l) => l !== "Error");
684
- }
685
- /**
686
- * Gcloud parses JSON in stdout
687
- */
688
- static #toGcloud(entry) {
689
- const details = entry.details?.length === 1 ? entry.details[0] : entry.details;
690
- const output = {
691
- ...entry,
692
- details,
693
- stack: entry.stack || this.getStack()
694
- };
695
- console.log(JSON.stringify(snapshot(output)));
696
- }
697
- /**
698
- * Includes colors and better inspection for logging during dev
699
- */
700
- static #toConsole(entry, color) {
701
- if (entry.message) console.log(color(`${Format.date("h:m:s")} [${entry.severity}] ${entry.message}`));
702
- entry.details?.forEach((detail) => {
703
- console.log(inspect(detail, {
704
- depth: 10,
705
- breakLength: 100,
706
- compact: true,
707
- colors: true
708
- }));
709
- });
710
- }
711
- static #log({ severity, color }, ...input) {
712
- const { message, details } = this.prepare(...input);
713
- const entry = {
714
- message,
715
- severity,
716
- details
717
- };
718
- if (process.env.K_SERVICE !== void 0 || process.env.CLOUD_RUN_JOB !== void 0) this.#toGcloud(entry);
719
- else this.#toConsole(entry, color);
720
- return entry;
721
- }
722
- /**
723
- * Handle first argument being a string or an object with a 'message' prop
724
- */
725
- static prepare(...input) {
726
- let [firstArg, ...rest] = input;
727
- if (typeof firstArg === "string") return {
728
- message: firstArg,
729
- details: rest
730
- };
731
- if (isObjectLike(firstArg) && typeof firstArg["message"] === "string") {
732
- const { message, ...firstDetails } = firstArg;
733
- return {
734
- message,
735
- details: [firstDetails, ...rest]
736
- };
737
- }
738
- return { details: input };
739
- }
740
- /**
741
- * Events that require action or attention immediately
742
- */
743
- static alert(...input) {
744
- return this.#log({
745
- severity: "ALERT",
746
- color: chalk.bgRed
747
- }, ...input);
748
- }
749
- /**
750
- * Events that cause problems
751
- */
752
- static error(...input) {
753
- return this.#log({
754
- severity: "ERROR",
755
- color: chalk.red
756
- }, ...input);
757
- }
758
- /**
759
- * Events that might cause problems
760
- */
761
- static warn(...input) {
762
- return this.#log({
763
- severity: "WARNING",
764
- color: chalk.yellow
765
- }, ...input);
666
+ static #logger;
667
+ static #options;
668
+ static createLogger() {
669
+ const isProduction = this.#options?.environment === "production" || process.env.NODE_ENV === "production";
670
+ return pino(merge({
671
+ level: process.env.LOG_LEVEL ?? (isProduction ? "info" : "debug"),
672
+ timestamp: pino.stdTimeFunctions.isoTime,
673
+ formatters: { level(label) {
674
+ return { level: label };
675
+ } },
676
+ transport: isProduction ? void 0 : {
677
+ target: "pino-pretty",
678
+ options: {
679
+ colorize: true,
680
+ singleLine: true,
681
+ ignore: "pid,hostname"
682
+ }
683
+ }
684
+ }, this.#options));
685
+ }
686
+ static configure(options = {}) {
687
+ this.#options = options;
688
+ this.#logger = this.createLogger();
689
+ }
690
+ static #getLogger() {
691
+ return this.#logger ??= this.createLogger();
692
+ }
693
+ static #write(level, message, details) {
694
+ if (details === void 0) Log.#getLogger()[level](message);
695
+ else Log.#getLogger()[level](details, message);
696
+ }
697
+ static trace(message, details) {
698
+ Log.#write("trace", message, details);
699
+ }
700
+ static debug(message, details) {
701
+ Log.#write("debug", message, details);
702
+ }
703
+ static info(message, details) {
704
+ Log.#write("info", message, details);
705
+ }
706
+ static warn(message, details) {
707
+ Log.#write("warn", message, details);
708
+ }
709
+ static error(message, details) {
710
+ Log.#write("error", message, details);
711
+ }
712
+ static fatal(message, details) {
713
+ Log.#write("fatal", message, details);
766
714
  }
767
- /**
768
- * Normal but significant events, such as start up, shut down, or a configuration change
769
- */
770
- static notice(...input) {
771
- return this.#log({
772
- severity: "NOTICE",
773
- color: chalk.cyan
774
- }, ...input);
775
- }
776
- /**
777
- * Routine information, such as ongoing status or performance
778
- */
779
- static info(...input) {
780
- return this.#log({
781
- severity: "INFO",
782
- color: chalk.white
783
- }, ...input);
715
+ };
716
+
717
+ //#endregion
718
+ //#region src/snapshot.ts
719
+ /**
720
+ * @deprecated
721
+ * Allows special objects (Error, Headers, Set) to be included in JSON.stringify output. Functions are removed.
722
+ * ⚠️ This is bad! Only use it for debugging!
723
+ */
724
+ function snapshot(i, max = 50, depth = 0) {
725
+ if (Array.isArray(i)) {
726
+ if (depth === max) return [];
727
+ return i.map((c) => snapshot(c, max, depth + 1));
784
728
  }
785
- /**
786
- * Debug or trace information
787
- */
788
- static debug(...input) {
789
- return this.#log({
790
- severity: "DEBUG",
791
- color: chalk.gray
792
- }, ...input);
729
+ if (typeof i === "function") return void 0;
730
+ if (!isObjectLike(i)) return i;
731
+ if (depth === max) return {};
732
+ let output = {};
733
+ if (typeof i.entries === "function") {
734
+ for (let [k, v] of i.entries()) output[k] = snapshot(v, max, depth + 1);
735
+ return output;
793
736
  }
794
- };
737
+ const obj = i;
738
+ for (let key in obj) output[key] = snapshot(obj[key], max, depth + 1);
739
+ Object.getOwnPropertyNames(obj).forEach((key) => {
740
+ output[key] = snapshot(obj[key], max, depth + 1);
741
+ });
742
+ return output;
743
+ }
795
744
 
796
745
  //#endregion
797
746
  //#region src/timeout.ts
@@ -803,6 +752,14 @@ async function timeout(ms) {
803
752
 
804
753
  //#endregion
805
754
  //#region src/TypeWriter.ts
755
+ /**
756
+ * Wrapper for [quicktype-core](https://github.com/glideapps/quicktype)
757
+ * @example
758
+ * const group = new TypeWriter('Group');
759
+ * await types.addMember('Thing', [{ a: 1 }, { a: 2, b: 1 }]);
760
+ * await types.toFile();
761
+ * // type def for `Thing` saved in `types/Group.types.ts`
762
+ */
806
763
  var TypeWriter = class {
807
764
  moduleName;
808
765
  input = qt.jsonInputForTargetLanguage("typescript");
@@ -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/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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"}
1
+ {"version":3,"file":"index.mjs","names":["#resolve","parsed: Row[]","#parseVal","#inputPath","#resolved","params: [string, string][]","timeout","#logger","#options","#getLogger","#write","output: Record<string, any>","obj: Record<string, any>"],"sources":["../src/File.ts","../src/Format.ts","../src/Dir.ts","../src/Cache.ts","../src/Fetcher.ts","../src/Log.ts","../src/snapshot.ts","../src/timeout.ts","../src/TypeWriter.ts"],"sourcesContent":["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: string;\n root: string;\n dir: string;\n base: string;\n name: string;\n ext: string;\n type?: string;\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): 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(): boolean {\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(): void {\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(): string | undefined {\n return this.exists ? fs.readFileSync(this.path, 'utf8') : undefined;\n }\n\n /**\n * @returns lines as strings, removes trailing '\\n'\n */\n lines(): string[] {\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(): fs.ReadStream | Readable {\n return this.exists ? fs.createReadStream(this.path) : Readable.from([]);\n }\n\n get writeStream(): fs.WriteStream {\n fs.mkdirSync(this.dir, { recursive: true });\n return fs.createWriteStream(this.path);\n }\n\n write(contents: string | ReadableStream): void | Promise<void> {\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[]): void {\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): FileTypeJson<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(): typeof FileTypeJson {\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[]): FileTypeNdjson<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(): typeof FileTypeNdjson {\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[], options?: FileTypeCsvOptions<T>): Promise<FileTypeCsv<T>> {\n const csvFile = new FileTypeCsv<T>(this.path, options);\n if (rows) await csvFile.write(rows);\n return csvFile;\n }\n\n static get csv(): typeof FileTypeCsv {\n return FileTypeCsv;\n }\n}\n\n/**\n * A generic file adaptor, extended by specific file type implementations\n */\nexport class FileType {\n file: 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(): string {\n return this.file.path;\n }\n\n get root(): string {\n return this.file.root;\n }\n\n get dir(): string {\n return this.file.dir;\n }\n\n get base(): string {\n return this.file.base;\n }\n\n get name(): string {\n return this.file.name;\n }\n\n get ext(): string {\n return this.file.ext;\n }\n\n get type(): string | undefined {\n return this.file.type;\n }\n\n get exists(): boolean {\n return this.file.exists;\n }\n\n get stats(): Partial<fs.Stats> {\n return this.file.stats;\n }\n\n delete(): void {\n this.file.delete();\n }\n\n get readStream(): fs.ReadStream | Readable {\n return this.file.readStream;\n }\n\n get writeStream(): fs.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, 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(): T | undefined {\n const contents = this.file.read();\n return contents ? (JSON.parse(contents) as T) : undefined;\n }\n\n write(contents: T): void {\n this.file.write(JSON.stringify(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[]): void {\n this.file.append(Array.isArray(lines) ? lines.map(l => JSON.stringify(l)) : JSON.stringify(lines));\n }\n\n lines(): T[] {\n return this.file.lines().map(l => JSON.parse(l) as T);\n }\n}\n\ntype Key<T extends object> = keyof T;\n\ntype FileTypeCsvOptions<Row extends object> = {\n parseNumbers?: boolean;\n parseBooleans?: boolean;\n parseNulls?: boolean;\n keys?: Key<Row>[];\n};\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 options: FileTypeCsvOptions<Row>;\n\n constructor(filepath: string, options: FileTypeCsvOptions<Row> = {}) {\n super(filepath.endsWith('.csv') ? filepath : filepath + '.csv');\n this.options = {\n parseNumbers: true,\n parseBooleans: true,\n parseNulls: true,\n ...options,\n };\n }\n\n async write(rows: Row[]): Promise<void> {\n const headerSet = new Set<Key<Row>>();\n if (this.options.keys) {\n for (const key of this.options.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): string | number | boolean | null {\n const { parseNumbers, parseBooleans, parseNulls } = this.options;\n if (parseBooleans && val.toLowerCase() === 'false') return false;\n if (parseBooleans && val.toLowerCase() === 'true') return true;\n if (parseNulls && (val.length === 0 || val.toLowerCase() === 'null')) return null;\n if (parseNumbers && /^[\\.0-9]+$/.test(val)) return Number(val);\n return val;\n }\n\n async read(): Promise<Row[]> {\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 ): string {\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): string {\n return new Intl.NumberFormat('en-US', { maximumFractionDigits: places }).format(n);\n }\n\n static plural(amount: number, singular: string, multiple?: string): 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'): string {\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): string {\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: string;\n #resolved?: string;\n isTemp: boolean;\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(): string {\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(): string {\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(): string {\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 }): Dir {\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): Dir {\n return this.dir(subPath, { temp: true });\n }\n\n sanitize(filename: string): 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): 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')): File {\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(): Dir[] {\n return this.contents.filter(f => f instanceof Dir);\n }\n\n /**\n * All files in this directory\n */\n get files(): File[] {\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(): File[] {\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(): File[] {\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(): File[] {\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(): File[] {\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(): File[] {\n return this.files.filter(f => f.ext === '.csv');\n }\n\n /**\n * All files with ext \".txt\"\n */\n get txtFiles(): File[] {\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(): void {\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 { type FileTypeJson } from './File.ts';\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: FileTypeJson<{ savedAt: string; data: T }>;\n ttl: Duration;\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();\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: FetchOptions;\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 = {}): HeadersInit & Record<string, string> {\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 { merge } from 'lodash-es';\nimport { default as pino, type Logger } from 'pino';\n\nexport type LogDetails = Record<string, unknown>;\n\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\nexport type LogOptions = pino.LoggerOptions & {\n environment?: string;\n};\n\n/**\n * Wrapper for [pino](https://github.com/pinojs/pino)\n * Levels: fatal, error, warn, info, debug, trace\n * Use `LOG_LEVL=info` to limit what's printed to console\n * Use `Log.configure` to customize the pino instance\n */\nexport class Log {\n static #logger?: Logger;\n static #options: LogOptions;\n\n static createLogger(): Logger {\n const isProduction = this.#options?.environment === 'production' || process.env.NODE_ENV === 'production';\n const defaultOptions: LogOptions = {\n level: process.env.LOG_LEVEL ?? (isProduction ? 'info' : 'debug'),\n timestamp: pino.stdTimeFunctions.isoTime,\n formatters: {\n level(label: string) {\n return { level: label };\n },\n },\n transport: isProduction\n ? undefined\n : {\n target: 'pino-pretty',\n options: {\n colorize: true,\n singleLine: true,\n ignore: 'pid,hostname',\n },\n },\n };\n return pino(merge(defaultOptions, this.#options));\n }\n\n static configure(options: LogOptions = {}): void {\n this.#options = options;\n this.#logger = this.createLogger();\n }\n\n static #getLogger(): Logger {\n return (this.#logger ??= this.createLogger());\n }\n\n static #write(level: LogLevel, message: string, details?: LogDetails): void {\n if (details === undefined) {\n Log.#getLogger()[level](message);\n } else {\n Log.#getLogger()[level](details, message);\n }\n }\n\n static trace(message: string, details?: LogDetails): void {\n Log.#write('trace', message, details);\n }\n\n static debug(message: string, details?: LogDetails): void {\n Log.#write('debug', message, details);\n }\n\n static info(message: string, details?: LogDetails): void {\n Log.#write('info', message, details);\n }\n\n static warn(message: string, details?: LogDetails): void {\n Log.#write('warn', message, details);\n }\n\n static error(message: string, details?: LogDetails): void {\n Log.#write('error', message, details);\n }\n\n static fatal(message: string, details?: LogDetails): void {\n Log.#write('fatal', message, details);\n }\n}\n","import { isObjectLike } from 'lodash-es';\n\n/**\n * @deprecated\n * Allows special objects (Error, Headers, Set) to be included in JSON.stringify output. Functions are removed.\n * ⚠️ This is bad! Only use it for debugging!\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","export async function timeout(ms: number): Promise<void> {\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\n/**\n * Wrapper for [quicktype-core](https://github.com/glideapps/quicktype)\n * @example\n * const group = new TypeWriter('Group');\n * await types.addMember('Thing', [{ a: 1 }, { a: 2, b: 1 }]);\n * await types.toFile();\n * // type def for `Thing` saved in `types/Group.types.ts`\n */\nexport class TypeWriter {\n moduleName: string;\n input = qt.jsonInputForTargetLanguage('typescript');\n outDir: string;\n outFile: string;\n qtSettings: Partial<qt.Options>;\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[]): Promise<void> {\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(): Promise<string> {\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(): Promise<void> {\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":";;;;;;;;;;;;;;;;;;AAWA,IAAa,OAAb,MAAkB;CAChB;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,UAAkB;AAC5B,OAAK,OAAO,MAAKA,QAAS,SAAS;EACnC,MAAM,EAAE,MAAM,KAAK,MAAM,KAAK,SAAS,KAAK,MAAM,KAAK,KAAK;AAC5D,OAAK,OAAO;AACZ,OAAK,MAAM;AACX,OAAK,OAAO;AACZ,OAAK,OAAO;AACZ,OAAK,MAAM;AACX,OAAK,OAAO,KAAK,OAAO,IAAI,IAAI;;CAGlC,SAAS,UAA0B;AACjC,MAAI,SAAS,OAAO,IAClB,KAAI,QAAQ,IAAI,KACd,QAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,SAAS,MAAM,EAAE,CAAC;MAErD,SAAQ,KAAK,4EAA0E;AAG3F,SAAO,KAAK,QAAQ,SAAS;;CAG/B,IAAI,SAAkB;AACpB,SAAO,GAAG,WAAW,KAAK,KAAK;;CAGjC,IAAI,QAA2B;AAC7B,SAAO,KAAK,SAAS,GAAG,SAAS,KAAK,KAAK,GAAG,EAAE;;;;;CAMlD,SAAe;AACb,KAAG,OAAO,KAAK,MAAM,EAAE,OAAO,MAAM,CAAC;;;;;CAMvC,OAA2B;AACzB,SAAO,KAAK,SAAS,GAAG,aAAa,KAAK,MAAM,OAAO,GAAG;;;;;CAM5D,QAAkB;EAChB,MAAM,YAAY,KAAK,MAAM,IAAI,IAAI,MAAM,KAAK;AAChD,SAAO,SAAS,GAAG,GAAG,EAAE,SAAS,WAAW,SAAS,MAAM,GAAG,SAAS,SAAS,EAAE;;CAGpF,IAAI,aAAuC;AACzC,SAAO,KAAK,SAAS,GAAG,iBAAiB,KAAK,KAAK,GAAG,SAAS,KAAK,EAAE,CAAC;;CAGzE,IAAI,cAA8B;AAChC,KAAG,UAAU,KAAK,KAAK,EAAE,WAAW,MAAM,CAAC;AAC3C,SAAO,GAAG,kBAAkB,KAAK,KAAK;;CAGxC,MAAM,UAAyD;AAC7D,KAAG,UAAU,KAAK,KAAK,EAAE,WAAW,MAAM,CAAC;AAC3C,MAAI,OAAO,aAAa,SAAU,QAAO,GAAG,cAAc,KAAK,MAAM,SAAS;AAC9E,MAAI,oBAAoB,eAAgB,QAAO,SAAS,SAAS,KAAK,SAAS,CAAC,KAAK,KAAK,YAAY,CAAC;AACvG,QAAM,IAAI,MAAM,yBAAyB,OAAO,WAAW;;;;;;CAO7D,OAAO,OAAgC;AACrC,MAAI,CAAC,KAAK,OAAQ,MAAK,MAAM,GAAG;EAChC,MAAM,WAAW,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,KAAK,GAAG;AAC3D,KAAG,eAAe,KAAK,MAAM,WAAW,KAAK;;;;;;;;;;;;CAa/C,KAAQ,UAA+B;AACrC,SAAO,IAAI,aAAgB,KAAK,MAAM,SAAS;;;;;;CAOjD,WAAW,OAA4B;AACrC,SAAO;;;;;CAMT,OAAyB,OAAoC;AAC3D,SAAO,IAAI,eAAkB,KAAK,MAAM,MAAM;;;;;;;CAOhD,WAAW,SAAgC;AACzC,SAAO;;;;;;;;;;CAWT,MAAM,IAAsB,MAAY,SAA0D;EAChG,MAAM,UAAU,IAAI,YAAe,KAAK,MAAM,QAAQ;AACtD,MAAI,KAAM,OAAM,QAAQ,MAAM,KAAK;AACnC,SAAO;;CAGT,WAAW,MAA0B;AACnC,SAAO;;;;;;AAOX,IAAa,WAAb,MAAsB;CACpB;CAEA,YAAY,UAAkB,UAAmB;AAC/C,OAAK,OAAO,IAAI,KAAK,SAAS;AAC9B,MAAI,SAAU,MAAK,KAAK,MAAM,SAAS;;CAGzC,IAAI,OAAe;AACjB,SAAO,KAAK,KAAK;;CAGnB,IAAI,OAAe;AACjB,SAAO,KAAK,KAAK;;CAGnB,IAAI,MAAc;AAChB,SAAO,KAAK,KAAK;;CAGnB,IAAI,OAAe;AACjB,SAAO,KAAK,KAAK;;CAGnB,IAAI,OAAe;AACjB,SAAO,KAAK,KAAK;;CAGnB,IAAI,MAAc;AAChB,SAAO,KAAK,KAAK;;CAGnB,IAAI,OAA2B;AAC7B,SAAO,KAAK,KAAK;;CAGnB,IAAI,SAAkB;AACpB,SAAO,KAAK,KAAK;;CAGnB,IAAI,QAA2B;AAC7B,SAAO,KAAK,KAAK;;CAGnB,SAAe;AACb,OAAK,KAAK,QAAQ;;CAGpB,IAAI,aAAuC;AACzC,SAAO,KAAK,KAAK;;CAGnB,IAAI,cAA8B;AAChC,SAAO,KAAK,KAAK;;;;;;;;;;;;;;AAerB,IAAa,eAAb,cAAqC,SAAS;CAC5C,YAAY,UAAkB,UAAc;AAC1C,QAAM,SAAS,SAAS,QAAQ,GAAG,WAAW,WAAW,QAAQ;AACjE,MAAI,SAAU,MAAK,MAAM,SAAS;;CAGpC,OAAsB;EACpB,MAAM,WAAW,KAAK,KAAK,MAAM;AACjC,SAAO,WAAY,KAAK,MAAM,SAAS,GAAS;;CAGlD,MAAM,UAAmB;AACvB,OAAK,KAAK,MAAM,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;;;;;;;AAQtD,IAAa,iBAAb,cAAsD,SAAS;CAC7D,YAAY,UAAkB,OAAiB;AAC7C,QAAM,SAAS,SAAS,UAAU,GAAG,WAAW,WAAW,UAAU;AACrE,MAAI,MAAO,MAAK,OAAO,MAAM;;CAG/B,OAAO,OAAsB;AAC3B,OAAK,KAAK,OAAO,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAI,MAAK,KAAK,UAAU,EAAE,CAAC,GAAG,KAAK,UAAU,MAAM,CAAC;;CAGpG,QAAa;AACX,SAAO,KAAK,KAAK,OAAO,CAAC,KAAI,MAAK,KAAK,MAAM,EAAE,CAAM;;;;;;;AAiBzD,IAAa,cAAb,cAAqD,SAAS;CAC5D;CAEA,YAAY,UAAkB,UAAmC,EAAE,EAAE;AACnE,QAAM,SAAS,SAAS,OAAO,GAAG,WAAW,WAAW,OAAO;AAC/D,OAAK,UAAU;GACb,cAAc;GACd,eAAe;GACf,YAAY;GACZ,GAAG;GACJ;;CAGH,MAAM,MAAM,MAA4B;EACtC,MAAM,4BAAY,IAAI,KAAe;AACrC,MAAI,KAAK,QAAQ,KACf,MAAK,MAAM,OAAO,KAAK,QAAQ,KAAM,WAAU,IAAI,IAAI;MAEvD,MAAK,MAAM,OAAO,KAChB,MAAK,MAAM,OAAO,IAAK,WAAU,IAAI,IAAI;EAG7C,MAAM,UAAU,MAAM,KAAK,UAAU;EACrC,MAAM,UAAU,KAAK,KAAI,QAAO,QAAQ,KAAI,QAAO,IAAI,KAAK,CAAC;AAC7D,SAAO,SAAS,cAAc,KAAK,KAAK,aAAa,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;;CAG9E,UAAU,KAA+C;EACvD,MAAM,EAAE,cAAc,eAAe,eAAe,KAAK;AACzD,MAAI,iBAAiB,IAAI,aAAa,KAAK,QAAS,QAAO;AAC3D,MAAI,iBAAiB,IAAI,aAAa,KAAK,OAAQ,QAAO;AAC1D,MAAI,eAAe,IAAI,WAAW,KAAK,IAAI,aAAa,KAAK,QAAS,QAAO;AAC7E,MAAI,gBAAgB,aAAa,KAAK,IAAI,CAAE,QAAO,OAAO,IAAI;AAC9D,SAAO;;CAGT,MAAM,OAAuB;AAC3B,SAAO,IAAI,SAAgB,SAAS,WAAW;GAC7C,MAAMC,SAAgB,EAAE;AACxB,eAAY,KAAK,KAAK,YAAY,EAAE,SAAS,MAAM,CAAC,CACjD,GAAG,SAAS,QAAkC;AAC7C,WAAO,KACL,OAAO,QAAQ,IAAI,CAAC,QACjB,KAAK,CAAC,KAAK,UAAU;KACpB,GAAG;MACF,MAAM,MAAKC,SAAU,IAAc;KACrC,GACD,EAAE,CACH,CACF;KACD,CACD,GAAG,UAAS,MAAK,OAAO,EAAE,CAAC,CAC3B,GAAG,aAAa,QAAQ,OAAO,CAAC;IACnC;;;;;;;;;AChUN,IAAa,SAAb,MAAoB;;;;;;;;;;;;;CAalB,OAAO,KACL,YAAqE,OACrE,oBAAmB,IAAI,MAAM,EACrB;AACR,MAAI,cAAc,MAAO,QAAO,UAAU,EAAE;AAC5C,MAAI,cAAc,MAAO,QAAO,OAAO,GAAG,WAAW;AACrD,MAAI,cAAc,SAAU,QAAO,OAAO,GAAG,gBAAgB;AAC7D,MAAI,cAAc,UAAW,QAAO,OAAO,GAAG,kBAAkB;AAChE,MAAI,cAAc,QAAS,QAAO,OAAO,GAAG,WAAW;AACvD,SAAO,OAAO,GAAG,UAAU;;;;;CAM7B,OAAO,MAAM,GAAW,SAAS,GAAW;AAC1C,SAAO,IAAI,KAAK,aAAa,SAAS,EAAE,uBAAuB,QAAQ,CAAC,CAAC,OAAO,EAAE;;CAGpF,OAAO,OAAO,QAAgB,UAAkB,UAA2B;AACzE,SAAO,WAAW,IAAI,GAAG,OAAO,GAAG,aAAa,GAAG,OAAO,GAAG,YAAY,WAAW;;;;;;;;;CAUtF,OAAO,GAAG,IAAY,OAA2B;AAC/C,MAAI,UAAU,UAAW,QAAO,eAAe,IAAI,EAAE,SAAS,MAAM,CAAC;AACrE,MAAI,KAAK,IAAM,QAAO,GAAG,KAAK,MAAM,GAAG,CAAC;EACxC,MAAM,IAAI,KAAK;AACf,MAAI,IAAI,GAAI,QAAO,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC;EACvC,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAC5B,MAAI,IAAI,GAAI,QAAO,GAAG,EAAE,IAAI,KAAK,MAAM,EAAE,GAAG,GAAG;EAC/C,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG;AAC5B,MAAI,IAAI,GAAI,QAAO,GAAG,EAAE,IAAI,IAAI,GAAG;AAEnC,SAAO,GADG,KAAK,MAAM,IAAI,GAAG,CAChB,IAAI,IAAI,GAAG;;CAGzB,OAAO,MAAM,GAAmB;EAC9B,MAAM,SAAS;GAAC;GAAK;GAAM;GAAM;GAAM;GAAK;EAC5C,IAAI,SAAS;AACb,SAAO,KAAK,QAAQ,OAAO,SAAS,IAAI;AACtC,OAAI,IAAI;AACR;;AAEF,SAAO,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC,GAAG,OAAO;;;;;;;;;;;;;ACpDzC,IAAa,MAAb,MAAa,IAAI;CACf;CACA;CACA;;;;CAKA,YAAY,YAAY,OAAO,KAAK,MAAM,EAAE,UAAsB,EAAE,EAAE;AACpE,QAAKC,YAAa;AAClB,OAAK,SAAS,QAAQ,QAAQ,KAAK;;;;;CAMrC,IAAI,aAAqB;AACvB,MAAI,MAAKC,SAAW,QAAO,MAAKA;AAChC,MAAI,MAAKD,UAAW,OAAO,IACzB,KAAI,QAAQ,IAAI,KACd,QAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,MAAKA,UAAW,MAAM,EAAE,CAAC;MAE5D,SAAQ,KAAK,4EAA0E;AAG3F,SAAO,KAAK,QAAQ,MAAKA,UAAW;;;;;;CAOtC,IAAI,OAAe;AAEjB,MAAI,CAAC,MAAKC,UAAW;AACnB,SAAKA,WAAY,KAAK;AACtB,MAAG,UAAU,MAAKA,UAAW,EAAE,WAAW,MAAM,CAAC;;AAEnD,SAAO,MAAKA;;;;;;;;CASd,IAAI,OAAe;AACjB,SAAO,KAAK,WAAW,MAAM,KAAK,IAAI,CAAC,GAAG,GAAG;;;;;;;;;;;;;;CAe/C,IAAI,UAAU,OAAO,KAAK,MAAM,EAAE,UAAsB,EAAE,MAAM,KAAK,QAAQ,EAAO;AAClF,SAAO,IAAK,KAAK,YAA2B,KAAK,KAAK,KAAK,MAAM,QAAQ,EAAE,QAAQ;;;;;;CAOrF,QAAQ,SAAuB;AAC7B,SAAO,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;;CAG1C,SAAS,UAA0B;AAEjC,SAAO,iBADQ,SAAS,QAAQ,YAAY,GAAG,CAAC,QAAQ,QAAQ,GAAG,EACnC,EAAE,aAAa,KAAK,CAAC,CAAC,MAAM,KAAK;;;;;;;;;CAUnE,SAAS,MAAsB;AAC7B,SAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,SAAS,KAAK,CAAC;;;;;CAMrD,KAAK,OAAO,OAAO,KAAK,UAAU,EAAQ;AACxC,SAAO,IAAI,KAAK,KAAK,SAAS,KAAK,CAAC;;;;;CAMtC,IAAI,WAA2B;AAC7B,SAAO,GACJ,YAAY,KAAK,KAAK,CACtB,KAAI,SAAS,GAAG,SAAS,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC,aAAa,GAAG,KAAK,IAAI,KAAK,GAAG,KAAK,KAAK,KAAK,CAAE;;;;;CAM5G,IAAI,OAAc;AAChB,SAAO,KAAK,SAAS,QAAO,MAAK,aAAa,IAAI;;;;;CAMpD,IAAI,QAAgB;AAClB,SAAO,KAAK,SAAS,QAAO,MAAK,aAAa,KAAK;;;;;CAMrD,IAAI,SAAiB;AACnB,SAAO,KAAK,MAAM,QAAO,MAAK,EAAE,MAAM,SAAS,QAAQ,CAAC;;;;;CAM1D,IAAI,SAAiB;AACnB,SAAO,KAAK,MAAM,QAAO,MAAK,EAAE,MAAM,SAAS,QAAQ,CAAC;;;;;;;;;CAU1D,IAAI,YAAoB;AACtB,SAAO,KAAK,MAAM,QAAO,MAAK,EAAE,QAAQ,QAAQ;;;;;;;;;CAUlD,IAAI,cAAsB;AACxB,SAAO,KAAK,MAAM,QAAO,MAAK,EAAE,QAAQ,UAAU;;;;;;;;;CAUpD,IAAI,WAAmB;AACrB,SAAO,KAAK,MAAM,QAAO,MAAK,EAAE,QAAQ,OAAO;;;;;CAMjD,IAAI,WAAmB;AACrB,SAAO,KAAK,MAAM,QAAO,MAAK,EAAE,QAAQ,OAAO;;;;;CAMjD,QAAc;AACZ,MAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,uBAAuB;AACzD,KAAG,OAAO,KAAK,MAAM;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;AACtD,KAAG,UAAU,KAAK,MAAM,EAAE,WAAW,MAAM,CAAC;;;;;;AAOhD,MAAa,MAAM,IAAI,IAAI,KAAK;;;;AAIhC,MAAa,OAAO,IAAI,QAAQ,QAAQ;;;;;;;;;ACxMxC,IAAa,QAAb,MAAsB;CACpB;CACA;CAEA,YAAY,KAAa,KAAwB,aAAiB;AAEhE,OAAK,OADO,IAAI,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC,CAC7B,KAAK,IAAI,CAAC,MAAM;AAChC,OAAK,MAAM,OAAO,QAAQ,WAAW,EAAE,SAAS,KAAK,GAAG;AACxD,MAAI,YAAa,MAAK,MAAM,YAAY;;CAG1C,MAAM,MAAS;AACb,OAAK,KAAK,MAAM;GAAE,0BAAS,IAAI,MAAM,EAAC,aAAa;GAAE;GAAM,CAAC;;CAG9D,OAAiC;EAC/B,MAAM,EAAE,SAAS,SAAS,KAAK,KAAK,MAAM,IAAI,EAAE;AAEhD,SAAO,CAAC,MADQ,QAAQ,WAAW,QAAQ,IAAI,SAAS,KAAK,IAAI,kBAAE,IAAI,MAAM,CAAC,CAAC,CACzD;;;;;;;;;;;ACJ1B,IAAa,UAAb,MAAqB;CACnB;CAEA,YAAY,OAAqB,EAAE,EAAE;AACnC,OAAK,iBAAiB;GACpB,SAAS;GACT,SAAS;GACT,YAAY;GACZ,GAAG;GACJ;;;;;;;;;;CAWH,SAAS,OAAc,OAAqB,EAAE,EAAiB;EAC7D,MAAM,WAAW,iBAAiB,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,QAAQ,KAAK,eAAe,KAAK;EACrG,MAAM,aAAa,OAAO,YAAY,SAAS,aAAa;EAC5D,MAAM,gBAAgB,MAAM,EAAE,EAAE,KAAK,gBAAgB,EAAE,OAAO,YAAY,EAAE,KAAK;EACjF,MAAMC,SAA6B,EAAE;AACrC,SAAO,QAAQ,cAAc,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,SAAS;AAChE,OAAI,QAAQ,OAAW;AACvB,OAAI,MAAM,QAAQ,IAAI,CACpB,KAAI,SAAQ,MAAK;AACf,WAAO,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;KAC1B;OAEF,QAAO,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;IAE9B;EACF,MAAM,SAAS,OAAO,SAAS,IAAI,MAAM,IAAI,gBAAgB,OAAO,CAAC,UAAU,GAAG;EAClF,MAAM,MAAM,IAAI,IAAI,QAAQ,QAAQ,cAAc,KAAK;AAEvD,SAAO,CAAC,KADO,cAAc,IAAI,KAAK,CAClB;;;;;CAMtB,aAAa,OAAc,OAAqB,EAAE,EAAwC;EACxF,MAAM,EAAE,YAAY,MAAM,EAAE,EAAE,KAAK,gBAAgB,KAAK;AACxD,SAAO,WAAW,EAAE;;;;;;CAOtB,aAAa,OAAc,OAAqB,EAAE,EAAmC;EACnF,MAAM,gBAAgB,MAAM,EAAE,EAAE,KAAK,gBAAgB,KAAK;EAC1D,MAAM,EAAE,OAAO,MAAM,oBAAS,SAAS,GAAG,SAAS;AACnD,OAAK,UAAU,KAAK,aAAa,OAAO,cAAc;AACtD,MAAI,MAAM;AACR,QAAK,QAAQ,kBAAkB,KAAK,QAAQ,mBAAmB;AAC/D,QAAK,SAAS,KAAK,UAAU;AAC7B,QAAK,OAAO,KAAK,UAAU,KAAK;;AAElC,MAAIC,UACF,MAAK,SAAS,YAAY,QAAQA,UAAQ;EAE5C,MAAM,CAAC,KAAK,UAAU,KAAK,SAAS,OAAO,cAAc;AAEzD,SAAO;GADK,IAAI,QAAQ,KAAK,KAAK;GACrB;GAAe;GAAO;;;;;;;CAQrC,MAAM,MAAM,OAAc,OAAqB,EAAE,EAAgC;EAC/E,MAAM,CAAC,MAAM,WAAW,KAAK,aAAa,OAAO,KAAK;EACtD,MAAM,eAAe,QAAQ,WAAW,KAAK;EAC7C,IAAI,UAAU;AACd,SAAO,UAAU,aAAa;AAC5B;GACA,MAAM,CAAC,OAAO,KAAK,aAAa,OAAO,KAAK;GAC5C,MAAM,MAAM,MAAM,MAAM,IAAI,CACzB,MAAK,MAAK;AACT,QAAI,CAAC,EAAE,GAAI,OAAM,IAAI,MAAM,EAAE,WAAW;AACxC,WAAO;KACP,CACD,MAAM,OAAM,UAAS;AACpB,QAAI,UAAU,aAAa;KACzB,MAAM,OAAO,UAAU;AACvB,aAAQ,KAAK,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,YAAY,QAAQ,MAAM,YAAY,IAAI,MAAM;AACtF,WAAM,IAAI,SAAQ,YAAW,WAAW,SAAS,KAAK,CAAC;UAEvD,OAAM,IAAI,MAAM,MAAM;KAExB;AACJ,OAAI,IAAK,QAAO,CAAC,KAAK,IAAI;;AAE5B,QAAM,IAAI,MAAM,mBAAmB,KAAK,MAAM;;CAGhD,MAAM,UAAU,OAAc,OAAqB,EAAE,EAAwC;AAC3F,SAAO,KAAK,MAAM,OAAO,KAAK,CAAC,KAAK,OAAO,CAAC,KAAK,SAAS;AAExD,UAAO;IADM,MAAM,IAAI,MAAM;IACf;IAAK;IAAI;IACvB;;CAGJ,MAAM,UAAa,OAAc,OAAqB,EAAE,EAAmC;AACzF,SAAO,KAAK,UAAU,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS;GAAC,KAAK,MAAM,IAAI;GAAO;GAAK;GAAI,CAAC;;;;;;;;;;;;ACnHlG,IAAa,MAAb,MAAa,IAAI;CACf,QAAOC;CACP,QAAOC;CAEP,OAAO,eAAuB;EAC5B,MAAM,eAAe,MAAKA,SAAU,gBAAgB,gBAAgB,QAAQ,IAAI,aAAa;AAoB7F,SAAO,KAAK,MAnBuB;GACjC,OAAO,QAAQ,IAAI,cAAc,eAAe,SAAS;GACzD,WAAW,KAAK,iBAAiB;GACjC,YAAY,EACV,MAAM,OAAe;AACnB,WAAO,EAAE,OAAO,OAAO;MAE1B;GACD,WAAW,eACP,SACA;IACE,QAAQ;IACR,SAAS;KACP,UAAU;KACV,YAAY;KACZ,QAAQ;KACT;IACF;GACN,EACiC,MAAKA,QAAS,CAAC;;CAGnD,OAAO,UAAU,UAAsB,EAAE,EAAQ;AAC/C,QAAKA,UAAW;AAChB,QAAKD,SAAU,KAAK,cAAc;;CAGpC,QAAOE,YAAqB;AAC1B,SAAQ,MAAKF,WAAY,KAAK,cAAc;;CAG9C,QAAOG,MAAO,OAAiB,SAAiB,SAA4B;AAC1E,MAAI,YAAY,OACd,MAAID,WAAY,CAAC,OAAO,QAAQ;MAEhC,MAAIA,WAAY,CAAC,OAAO,SAAS,QAAQ;;CAI7C,OAAO,MAAM,SAAiB,SAA4B;AACxD,OAAIC,MAAO,SAAS,SAAS,QAAQ;;CAGvC,OAAO,MAAM,SAAiB,SAA4B;AACxD,OAAIA,MAAO,SAAS,SAAS,QAAQ;;CAGvC,OAAO,KAAK,SAAiB,SAA4B;AACvD,OAAIA,MAAO,QAAQ,SAAS,QAAQ;;CAGtC,OAAO,KAAK,SAAiB,SAA4B;AACvD,OAAIA,MAAO,QAAQ,SAAS,QAAQ;;CAGtC,OAAO,MAAM,SAAiB,SAA4B;AACxD,OAAIA,MAAO,SAAS,SAAS,QAAQ;;CAGvC,OAAO,MAAM,SAAiB,SAA4B;AACxD,OAAIA,MAAO,SAAS,SAAS,QAAQ;;;;;;;;;;;AC5EzC,SAAgB,SAAS,GAAY,MAAM,IAAI,QAAQ,GAAQ;AAC7D,KAAI,MAAM,QAAQ,EAAE,EAAE;AACpB,MAAI,UAAU,IAAK,QAAO,EAAE;AAC5B,SAAO,EAAE,KAAI,MAAK,SAAS,GAAG,KAAK,QAAQ,EAAE,CAAC;;AAEhD,KAAI,OAAO,MAAM,WAAY,QAAO;AACpC,KAAI,CAAC,aAAa,EAAE,CAAE,QAAO;AAE7B,KAAI,UAAU,IAAK,QAAO,EAAE;CAC5B,IAAIC,SAA8B,EAAE;AAEpC,KAAI,OAAO,EAAE,YAAY,YAAY;AAEnC,OAAK,IAAI,CAAC,GAAG,MAAM,EAAE,SAAS,CAC5B,QAAO,KAAK,SAAS,GAAG,KAAK,QAAQ,EAAE;AAEzC,SAAO;;CAMT,MAAMC,MAA2B;AACjC,MAAK,IAAI,OAAO,IACd,QAAO,OAAO,SAAS,IAAI,MAAM,KAAK,QAAQ,EAAE;AAIlD,QAAO,oBAAoB,IAAI,CAAC,SAAQ,QAAO;AAC7C,SAAO,OAAO,SAAS,IAAI,MAAM,KAAK,QAAQ,EAAE;GAChD;AAEF,QAAO;;;;;ACvCT,eAAsB,QAAQ,IAA2B;AACvD,QAAO,IAAI,SAAQ,YAAW;AAC5B,aAAW,SAAS,GAAG;GACvB;;;;;;;;;;;;;ACSJ,IAAa,aAAb,MAAwB;CACtB;CACA,QAAQ,GAAG,2BAA2B,aAAa;CACnD;CACA;CACA;CAEA,YAAY,YAAoB,WAAwE,EAAE,EAAE;AAC1G,OAAK,aAAa;EAClB,MAAM,EAAE,QAAQ,SAAS,GAAG,eAAe;AAC3C,OAAK,SAAS,UAAU;AACxB,OAAK,UAAU,WAAW,GAAG,KAAK,WAAW;AAU7C,OAAK,aAAa,MATM;GACtB,MAAM;GACN,iBAAiB;IACf,cAAc;IACd,gBAAgB;IACjB;GACD,YAAY;GACZ,gBAAgB;GACjB,EACwC,WAAW;;CAGtD,MAAM,UAAU,MAAc,UAAgC;EAC5D,MAAM,UAAU,SAAS,KAAI,MAAM,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,EAAE,CAAE;AAClF,QAAM,KAAK,MAAM,UAAU;GAAE;GAAM;GAAS,CAAC;;CAG/C,MAAM,WAA4B;EAChC,MAAM,YAAY,IAAI,GAAG,WAAW;AACpC,YAAU,SAAS,KAAK,MAAM;AAK9B,UAJe,MAAM,GAAG,UAAU;GAChC;GACA,GAAG,KAAK;GACT,CAAC,EACY,MAAM,KAAK,KAAK;;CAGhC,MAAM,SAAwB;EAC5B,MAAM,SAAS,MAAM,KAAK,UAAU;AACpC,KAAG,UAAU,KAAK,QAAQ,EAAE,WAAW,MAAM,CAAC;AAC9C,KAAG,cAAc,GAAG,KAAK,OAAO,GAAG,KAAK,WAAW,OAAO"}