@telorun/cli 0.73.0 → 0.75.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/bundle/manifest-text.d.ts +28 -0
- package/dist/bundle/manifest-text.d.ts.map +1 -0
- package/dist/bundle/manifest-text.js +92 -0
- package/dist/bundle/manifest-text.js.map +1 -0
- package/dist/bundle/module-payload.d.ts +157 -0
- package/dist/bundle/module-payload.d.ts.map +1 -0
- package/dist/bundle/module-payload.js +273 -0
- package/dist/bundle/module-payload.js.map +1 -0
- package/dist/bundle/payload-drift.d.ts +14 -8
- package/dist/bundle/payload-drift.d.ts.map +1 -1
- package/dist/bundle/payload-drift.js +23 -3
- package/dist/bundle/payload-drift.js.map +1 -1
- package/dist/bundle/select-files.d.ts +16 -4
- package/dist/bundle/select-files.d.ts.map +1 -1
- package/dist/bundle/select-files.js +25 -7
- package/dist/bundle/select-files.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/publish.d.ts +7 -18
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +60 -250
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/release.d.ts +16 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +376 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/output.d.ts +40 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +86 -2
- package/dist/output.js.map +1 -1
- package/dist/release/apply-plan.d.ts +38 -0
- package/dist/release/apply-plan.d.ts.map +1 -0
- package/dist/release/apply-plan.js +103 -0
- package/dist/release/apply-plan.js.map +1 -0
- package/dist/release/evidence.d.ts +56 -0
- package/dist/release/evidence.d.ts.map +1 -0
- package/dist/release/evidence.js +245 -0
- package/dist/release/evidence.js.map +1 -0
- package/dist/release/ledger-store.d.ts +27 -0
- package/dist/release/ledger-store.d.ts.map +1 -0
- package/dist/release/ledger-store.js +62 -0
- package/dist/release/ledger-store.js.map +1 -0
- package/dist/release/render.d.ts +17 -0
- package/dist/release/render.d.ts.map +1 -0
- package/dist/release/render.js +71 -0
- package/dist/release/render.js.map +1 -0
- package/dist/release/workspace.d.ts +58 -0
- package/dist/release/workspace.d.ts.map +1 -0
- package/dist/release/workspace.js +138 -0
- package/dist/release/workspace.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `telo release` — one release system over the modules of a declared workspace.
|
|
3
|
+
*
|
|
4
|
+
* `add` writes a fragment; `status` explains what would bump and why; `check` is
|
|
5
|
+
* the CI gate; `apply` produces the Version PR; `verify` reconciles the ledger
|
|
6
|
+
* against the registry. `telo publish` still keys off version movement.
|
|
7
|
+
*
|
|
8
|
+
* The command reads `telo-workspace.yaml` and **nothing else does**: `run`,
|
|
9
|
+
* `check`, `publish`, `install`, `upgrade`, `migrate`, `module` and the kernel
|
|
10
|
+
* behave identically with or without one, which is what keeps a single-manifest
|
|
11
|
+
* repo, a bare `examples/` directory and a third-party module checkout working
|
|
12
|
+
* with nothing added.
|
|
13
|
+
*/
|
|
14
|
+
import { LEDGER_PATH, LOCALLY_DERIVED_LAYERS, diffLayerDigests, isFragmentKind, orderByImports, planRelease, serializeFragment, } from "@telorun/analyzer";
|
|
15
|
+
import * as path from "node:path";
|
|
16
|
+
import { readPublishedDigests } from "../bundle/payload-drift.js";
|
|
17
|
+
import { ModulePayloadBuilder } from "../bundle/module-payload.js";
|
|
18
|
+
import { createLogger } from "../logger.js";
|
|
19
|
+
import { outEmit, outErrLine, outLine, outProgress } from "../output.js";
|
|
20
|
+
import { recordLedger, writePlannedVersions } from "../release/apply-plan.js";
|
|
21
|
+
import { collectEvidence, destinationFor } from "../release/evidence.js";
|
|
22
|
+
import { deleteFragment, readFragments, readLedger, writeFragment, writeLedger, } from "../release/ledger-store.js";
|
|
23
|
+
import { planPayload, renderDiagnostics, renderPlan } from "../release/render.js";
|
|
24
|
+
import { loadWorkspace, requireModule } from "../release/workspace.js";
|
|
25
|
+
/**
|
|
26
|
+
* The publish destination base.
|
|
27
|
+
*
|
|
28
|
+
* The ledger's recorded base wins, because the digests beside it were taken
|
|
29
|
+
* against it — building against a different one produces different manifest
|
|
30
|
+
* layers and would report every module as changed. A flag or the ambient
|
|
31
|
+
* variable seeds it for a workspace that has published nothing yet.
|
|
32
|
+
*/
|
|
33
|
+
function resolveRegistry(workspace, argv, ledger) {
|
|
34
|
+
const recorded = ledger.registry;
|
|
35
|
+
const requested = argv.registry ?? process.env.TELO_OCI_REGISTRY;
|
|
36
|
+
if (recorded && requested && recorded !== requested) {
|
|
37
|
+
throw new Error(`${LEDGER_PATH} records its digests against '${recorded}', but '${requested}' was requested. ` +
|
|
38
|
+
`Canonicalization writes the destination into every relative import, so the two produce ` +
|
|
39
|
+
`different manifest bytes. Publish to the recorded base, or re-record the ledger with ` +
|
|
40
|
+
`\`telo release verify --registry ${requested}\`.`);
|
|
41
|
+
}
|
|
42
|
+
const registry = recorded ?? requested;
|
|
43
|
+
if (!registry) {
|
|
44
|
+
throw new Error(`No publish destination is known. ${LEDGER_PATH} records none (nothing has been published ` +
|
|
45
|
+
`from this workspace yet), so pass --registry oci://host/org or set TELO_OCI_REGISTRY. ` +
|
|
46
|
+
`It is recorded on the first \`telo release apply\`, because the digests only mean ` +
|
|
47
|
+
`anything against the base they were taken at.`);
|
|
48
|
+
}
|
|
49
|
+
return registry.replace(/\/+$/, "");
|
|
50
|
+
}
|
|
51
|
+
async function buildPlan(argv, log) {
|
|
52
|
+
const workspace = loadWorkspace();
|
|
53
|
+
const ledger = readLedger(workspace.root);
|
|
54
|
+
const registry = resolveRegistry(workspace, argv, ledger);
|
|
55
|
+
const fragments = readFragments(workspace.root);
|
|
56
|
+
const modules = await collectEvidence(workspace, {
|
|
57
|
+
registry,
|
|
58
|
+
baseRef: argv.base,
|
|
59
|
+
// A ticker, not a diagnostic: sixty-one of these are what a human watching a
|
|
60
|
+
// two-minute build wants and what a CI log or a `-o json` consumer does not.
|
|
61
|
+
onModule: (module, index, total) => outProgress(log.err.dim(` [${index + 1}/${total}] ${module.key}`)),
|
|
62
|
+
});
|
|
63
|
+
return { workspace, registry, plan: planRelease({ modules, ledger, fragments, registry }) };
|
|
64
|
+
}
|
|
65
|
+
/** The registry-verifiable half of a digest map. */
|
|
66
|
+
function withoutLocallyDerived(layers) {
|
|
67
|
+
return Object.fromEntries(Object.entries(layers).filter(([layer]) => !LOCALLY_DERIVED_LAYERS.has(layer)));
|
|
68
|
+
}
|
|
69
|
+
/** The half the registry cannot answer for, kept across a reconciliation. */
|
|
70
|
+
function localOnly(layers) {
|
|
71
|
+
return Object.fromEntries(Object.entries(layers).filter(([layer]) => LOCALLY_DERIVED_LAYERS.has(layer)));
|
|
72
|
+
}
|
|
73
|
+
function reportDiagnostics(plan, log) {
|
|
74
|
+
for (const line of renderDiagnostics(plan, log))
|
|
75
|
+
outErrLine(line);
|
|
76
|
+
return plan.diagnostics.filter((diagnostic) => diagnostic.severity === "error").length;
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// add
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
/** `<kind>-<slug>.yaml`, so the pending directory sorts by kind and a second
|
|
82
|
+
* fragment for the same change is a visible duplicate rather than an
|
|
83
|
+
* overwrite. Deliberately not timestamped: a timestamp made every changie
|
|
84
|
+
* filename unique and therefore meaningless to read. */
|
|
85
|
+
function fragmentFilename(kinds, body) {
|
|
86
|
+
const kind = [...kinds][0] ?? "Fixed";
|
|
87
|
+
const slug = body
|
|
88
|
+
.toLowerCase()
|
|
89
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
90
|
+
.replace(/^-|-$/g, "")
|
|
91
|
+
.split("-")
|
|
92
|
+
.slice(0, 6)
|
|
93
|
+
.join("-") || "change";
|
|
94
|
+
return `${kind.toLowerCase()}-${slug}.yaml`;
|
|
95
|
+
}
|
|
96
|
+
async function add(argv) {
|
|
97
|
+
const log = createLogger(false);
|
|
98
|
+
const workspace = loadWorkspace();
|
|
99
|
+
if (!isFragmentKind(argv.kind)) {
|
|
100
|
+
outErrLine(log.err.error("error") +
|
|
101
|
+
` '${argv.kind}' is not a release kind. Use Added, Changed, Deprecated, Removed, ` +
|
|
102
|
+
`Fixed or Security.`);
|
|
103
|
+
process.exitCode = 1;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const modules = new Map();
|
|
107
|
+
for (const key of argv.module) {
|
|
108
|
+
modules.set(requireModule(workspace, key).key, argv.kind);
|
|
109
|
+
}
|
|
110
|
+
const source = writeFragment(workspace.root, fragmentFilename(modules.values(), argv.body), serializeFragment(modules, argv.body));
|
|
111
|
+
outLine(`${log.ok("✓")} ${source}`);
|
|
112
|
+
outEmit({ ok: true, fragment: source, modules: [...modules.keys()] });
|
|
113
|
+
}
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// status / check
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
async function status(argv) {
|
|
118
|
+
const log = createLogger(false);
|
|
119
|
+
const { plan } = await buildPlan(argv, log);
|
|
120
|
+
for (const line of renderPlan(plan, log))
|
|
121
|
+
outLine(line);
|
|
122
|
+
reportDiagnostics(plan, log);
|
|
123
|
+
outEmit({ ok: true, ...planPayload(plan) });
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The CI gate.
|
|
127
|
+
*
|
|
128
|
+
* It does **not** fail because a payload moved. Under a toolchain bump every
|
|
129
|
+
* module's digest moves, and demanding sixty hand-written fragments for that
|
|
130
|
+
* would be a tax on nobody's behalf — those land in the unattributed case, take
|
|
131
|
+
* a patch, and ship. What it fails on is a plan that cannot be formed: a
|
|
132
|
+
* fragment naming an unknown module, a major-inducing kind, a manifest version
|
|
133
|
+
* that disagrees with its ledger entry, or digests taken against another
|
|
134
|
+
* registry base.
|
|
135
|
+
*/
|
|
136
|
+
async function check(argv) {
|
|
137
|
+
const log = createLogger(false);
|
|
138
|
+
const { plan } = await buildPlan(argv, log);
|
|
139
|
+
for (const line of renderPlan(plan, log))
|
|
140
|
+
outLine(line);
|
|
141
|
+
const errors = reportDiagnostics(plan, log);
|
|
142
|
+
outEmit({ ok: errors === 0, ...planPayload(plan) });
|
|
143
|
+
if (errors > 0)
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// apply
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
/**
|
|
150
|
+
* Write the plan: every manifest a module owns, its changelog, the ledger, and
|
|
151
|
+
* the fragments consumed.
|
|
152
|
+
*
|
|
153
|
+
* The writes live in `release/apply-plan.ts`; this is the wiring — resolve, plan,
|
|
154
|
+
* report, hand over.
|
|
155
|
+
*/
|
|
156
|
+
async function apply(argv) {
|
|
157
|
+
const log = createLogger(false);
|
|
158
|
+
const { workspace, registry, plan } = await buildPlan(argv, log);
|
|
159
|
+
const errors = reportDiagnostics(plan, log);
|
|
160
|
+
if (errors > 0) {
|
|
161
|
+
outEmit({ ok: false, ...planPayload(plan) });
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (plan.modules.length === 0) {
|
|
166
|
+
outLine("Nothing to release — every module matches the ledger.");
|
|
167
|
+
outEmit({ ok: true, modules: [] });
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const applied = writePlannedVersions(workspace, plan, argv.date ?? new Date().toISOString().slice(0, 10));
|
|
171
|
+
for (const module of applied) {
|
|
172
|
+
outLine(`${log.ok("✓")} ${module.key} ${module.from} → ${module.to}`);
|
|
173
|
+
}
|
|
174
|
+
writeLedger(workspace.root, await recordLedger(workspace.root, registry, plan));
|
|
175
|
+
for (const fragment of plan.fragments)
|
|
176
|
+
deleteFragment(workspace.root, fragment);
|
|
177
|
+
outLine(`${log.ok("✓")} ${LEDGER_PATH}, ${plan.fragments.length} fragment(s) consumed`);
|
|
178
|
+
outEmit({
|
|
179
|
+
ok: true,
|
|
180
|
+
...planPayload(plan),
|
|
181
|
+
written: [...applied.flatMap((module) => module.files), LEDGER_PATH],
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// order
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
/**
|
|
188
|
+
* The workspace's modules in publish order — a dependency before its dependents.
|
|
189
|
+
*
|
|
190
|
+
* Not optional at publish time: canonicalization rewrites a relative import to
|
|
191
|
+
* `<base>/<sibling>@<version>` and publish then hard-fails when that ref does not
|
|
192
|
+
* already resolve, so a sibling has to be pushed first. This replaced a regex
|
|
193
|
+
* that read `imports:` out of the first YAML document by line shape.
|
|
194
|
+
*
|
|
195
|
+
* Reads the import graph only — no payloads are built, so it is cheap enough to
|
|
196
|
+
* call from a release script.
|
|
197
|
+
*/
|
|
198
|
+
async function order(argv) {
|
|
199
|
+
const workspace = loadWorkspace();
|
|
200
|
+
const registry = resolveRegistry(workspace, argv, readLedger(workspace.root));
|
|
201
|
+
const builder = new ModulePayloadBuilder({ cacheRoot: path.join(workspace.root, ".telo") });
|
|
202
|
+
const byDir = new Map(workspace.modules.map((module) => [path.resolve(module.dir), module]));
|
|
203
|
+
const evidence = [];
|
|
204
|
+
for (const module of workspace.modules) {
|
|
205
|
+
// Only the manifest transform runs here, which is what carries the imports.
|
|
206
|
+
const imports = module.artifactKind === "image"
|
|
207
|
+
? []
|
|
208
|
+
: (await builder.relativeImportsOf(module.manifestPath, destinationFor(registry, module)))
|
|
209
|
+
.map((entry) => byDir.get(path.resolve(path.dirname(entry.manifestPath)))?.key)
|
|
210
|
+
.filter((key) => key !== undefined && key !== module.key);
|
|
211
|
+
evidence.push({
|
|
212
|
+
key: module.key,
|
|
213
|
+
name: module.name,
|
|
214
|
+
version: module.version,
|
|
215
|
+
artifactKind: module.artifactKind,
|
|
216
|
+
layers: {},
|
|
217
|
+
inlines: new Map(),
|
|
218
|
+
imports,
|
|
219
|
+
ownFilesChanged: false,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const ordered = orderByImports(evidence).map((module) => module.key);
|
|
223
|
+
for (const key of ordered)
|
|
224
|
+
outLine(key);
|
|
225
|
+
outEmit({ ok: true, order: ordered });
|
|
226
|
+
}
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
// verify
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
/**
|
|
231
|
+
* Reconcile the ledger against the registry.
|
|
232
|
+
*
|
|
233
|
+
* **Ledger versus registry, not working copy versus registry.** The ledger is a
|
|
234
|
+
* cache of the registry's answer, so the only question here is whether the cache
|
|
235
|
+
* is stale — a hand edit, an `apply` whose publish then failed, a push made
|
|
236
|
+
* outside the pipeline. It builds nothing and reads no local bytes.
|
|
237
|
+
*
|
|
238
|
+
* Comparing the local build instead would answer the PUBLISH gate's question
|
|
239
|
+
* ("am I about to ship changed bytes at an unchanged version?"), which is
|
|
240
|
+
* `payload-drift.ts`'s job and fires for every module on any commit after a
|
|
241
|
+
* release — a shared-library edit, a lockfile bump, any source change at all
|
|
242
|
+
* makes the working copy differ from what is published at the current version.
|
|
243
|
+
* That is normal and is what `check` plans a bump for; reporting it here made
|
|
244
|
+
* `verify` shout about all 59 modules and, worse, made `--write` fail to settle
|
|
245
|
+
* anything, because re-recording the ledger cannot change what the working copy
|
|
246
|
+
* builds.
|
|
247
|
+
*/
|
|
248
|
+
async function verify(argv) {
|
|
249
|
+
const log = createLogger(false);
|
|
250
|
+
const workspace = loadWorkspace();
|
|
251
|
+
const ledger = readLedger(workspace.root);
|
|
252
|
+
const registry = resolveRegistry(workspace, argv, ledger);
|
|
253
|
+
const drifted = [];
|
|
254
|
+
const repaired = new Map(ledger.modules);
|
|
255
|
+
const reportDrift = (key, detail) => {
|
|
256
|
+
drifted.push({ key, detail });
|
|
257
|
+
outErrLine(`${log.err.warn("drift")} ${key}: ${detail}`);
|
|
258
|
+
};
|
|
259
|
+
// Only the registry-artifact modules are reconciled — an image module has no
|
|
260
|
+
// published artifact to read a layer index from — so the count is theirs, not
|
|
261
|
+
// the workspace's, or the ticker would stall at a number it never reaches.
|
|
262
|
+
const reconciled = workspace.modules.filter((module) => module.artifactKind !== "image");
|
|
263
|
+
for (const [index, module] of reconciled.entries()) {
|
|
264
|
+
outProgress(log.err.dim(` [${index + 1}/${reconciled.length}] ${module.key}`));
|
|
265
|
+
const recorded = ledger.modules.get(module.key);
|
|
266
|
+
const published = await readPublishedDigests(destinationFor(registry, module), module.version, registry);
|
|
267
|
+
if (published === null) {
|
|
268
|
+
// Nothing published at this version. Not drift on its own — a module that
|
|
269
|
+
// has never shipped has nothing to disagree with — but a ledger entry for
|
|
270
|
+
// it is a claim about a version the registry does not have.
|
|
271
|
+
if (recorded) {
|
|
272
|
+
reportDrift(module.key, `the ledger records ${module.version}, which is not published`);
|
|
273
|
+
if (argv.write)
|
|
274
|
+
repaired.delete(module.key);
|
|
275
|
+
}
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (!recorded) {
|
|
279
|
+
reportDrift(module.key, `published at ${module.version}, but the ledger has no entry`);
|
|
280
|
+
// Recorded without a `manifest` digest, which nothing here can supply.
|
|
281
|
+
// `check` then reads that as drift and plans a patch — the safe direction
|
|
282
|
+
// (bump rather than miss), and the next `apply` fills it in.
|
|
283
|
+
if (argv.write)
|
|
284
|
+
repaired.set(module.key, { version: module.version, layers: published });
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
// Compare only what the registry can answer for. The `manifest` digest is
|
|
288
|
+
// locally derived and unverifiable by construction (see
|
|
289
|
+
// LOCALLY_DERIVED_LAYERS), so diffing the whole map would report it as
|
|
290
|
+
// removed for every module, every run — a permanent false finding.
|
|
291
|
+
const changes = diffLayerDigests(withoutLocallyDerived(recorded.layers), withoutLocallyDerived(published));
|
|
292
|
+
if (changes.length > 0) {
|
|
293
|
+
reportDrift(module.key, `${changes.map((change) => change.layer).join(", ")} — the ledger disagrees with what ` +
|
|
294
|
+
`is published at ${module.version}`);
|
|
295
|
+
}
|
|
296
|
+
// Merge rather than replace, so reconciling the verifiable half does not
|
|
297
|
+
// discard the half that has no other source.
|
|
298
|
+
if (argv.write) {
|
|
299
|
+
repaired.set(module.key, {
|
|
300
|
+
version: module.version,
|
|
301
|
+
layers: { ...localOnly(recorded.layers), ...published },
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (argv.write) {
|
|
306
|
+
writeLedger(workspace.root, { registry, modules: repaired });
|
|
307
|
+
outLine(`${log.ok("✓")} ${LEDGER_PATH} re-recorded from the registry`);
|
|
308
|
+
}
|
|
309
|
+
else if (drifted.length === 0) {
|
|
310
|
+
outLine(`${log.ok("✓")} ${LEDGER_PATH} matches the registry`);
|
|
311
|
+
}
|
|
312
|
+
outEmit({ ok: drifted.length === 0 || argv.write, drifted });
|
|
313
|
+
if (drifted.length > 0 && !argv.write)
|
|
314
|
+
process.exitCode = 1;
|
|
315
|
+
}
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// Command
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
/** Wrap a handler so a workspace/ledger/fragment problem is one actionable line
|
|
320
|
+
* rather than a stack trace — these are all "fix the repo state" errors. */
|
|
321
|
+
function guarded(handler) {
|
|
322
|
+
return async (argv) => {
|
|
323
|
+
try {
|
|
324
|
+
await handler(argv);
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
outErrLine(createLogger(false).err.error("error") +
|
|
328
|
+
` ${err instanceof Error ? err.message : String(err)}`);
|
|
329
|
+
outEmit({ ok: false });
|
|
330
|
+
process.exitCode = 1;
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
export function releaseCommand(yargs) {
|
|
335
|
+
return yargs.command("release <subcommand>", "Plan and apply module version bumps across a workspace", (y) => y
|
|
336
|
+
.option("registry", {
|
|
337
|
+
type: "string",
|
|
338
|
+
describe: "Publish destination base (oci://host/org). Defaults to the ledger's recorded base, then TELO_OCI_REGISTRY.",
|
|
339
|
+
})
|
|
340
|
+
.option("base", {
|
|
341
|
+
type: "string",
|
|
342
|
+
default: "origin/main",
|
|
343
|
+
describe: "Git ref the changed-files reading diffs against. Decides only whether a changelog entry is requested.",
|
|
344
|
+
})
|
|
345
|
+
.command("add", "Write a pending fragment describing a change", (c) => c
|
|
346
|
+
.option("module", {
|
|
347
|
+
type: "string",
|
|
348
|
+
array: true,
|
|
349
|
+
demandOption: true,
|
|
350
|
+
describe: "Module path (modules/sql). Repeat for a change that spans several modules.",
|
|
351
|
+
})
|
|
352
|
+
.option("kind", {
|
|
353
|
+
type: "string",
|
|
354
|
+
default: "Fixed",
|
|
355
|
+
describe: "Added | Changed | Deprecated | Removed | Fixed | Security",
|
|
356
|
+
})
|
|
357
|
+
.option("body", {
|
|
358
|
+
type: "string",
|
|
359
|
+
demandOption: true,
|
|
360
|
+
describe: "The changelog line",
|
|
361
|
+
}), guarded(add))
|
|
362
|
+
.command("status", "Show what would bump and why", (c) => c, guarded(status))
|
|
363
|
+
.command("order", "List the workspace's modules in publish order (a dependency before its dependents)", (c) => c, guarded(order))
|
|
364
|
+
.command("check", "Fail when no consistent release plan can be formed", (c) => c, guarded(check))
|
|
365
|
+
.command("apply", "Write versions, changelogs and the ledger, and consume the fragments", (c) => c.option("date", {
|
|
366
|
+
type: "string",
|
|
367
|
+
describe: "Release date for the changelog entries (YYYY-MM-DD). Defaults to today.",
|
|
368
|
+
}), guarded(apply))
|
|
369
|
+
.command("verify", "Reconcile the ledger against the registry", (c) => c.option("write", {
|
|
370
|
+
type: "boolean",
|
|
371
|
+
default: false,
|
|
372
|
+
describe: "Re-record the ledger from what the registry actually serves",
|
|
373
|
+
}), guarded(verify))
|
|
374
|
+
.demandCommand(1, "Specify a release subcommand (add | status | order | check | apply | verify)"), () => { });
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=release.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release.js","sourceRoot":"","sources":["../../src/commands/release.ts"],"names":[],"mappings":"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"}
|
package/dist/output.d.ts
CHANGED
|
@@ -20,6 +20,11 @@ export interface Palette {
|
|
|
20
20
|
* in a recording pair, so `Output` never reads process globals. */
|
|
21
21
|
export interface OutputStream {
|
|
22
22
|
isTTY?: boolean;
|
|
23
|
+
/** Terminal width, when the stream is one. A transient progress line is
|
|
24
|
+
* truncated to it: a line that wraps occupies two rows, and the erase
|
|
25
|
+
* sequence clears only the row the cursor is on, so the overflow would be
|
|
26
|
+
* left on screen for the next line to be written over. */
|
|
27
|
+
columns?: number;
|
|
23
28
|
write(chunk: string): unknown;
|
|
24
29
|
}
|
|
25
30
|
export interface OutputOptions {
|
|
@@ -48,13 +53,46 @@ export declare class Output {
|
|
|
48
53
|
private readonly outStream;
|
|
49
54
|
private readonly errStream;
|
|
50
55
|
constructor(options: OutputOptions);
|
|
56
|
+
/** Whether a transient progress line is currently on screen, waiting to be
|
|
57
|
+
* overwritten. Owned here because the rule it implies — every other write
|
|
58
|
+
* must erase it first — has to hold for every write method, and a call site
|
|
59
|
+
* that forgot would leave its output glued to the end of a ticker. */
|
|
60
|
+
private transient;
|
|
51
61
|
get isJson(): boolean;
|
|
62
|
+
/** Erase a pending transient line, so the next write starts on a clean row.
|
|
63
|
+
* `\r` returns to column 0 and `\x1b[2K` clears the row; both are cursor
|
|
64
|
+
* control rather than colour, so they are gated on the stream being a TTY and
|
|
65
|
+
* not on the palette — a `NO_COLOR` terminal still has a cursor. */
|
|
66
|
+
private clearTransient;
|
|
67
|
+
/** Drop any pending progress line without writing anything else. For a
|
|
68
|
+
* command that finishes without a further write and would otherwise leave the
|
|
69
|
+
* shell prompt sitting after a half-drawn ticker. */
|
|
70
|
+
endProgress(): void;
|
|
52
71
|
/** Human-readable line on stdout. Suppressed under `-o json`, where stdout is
|
|
53
72
|
* reserved for the payload. */
|
|
54
73
|
line(text?: string): void;
|
|
55
74
|
/** Human-readable line on stderr. Written in BOTH formats — stderr is not the
|
|
56
75
|
* machine contract, and silencing it loses the reason a command failed. */
|
|
57
76
|
errLine(text?: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* A progress tick on stderr, written only in text format and only to a TTY.
|
|
79
|
+
*
|
|
80
|
+
* The distinction this draws is between a **diagnostic** and a **progress
|
|
81
|
+
* indicator**, and it is why the rule is not the one `errLine` follows.
|
|
82
|
+
* `errLine` must write in every format because silencing it would lose the
|
|
83
|
+
* reason a command failed — that is error swallowing. A tick explains nothing.
|
|
84
|
+
* It is an affordance of the human-formatted mode: something for a person
|
|
85
|
+
* watching a long operation, so that a two-minute build does not look hung.
|
|
86
|
+
*
|
|
87
|
+
* BOTH conditions, because either one alone leaves a case wrong. `-o json`
|
|
88
|
+
* says the output is a contract, and decorating that run with prose the caller
|
|
89
|
+
* did not ask for is noise in their terminal whether or not they are looking
|
|
90
|
+
* at it — the format is the caller's statement of intent, not a guess about
|
|
91
|
+
* where the bytes land. And a text run redirected into a file or a CI log has
|
|
92
|
+
* nobody watching either, where sixty ticks bury the output the reader came
|
|
93
|
+
* for.
|
|
94
|
+
*/
|
|
95
|
+
progress(text: string): void;
|
|
58
96
|
/** Emit a command's structured RESULT ENVELOPE. A no-op in text mode.
|
|
59
97
|
*
|
|
60
98
|
* Every command that owns its stdout calls this exactly once, including when
|
|
@@ -108,4 +146,6 @@ export declare const outLine: (text?: string) => void;
|
|
|
108
146
|
export declare const outErrLine: (text?: string) => void;
|
|
109
147
|
export declare const outEmit: (payload: unknown) => void;
|
|
110
148
|
export declare const outDocument: (payload: unknown) => void;
|
|
149
|
+
export declare const outProgress: (text: string) => void;
|
|
150
|
+
export declare const outEndProgress: () => void;
|
|
111
151
|
//# sourceMappingURL=output.d.ts.map
|
package/dist/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;+EAC+E;AAC/E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,eAAO,MAAM,cAAc,EAAE,YAAY,EAAqB,CAAC;AAE/D;;;;;;;+DAO+D;AAC/D,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAiBD;oEACoE;AACpE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;;;;;;;;;;gEAYgE;AAChE,qBAAa,MAAM;IACjB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,aAAa;IAkBlC,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;oCACgC;IAChC,IAAI,CAAC,IAAI,SAAK,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;+EAC+E;AAC/E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,eAAO,MAAM,cAAc,EAAE,YAAY,EAAqB,CAAC;AAE/D;;;;;;;+DAO+D;AAC/D,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAiBD;oEACoE;AACpE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;+DAG2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;;;;;;;;;;gEAYgE;AAChE,qBAAa,MAAM;IACjB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,aAAa;IAkBlC;;;2EAGuE;IACvE,OAAO,CAAC,SAAS,CAAS;IAE1B,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;;yEAGqE;IACrE,OAAO,CAAC,cAAc;IAMtB;;0DAEsD;IACtD,WAAW,IAAI,IAAI;IAInB;oCACgC;IAChC,IAAI,CAAC,IAAI,SAAK,GAAG,IAAI;IASrB;gFAC4E;IAC5E,OAAO,CAAC,IAAI,SAAK,GAAG,IAAI;IAKxB;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAW5B;;;;;;;;;;;;;;kBAcc;IACd,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAQ5B;;;;;;2EAMuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKhC;;;;;;gBAMY;IACZ,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAI3B;AA6BD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE1D;AAED;;;;2CAI2C;AAC3C,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,IAAI,CAM7D;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED;;;gDAGgD;AAChD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAK9D;AAED;;+EAE+E;AAC/E,eAAO,MAAM,OAAO,GAAI,aAAS,KAAG,IAA0B,CAAC;AAC/D,eAAO,MAAM,UAAU,GAAI,aAAS,KAAG,IAA6B,CAAC;AACrE,eAAO,MAAM,OAAO,GAAI,SAAS,OAAO,KAAG,IAA6B,CAAC;AACzE,eAAO,MAAM,WAAW,GAAI,SAAS,OAAO,KAAG,IAAiC,CAAC;AACjF,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,IAA8B,CAAC;AAC1E,eAAO,MAAM,cAAc,QAAO,IAA6B,CAAC"}
|
package/dist/output.js
CHANGED
|
@@ -45,20 +45,76 @@ export class Output {
|
|
|
45
45
|
this.stdout = format === "text" ? paletteFor(Boolean(stdout.isTTY), env) : PLAIN;
|
|
46
46
|
this.stderr = paletteFor(Boolean(stderr.isTTY), env);
|
|
47
47
|
}
|
|
48
|
+
/** Whether a transient progress line is currently on screen, waiting to be
|
|
49
|
+
* overwritten. Owned here because the rule it implies — every other write
|
|
50
|
+
* must erase it first — has to hold for every write method, and a call site
|
|
51
|
+
* that forgot would leave its output glued to the end of a ticker. */
|
|
52
|
+
transient = false;
|
|
48
53
|
get isJson() {
|
|
49
54
|
return this.format === "json";
|
|
50
55
|
}
|
|
56
|
+
/** Erase a pending transient line, so the next write starts on a clean row.
|
|
57
|
+
* `\r` returns to column 0 and `\x1b[2K` clears the row; both are cursor
|
|
58
|
+
* control rather than colour, so they are gated on the stream being a TTY and
|
|
59
|
+
* not on the palette — a `NO_COLOR` terminal still has a cursor. */
|
|
60
|
+
clearTransient() {
|
|
61
|
+
if (!this.transient)
|
|
62
|
+
return;
|
|
63
|
+
this.transient = false;
|
|
64
|
+
this.errStream.write("\r\x1b[2K");
|
|
65
|
+
}
|
|
66
|
+
/** Drop any pending progress line without writing anything else. For a
|
|
67
|
+
* command that finishes without a further write and would otherwise leave the
|
|
68
|
+
* shell prompt sitting after a half-drawn ticker. */
|
|
69
|
+
endProgress() {
|
|
70
|
+
this.clearTransient();
|
|
71
|
+
}
|
|
51
72
|
/** Human-readable line on stdout. Suppressed under `-o json`, where stdout is
|
|
52
73
|
* reserved for the payload. */
|
|
53
74
|
line(text = "") {
|
|
54
|
-
if (this.format
|
|
55
|
-
|
|
75
|
+
if (this.format !== "text")
|
|
76
|
+
return;
|
|
77
|
+
// Cleared even though this writes to the OTHER stream: both usually land on
|
|
78
|
+
// one terminal, so a stdout line written over a pending stderr ticker would
|
|
79
|
+
// start halfway across the row.
|
|
80
|
+
this.clearTransient();
|
|
81
|
+
this.outStream.write(`${text}\n`);
|
|
56
82
|
}
|
|
57
83
|
/** Human-readable line on stderr. Written in BOTH formats — stderr is not the
|
|
58
84
|
* machine contract, and silencing it loses the reason a command failed. */
|
|
59
85
|
errLine(text = "") {
|
|
86
|
+
this.clearTransient();
|
|
60
87
|
this.errStream.write(`${text}\n`);
|
|
61
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* A progress tick on stderr, written only in text format and only to a TTY.
|
|
91
|
+
*
|
|
92
|
+
* The distinction this draws is between a **diagnostic** and a **progress
|
|
93
|
+
* indicator**, and it is why the rule is not the one `errLine` follows.
|
|
94
|
+
* `errLine` must write in every format because silencing it would lose the
|
|
95
|
+
* reason a command failed — that is error swallowing. A tick explains nothing.
|
|
96
|
+
* It is an affordance of the human-formatted mode: something for a person
|
|
97
|
+
* watching a long operation, so that a two-minute build does not look hung.
|
|
98
|
+
*
|
|
99
|
+
* BOTH conditions, because either one alone leaves a case wrong. `-o json`
|
|
100
|
+
* says the output is a contract, and decorating that run with prose the caller
|
|
101
|
+
* did not ask for is noise in their terminal whether or not they are looking
|
|
102
|
+
* at it — the format is the caller's statement of intent, not a guess about
|
|
103
|
+
* where the bytes land. And a text run redirected into a file or a CI log has
|
|
104
|
+
* nobody watching either, where sixty ticks bury the output the reader came
|
|
105
|
+
* for.
|
|
106
|
+
*/
|
|
107
|
+
progress(text) {
|
|
108
|
+
if (this.format !== "text" || !this.errStream.isTTY)
|
|
109
|
+
return;
|
|
110
|
+
this.clearTransient();
|
|
111
|
+
// No newline: this line is TRANSIENT. The next tick overwrites it and any
|
|
112
|
+
// real output erases it, so a 59-module run leaves behind only the findings
|
|
113
|
+
// rather than 59 ticks interleaved with them — which is the whole reason a
|
|
114
|
+
// ticker is bearable at this length at all.
|
|
115
|
+
this.errStream.write(truncate(text, this.errStream.columns));
|
|
116
|
+
this.transient = true;
|
|
117
|
+
}
|
|
62
118
|
/** Emit a command's structured RESULT ENVELOPE. A no-op in text mode.
|
|
63
119
|
*
|
|
64
120
|
* Every command that owns its stdout calls this exactly once, including when
|
|
@@ -75,6 +131,10 @@ export class Output {
|
|
|
75
131
|
* whose wire protocol is framed per event precisely because it shares a
|
|
76
132
|
* stream. */
|
|
77
133
|
emit(payload) {
|
|
134
|
+
// Unconditionally, including under `text` where nothing is written: every
|
|
135
|
+
// command reports its result exactly once, so this is the lifecycle point at
|
|
136
|
+
// which a leftover ticker has to go.
|
|
137
|
+
this.clearTransient();
|
|
78
138
|
if (this.format === "json")
|
|
79
139
|
this.outStream.write(serialize(payload));
|
|
80
140
|
}
|
|
@@ -86,6 +146,7 @@ export class Output {
|
|
|
86
146
|
* must keep working under the default `text` format. One serializer with
|
|
87
147
|
* `emit`, so the CLI has a single JSON encoding rather than three. */
|
|
88
148
|
document(payload) {
|
|
149
|
+
this.clearTransient();
|
|
89
150
|
this.outStream.write(serialize(payload));
|
|
90
151
|
}
|
|
91
152
|
/** Write verbatim content to stdout, unconditionally and with no framing.
|
|
@@ -96,9 +157,30 @@ export class Output {
|
|
|
96
157
|
* — the `--json` path wraps them in a document instead and never reaches
|
|
97
158
|
* here. */
|
|
98
159
|
raw(content) {
|
|
160
|
+
this.clearTransient();
|
|
99
161
|
this.outStream.write(content);
|
|
100
162
|
}
|
|
101
163
|
}
|
|
164
|
+
/** Clip to the terminal width, measuring PRINTABLE characters so the escapes a
|
|
165
|
+
* palette wrapped the text in do not count toward it. A line that wraps
|
|
166
|
+
* occupies two rows and the erase sequence clears one. */
|
|
167
|
+
function truncate(text, columns) {
|
|
168
|
+
if (!columns || columns < 8)
|
|
169
|
+
return text;
|
|
170
|
+
let printable = 0;
|
|
171
|
+
for (let i = 0; i < text.length; i++) {
|
|
172
|
+
// Skip a CSI sequence wholesale: `\x1b[` … a final byte in `@`–`~`.
|
|
173
|
+
if (text[i] === "\x1b" && text[i + 1] === "[") {
|
|
174
|
+
i += 2;
|
|
175
|
+
while (i < text.length && !/[@-~]/.test(text[i]))
|
|
176
|
+
i++;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (++printable > columns - 1)
|
|
180
|
+
return `${text.slice(0, i)}…`;
|
|
181
|
+
}
|
|
182
|
+
return text;
|
|
183
|
+
}
|
|
102
184
|
function serialize(payload) {
|
|
103
185
|
return `${JSON.stringify(payload, null, 2)}\n`;
|
|
104
186
|
}
|
|
@@ -140,4 +222,6 @@ export const outLine = (text = "") => current.line(text);
|
|
|
140
222
|
export const outErrLine = (text = "") => current.errLine(text);
|
|
141
223
|
export const outEmit = (payload) => current.emit(payload);
|
|
142
224
|
export const outDocument = (payload) => current.document(payload);
|
|
225
|
+
export const outProgress = (text) => current.progress(text);
|
|
226
|
+
export const outEndProgress = () => current.endProgress();
|
|
143
227
|
//# sourceMappingURL=output.js.map
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAM9C,MAAM,CAAC,MAAM,cAAc,GAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAiB/D,MAAM,KAAK,GAAY;IACrB,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACZ,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACd,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACf,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;CACd,CAAC;AAEF,SAAS,UAAU,CAAC,KAAc,EAAE,GAAsB;IACxD,+EAA+E;IAC/E,0CAA0C;IAC1C,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,IAAI,IAAI,IAAI,SAAS,CAAC;IAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACjF,CAAC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAM9C,MAAM,CAAC,MAAM,cAAc,GAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAiB/D,MAAM,KAAK,GAAY;IACrB,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACZ,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACd,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACf,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;CACd,CAAC;AAEF,SAAS,UAAU,CAAC,KAAc,EAAE,GAAsB;IACxD,+EAA+E;IAC/E,0CAA0C;IAC1C,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,IAAI,IAAI,IAAI,SAAS,CAAC;IAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACjF,CAAC;AAqBD;;;;;;;;;;;;gEAYgE;AAChE,MAAM,OAAO,MAAM;IACR,MAAM,CAAe;IACrB,MAAM,CAAU;IAChB,MAAM,CAAU;IACR,SAAS,CAAe;IACxB,SAAS,CAAe;IAEzC,YAAY,OAAsB;QAChC,MAAM,EACJ,MAAM,EACN,MAAM,GAAG,OAAO,CAAC,MAAM,EACvB,MAAM,GAAG,OAAO,CAAC,MAAM,EACvB,GAAG,GAAG,OAAO,CAAC,GAAG,GAClB,GAAG,OAAO,CAAC;QACZ,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxB,2EAA2E;QAC3E,2EAA2E;QAC3E,2EAA2E;QAC3E,6DAA6D;QAC7D,IAAI,CAAC,MAAM,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjF,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED;;;2EAGuE;IAC/D,SAAS,GAAG,KAAK,CAAC;IAE1B,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC;IAChC,CAAC;IAED;;;yEAGqE;IAC7D,cAAc;QACpB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;IAED;;0DAEsD;IACtD,WAAW;QACT,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED;oCACgC;IAChC,IAAI,CAAC,IAAI,GAAG,EAAE;QACZ,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO;QACnC,4EAA4E;QAC5E,4EAA4E;QAC5E,gCAAgC;QAChC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;gFAC4E;IAC5E,OAAO,CAAC,IAAI,GAAG,EAAE;QACf,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,IAAY;QACnB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK;YAAE,OAAO;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,0EAA0E;QAC1E,4EAA4E;QAC5E,2EAA2E;QAC3E,4CAA4C;QAC5C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;kBAcc;IACd,IAAI,CAAC,OAAgB;QACnB,0EAA0E;QAC1E,6EAA6E;QAC7E,qCAAqC;QACrC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;YAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,CAAC;IAED;;;;;;2EAMuE;IACvE,QAAQ,CAAC,OAAgB;QACvB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;gBAMY;IACZ,GAAG,CAAC,OAAe;QACjB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;CACF;AAED;;2DAE2D;AAC3D,SAAS,QAAQ,CAAC,IAAY,EAAE,OAA2B;IACzD,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,oEAAoE;QACpE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9C,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,CAAC,EAAE,CAAC;YACtD,SAAS;QACX,CAAC;QACD,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,CAAC;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,OAAgB;IACjC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED;;6EAE6E;AAC7E,IAAI,OAAO,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE7C,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,OAAO,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;;2CAI2C;AAC3C,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC;IACzB,OAAO,GAAG,WAAW,CAAC;IACtB,OAAO,GAAG,EAAE;QACV,OAAO,GAAG,QAAQ,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;gDAGgD;AAChD,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAqB,CAAC;QAAE,OAAO,KAAqB,CAAC;IACjF,MAAM,IAAI,KAAK,CACb,gCAAgC,MAAM,CAAC,KAAK,CAAC,uBAAuB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACjG,CAAC;AACJ,CAAC;AAED;;+EAE+E;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAI,GAAG,EAAE,EAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,EAAE,EAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,OAAgB,EAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAgB,EAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC"}
|