@nekostack/cli 1.0.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/CHANGELOG.md +42 -0
- package/LICENSE +202 -0
- package/README.md +89 -0
- package/bin/neko +6 -0
- package/dist/.build.tsbuildinfo +1 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/cli.d.ts +60 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +355 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +11 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/schema/check.d.ts +55 -0
- package/dist/commands/schema/check.d.ts.map +1 -0
- package/dist/commands/schema/check.js +197 -0
- package/dist/commands/schema/check.js.map +1 -0
- package/dist/commands/schema/diff.d.ts +48 -0
- package/dist/commands/schema/diff.d.ts.map +1 -0
- package/dist/commands/schema/diff.js +245 -0
- package/dist/commands/schema/diff.js.map +1 -0
- package/dist/commands/schema/generate.d.ts +59 -0
- package/dist/commands/schema/generate.d.ts.map +1 -0
- package/dist/commands/schema/generate.js +135 -0
- package/dist/commands/schema/generate.js.map +1 -0
- package/dist/commands/schema/list.d.ts +50 -0
- package/dist/commands/schema/list.d.ts.map +1 -0
- package/dist/commands/schema/list.js +115 -0
- package/dist/commands/schema/list.js.map +1 -0
- package/dist/commands/schema/migrate/list.d.ts +65 -0
- package/dist/commands/schema/migrate/list.d.ts.map +1 -0
- package/dist/commands/schema/migrate/list.js +148 -0
- package/dist/commands/schema/migrate/list.js.map +1 -0
- package/dist/commands/schema/migrate/plan.d.ts +79 -0
- package/dist/commands/schema/migrate/plan.d.ts.map +1 -0
- package/dist/commands/schema/migrate/plan.js +255 -0
- package/dist/commands/schema/migrate/plan.js.map +1 -0
- package/dist/commands/schema/migrate/stub.d.ts +59 -0
- package/dist/commands/schema/migrate/stub.d.ts.map +1 -0
- package/dist/commands/schema/migrate/stub.js +195 -0
- package/dist/commands/schema/migrate/stub.js.map +1 -0
- package/dist/commands/schema/migrate/verify.d.ts +59 -0
- package/dist/commands/schema/migrate/verify.d.ts.map +1 -0
- package/dist/commands/schema/migrate/verify.js +268 -0
- package/dist/commands/schema/migrate/verify.js.map +1 -0
- package/dist/exit-codes.d.ts +47 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +46 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/formatters/json.d.ts +25 -0
- package/dist/formatters/json.d.ts.map +1 -0
- package/dist/formatters/json.js +27 -0
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/pretty.d.ts +131 -0
- package/dist/formatters/pretty.d.ts.map +1 -0
- package/dist/formatters/pretty.js +229 -0
- package/dist/formatters/pretty.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/loaders/read-artifacts.d.ts +55 -0
- package/dist/loaders/read-artifacts.d.ts.map +1 -0
- package/dist/loaders/read-artifacts.js +99 -0
- package/dist/loaders/read-artifacts.js.map +1 -0
- package/dist/loaders/read-migrations.d.ts +70 -0
- package/dist/loaders/read-migrations.d.ts.map +1 -0
- package/dist/loaders/read-migrations.js +206 -0
- package/dist/loaders/read-migrations.js.map +1 -0
- package/dist/loaders/tsx-loader.d.ts +116 -0
- package/dist/loaders/tsx-loader.d.ts.map +1 -0
- package/dist/loaders/tsx-loader.js +250 -0
- package/dist/loaders/tsx-loader.js.map +1 -0
- package/dist/loaders/walk-workspace.d.ts +62 -0
- package/dist/loaders/walk-workspace.d.ts.map +1 -0
- package/dist/loaders/walk-workspace.js +133 -0
- package/dist/loaders/walk-workspace.js.map +1 -0
- package/docs/SCOPE.md +42 -0
- package/package.json +39 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `neko schema migrate verify` command implementation (v0.8 Step 22).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `runMigratePlan`'s pure / writer-injected discipline
|
|
5
|
+
* (Master plan Decision #1).
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
*
|
|
9
|
+
* 1. `walkWorkspace({ root })` — load every `*.schema.{ts,js}`.
|
|
10
|
+
* Any per-file load failure → IO_ERROR.
|
|
11
|
+
* 2. `buildRegistry(walk.entries)` — index the schemas.
|
|
12
|
+
* `duplicate_schema_id` → LOGICAL_FAILURE; `integrity_error` →
|
|
13
|
+
* INTEGRITY_ERROR.
|
|
14
|
+
* 3. `readMigrations({ root })` — load every `*.migration.ts`.
|
|
15
|
+
* Any per-file load failure → IO_ERROR.
|
|
16
|
+
* 4. `buildMigrationRegistry(migWalk.entries)` — index migrations
|
|
17
|
+
* and parse each one's provenance. `duplicate_migration` →
|
|
18
|
+
* LOGICAL_FAILURE; `integrity_error` → INTEGRITY_ERROR.
|
|
19
|
+
* 5. **CLI-side verdict derivation** — walk the migration registry
|
|
20
|
+
* with the same classification rule as
|
|
21
|
+
* `verifyMigrationProvenance` so the CLI can surface verdicts +
|
|
22
|
+
* summary on BOTH the success and failure JSON branches. (The
|
|
23
|
+
* schema-side handler discards verdicts on failure; the v0.8
|
|
24
|
+
* verify-CLI contract requires them on both branches.)
|
|
25
|
+
* 6. `verifyMigrationsHandler({ schemaRegistry, migrationRegistry })`
|
|
26
|
+
* — gets the official success/failure determination and any
|
|
27
|
+
* `migration_drift` / `migration_missing_endpoint` issues.
|
|
28
|
+
* 7. Format and write:
|
|
29
|
+
* - `--json` (success) → `{ verdicts, summary }`
|
|
30
|
+
* - `--json` (failure) → `{ verdicts, summary, issues }`
|
|
31
|
+
* - pretty → summary header + per-verdict rows
|
|
32
|
+
* 8. Exit-code mapping:
|
|
33
|
+
* - any drift / missing_endpoint → LOGICAL_FAILURE
|
|
34
|
+
* - only bound / cosmetic_drift (or empty registry) → SUCCESS
|
|
35
|
+
*
|
|
36
|
+
* **Pure.** No `process.exit`, no `console.*`, no direct
|
|
37
|
+
* `process.stdout` / `process.stderr` writes. Writers are injected.
|
|
38
|
+
*
|
|
39
|
+
* **`migration.transform` is NEVER invoked here.** Verification is
|
|
40
|
+
* provenance-only (the v0.8 INVARIANTS contract). Static-scan
|
|
41
|
+
* asserted by [`../../../../tests/commands/schema-migrate-verify.test.ts`](../../../../tests/commands/schema-migrate-verify.test.ts).
|
|
42
|
+
*
|
|
43
|
+
* **JSON output never serializes `MigrationEntry.migration` or its
|
|
44
|
+
* `transform` closure.** Verdicts are already shaped as
|
|
45
|
+
* `{ status, schemaId, fromVersion, toVersion, sourcePath }` per the
|
|
46
|
+
* `MigrationVerdict` type — no migration reference — so the projection
|
|
47
|
+
* is the identity. Issue records likewise carry only structured
|
|
48
|
+
* metadata.
|
|
49
|
+
*/
|
|
50
|
+
import { buildMigrationRegistry, buildRegistry, findSchema, verifyMigrationsHandler, } from "@nekostack/schema/cli";
|
|
51
|
+
import { EXIT_CODES } from "../../../exit-codes.js";
|
|
52
|
+
import { formatJson } from "../../../formatters/json.js";
|
|
53
|
+
import { formatIssuesPretty, formatLoadFailuresPretty, } from "../../../formatters/pretty.js";
|
|
54
|
+
import { readMigrations } from "../../../loaders/read-migrations.js";
|
|
55
|
+
import { walkWorkspace } from "../../../loaders/walk-workspace.js";
|
|
56
|
+
/**
|
|
57
|
+
* CLI-side mirror of `verifyMigrationProvenance`'s classification +
|
|
58
|
+
* iteration discipline. Produces verdicts on **every** invocation —
|
|
59
|
+
* the schema-side handler drops them on the failure branch, but the
|
|
60
|
+
* CLI must surface them on both branches per the Step 22 JSON
|
|
61
|
+
* contract.
|
|
62
|
+
*
|
|
63
|
+
* Source of truth for the classification rule is
|
|
64
|
+
* [`packages/schema/src/migrations/verify-provenance.ts`](../../../../../schema/src/migrations/verify-provenance.ts).
|
|
65
|
+
* Decision #9 (the four-way verdict matrix) is locked in
|
|
66
|
+
* `packages/schema/docs/MIGRATIONS.md`; any future change there must
|
|
67
|
+
* land here too.
|
|
68
|
+
*
|
|
69
|
+
* Iteration is `(schemaId, fromVersion, toVersion)` lex-ascending so
|
|
70
|
+
* the CLI verdicts list matches the handler's on success.
|
|
71
|
+
*/
|
|
72
|
+
function deriveVerdicts(schemaRegistry, migrationRegistry) {
|
|
73
|
+
const verdicts = [];
|
|
74
|
+
const counts = { bound: 0, cosmetic_drift: 0, drift: 0, missing_endpoint: 0 };
|
|
75
|
+
for (const entry of iterateRegistry(migrationRegistry)) {
|
|
76
|
+
const verdict = classifyEntry(entry, schemaRegistry);
|
|
77
|
+
verdicts.push(verdict);
|
|
78
|
+
counts[verdict.status] += 1;
|
|
79
|
+
}
|
|
80
|
+
return { verdicts, summary: counts };
|
|
81
|
+
}
|
|
82
|
+
function* iterateRegistry(registry) {
|
|
83
|
+
const schemaIds = [...registry.keys()].sort();
|
|
84
|
+
for (const schemaId of schemaIds) {
|
|
85
|
+
const byFrom = registry.get(schemaId);
|
|
86
|
+
if (byFrom === undefined)
|
|
87
|
+
continue;
|
|
88
|
+
const fromVersions = [...byFrom.keys()].sort();
|
|
89
|
+
for (const fromVersion of fromVersions) {
|
|
90
|
+
const byTo = byFrom.get(fromVersion);
|
|
91
|
+
if (byTo === undefined)
|
|
92
|
+
continue;
|
|
93
|
+
const toVersions = [...byTo.keys()].sort();
|
|
94
|
+
for (const toVersion of toVersions) {
|
|
95
|
+
const entry = byTo.get(toVersion);
|
|
96
|
+
if (entry !== undefined)
|
|
97
|
+
yield entry;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function classifyEntry(entry, schemaRegistry) {
|
|
103
|
+
const base = {
|
|
104
|
+
sourcePath: entry.sourcePath,
|
|
105
|
+
schemaId: entry.schemaId,
|
|
106
|
+
fromVersion: entry.fromVersion,
|
|
107
|
+
toVersion: entry.toVersion,
|
|
108
|
+
};
|
|
109
|
+
const fromSchema = findSchema(schemaRegistry, entry.schemaId, entry.fromVersion);
|
|
110
|
+
const toSchema = findSchema(schemaRegistry, entry.schemaId, entry.toVersion);
|
|
111
|
+
if (fromSchema === undefined || toSchema === undefined) {
|
|
112
|
+
return { status: "missing_endpoint", ...base };
|
|
113
|
+
}
|
|
114
|
+
const fromIrMatch = entry.fromIrHash === fromSchema.irHash;
|
|
115
|
+
const toIrMatch = entry.toIrHash === toSchema.irHash;
|
|
116
|
+
if (!fromIrMatch || !toIrMatch) {
|
|
117
|
+
return { status: "drift", ...base };
|
|
118
|
+
}
|
|
119
|
+
const fromSourceMatch = entry.fromSourceHash === fromSchema.sourceHash;
|
|
120
|
+
const toSourceMatch = entry.toSourceHash === toSchema.sourceHash;
|
|
121
|
+
if (!fromSourceMatch || !toSourceMatch) {
|
|
122
|
+
return { status: "cosmetic_drift", ...base };
|
|
123
|
+
}
|
|
124
|
+
return { status: "bound", ...base };
|
|
125
|
+
}
|
|
126
|
+
// =============================================================================
|
|
127
|
+
// Pretty formatter
|
|
128
|
+
// =============================================================================
|
|
129
|
+
function formatVerifyPretty(d) {
|
|
130
|
+
const { verdicts, summary } = d;
|
|
131
|
+
const total = verdicts.length;
|
|
132
|
+
if (total === 0) {
|
|
133
|
+
return "No migrations to verify.\n";
|
|
134
|
+
}
|
|
135
|
+
const lines = [];
|
|
136
|
+
lines.push(`Verified ${total} migration${total === 1 ? "" : "s"}:` +
|
|
137
|
+
` bound=${summary.bound}` +
|
|
138
|
+
` cosmetic_drift=${summary.cosmetic_drift}` +
|
|
139
|
+
` drift=${summary.drift}` +
|
|
140
|
+
` missing_endpoint=${summary.missing_endpoint}`);
|
|
141
|
+
const idWidth = maxWidth(verdicts.map((v) => v.schemaId));
|
|
142
|
+
const versionsWidth = maxWidth(verdicts.map((v) => `${v.fromVersion} → ${v.toVersion}`));
|
|
143
|
+
for (const v of verdicts) {
|
|
144
|
+
const versions = `${v.fromVersion} → ${v.toVersion}`;
|
|
145
|
+
const tag = v.status === "bound"
|
|
146
|
+
? "[bound]"
|
|
147
|
+
: v.status === "cosmetic_drift"
|
|
148
|
+
? "[warn ] cosmetic_drift"
|
|
149
|
+
: v.status === "drift"
|
|
150
|
+
? "[FAIL ] drift"
|
|
151
|
+
: "[FAIL ] missing_endpoint";
|
|
152
|
+
lines.push(` ${v.schemaId.padEnd(idWidth)} ${versions.padEnd(versionsWidth)} ${tag} ${v.sourcePath}`);
|
|
153
|
+
}
|
|
154
|
+
return lines.join("\n") + "\n";
|
|
155
|
+
}
|
|
156
|
+
function maxWidth(values) {
|
|
157
|
+
let max = 0;
|
|
158
|
+
for (const v of values)
|
|
159
|
+
if (v.length > max)
|
|
160
|
+
max = v.length;
|
|
161
|
+
return max;
|
|
162
|
+
}
|
|
163
|
+
// =============================================================================
|
|
164
|
+
// Failure helpers
|
|
165
|
+
// =============================================================================
|
|
166
|
+
function toSerializableLoadFailure(f) {
|
|
167
|
+
return { path: f.path, reason: f.reason, message: f.message };
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* `buildRegistry` / `buildMigrationRegistry` failure → exit code.
|
|
171
|
+
* Same mapping as `runMigratePlan` / `runMigrateList`.
|
|
172
|
+
*/
|
|
173
|
+
function pickRegistryFailureExitCode(issues) {
|
|
174
|
+
for (const i of issues) {
|
|
175
|
+
if (i.code === "integrity_error")
|
|
176
|
+
return EXIT_CODES.INTEGRITY_ERROR;
|
|
177
|
+
}
|
|
178
|
+
return EXIT_CODES.LOGICAL_FAILURE;
|
|
179
|
+
}
|
|
180
|
+
// =============================================================================
|
|
181
|
+
// Public entry
|
|
182
|
+
// =============================================================================
|
|
183
|
+
export async function runMigrateVerify(opts) {
|
|
184
|
+
// 1. Schema walk + load failures → IO_ERROR.
|
|
185
|
+
const walk = await walkWorkspace({ root: opts.root });
|
|
186
|
+
if (walk.failures.length > 0) {
|
|
187
|
+
if (opts.json) {
|
|
188
|
+
opts.stdout(formatJson({ failures: walk.failures.map(toSerializableLoadFailure) }));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
opts.stderr(formatLoadFailuresPretty(walk.failures));
|
|
192
|
+
}
|
|
193
|
+
return EXIT_CODES.IO_ERROR;
|
|
194
|
+
}
|
|
195
|
+
// 2. Build the schema registry.
|
|
196
|
+
const reg = buildRegistry(walk.entries);
|
|
197
|
+
if (!reg.success) {
|
|
198
|
+
if (opts.json) {
|
|
199
|
+
opts.stdout(formatJson({ issues: reg.issues }));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
opts.stderr(formatIssuesPretty(reg.issues));
|
|
203
|
+
}
|
|
204
|
+
return pickRegistryFailureExitCode(reg.issues);
|
|
205
|
+
}
|
|
206
|
+
// 3. Migration walk + load failures → IO_ERROR.
|
|
207
|
+
const migWalk = await readMigrations({ root: opts.root });
|
|
208
|
+
if (migWalk.failures.length > 0) {
|
|
209
|
+
if (opts.json) {
|
|
210
|
+
opts.stdout(formatJson({
|
|
211
|
+
failures: migWalk.failures.map(toSerializableLoadFailure),
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
opts.stderr(formatLoadFailuresPretty(migWalk.failures, {
|
|
216
|
+
noun: { singular: "migration file", plural: "migration files" },
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
return EXIT_CODES.IO_ERROR;
|
|
220
|
+
}
|
|
221
|
+
// 4. Build the migration registry.
|
|
222
|
+
const migReg = buildMigrationRegistry(migWalk.entries);
|
|
223
|
+
if (!migReg.success) {
|
|
224
|
+
if (opts.json) {
|
|
225
|
+
opts.stdout(formatJson({ issues: migReg.issues }));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
opts.stderr(formatIssuesPretty(migReg.issues));
|
|
229
|
+
}
|
|
230
|
+
return pickRegistryFailureExitCode(migReg.issues);
|
|
231
|
+
}
|
|
232
|
+
// 5. Derive verdicts on the CLI side (mirrors the handler's
|
|
233
|
+
// classification so verdicts + summary are available on the
|
|
234
|
+
// failure branch).
|
|
235
|
+
const derived = deriveVerdicts(reg.data, migReg.data);
|
|
236
|
+
// 6. Call the handler for success/failure determination + issues.
|
|
237
|
+
const result = verifyMigrationsHandler({
|
|
238
|
+
schemaRegistry: reg.data,
|
|
239
|
+
migrationRegistry: migReg.data,
|
|
240
|
+
});
|
|
241
|
+
// 7. Emit and pick exit code.
|
|
242
|
+
if (result.success) {
|
|
243
|
+
if (opts.json) {
|
|
244
|
+
opts.stdout(formatJson({
|
|
245
|
+
verdicts: derived.verdicts,
|
|
246
|
+
summary: derived.summary,
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
opts.stdout(formatVerifyPretty(derived));
|
|
251
|
+
}
|
|
252
|
+
return EXIT_CODES.SUCCESS;
|
|
253
|
+
}
|
|
254
|
+
// Failure branch: verdicts + summary + issues all in the JSON.
|
|
255
|
+
if (opts.json) {
|
|
256
|
+
opts.stdout(formatJson({
|
|
257
|
+
verdicts: derived.verdicts,
|
|
258
|
+
summary: derived.summary,
|
|
259
|
+
issues: result.issues,
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
opts.stdout(formatVerifyPretty(derived));
|
|
264
|
+
opts.stderr(formatIssuesPretty(result.issues));
|
|
265
|
+
}
|
|
266
|
+
return EXIT_CODES.LOGICAL_FAILURE;
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../../src/commands/schema/migrate/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,UAAU,EACV,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAAE,UAAU,EAAiB,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AA+BnE;;;;;;;;;;;;;;;GAeG;AACH,SAAS,cAAc,CACrB,cAAwB,EACxB,iBAAoC;IAEpC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IAE9E,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACrD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,QAAQ,CAAC,CAAC,eAAe,CACvB,QAA2B;IAE3B,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAClC,IAAI,KAAK,KAAK,SAAS;oBAAE,MAAM,KAAK,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,KAAqB,EACrB,cAAwB;IAExB,MAAM,IAAI,GAAG;QACX,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;KAClB,CAAC;IAEX,MAAM,UAAU,GAAG,UAAU,CAAC,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAE7E,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACvD,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,MAAM,CAAC;IAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,CAAC;IACrD,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,KAAK,UAAU,CAAC,UAAU,CAAC;IACvE,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,KAAK,QAAQ,CAAC,UAAU,CAAC;IACjE,IAAI,CAAC,eAAe,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;AACtC,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF,SAAS,kBAAkB,CAAC,CAAkB;IAC5C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC9B,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,4BAA4B,CAAC;IACtC,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CACR,YAAY,KAAK,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACrD,WAAW,OAAO,CAAC,KAAK,EAAE;QAC1B,oBAAoB,OAAO,CAAC,cAAc,EAAE;QAC5C,WAAW,OAAO,CAAC,KAAK,EAAE;QAC1B,sBAAsB,OAAO,CAAC,gBAAgB,EAAE,CACnD,CAAC;IAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,QAAQ,CAC5B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CACzD,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,WAAW,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;QACrD,MAAM,GAAG,GACP,CAAC,CAAC,MAAM,KAAK,OAAO;YAClB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB;gBAC7B,CAAC,CAAC,wBAAwB;gBAC1B,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO;oBACpB,CAAC,CAAC,eAAe;oBACjB,CAAC,CAAC,0BAA0B,CAAC;QACrC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,UAAU,EAAE,CACjG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,QAAQ,CAAC,MAAyB;IACzC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG;YAAE,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF,SAAS,yBAAyB,CAChC,CAAc;IAEd,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,SAAS,2BAA2B,CAAC,MAAwB;IAC3D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO,UAAU,CAAC,eAAe,CAAC;IACtE,CAAC;IACD,OAAO,UAAU,CAAC,eAAe,CAAC;AACpC,CAAC;AAED,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAA6B;IAE7B,6CAA6C;IAC7C,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CACT,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,CAAC,CACvE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED,gCAAgC;IAChC,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,2BAA2B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,gDAAgD;IAChD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CACT,UAAU,CAAC;gBACT,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,yBAAyB,CAAC;aAC1D,CAAC,CACH,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CACT,wBAAwB,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,IAAI,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAE;aAChE,CAAC,CACH,CAAC;QACJ,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED,mCAAmC;IACnC,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,2BAA2B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,4DAA4D;IAC5D,+DAA+D;IAC/D,sBAAsB;IACtB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtD,kEAAkE;IAClE,MAAM,MAAM,GAAG,uBAAuB,CAAC;QACrC,cAAc,EAAE,GAAG,CAAC,IAAI;QACxB,iBAAiB,EAAE,MAAM,CAAC,IAAI;KAC/B,CAAC,CAAC;IAEH,8BAA8B;IAC9B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CACT,UAAU,CAAC;gBACT,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;aACzB,CAAC,CACH,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,UAAU,CAAC,OAAO,CAAC;IAC5B,CAAC;IAED,+DAA+D;IAC/D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,MAAM,CACT,UAAU,CAAC;YACT,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CACH,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,UAAU,CAAC,eAAe,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI exit-code contract (v0.7 Step 26).
|
|
3
|
+
*
|
|
4
|
+
* The locked five-value enum from CLI plan Decision #6. Imported by
|
|
5
|
+
* `dispatch()` in `cli.ts` and by each schema-verb command module
|
|
6
|
+
* (Steps 29–32) so every code path uses the same vocabulary instead
|
|
7
|
+
* of inlining magic numbers.
|
|
8
|
+
*
|
|
9
|
+
* Semantics:
|
|
10
|
+
*
|
|
11
|
+
* 0 SUCCESS — command completed without issue.
|
|
12
|
+
* 1 LOGICAL_FAILURE — load-bearing CI signal. Verdict-level
|
|
13
|
+
* problems found by the verb itself: stale
|
|
14
|
+
* generated artifacts (`check`), a breaking
|
|
15
|
+
* diff (`diff`), a missing schema referenced
|
|
16
|
+
* on the argv (`diff` / `check`), etc.
|
|
17
|
+
* CI should fail on this.
|
|
18
|
+
* 2 USAGE_ERROR — argv shape is wrong: unknown command,
|
|
19
|
+
* missing argument, unknown option, bad
|
|
20
|
+
* flag value.
|
|
21
|
+
* 3 IO_ERROR — workspace not readable, schema source
|
|
22
|
+
* file failed to load (any of the four
|
|
23
|
+
* `schema_load_failed` reasons), committed
|
|
24
|
+
* artifact unreadable.
|
|
25
|
+
* 4 INTEGRITY_ERROR — the "impossible" two-hash row from
|
|
26
|
+
* Master plan Decision #6: the artifact's
|
|
27
|
+
* recorded `sourceHash` matches the schema
|
|
28
|
+
* source but the `irHash` differs. Suggests
|
|
29
|
+
* hand-edited artifact or tampered
|
|
30
|
+
* provenance. The CLI does NOT auto-
|
|
31
|
+
* regenerate when this fires.
|
|
32
|
+
*
|
|
33
|
+
* Anything ≥ 2 is a problem with the invocation or the workspace,
|
|
34
|
+
* not with the schemas under inspection. Tooling layered on top of
|
|
35
|
+
* `neko schema *` (e.g., CI helpers, future `@nekostack/migrate`)
|
|
36
|
+
* should treat 1 as "the schemas need attention" and ≥ 2 as
|
|
37
|
+
* "something else is wrong before we can even check the schemas."
|
|
38
|
+
*/
|
|
39
|
+
export declare const EXIT_CODES: {
|
|
40
|
+
readonly SUCCESS: 0;
|
|
41
|
+
readonly LOGICAL_FAILURE: 1;
|
|
42
|
+
readonly USAGE_ERROR: 2;
|
|
43
|
+
readonly IO_ERROR: 3;
|
|
44
|
+
readonly INTEGRITY_ERROR: 4;
|
|
45
|
+
};
|
|
46
|
+
export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
|
|
47
|
+
//# sourceMappingURL=exit-codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,eAAO,MAAM,UAAU;;;;;;CAMb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI exit-code contract (v0.7 Step 26).
|
|
3
|
+
*
|
|
4
|
+
* The locked five-value enum from CLI plan Decision #6. Imported by
|
|
5
|
+
* `dispatch()` in `cli.ts` and by each schema-verb command module
|
|
6
|
+
* (Steps 29–32) so every code path uses the same vocabulary instead
|
|
7
|
+
* of inlining magic numbers.
|
|
8
|
+
*
|
|
9
|
+
* Semantics:
|
|
10
|
+
*
|
|
11
|
+
* 0 SUCCESS — command completed without issue.
|
|
12
|
+
* 1 LOGICAL_FAILURE — load-bearing CI signal. Verdict-level
|
|
13
|
+
* problems found by the verb itself: stale
|
|
14
|
+
* generated artifacts (`check`), a breaking
|
|
15
|
+
* diff (`diff`), a missing schema referenced
|
|
16
|
+
* on the argv (`diff` / `check`), etc.
|
|
17
|
+
* CI should fail on this.
|
|
18
|
+
* 2 USAGE_ERROR — argv shape is wrong: unknown command,
|
|
19
|
+
* missing argument, unknown option, bad
|
|
20
|
+
* flag value.
|
|
21
|
+
* 3 IO_ERROR — workspace not readable, schema source
|
|
22
|
+
* file failed to load (any of the four
|
|
23
|
+
* `schema_load_failed` reasons), committed
|
|
24
|
+
* artifact unreadable.
|
|
25
|
+
* 4 INTEGRITY_ERROR — the "impossible" two-hash row from
|
|
26
|
+
* Master plan Decision #6: the artifact's
|
|
27
|
+
* recorded `sourceHash` matches the schema
|
|
28
|
+
* source but the `irHash` differs. Suggests
|
|
29
|
+
* hand-edited artifact or tampered
|
|
30
|
+
* provenance. The CLI does NOT auto-
|
|
31
|
+
* regenerate when this fires.
|
|
32
|
+
*
|
|
33
|
+
* Anything ≥ 2 is a problem with the invocation or the workspace,
|
|
34
|
+
* not with the schemas under inspection. Tooling layered on top of
|
|
35
|
+
* `neko schema *` (e.g., CI helpers, future `@nekostack/migrate`)
|
|
36
|
+
* should treat 1 as "the schemas need attention" and ≥ 2 as
|
|
37
|
+
* "something else is wrong before we can even check the schemas."
|
|
38
|
+
*/
|
|
39
|
+
export const EXIT_CODES = {
|
|
40
|
+
SUCCESS: 0,
|
|
41
|
+
LOGICAL_FAILURE: 1,
|
|
42
|
+
USAGE_ERROR: 2,
|
|
43
|
+
IO_ERROR: 3,
|
|
44
|
+
INTEGRITY_ERROR: 4,
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=exit-codes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO,EAAE,CAAC;IACV,eAAe,EAAE,CAAC;IAClB,WAAW,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC;IACX,eAAe,EAAE,CAAC;CACV,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `formatJson(payload)` — single-line JSON output formatter (v0.7 Step 27).
|
|
3
|
+
*
|
|
4
|
+
* The `--json` flag on every `neko schema *` verb routes through this
|
|
5
|
+
* function. CLI plan §"Output formats" locks the contract:
|
|
6
|
+
*
|
|
7
|
+
* - One line per invocation (no pretty-printing) — pipeable.
|
|
8
|
+
* - Exactly one trailing newline so callers can `writeOut(formatJson(x))`
|
|
9
|
+
* without remembering to add `\n`.
|
|
10
|
+
* - `JSON.stringify` errors propagate. Unserializable inputs (cycles,
|
|
11
|
+
* `BigInt`, etc.) are programmer errors, not user errors; the
|
|
12
|
+
* dispatch layer treats an unhandled throw as an unexpected
|
|
13
|
+
* condition rather than masking it behind a fake success line.
|
|
14
|
+
*
|
|
15
|
+
* Pure utility — no `console.*`, no `process.*`, no `fs.*`. Static-
|
|
16
|
+
* scan asserted by [`../../tests/formatters/json.test.ts`](../../tests/formatters/json.test.ts).
|
|
17
|
+
*
|
|
18
|
+
* Per-command JSON schemas (the shape each verb emits) are locked by
|
|
19
|
+
* the schema-side `*Result` types those verbs wrap; this formatter
|
|
20
|
+
* is shape-agnostic. When a `*Result` shape changes, the
|
|
21
|
+
* corresponding command's snapshot test catches it without anything
|
|
22
|
+
* here needing to change.
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatJson(payload: unknown): string;
|
|
25
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/formatters/json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `formatJson(payload)` — single-line JSON output formatter (v0.7 Step 27).
|
|
3
|
+
*
|
|
4
|
+
* The `--json` flag on every `neko schema *` verb routes through this
|
|
5
|
+
* function. CLI plan §"Output formats" locks the contract:
|
|
6
|
+
*
|
|
7
|
+
* - One line per invocation (no pretty-printing) — pipeable.
|
|
8
|
+
* - Exactly one trailing newline so callers can `writeOut(formatJson(x))`
|
|
9
|
+
* without remembering to add `\n`.
|
|
10
|
+
* - `JSON.stringify` errors propagate. Unserializable inputs (cycles,
|
|
11
|
+
* `BigInt`, etc.) are programmer errors, not user errors; the
|
|
12
|
+
* dispatch layer treats an unhandled throw as an unexpected
|
|
13
|
+
* condition rather than masking it behind a fake success line.
|
|
14
|
+
*
|
|
15
|
+
* Pure utility — no `console.*`, no `process.*`, no `fs.*`. Static-
|
|
16
|
+
* scan asserted by [`../../tests/formatters/json.test.ts`](../../tests/formatters/json.test.ts).
|
|
17
|
+
*
|
|
18
|
+
* Per-command JSON schemas (the shape each verb emits) are locked by
|
|
19
|
+
* the schema-side `*Result` types those verbs wrap; this formatter
|
|
20
|
+
* is shape-agnostic. When a `*Result` shape changes, the
|
|
21
|
+
* corresponding command's snapshot test catches it without anything
|
|
22
|
+
* here needing to change.
|
|
23
|
+
*/
|
|
24
|
+
export function formatJson(payload) {
|
|
25
|
+
return JSON.stringify(payload) + "\n";
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/formatters/json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal-readable formatters for the four `neko schema *` verbs
|
|
3
|
+
* plus the two cross-cutting result kinds (load failures and Issues).
|
|
4
|
+
* v0.7 Step 28.
|
|
5
|
+
*
|
|
6
|
+
* Each function returns a `string` ending in exactly one trailing
|
|
7
|
+
* newline — same shape as `formatJson` (Step 27), so command modules
|
|
8
|
+
* can write either through the same `stdout`/`stderr` writer without
|
|
9
|
+
* remembering to add `\n`.
|
|
10
|
+
*
|
|
11
|
+
* Pure utility. No `console.*`, no `process.*`, no `fs.*`. Static-
|
|
12
|
+
* scan asserted by [`../../tests/formatters/pretty.test.ts`](../../tests/formatters/pretty.test.ts).
|
|
13
|
+
*
|
|
14
|
+
* Color is NOT applied here. CLI plan §"Explicit non-scope" defers
|
|
15
|
+
* richer color to a later phase; v0.7 ships plain ANSI-free output
|
|
16
|
+
* that respects `NO_COLOR` by default (i.e., never emits codes).
|
|
17
|
+
*
|
|
18
|
+
* Output stability — pretty output is **not** a contract across
|
|
19
|
+
* versions (the locked promise is `--json`, see [`./json.ts`](./json.ts)).
|
|
20
|
+
* These functions still aim for a deterministic shape so snapshot
|
|
21
|
+
* tests can compare against known strings; downstream consumers
|
|
22
|
+
* should consume `--json` rather than parsing pretty output.
|
|
23
|
+
*
|
|
24
|
+
* Pure: takes data in, returns a string. Inputs are never mutated;
|
|
25
|
+
* sorted/iterated lazily and the caller's arrays are preserved.
|
|
26
|
+
*/
|
|
27
|
+
import type { DiffChange, DiffSeverity, FreshnessVerdict, GeneratedArtifact, MigrationEntry, RegistryEntry } from "@nekostack/schema/cli";
|
|
28
|
+
import type { Issue } from "@nekostack/schema";
|
|
29
|
+
import type { LoadFailure } from "../loaders/tsx-loader.js";
|
|
30
|
+
/**
|
|
31
|
+
* Render a registry-listing as a fixed-width table. Format matches
|
|
32
|
+
* the example in the CLI companion plan:
|
|
33
|
+
*
|
|
34
|
+
* 3 schemas in workspace:
|
|
35
|
+
* com.nekostack.tenant.Tenant 1.0.0 path/to/tenant.schema.ts
|
|
36
|
+
* com.nekostack.audit.AuditEvent 1.0.0 path/to/audit-event.schema.ts
|
|
37
|
+
*
|
|
38
|
+
* Empty input produces a single human-readable line. Versions are
|
|
39
|
+
* displayed as `(unversioned)` when the entry's `schemaVersion` is
|
|
40
|
+
* `undefined`. Entries are NOT re-sorted here — `listHandler`
|
|
41
|
+
* already returns them in deterministic schemaId-ascending order.
|
|
42
|
+
*/
|
|
43
|
+
export declare function formatListPretty(entries: readonly RegistryEntry[]): string;
|
|
44
|
+
/**
|
|
45
|
+
* Render a migration-listing as a fixed-width table. Same shape as
|
|
46
|
+
* `formatListPretty` but with `(schemaId, fromVersion → toVersion,
|
|
47
|
+
* sourcePath)` columns. Entries are NOT re-sorted —
|
|
48
|
+
* `listMigrationsHandler` already returns them in
|
|
49
|
+
* `(schemaId, fromVersion, toVersion)` ascending order.
|
|
50
|
+
*
|
|
51
|
+
* The `migration` field on `MigrationEntry` (the loaded `AnyMigration`)
|
|
52
|
+
* is deliberately NOT rendered: it carries a closure `transform` that
|
|
53
|
+
* the v0.8 boundary forbids touching here, and the pretty output is
|
|
54
|
+
* for human review of the registry shape only.
|
|
55
|
+
*/
|
|
56
|
+
export declare function formatMigrationListPretty(entries: readonly MigrationEntry[]): string;
|
|
57
|
+
/**
|
|
58
|
+
* Render a `DiffResult.data` payload (the unwrapped success branch).
|
|
59
|
+
* Header carries the count + `worstSeverity`; rows list each change
|
|
60
|
+
* as `[severity] kind at path — message`.
|
|
61
|
+
*
|
|
62
|
+
* Empty change list prints `No changes.` with the worst-severity
|
|
63
|
+
* sentinel `null`. Non-empty lists print the count and severity in
|
|
64
|
+
* a uniform header so machine post-processing (e.g., a CI script
|
|
65
|
+
* grepping the pretty output, even though `--json` is the contract)
|
|
66
|
+
* has a stable single-line summary at the top.
|
|
67
|
+
*/
|
|
68
|
+
export declare function formatDiffPretty(payload: {
|
|
69
|
+
readonly changes: readonly DiffChange[];
|
|
70
|
+
readonly worstSeverity: DiffSeverity | null;
|
|
71
|
+
}): string;
|
|
72
|
+
/**
|
|
73
|
+
* Render a list of freshness verdicts (`CheckResult.data.verdicts`).
|
|
74
|
+
* Header is a per-status tally:
|
|
75
|
+
*
|
|
76
|
+
* 4 artifacts: 2 clean, 1 cosmetic_drift, 1 stale
|
|
77
|
+
*
|
|
78
|
+
* Body lists each verdict as `[status] artifactPath` in input order
|
|
79
|
+
* (the schema-side handler emits in the order the CLI handed it the
|
|
80
|
+
* artifacts, which is already deterministic — see Step 24).
|
|
81
|
+
*
|
|
82
|
+
* Empty input prints a single human-readable line; the CLI dispatch
|
|
83
|
+
* layer is responsible for deciding what an empty `check` exits as.
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatCheckPretty(verdicts: readonly FreshnessVerdict[]): string;
|
|
86
|
+
/**
|
|
87
|
+
* Render the list of `GeneratedArtifact`s `generateHandler` returned.
|
|
88
|
+
* The CLI dispatch layer is what actually writes each artifact's
|
|
89
|
+
* `content` to its `suggestedPath`; this formatter only summarizes
|
|
90
|
+
* the plan for the user's terminal.
|
|
91
|
+
*
|
|
92
|
+
* Generated 12 artifacts (3 schemas × 4 kinds):
|
|
93
|
+
* com.x.Tenant typescript schemas/generated/tenant.types.ts
|
|
94
|
+
* com.x.Tenant zod schemas/generated/tenant.zod.ts
|
|
95
|
+
* …
|
|
96
|
+
*
|
|
97
|
+
* Empty input prints a single human-readable line. Artifacts are
|
|
98
|
+
* NOT re-sorted — `generateHandler` already emits them in
|
|
99
|
+
* deterministic schemaId-then-kind order.
|
|
100
|
+
*/
|
|
101
|
+
export declare function formatGeneratePretty(artifacts: readonly GeneratedArtifact[]): string;
|
|
102
|
+
/**
|
|
103
|
+
* Render `LoadFailure[]` from a CLI loader (`walk-workspace.ts` for
|
|
104
|
+
* schema files, `read-migrations.ts` for migration files). Each row
|
|
105
|
+
* carries the file path, the locked reason, and the underlying
|
|
106
|
+
* message. Used by the CLI dispatch layer when one or more files
|
|
107
|
+
* failed to load — distinct concern from `Issue[]` (the schema-side
|
|
108
|
+
* normalized error vocabulary).
|
|
109
|
+
*
|
|
110
|
+
* The header noun defaults to `"schema file" / "schema files"` so
|
|
111
|
+
* the existing `neko schema list / diff / check / generate` commands
|
|
112
|
+
* keep their byte-identical output. Migration commands pass
|
|
113
|
+
* `{ noun: { singular: "migration file", plural: "migration files" } }`
|
|
114
|
+
* so their stderr is unambiguous.
|
|
115
|
+
*/
|
|
116
|
+
export interface LoadFailuresPrettyOpts {
|
|
117
|
+
readonly noun?: {
|
|
118
|
+
readonly singular: string;
|
|
119
|
+
readonly plural: string;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export declare function formatLoadFailuresPretty(failures: readonly LoadFailure[], opts?: LoadFailuresPrettyOpts): string;
|
|
123
|
+
/**
|
|
124
|
+
* Render a list of `Issue`s — used when a schema-side handler returns
|
|
125
|
+
* `Result.failure` and the CLI needs a human-readable digest.
|
|
126
|
+
* Severity prefixes the message; `error` is the only severity v0.7
|
|
127
|
+
* emits, but the formatter handles the full vocabulary for
|
|
128
|
+
* forward compatibility.
|
|
129
|
+
*/
|
|
130
|
+
export declare function formatIssuesPretty(issues: readonly Issue[]): string;
|
|
131
|
+
//# sourceMappingURL=pretty.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pretty.d.ts","sourceRoot":"","sources":["../../src/formatters/pretty.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM5D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,aAAa,EAAE,GAChC,MAAM,CAiBR;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,MAAM,CAiBR;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE;IACP,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7C,GACA,MAAM,CAMR;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,MAAM,CA0BR;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,SAAS,iBAAiB,EAAE,GACtC,MAAM,CAcR;AAMD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,IAAI,GAAE,sBAA2B,GAChC,MAAM,CASR;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAUnE"}
|