@leemour/cli-core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -3
- package/dist/logging.d.ts +6 -1
- package/dist/logging.d.ts.map +1 -1
- package/dist/logging.js +4 -1
- package/dist/logging.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ keyring behind a testable seam, and injectable clocks.
|
|
|
7
7
|
Extracted from [`brazecli`](https://github.com/leemour/brazecli), where each piece earned its
|
|
8
8
|
shape, and shared with [`max-cli`](https://github.com/leemour/max-cli).
|
|
9
9
|
|
|
10
|
-
**Status: 0.1.
|
|
11
|
-
unchanged, and the ones that needed a parameter threaded through.
|
|
10
|
+
**Status: 0.1.1.** Published on npm, used by `max-cli`. Both extraction steps have landed: the
|
|
11
|
+
files that move unchanged, and the ones that needed a parameter threaded through. 75 tests.
|
|
12
12
|
|
|
13
13
|
## The rule this package exists to keep
|
|
14
14
|
|
|
@@ -40,7 +40,7 @@ streams.stderr // []
|
|
|
40
40
|
| `paths` | `env-paths` for config, state and cache, each overridable by environment variable |
|
|
41
41
|
| `config` | JSON config loading that names the bad field, and an atomic write that locks the directory down |
|
|
42
42
|
| `credentials` | environment → keyring → file, warning once and falling through when the keyring refuses |
|
|
43
|
-
| `logging` | a Pino adapter writing JSON lines with secrets redacted by field name |
|
|
43
|
+
| `logging` | a Pino adapter writing JSON lines with secrets redacted by field name; a file that cannot be written is reported to `onError`, never thrown |
|
|
44
44
|
| `retry` | full-jitter backoff, and the distinction between "no answer came" and "safe to repeat" |
|
|
45
45
|
| `/testing` | `captureStreams`, `memoryKeyring`, `brokenKeyring`, `fakeClock` |
|
|
46
46
|
|
|
@@ -101,6 +101,19 @@ pnpm typecheck
|
|
|
101
101
|
pnpm build
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
+
## Releasing
|
|
105
|
+
|
|
106
|
+
Raise `version` in `package.json` through a pull request, merge it, then on `main`:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
bin/release
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
It refuses a dirty tree, a branch other than `main` and a version npm already has, runs every
|
|
113
|
+
check, publishes with the npm token from the keyring (`secret-tool`, service `npm`, account
|
|
114
|
+
`leemour`) without printing it, and tags `v<version>` only once npm shows the new version. The
|
|
115
|
+
token must be allowed to write `@leemour/cli-core`, not only `@leemour/max-cli`.
|
|
116
|
+
|
|
104
117
|
## Licence
|
|
105
118
|
|
|
106
119
|
MIT.
|
package/dist/logging.d.ts
CHANGED
|
@@ -16,11 +16,16 @@ export interface FileLoggerOptions {
|
|
|
16
16
|
base?: Record<string, unknown>;
|
|
17
17
|
/** Added to `REDACTED_FIELDS` — the names only this program knows about. */
|
|
18
18
|
redact?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Told once when the file cannot be opened or written; every record after that is dropped.
|
|
21
|
+
* Without it the failure is silent, so a host that promised a log should say it is gone.
|
|
22
|
+
*/
|
|
23
|
+
onError?: (error: Error) => void;
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
21
26
|
* Structured records for machines: JSON lines, no ANSI ever, secrets redacted. The terminal is a
|
|
22
27
|
* different concern and goes through the renderer — a spinner frame must never reach a log file,
|
|
23
28
|
* and a log record must never reach stdout.
|
|
24
29
|
*/
|
|
25
|
-
export declare const createFileLogger: ({ path, level, base, redact, }?: FileLoggerOptions) => FileLogger;
|
|
30
|
+
export declare const createFileLogger: ({ path, level, base, redact, onError, }?: FileLoggerOptions) => FileLogger;
|
|
26
31
|
//# sourceMappingURL=logging.d.ts.map
|
package/dist/logging.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,UAa3B,CAAA;AAED,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,iFAAiF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,UAa3B,CAAA;AAED,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,iFAAiF;IACjF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,0CAM9B,iBAAsB,KAAG,UA8B3B,CAAA"}
|
package/dist/logging.js
CHANGED
|
@@ -24,13 +24,16 @@ export const REDACTED_FIELDS = [
|
|
|
24
24
|
* different concern and goes through the renderer — a spinner frame must never reach a log file,
|
|
25
25
|
* and a log record must never reach stdout.
|
|
26
26
|
*/
|
|
27
|
-
export const createFileLogger = ({ path, level = "info", base = {}, redact = [], } = {}) => {
|
|
27
|
+
export const createFileLogger = ({ path, level = "info", base = {}, redact = [], onError = () => { }, } = {}) => {
|
|
28
28
|
if (!path)
|
|
29
29
|
return { ...silent, close: async () => { } };
|
|
30
30
|
// A plain append stream, not a worker transport: logging must not need a second process, and
|
|
31
31
|
// `sync: false` drops the tail of the file when a command exits — which is exactly the failure
|
|
32
32
|
// the log exists to explain.
|
|
33
33
|
const file = createWriteStream(path, { flags: "a" });
|
|
34
|
+
// The open is asynchronous, so a directory removed a moment ago surfaces here as an `error`
|
|
35
|
+
// event — and one with no listener kills the process the log was only meant to describe.
|
|
36
|
+
file.on("error", onError);
|
|
34
37
|
const fields = [...new Set([...REDACTED_FIELDS, ...redact])];
|
|
35
38
|
const paths = fields.flatMap((field) => [field, `*.${field}`, `*.*.${field}`]);
|
|
36
39
|
const logger = pino({ level, base, redact: { paths, censor: "[redacted]" }, timestamp: pino.stdTimeFunctions.isoTime }, file);
|
package/dist/logging.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,eAAe;IACf,eAAe;IACf,QAAQ;IACR,SAAS;IACT,OAAO;IACP,aAAa;IACb,cAAc;IACd,cAAc;IACd,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,OAAO;CACR,CAAA;
|
|
1
|
+
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,eAAe;IACf,eAAe;IACf,QAAQ;IACR,SAAS;IACT,OAAO;IACP,aAAa;IACb,cAAc;IACd,cAAc;IACd,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,OAAO;CACR,CAAA;AAqBD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAC/B,IAAI,EACJ,KAAK,GAAG,MAAM,EACd,IAAI,GAAG,EAAE,EACT,MAAM,GAAG,EAAE,EACX,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,MACG,EAAE,EAAc,EAAE;IACvC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAE,CAAA;IAEtD,6FAA6F;IAC7F,+FAA+F;IAC/F,6BAA6B;IAC7B,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACpD,4FAA4F;IAC5F,yFAAyF;IACzF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACzB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,EAAE,EAAE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAA;IAE9E,MAAM,MAAM,GAAG,IAAI,CACjB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAClG,IAAI,CACL,CAAA;IAED,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;QACvD,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;QACrD,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;QACrD,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;QACvD,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE;gBACZ,OAAO,EAAE,CAAA;YACX,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC;KACL,CAAA;AACH,CAAC,CAAA;AAED,MAAM,MAAM,GAAW;IACrB,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leemour/cli-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "The parts every command line tool needs: output modes, terminal rendering, error model, exit codes, credentials, clocks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|