@trazum/cli 1.46.0 → 1.48.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.
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +29 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +29 -1
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/types.d.ts +43 -1
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.js +146 -24
- package/dist/index.js.map +1 -1
- package/dist/waiver-log.d.ts +42 -0
- package/dist/waiver-log.d.ts.map +1 -0
- package/dist/waiver-log.js +74 -0
- package/dist/waiver-log.js.map +1 -0
- package/package.json +2 -2
- package/src/i18n/en.ts +41 -2
- package/src/i18n/es.ts +41 -2
- package/src/i18n/types.ts +37 -1
- package/src/index.ts +157 -21
- package/src/waiver-log.ts +81 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a waiver's uses are written down.
|
|
3
|
+
*
|
|
4
|
+
* The core decides what a use means and what a run of them adds up to; this
|
|
5
|
+
* decides where the bytes go — the same split every module here follows, so
|
|
6
|
+
* `@trazum/core` stays browser-safe and the CLI keeps its monopoly on I/O.
|
|
7
|
+
*
|
|
8
|
+
* **Append-only, and never rewritten.** There is deliberately no prune, no
|
|
9
|
+
* compaction and no `--clear`: a record of decisions that the tool can erase
|
|
10
|
+
* is a record nobody can rely on, and the one thing a waiver history is for is
|
|
11
|
+
* being awkward six months later. Deleting the file is a thing a person does
|
|
12
|
+
* with `rm`, on purpose, having seen it.
|
|
13
|
+
*
|
|
14
|
+
* **A write that fails never fails the run.** The gate's job is the exit code.
|
|
15
|
+
* A read-only checkout, a full disk or a directory somebody's CI cannot create
|
|
16
|
+
* must not turn a passing build red on account of bookkeeping — the failure is
|
|
17
|
+
* reported and the gate's own verdict stands.
|
|
18
|
+
*
|
|
19
|
+
* **A line that will not parse is counted and skipped**, exactly as in the
|
|
20
|
+
* store. Losing the whole history because one line is broken would be the
|
|
21
|
+
* worst possible response; pretending the history is complete would be the
|
|
22
|
+
* second worst.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
26
|
+
import { join } from 'node:path';
|
|
27
|
+
import { isWaiverUse } from '@trazum/core';
|
|
28
|
+
import type { WaiverUse } from '@trazum/core';
|
|
29
|
+
|
|
30
|
+
/** One file, not one per month: a waiver history is small and read whole. */
|
|
31
|
+
export const WAIVER_LOG = '.trazum/waivers.jsonl';
|
|
32
|
+
|
|
33
|
+
export interface WaiverReadResult {
|
|
34
|
+
uses: WaiverUse[];
|
|
35
|
+
/** 1-based positions of lines that would not parse. Named, never dropped quietly. */
|
|
36
|
+
unreadable: number[];
|
|
37
|
+
/** False when the file does not exist — "nothing recorded" is not "no file". */
|
|
38
|
+
present: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function readWaiverLog(root: string): Promise<WaiverReadResult> {
|
|
42
|
+
let raw: string;
|
|
43
|
+
try {
|
|
44
|
+
raw = await readFile(join(root, WAIVER_LOG), 'utf8');
|
|
45
|
+
} catch {
|
|
46
|
+
// Absent is the normal state of a repository that has never waived
|
|
47
|
+
// anything, and it is not an error.
|
|
48
|
+
return { uses: [], unreadable: [], present: false };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const uses: WaiverUse[] = [];
|
|
52
|
+
const unreadable: number[] = [];
|
|
53
|
+
raw.split('\n').forEach((line, index) => {
|
|
54
|
+
if (line.trim() === '') return;
|
|
55
|
+
try {
|
|
56
|
+
const parsed: unknown = JSON.parse(line);
|
|
57
|
+
if (isWaiverUse(parsed)) uses.push(parsed);
|
|
58
|
+
else unreadable.push(index + 1);
|
|
59
|
+
} catch {
|
|
60
|
+
unreadable.push(index + 1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return { uses, unreadable, present: true };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Appends one use, and swallows any failure after reporting it.
|
|
68
|
+
*
|
|
69
|
+
* Returns the error message rather than throwing, so the caller can print it
|
|
70
|
+
* beside the gate's own output without the gate ever depending on the write.
|
|
71
|
+
*/
|
|
72
|
+
export async function appendWaiverUse(root: string, use: WaiverUse): Promise<string | null> {
|
|
73
|
+
const path = join(root, WAIVER_LOG);
|
|
74
|
+
try {
|
|
75
|
+
await mkdir(join(path, '..'), { recursive: true });
|
|
76
|
+
await writeFile(path, `${JSON.stringify(use)}\n`, { flag: 'a', mode: 0o600 });
|
|
77
|
+
return null;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return error instanceof Error ? error.message : String(error);
|
|
80
|
+
}
|
|
81
|
+
}
|