@brianbuie/node-kit 0.12.4 → 0.12.5
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 +49 -9
- package/dist/index.d.mts +26 -29
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +54 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/prettier.config.ts +1 -3
- package/src/Dir.ts +7 -3
- package/src/Format.ts +29 -6
- package/src/Log.test.ts +0 -13
- package/src/Log.ts +32 -26
package/README.md
CHANGED
|
@@ -514,9 +514,10 @@ Helpers for formatting dates, times, and numbers as strings
|
|
|
514
514
|
|
|
515
515
|
```ts
|
|
516
516
|
export class Format {
|
|
517
|
-
static date(formatStr: "iso" | "ymd" | string = "iso", d: DateArg<Date> = new Date())
|
|
517
|
+
static date(formatStr: "iso" | "ymd" | "ymd-hm" | "ymd-hms" | "h:m:s" | string = "iso", d: DateArg<Date> = new Date())
|
|
518
518
|
static round(n: number, places = 0)
|
|
519
|
-
static
|
|
519
|
+
static plural(amount: number, singular: string, multiple?: string)
|
|
520
|
+
static ms(ms: number, style?: "digital")
|
|
520
521
|
static bytes(b: number)
|
|
521
522
|
}
|
|
522
523
|
```
|
|
@@ -530,22 +531,41 @@ export class Format {
|
|
|
530
531
|
date-fns format() with some shortcuts
|
|
531
532
|
|
|
532
533
|
```ts
|
|
533
|
-
static date(formatStr: "iso" | "ymd" | string = "iso", d: DateArg<Date> = new Date())
|
|
534
|
+
static date(formatStr: "iso" | "ymd" | "ymd-hm" | "ymd-hms" | "h:m:s" | string = "iso", d: DateArg<Date> = new Date())
|
|
534
535
|
```
|
|
535
536
|
|
|
536
537
|
Argument Details
|
|
537
538
|
|
|
538
539
|
+ **formatStr**
|
|
539
|
-
+
|
|
540
|
+
+ the format to use
|
|
541
|
+
+ **date**
|
|
542
|
+
+ the date to format, default `new Date()`
|
|
543
|
+
|
|
544
|
+
Example
|
|
545
|
+
|
|
546
|
+
```ts
|
|
547
|
+
Format.date('iso') // '2026-04-08T13:56:45Z'
|
|
548
|
+
Format.date('ymd') // '20260408'
|
|
549
|
+
Format.date('ymd-hm') // '20260408-1356'
|
|
550
|
+
Format.date('ymd-hms') // '20260408-135645'
|
|
551
|
+
Format.date('h:m:s') // '13:56:45'
|
|
552
|
+
```
|
|
540
553
|
|
|
541
554
|
### Method ms
|
|
542
555
|
|
|
543
556
|
Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")
|
|
544
557
|
|
|
545
558
|
```ts
|
|
546
|
-
static ms(ms: number)
|
|
559
|
+
static ms(ms: number, style?: "digital")
|
|
547
560
|
```
|
|
548
561
|
|
|
562
|
+
Argument Details
|
|
563
|
+
|
|
564
|
+
+ **ms**
|
|
565
|
+
+ milliseconds
|
|
566
|
+
+ **style**
|
|
567
|
+
+ 'digital' to output as 'HH:MM:SS'
|
|
568
|
+
|
|
549
569
|
### Method round
|
|
550
570
|
|
|
551
571
|
Round a number to a specific set of places
|
|
@@ -563,10 +583,10 @@ Links: [API](#api), [Classes](#classes), [Functions](#functions), [Types](#types
|
|
|
563
583
|
|
|
564
584
|
```ts
|
|
565
585
|
export class Log {
|
|
566
|
-
static
|
|
586
|
+
static getStack()
|
|
567
587
|
static #toGcloud(entry: Entry)
|
|
568
588
|
static #toConsole(entry: Entry, color: ChalkInstance)
|
|
569
|
-
static #log(
|
|
589
|
+
static #log({ severity, color }: Options, ...input: unknown[])
|
|
570
590
|
static prepare(...input: unknown[]): {
|
|
571
591
|
message?: string;
|
|
572
592
|
details: unknown[];
|
|
@@ -771,13 +791,33 @@ Links: [API](#api), [Classes](#classes), [Functions](#functions), [Types](#types
|
|
|
771
791
|
---
|
|
772
792
|
# Variables
|
|
773
793
|
|
|
794
|
+
| |
|
|
795
|
+
| --- |
|
|
796
|
+
| [cwd](#variable-cwd) |
|
|
797
|
+
| [temp](#variable-temp) |
|
|
798
|
+
|
|
799
|
+
Links: [API](#api), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
|
|
800
|
+
|
|
801
|
+
---
|
|
802
|
+
|
|
803
|
+
## Variable: cwd
|
|
804
|
+
|
|
805
|
+
```ts
|
|
806
|
+
cwd = new Dir("./")
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
See also: [Dir](#class-dir)
|
|
810
|
+
|
|
811
|
+
Links: [API](#api), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
|
|
812
|
+
|
|
813
|
+
---
|
|
774
814
|
## Variable: temp
|
|
775
815
|
|
|
776
816
|
```ts
|
|
777
|
-
temp =
|
|
817
|
+
temp = cwd.tempDir(".temp")
|
|
778
818
|
```
|
|
779
819
|
|
|
780
|
-
See also: [
|
|
820
|
+
See also: [cwd](#variable-cwd)
|
|
781
821
|
|
|
782
822
|
Links: [API](#api), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
|
|
783
823
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import { Readable } from "node:stream";
|
|
3
3
|
import { DateArg, Duration } from "date-fns";
|
|
4
|
-
import { ChalkInstance } from "chalk";
|
|
5
4
|
import * as qt from "quicktype-core";
|
|
6
5
|
import * as quicktype_core_dist_TargetLanguage_js0 from "quicktype-core/dist/TargetLanguage.js";
|
|
7
6
|
import * as quicktype_core_dist_support_Comments_js0 from "quicktype-core/dist/support/Comments.js";
|
|
@@ -196,7 +195,7 @@ declare class TempDir extends Dir {
|
|
|
196
195
|
clear(): void;
|
|
197
196
|
}
|
|
198
197
|
/**
|
|
199
|
-
*
|
|
198
|
+
* ./.temp in current working directory
|
|
200
199
|
*/
|
|
201
200
|
declare const temp: TempDir;
|
|
202
201
|
//#endregion
|
|
@@ -290,30 +289,44 @@ declare class Fetcher {
|
|
|
290
289
|
declare class Format {
|
|
291
290
|
/**
|
|
292
291
|
* date-fns format() with some shortcuts
|
|
293
|
-
* @param formatStr
|
|
294
|
-
*
|
|
292
|
+
* @param formatStr the format to use
|
|
293
|
+
* @param date the date to format, default `new Date()`
|
|
294
|
+
* @example
|
|
295
|
+
* Format.date('iso') // '2026-04-08T13:56:45Z'
|
|
296
|
+
* Format.date('ymd') // '20260408'
|
|
297
|
+
* Format.date('ymd-hm') // '20260408-1356'
|
|
298
|
+
* Format.date('ymd-hms') // '20260408-135645'
|
|
299
|
+
* Format.date('h:m:s') // '13:56:45'
|
|
300
|
+
* @see more format options https://date-fns.org/v4.1.0/docs/format
|
|
295
301
|
*/
|
|
296
|
-
static date(formatStr?: 'iso' | 'ymd' | string, d?: DateArg<Date>): string;
|
|
302
|
+
static date(formatStr?: 'iso' | 'ymd' | 'ymd-hm' | 'ymd-hms' | 'h:m:s' | string, d?: DateArg<Date>): string;
|
|
297
303
|
/**
|
|
298
304
|
* Round a number to a specific set of places
|
|
299
305
|
*/
|
|
300
306
|
static round(n: number, places?: number): string;
|
|
307
|
+
static plural(amount: number, singular: string, multiple?: string): string;
|
|
301
308
|
/**
|
|
302
309
|
* Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")
|
|
310
|
+
* @param ms milliseconds
|
|
311
|
+
* @param style 'digital' to output as 'HH:MM:SS'
|
|
312
|
+
* @see details on 'digital' format https://github.com/ungoldman/format-duration
|
|
313
|
+
* @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608
|
|
303
314
|
*/
|
|
304
|
-
static ms(ms: number): string;
|
|
315
|
+
static ms(ms: number, style?: 'digital'): string;
|
|
305
316
|
static bytes(b: number): string;
|
|
306
317
|
}
|
|
307
318
|
//#endregion
|
|
308
319
|
//#region src/Log.d.ts
|
|
309
320
|
type Severity = 'DEFAULT' | 'DEBUG' | 'INFO' | 'NOTICE' | 'WARNING' | 'ERROR' | 'CRITICAL' | 'ALERT' | 'EMERGENCY';
|
|
310
|
-
type
|
|
321
|
+
type Entry = {
|
|
322
|
+
message?: string;
|
|
311
323
|
severity: Severity;
|
|
312
|
-
|
|
324
|
+
stack?: string;
|
|
325
|
+
details?: unknown[];
|
|
313
326
|
};
|
|
314
327
|
declare class Log {
|
|
315
328
|
#private;
|
|
316
|
-
static
|
|
329
|
+
static getStack(): string[];
|
|
317
330
|
/**
|
|
318
331
|
* Handle first argument being a string or an object with a 'message' prop
|
|
319
332
|
*/
|
|
@@ -325,26 +338,10 @@ declare class Log {
|
|
|
325
338
|
* Logs error details before throwing
|
|
326
339
|
*/
|
|
327
340
|
static error(...input: unknown[]): void;
|
|
328
|
-
static warn(...input: unknown[]):
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
};
|
|
333
|
-
static notice(...input: unknown[]): {
|
|
334
|
-
message: string | undefined;
|
|
335
|
-
details: unknown[];
|
|
336
|
-
options: Options;
|
|
337
|
-
};
|
|
338
|
-
static info(...input: unknown[]): {
|
|
339
|
-
message: string | undefined;
|
|
340
|
-
details: unknown[];
|
|
341
|
-
options: Options;
|
|
342
|
-
};
|
|
343
|
-
static debug(...input: unknown[]): {
|
|
344
|
-
message: string | undefined;
|
|
345
|
-
details: unknown[];
|
|
346
|
-
options: Options;
|
|
347
|
-
} | undefined;
|
|
341
|
+
static warn(...input: unknown[]): Entry;
|
|
342
|
+
static notice(...input: unknown[]): Entry;
|
|
343
|
+
static info(...input: unknown[]): Entry;
|
|
344
|
+
static debug(...input: unknown[]): Entry;
|
|
348
345
|
}
|
|
349
346
|
//#endregion
|
|
350
347
|
//#region src/snapshot.d.ts
|
package/dist/index.d.mts.map
CHANGED
|
@@ -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
|
@@ -8,6 +8,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
10
|
import extractDomain from "extract-domain";
|
|
11
|
+
import formatDuration from "format-duration";
|
|
11
12
|
import { inspect } from "node:util";
|
|
12
13
|
import chalk from "chalk";
|
|
13
14
|
import * as qt from "quicktype-core";
|
|
@@ -366,9 +367,13 @@ var TempDir = class extends Dir {
|
|
|
366
367
|
}
|
|
367
368
|
};
|
|
368
369
|
/**
|
|
369
|
-
*
|
|
370
|
+
* Current working directory
|
|
370
371
|
*/
|
|
371
|
-
const
|
|
372
|
+
const cwd = new Dir("./");
|
|
373
|
+
/**
|
|
374
|
+
* ./.temp in current working directory
|
|
375
|
+
*/
|
|
376
|
+
const temp = cwd.tempDir(".temp");
|
|
372
377
|
|
|
373
378
|
//#endregion
|
|
374
379
|
//#region src/Cache.ts
|
|
@@ -512,12 +517,22 @@ var Fetcher = class {
|
|
|
512
517
|
var Format = class {
|
|
513
518
|
/**
|
|
514
519
|
* date-fns format() with some shortcuts
|
|
515
|
-
* @param formatStr
|
|
516
|
-
*
|
|
520
|
+
* @param formatStr the format to use
|
|
521
|
+
* @param date the date to format, default `new Date()`
|
|
522
|
+
* @example
|
|
523
|
+
* Format.date('iso') // '2026-04-08T13:56:45Z'
|
|
524
|
+
* Format.date('ymd') // '20260408'
|
|
525
|
+
* Format.date('ymd-hm') // '20260408-1356'
|
|
526
|
+
* Format.date('ymd-hms') // '20260408-135645'
|
|
527
|
+
* Format.date('h:m:s') // '13:56:45'
|
|
528
|
+
* @see more format options https://date-fns.org/v4.1.0/docs/format
|
|
517
529
|
*/
|
|
518
530
|
static date(formatStr = "iso", d = /* @__PURE__ */ new Date()) {
|
|
519
531
|
if (formatStr === "iso") return formatISO(d);
|
|
520
|
-
if (formatStr === "ymd") return format(d, "
|
|
532
|
+
if (formatStr === "ymd") return format(d, "yyyyMMdd");
|
|
533
|
+
if (formatStr === "ymd-hm") return format(d, "yyyyMMdd-HHmm");
|
|
534
|
+
if (formatStr === "ymd-hms") return format(d, "yyyyMMdd-HHmmss");
|
|
535
|
+
if (formatStr === "h:m:s") return format(d, "HH:mm:ss");
|
|
521
536
|
return format(d, formatStr);
|
|
522
537
|
}
|
|
523
538
|
/**
|
|
@@ -526,10 +541,18 @@ var Format = class {
|
|
|
526
541
|
static round(n, places = 0) {
|
|
527
542
|
return new Intl.NumberFormat("en-US", { maximumFractionDigits: places }).format(n);
|
|
528
543
|
}
|
|
544
|
+
static plural(amount, singular, multiple) {
|
|
545
|
+
return amount === 1 ? `${amount} ${singular}` : `${amount} ${multiple || singular + "s"}`;
|
|
546
|
+
}
|
|
529
547
|
/**
|
|
530
548
|
* Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")
|
|
549
|
+
* @param ms milliseconds
|
|
550
|
+
* @param style 'digital' to output as 'HH:MM:SS'
|
|
551
|
+
* @see details on 'digital' format https://github.com/ungoldman/format-duration
|
|
552
|
+
* @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608
|
|
531
553
|
*/
|
|
532
|
-
static ms(ms) {
|
|
554
|
+
static ms(ms, style) {
|
|
555
|
+
if (style === "digital") return formatDuration(ms, { leading: true });
|
|
533
556
|
if (ms < 1e3) return `${this.round(ms)}ms`;
|
|
534
557
|
const s = ms / 1e3;
|
|
535
558
|
if (s < 60) return `${this.round(s, 2)}s`;
|
|
@@ -558,23 +581,29 @@ var Format = class {
|
|
|
558
581
|
|
|
559
582
|
//#endregion
|
|
560
583
|
//#region src/Log.ts
|
|
561
|
-
var Log = class {
|
|
562
|
-
static
|
|
584
|
+
var Log = class Log {
|
|
585
|
+
static getStack() {
|
|
586
|
+
const details = { stack: "" };
|
|
587
|
+
Error.captureStackTrace(details, Log.getStack);
|
|
588
|
+
return details.stack.split("\n").map((l) => l.trim()).filter((l) => l !== "Error");
|
|
589
|
+
}
|
|
563
590
|
/**
|
|
564
591
|
* Gcloud parses JSON in stdout
|
|
565
592
|
*/
|
|
566
593
|
static #toGcloud(entry) {
|
|
567
|
-
|
|
594
|
+
const details = entry.details?.length === 1 ? entry.details[0] : entry.details;
|
|
595
|
+
const output = {
|
|
568
596
|
...entry,
|
|
569
|
-
details
|
|
570
|
-
|
|
571
|
-
|
|
597
|
+
details,
|
|
598
|
+
stack: entry.stack || this.getStack()
|
|
599
|
+
};
|
|
600
|
+
console.log(JSON.stringify(snapshot(output)));
|
|
572
601
|
}
|
|
573
602
|
/**
|
|
574
603
|
* Includes colors and better inspection for logging during dev
|
|
575
604
|
*/
|
|
576
605
|
static #toConsole(entry, color) {
|
|
577
|
-
if (entry.message) console.log(color(
|
|
606
|
+
if (entry.message) console.log(color(`${Format.date("h:m:s")} [${entry.severity}] ${entry.message}`));
|
|
578
607
|
entry.details?.forEach((detail) => {
|
|
579
608
|
console.log(inspect(detail, {
|
|
580
609
|
depth: 10,
|
|
@@ -584,42 +613,28 @@ var Log = class {
|
|
|
584
613
|
}));
|
|
585
614
|
});
|
|
586
615
|
}
|
|
587
|
-
static #log(
|
|
616
|
+
static #log({ severity, color }, ...input) {
|
|
588
617
|
const { message, details } = this.prepare(...input);
|
|
589
|
-
|
|
590
|
-
this.#toGcloud({
|
|
591
|
-
message,
|
|
592
|
-
severity: options.severity,
|
|
593
|
-
details
|
|
594
|
-
});
|
|
595
|
-
return {
|
|
596
|
-
message,
|
|
597
|
-
details,
|
|
598
|
-
options
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
if (!this.isTest) this.#toConsole({
|
|
618
|
+
const entry = {
|
|
602
619
|
message,
|
|
603
|
-
severity
|
|
620
|
+
severity,
|
|
604
621
|
details
|
|
605
|
-
}, options.color);
|
|
606
|
-
return {
|
|
607
|
-
message,
|
|
608
|
-
details,
|
|
609
|
-
options
|
|
610
622
|
};
|
|
623
|
+
if (process.env.K_SERVICE !== void 0 || process.env.CLOUD_RUN_JOB !== void 0) this.#toGcloud(entry);
|
|
624
|
+
else this.#toConsole(entry, color);
|
|
625
|
+
return entry;
|
|
611
626
|
}
|
|
612
627
|
/**
|
|
613
628
|
* Handle first argument being a string or an object with a 'message' prop
|
|
614
629
|
*/
|
|
615
630
|
static prepare(...input) {
|
|
616
|
-
let [
|
|
617
|
-
if (typeof
|
|
618
|
-
message:
|
|
631
|
+
let [firstArg, ...rest] = input;
|
|
632
|
+
if (typeof firstArg === "string") return {
|
|
633
|
+
message: firstArg,
|
|
619
634
|
details: rest
|
|
620
635
|
};
|
|
621
|
-
if (isObjectLike(
|
|
622
|
-
const { message, ...firstDetails } =
|
|
636
|
+
if (isObjectLike(firstArg) && typeof firstArg["message"] === "string") {
|
|
637
|
+
const { message, ...firstDetails } = firstArg;
|
|
623
638
|
return {
|
|
624
639
|
message,
|
|
625
640
|
details: [firstDetails, ...rest]
|
|
@@ -656,7 +671,7 @@ var Log = class {
|
|
|
656
671
|
}, ...input);
|
|
657
672
|
}
|
|
658
673
|
static debug(...input) {
|
|
659
|
-
|
|
674
|
+
return this.#log({
|
|
660
675
|
severity: "DEBUG",
|
|
661
676
|
color: chalk.gray
|
|
662
677
|
}, ...input);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["output: Record<string, any>","obj: Record<string, any>","parsed: Row[]","#parseVal","#inputPath","#resolved","params: [string, string][]","timeout","#toGcloud","#toConsole","#log"],"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 = path.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 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\n/**\n * Reference to a specific directory with methods to create and list files.\n * Default path: '.'\n * > Created on file system the first time .path is read or any methods are used\n */\nexport class Dir {\n #inputPath;\n #resolved?: string;\n\n /**\n * @param path can be relative to workspace or absolute\n */\n constructor(inputPath = '.') {\n this.#inputPath = inputPath;\n }\n\n /**\n * The path of this Dir instance. Created on file system the first time this property is read/used.\n */\n get path() {\n if (!this.#resolved) {\n this.#resolved = path.resolve(this.#inputPath);\n fs.mkdirSync(this.#resolved, { recursive: true });\n }\n return this.#resolved;\n }\n\n /**\n * Create a new Dir inside the current Dir\n * @param subPath joined with parent Dir's path to make new Dir\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) {\n return new Dir(path.join(this.path, subPath));\n }\n\n /**\n * Creates a new TempDir inside current Dir\n * @param subPath joined with parent Dir's path to make new TempDir\n */\n tempDir(subPath: string) {\n return new TempDir(path.join(this.path, subPath));\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 file(base: string) {\n return new File(this.filepath(base));\n }\n\n get files() {\n return fs.readdirSync(this.path).map((filename) => this.file(filename));\n }\n}\n\n/**\n * Extends Dir class with method to `clear()` contents.\n * Default path: `./.temp`\n */\nexport class TempDir extends Dir {\n constructor(inputPath = `./.temp`) {\n super(inputPath);\n }\n\n /**\n * > ⚠️ Warning! This deletes the directory!\n */\n clear() {\n fs.rmSync(this.path, { recursive: true, force: true });\n fs.mkdirSync(this.path, { recursive: true });\n }\n}\n\n/**\n * './.temp' in current working directory\n */\nexport const temp = new TempDir();\n","import { type Duration, isAfter, add } from 'date-fns';\nimport { TempDir } 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 TempDir('.cache');\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 */\n buildUrl(route: Route, opts: FetchOptions = {}): [URL, string] {\n const mergedOptions = merge({}, this.defaultOptions, 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, this.defaultOptions.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 } from 'date-fns';\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\n * 'iso' to get ISO date, 'ymd' to format as 'yyyy-MM-dd', full options: https://date-fns.org/v4.1.0/docs/format\n */\n static date(formatStr: 'iso' | 'ymd' | string = 'iso', d: DateArg<Date> = new Date()) {\n if (formatStr === 'iso') return formatISO(d);\n if (formatStr === 'ymd') return format(d, 'yyyy-MM-dd');\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 /**\n * Make millisecond durations actually readable (eg \"123ms\", \"3.56s\", \"1m 34s\", \"3h 24m\", \"2d 4h\")\n */\n static ms(ms: number) {\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';\n\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 details?: unknown[];\n};\n\nexport class Log {\n // Only silence logs when THIS package is running its own tests\n static isTest = process.env.npm_package_name === '@brianbuie/node-kit' && process.env.npm_lifecycle_event === 'test';\n\n /**\n * Gcloud parses JSON in stdout\n */\n static #toGcloud(entry: Entry) {\n if (entry.details?.length === 1) {\n console.log(JSON.stringify(snapshot({ ...entry, details: entry.details[0] })));\n } else {\n console.log(JSON.stringify(snapshot(entry)));\n }\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(`[${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(options: Options, ...input: unknown[]) {\n const { message, details } = this.prepare(...input);\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({ message, severity: options.severity, details });\n return { message, details, options };\n }\n // Hide output while testing this package\n if (!this.isTest) {\n this.#toConsole({ message, severity: options.severity, details }, options.color);\n }\n return { message, details, options };\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 [first, ...rest] = input;\n if (typeof first === 'string') {\n return { message: first, details: rest };\n }\n // @ts-ignore\n if (isObjectLike(first) && typeof first['message'] === 'string') {\n const { message, ...firstDetails } = first as { message: string };\n return { message, details: [firstDetails, ...rest] };\n }\n return { details: input };\n }\n\n /**\n * Logs error details before throwing\n */\n static error(...input: unknown[]) {\n const { message } = this.#log({ severity: 'ERROR', color: chalk.red }, ...input);\n throw new Error(message);\n }\n\n static warn(...input: unknown[]) {\n return this.#log({ severity: 'WARNING', color: chalk.yellow }, ...input);\n }\n\n static notice(...input: unknown[]) {\n return this.#log({ severity: 'NOTICE', color: chalk.cyan }, ...input);\n }\n\n static info(...input: unknown[]) {\n return this.#log({ severity: 'INFO', color: chalk.white }, ...input);\n }\n\n static debug(...input: unknown[]) {\n const debugging = process.argv.some((arg) => arg.includes('--debug')) || process.env.DEBUG !== undefined;\n if (debugging || process.env.NODE_ENV !== 'production') {\n return this.#log({ severity: 'DEBUG', color: chalk.gray }, ...input);\n }\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>","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 = path.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 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\n/**\n * Reference to a specific directory with methods to create and list files.\n * Default path: '.'\n * > Created on file system the first time .path is read or any methods are used\n */\nexport class Dir {\n #inputPath;\n #resolved?: string;\n\n /**\n * @param path can be relative to workspace or absolute\n */\n constructor(inputPath = '.') {\n this.#inputPath = inputPath;\n }\n\n /**\n * The path of this Dir instance. Created on file system the first time this property is read/used.\n */\n get path() {\n if (!this.#resolved) {\n this.#resolved = path.resolve(this.#inputPath);\n fs.mkdirSync(this.#resolved, { recursive: true });\n }\n return this.#resolved;\n }\n\n /**\n * Create a new Dir inside the current Dir\n * @param subPath joined with parent Dir's path to make new Dir\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) {\n return new Dir(path.join(this.path, subPath));\n }\n\n /**\n * Creates a new TempDir inside current Dir\n * @param subPath joined with parent Dir's path to make new TempDir\n */\n tempDir(subPath: string) {\n return new TempDir(path.join(this.path, subPath));\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 file(base: string) {\n return new File(this.filepath(base));\n }\n\n get files() {\n return fs.readdirSync(this.path).map(filename => this.file(filename));\n }\n}\n\n/**\n * Extends Dir class with method to `clear()` contents.\n * Default path: `./.temp`\n */\nexport class TempDir extends Dir {\n constructor(inputPath = `./.temp`) {\n super(inputPath);\n }\n\n /**\n * > ⚠️ Warning! This deletes the directory!\n */\n clear() {\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 { TempDir } 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 TempDir('.cache');\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 */\n buildUrl(route: Route, opts: FetchOptions = {}): [URL, string] {\n const mergedOptions = merge({}, this.defaultOptions, 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, this.defaultOptions.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\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 * Logs error details before throwing\n */\n static error(...input: unknown[]) {\n const { message } = this.#log({ severity: 'ERROR', color: chalk.red }, ...input);\n throw new Error(message);\n }\n\n static warn(...input: unknown[]) {\n return this.#log({ severity: 'WARNING', color: chalk.yellow }, ...input);\n }\n\n static notice(...input: unknown[]) {\n return this.#log({ severity: 'NOTICE', color: chalk.cyan }, ...input);\n }\n\n static info(...input: unknown[]) {\n return this.#log({ severity: 'INFO', color: chalk.white }, ...input);\n }\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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brianbuie/node-kit",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.5",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"description": "Basic tools for Node.js projects",
|
|
6
6
|
"author": "Brian Buie <brian@buie.dev>",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"date-fns": "^4.1.0",
|
|
39
39
|
"extract-domain": "^5.0.2",
|
|
40
40
|
"fast-csv": "^5.0.5",
|
|
41
|
+
"format-duration": "^3.0.2",
|
|
41
42
|
"lodash-es": "^4.17.21",
|
|
42
43
|
"mime-types": "^3.0.2",
|
|
43
44
|
"quicktype-core": "^23.2.6",
|
package/prettier.config.ts
CHANGED
package/src/Dir.ts
CHANGED
|
@@ -72,7 +72,7 @@ export class Dir {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
get files() {
|
|
75
|
-
return fs.readdirSync(this.path).map(
|
|
75
|
+
return fs.readdirSync(this.path).map(filename => this.file(filename));
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -95,6 +95,10 @@ export class TempDir extends Dir {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
98
|
+
* Current working directory
|
|
99
99
|
*/
|
|
100
|
-
export const
|
|
100
|
+
export const cwd = new Dir('./');
|
|
101
|
+
/**
|
|
102
|
+
* ./.temp in current working directory
|
|
103
|
+
*/
|
|
104
|
+
export const temp = cwd.tempDir('.temp');
|
package/src/Format.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { format, formatISO, type DateArg } from 'date-fns';
|
|
1
|
+
import { format, formatISO, type DateArg, type Duration } from 'date-fns';
|
|
2
|
+
import formatDuration from 'format-duration';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Helpers for formatting dates, times, and numbers as strings
|
|
@@ -6,12 +7,25 @@ import { format, formatISO, type DateArg } from 'date-fns';
|
|
|
6
7
|
export class Format {
|
|
7
8
|
/**
|
|
8
9
|
* date-fns format() with some shortcuts
|
|
9
|
-
* @param formatStr
|
|
10
|
-
*
|
|
10
|
+
* @param formatStr the format to use
|
|
11
|
+
* @param date the date to format, default `new Date()`
|
|
12
|
+
* @example
|
|
13
|
+
* Format.date('iso') // '2026-04-08T13:56:45Z'
|
|
14
|
+
* Format.date('ymd') // '20260408'
|
|
15
|
+
* Format.date('ymd-hm') // '20260408-1356'
|
|
16
|
+
* Format.date('ymd-hms') // '20260408-135645'
|
|
17
|
+
* Format.date('h:m:s') // '13:56:45'
|
|
18
|
+
* @see more format options https://date-fns.org/v4.1.0/docs/format
|
|
11
19
|
*/
|
|
12
|
-
static date(
|
|
20
|
+
static date(
|
|
21
|
+
formatStr: 'iso' | 'ymd' | 'ymd-hm' | 'ymd-hms' | 'h:m:s' | string = 'iso',
|
|
22
|
+
d: DateArg<Date> = new Date(),
|
|
23
|
+
) {
|
|
13
24
|
if (formatStr === 'iso') return formatISO(d);
|
|
14
|
-
if (formatStr === 'ymd') return format(d, '
|
|
25
|
+
if (formatStr === 'ymd') return format(d, 'yyyyMMdd');
|
|
26
|
+
if (formatStr === 'ymd-hm') return format(d, 'yyyyMMdd-HHmm');
|
|
27
|
+
if (formatStr === 'ymd-hms') return format(d, 'yyyyMMdd-HHmmss');
|
|
28
|
+
if (formatStr === 'h:m:s') return format(d, 'HH:mm:ss');
|
|
15
29
|
return format(d, formatStr);
|
|
16
30
|
}
|
|
17
31
|
|
|
@@ -22,10 +36,19 @@ export class Format {
|
|
|
22
36
|
return new Intl.NumberFormat('en-US', { maximumFractionDigits: places }).format(n);
|
|
23
37
|
}
|
|
24
38
|
|
|
39
|
+
static plural(amount: number, singular: string, multiple?: string) {
|
|
40
|
+
return amount === 1 ? `${amount} ${singular}` : `${amount} ${multiple || singular + 's'}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
25
43
|
/**
|
|
26
44
|
* Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")
|
|
45
|
+
* @param ms milliseconds
|
|
46
|
+
* @param style 'digital' to output as 'HH:MM:SS'
|
|
47
|
+
* @see details on 'digital' format https://github.com/ungoldman/format-duration
|
|
48
|
+
* @see waiting on `Intl.DurationFormat({ style: 'digital' })` types https://github.com/microsoft/TypeScript/issues/60608
|
|
27
49
|
*/
|
|
28
|
-
static ms(ms: number) {
|
|
50
|
+
static ms(ms: number, style?: 'digital') {
|
|
51
|
+
if (style === 'digital') return formatDuration(ms, { leading: true });
|
|
29
52
|
if (ms < 1000) return `${this.round(ms)}ms`;
|
|
30
53
|
const s = ms / 1000;
|
|
31
54
|
if (s < 60) return `${this.round(s, 2)}s`;
|
package/src/Log.test.ts
CHANGED
|
@@ -3,19 +3,6 @@ import assert from 'node:assert';
|
|
|
3
3
|
import { Log } from './Log.ts';
|
|
4
4
|
|
|
5
5
|
describe('Log', () => {
|
|
6
|
-
it('Throws error', () => {
|
|
7
|
-
try {
|
|
8
|
-
Log.error('Test error');
|
|
9
|
-
} catch (e) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
assert(false, 'Did not throw error');
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('Recognizes this is a test', () => {
|
|
16
|
-
assert(Log.isTest);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
6
|
it('Uses first argument as message when string', () => {
|
|
20
7
|
const result = Log.prepare('test', { something: 'else' });
|
|
21
8
|
assert(result.message === 'test');
|
package/src/Log.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { inspect } from 'node:util';
|
|
|
2
2
|
import { isObjectLike } from 'lodash-es';
|
|
3
3
|
import chalk, { type ChalkInstance } from 'chalk';
|
|
4
4
|
import { snapshot } from './snapshot.ts';
|
|
5
|
+
import { Format } from './Format.ts';
|
|
5
6
|
|
|
6
7
|
type Severity = 'DEFAULT' | 'DEBUG' | 'INFO' | 'NOTICE' | 'WARNING' | 'ERROR' | 'CRITICAL' | 'ALERT' | 'EMERGENCY';
|
|
7
8
|
|
|
@@ -13,62 +14,70 @@ type Options = {
|
|
|
13
14
|
type Entry = {
|
|
14
15
|
message?: string;
|
|
15
16
|
severity: Severity;
|
|
17
|
+
stack?: string;
|
|
16
18
|
details?: unknown[];
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export class Log {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
static getStack() {
|
|
23
|
+
const details = { stack: '' };
|
|
24
|
+
// replaces details.stack with current stack trace, excluding this Log.getStack call
|
|
25
|
+
Error.captureStackTrace(details, Log.getStack);
|
|
26
|
+
// remove 'Error' on first line
|
|
27
|
+
return details.stack
|
|
28
|
+
.split('\n')
|
|
29
|
+
.map(l => l.trim())
|
|
30
|
+
.filter(l => l !== 'Error');
|
|
31
|
+
}
|
|
22
32
|
|
|
23
33
|
/**
|
|
24
34
|
* Gcloud parses JSON in stdout
|
|
25
35
|
*/
|
|
26
36
|
static #toGcloud(entry: Entry) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
console.log(JSON.stringify(snapshot(entry)));
|
|
31
|
-
}
|
|
37
|
+
const details = entry.details?.length === 1 ? entry.details[0] : entry.details;
|
|
38
|
+
const output = { ...entry, details, stack: entry.stack || this.getStack() };
|
|
39
|
+
console.log(JSON.stringify(snapshot(output)));
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
/**
|
|
35
43
|
* Includes colors and better inspection for logging during dev
|
|
36
44
|
*/
|
|
37
45
|
static #toConsole(entry: Entry, color: ChalkInstance) {
|
|
38
|
-
if (entry.message) console.log(color(
|
|
39
|
-
entry.details?.forEach(
|
|
46
|
+
if (entry.message) console.log(color(`${Format.date('h:m:s')} [${entry.severity}] ${entry.message}`));
|
|
47
|
+
entry.details?.forEach(detail => {
|
|
40
48
|
console.log(inspect(detail, { depth: 10, breakLength: 100, compact: true, colors: true }));
|
|
41
49
|
});
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
static #log(
|
|
52
|
+
static #log({ severity, color }: Options, ...input: unknown[]) {
|
|
45
53
|
const { message, details } = this.prepare(...input);
|
|
54
|
+
const entry: Entry = { message, severity, details };
|
|
46
55
|
// https://cloud.google.com/run/docs/container-contract#env-vars
|
|
47
56
|
const isGcloud = process.env.K_SERVICE !== undefined || process.env.CLOUD_RUN_JOB !== undefined;
|
|
48
57
|
if (isGcloud) {
|
|
49
|
-
this.#toGcloud(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
// Hide output while testing this package
|
|
53
|
-
if (!this.isTest) {
|
|
54
|
-
this.#toConsole({ message, severity: options.severity, details }, options.color);
|
|
58
|
+
this.#toGcloud(entry);
|
|
59
|
+
} else {
|
|
60
|
+
this.#toConsole(entry, color);
|
|
55
61
|
}
|
|
56
|
-
return
|
|
62
|
+
return entry;
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
/**
|
|
60
66
|
* Handle first argument being a string or an object with a 'message' prop
|
|
61
67
|
*/
|
|
62
68
|
static prepare(...input: unknown[]): { message?: string; details: unknown[] } {
|
|
63
|
-
let [
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
let [firstArg, ...rest] = input;
|
|
70
|
+
// First argument is a string, use that as the message
|
|
71
|
+
if (typeof firstArg === 'string') {
|
|
72
|
+
return { message: firstArg, details: rest };
|
|
66
73
|
}
|
|
74
|
+
// First argument is an object with a `message` property
|
|
67
75
|
// @ts-ignore
|
|
68
|
-
if (isObjectLike(
|
|
69
|
-
const { message, ...firstDetails } =
|
|
76
|
+
if (isObjectLike(firstArg) && typeof firstArg['message'] === 'string') {
|
|
77
|
+
const { message, ...firstDetails } = firstArg as { message: string };
|
|
70
78
|
return { message, details: [firstDetails, ...rest] };
|
|
71
79
|
}
|
|
80
|
+
// No message found, log all args as details
|
|
72
81
|
return { details: input };
|
|
73
82
|
}
|
|
74
83
|
|
|
@@ -93,9 +102,6 @@ export class Log {
|
|
|
93
102
|
}
|
|
94
103
|
|
|
95
104
|
static debug(...input: unknown[]) {
|
|
96
|
-
|
|
97
|
-
if (debugging || process.env.NODE_ENV !== 'production') {
|
|
98
|
-
return this.#log({ severity: 'DEBUG', color: chalk.gray }, ...input);
|
|
99
|
-
}
|
|
105
|
+
return this.#log({ severity: 'DEBUG', color: chalk.gray }, ...input);
|
|
100
106
|
}
|
|
101
107
|
}
|