@flow-as-code/cli 0.1.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/LICENSE +202 -0
- package/README.md +446 -0
- package/dist/aws.d.ts +28 -0
- package/dist/aws.d.ts.map +1 -0
- package/dist/aws.js +104 -0
- package/dist/aws.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +132 -0
- package/dist/bin.js.map +1 -0
- package/dist/bridge/exportFiles.d.ts +16 -0
- package/dist/bridge/exportFiles.d.ts.map +1 -0
- package/dist/bridge/exportFiles.js +95 -0
- package/dist/bridge/exportFiles.js.map +1 -0
- package/dist/bridge/pair.d.ts +103 -0
- package/dist/bridge/pair.d.ts.map +1 -0
- package/dist/bridge/pair.js +219 -0
- package/dist/bridge/pair.js.map +1 -0
- package/dist/bridge/protocol.d.ts +187 -0
- package/dist/bridge/protocol.d.ts.map +1 -0
- package/dist/bridge/protocol.js +132 -0
- package/dist/bridge/protocol.js.map +1 -0
- package/dist/bridge/server.d.ts +95 -0
- package/dist/bridge/server.d.ts.map +1 -0
- package/dist/bridge/server.js +669 -0
- package/dist/bridge/server.js.map +1 -0
- package/dist/cdk-scaffold.d.ts +16 -0
- package/dist/cdk-scaffold.d.ts.map +1 -0
- package/dist/cdk-scaffold.js +28 -0
- package/dist/cdk-scaffold.js.map +1 -0
- package/dist/codegen.d.ts +5 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +27 -0
- package/dist/codegen.js.map +1 -0
- package/dist/diff.d.ts +33 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +225 -0
- package/dist/diff.js.map +1 -0
- package/dist/docs.d.ts +46 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +223 -0
- package/dist/docs.js.map +1 -0
- package/dist/emit.d.ts +8 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +55 -0
- package/dist/emit.js.map +1 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/export.d.ts +27 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +126 -0
- package/dist/export.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/lint.d.ts +6 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +31 -0
- package/dist/lint.js.map +1 -0
- package/dist/render.d.ts +6 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +49 -0
- package/dist/render.js.map +1 -0
- package/dist/run.d.ts +13 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +38 -0
- package/dist/run.js.map +1 -0
- package/dist/simulate.d.ts +35 -0
- package/dist/simulate.d.ts.map +1 -0
- package/dist/simulate.js +194 -0
- package/dist/simulate.js.map +1 -0
- package/dist/studio.d.ts +23 -0
- package/dist/studio.d.ts.map +1 -0
- package/dist/studio.js +120 -0
- package/dist/studio.js.map +1 -0
- package/dist/synth-resolve-hook.d.ts +19 -0
- package/dist/synth-resolve-hook.d.ts.map +1 -0
- package/dist/synth-resolve-hook.js +127 -0
- package/dist/synth-resolve-hook.js.map +1 -0
- package/dist/synth-runner.d.ts +12 -0
- package/dist/synth-runner.d.ts.map +1 -0
- package/dist/synth-runner.js +145 -0
- package/dist/synth-runner.js.map +1 -0
- package/dist/synth.d.ts +55 -0
- package/dist/synth.d.ts.map +1 -0
- package/dist/synth.js +327 -0
- package/dist/synth.js.map +1 -0
- package/dist/watch.d.ts +66 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +293 -0
- package/dist/watch.js.map +1 -0
- package/package.json +85 -0
- package/schema/flowdoc-0.1.schema.json +669 -0
- package/schema/scenario-0.1.schema.json +318 -0
- package/src/aws.ts +149 -0
- package/src/bin.ts +179 -0
- package/src/bridge/exportFiles.ts +116 -0
- package/src/bridge/pair.ts +312 -0
- package/src/bridge/protocol.ts +289 -0
- package/src/bridge/server.ts +827 -0
- package/src/cdk-scaffold.ts +41 -0
- package/src/codegen.ts +36 -0
- package/src/diff.ts +279 -0
- package/src/docs.ts +249 -0
- package/src/emit.ts +69 -0
- package/src/errors.ts +27 -0
- package/src/export.ts +167 -0
- package/src/index.ts +27 -0
- package/src/lint.ts +42 -0
- package/src/render.ts +58 -0
- package/src/run.ts +42 -0
- package/src/simulate.ts +244 -0
- package/src/studio.ts +143 -0
- package/src/synth-resolve-hook.ts +152 -0
- package/src/synth-runner.ts +157 -0
- package/src/synth.ts +380 -0
- package/src/watch.ts +388 -0
package/dist/docs.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// Loading FlowDocs for the commands that take a `<dir-or-file>` argument.
|
|
6
|
+
//
|
|
7
|
+
// One entry point, one set of diagnostics: a path that does not exist, a file
|
|
8
|
+
// that is not JSON, and a document that does not satisfy the FlowDoc schema all
|
|
9
|
+
// come out as a CliError naming the offending path. Every problem in the set is
|
|
10
|
+
// reported, not just the first, so one run fixes one round of edits.
|
|
11
|
+
//
|
|
12
|
+
// schema/flowdoc-0.1.schema.json is a byte copy of
|
|
13
|
+
// conformance/schema/flowdoc-0.1.schema.json, kept inside the package because
|
|
14
|
+
// the conformance tree is not published. src/schema.test.ts fails if the two
|
|
15
|
+
// drift, so the CLI and the cross-language contract cannot disagree.
|
|
16
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
17
|
+
import { dirname, join, resolve } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
import { NO_LITERAL_ARN, literalArnMessage, literalArnPaths } from "@flow-as-code/core";
|
|
20
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
21
|
+
import { CliError, messageOf } from "./errors.js";
|
|
22
|
+
/** A directory argument loads every file with this suffix, sorted by name. */
|
|
23
|
+
export const FLOWDOC_SUFFIX = ".flowdoc.json";
|
|
24
|
+
/** Errors reported for one document before the rest are elided. */
|
|
25
|
+
const MAX_SCHEMA_ERRORS = 10;
|
|
26
|
+
/** Absolute path of the packaged FlowDoc schema (`../schema` from src or dist). */
|
|
27
|
+
export const SCHEMA_PATH = fileURLToPath(new URL("../schema/flowdoc-0.1.schema.json", import.meta.url));
|
|
28
|
+
let compiled;
|
|
29
|
+
function flowDocValidator() {
|
|
30
|
+
if (compiled === undefined) {
|
|
31
|
+
const schema = JSON.parse(readFileSync(SCHEMA_PATH, "utf8"));
|
|
32
|
+
compiled = new Ajv2020({ allErrors: true, strict: false }).compile(schema);
|
|
33
|
+
}
|
|
34
|
+
return compiled;
|
|
35
|
+
}
|
|
36
|
+
/** One schema violation, as "<where> <what>". */
|
|
37
|
+
function describeSchemaError(error) {
|
|
38
|
+
const where = error.instancePath === "" ? "(root)" : error.instancePath;
|
|
39
|
+
return `${where} ${error.message ?? "is invalid"}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* An ajv instancePath (`/content/Actions/3/Parameters/QueueId`) in the dotted
|
|
43
|
+
* form @flow-as-code/core's string walker produces
|
|
44
|
+
* (`content.Actions[3].Parameters.QueueId`), so the two can be compared.
|
|
45
|
+
*/
|
|
46
|
+
function pointerToPath(instancePath) {
|
|
47
|
+
let out = "";
|
|
48
|
+
for (const raw of instancePath.split("/").slice(1)) {
|
|
49
|
+
const segment = raw.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
50
|
+
if (/^\d+$/.test(segment))
|
|
51
|
+
out += `[${segment}]`;
|
|
52
|
+
else
|
|
53
|
+
out += out === "" ? segment : `.${segment}`;
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
/** True when this schema error is describing one of the literal ARNs found. */
|
|
58
|
+
function causedByLiteralArn(instancePath, arnPaths) {
|
|
59
|
+
const path = pointerToPath(instancePath);
|
|
60
|
+
const under = (parent, child) => child.startsWith(`${parent}.`) || child.startsWith(`${parent}[`);
|
|
61
|
+
return arnPaths.some((arn) => arn === path || under(path, arn) || under(arn, path));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Problems with a value that claims to be a FlowDoc, empty when it is one. The
|
|
65
|
+
* studio bridge validates documents arriving over HTTP with exactly the
|
|
66
|
+
* validator every command uses on documents read from disk.
|
|
67
|
+
*
|
|
68
|
+
* A literal ARN is reported once per offending field, by rule id, rather than
|
|
69
|
+
* as the several schema pattern errors one ARN produces: the token pattern
|
|
70
|
+
* fails, the alternative `$.` pattern fails, their `oneOf` fails, and the
|
|
71
|
+
* enclosing `if/then` fails, none of which say "literal ARN". The schema stays
|
|
72
|
+
* the backstop, and every schema error the ARN did not cause is still shown.
|
|
73
|
+
*
|
|
74
|
+
* The ARN scan runs whether or not the schema is satisfied. Only ref-shaped
|
|
75
|
+
* fields carry a `${cdref:...}` pattern, so an ARN pasted into free text
|
|
76
|
+
* (`Parameters.Text`, a prompt, a label) is schema-valid; `no-literal-arn` is
|
|
77
|
+
* a hard rule and the bridge write path has no other lint step, so scanning
|
|
78
|
+
* only after a schema failure would let exactly those documents onto disk.
|
|
79
|
+
*/
|
|
80
|
+
export function flowDocProblems(value) {
|
|
81
|
+
const validate = flowDocValidator();
|
|
82
|
+
const valid = validate(value);
|
|
83
|
+
const errors = valid ? [] : (validate.errors ?? []);
|
|
84
|
+
const arnPaths = literalArnPaths(value);
|
|
85
|
+
if (valid && arnPaths.length === 0)
|
|
86
|
+
return [];
|
|
87
|
+
const problems = [
|
|
88
|
+
...arnPaths.map((path) => `${NO_LITERAL_ARN}: ${literalArnMessage(path)}`),
|
|
89
|
+
...errors.filter((e) => !causedByLiteralArn(e.instancePath, arnPaths)).map(describeSchemaError),
|
|
90
|
+
];
|
|
91
|
+
const shown = problems.slice(0, MAX_SCHEMA_ERRORS);
|
|
92
|
+
if (problems.length > MAX_SCHEMA_ERRORS) {
|
|
93
|
+
shown.push(`... and ${String(problems.length - MAX_SCHEMA_ERRORS)} more`);
|
|
94
|
+
}
|
|
95
|
+
return shown;
|
|
96
|
+
}
|
|
97
|
+
/** A problem that names a lint rule already reads as a sentence on its own. */
|
|
98
|
+
function isRuleProblem(problem) {
|
|
99
|
+
return problem.startsWith(`${NO_LITERAL_ARN}: `);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Absolute paths of the documents a `<dir-or-file>` argument names. A directory
|
|
103
|
+
* contributes every `*.flowdoc.json` in it, sorted, and is not walked
|
|
104
|
+
* recursively; a file contributes itself whatever its extension.
|
|
105
|
+
*/
|
|
106
|
+
export function resolveDocPaths(target) {
|
|
107
|
+
const abs = resolve(target);
|
|
108
|
+
let stat;
|
|
109
|
+
try {
|
|
110
|
+
stat = statSync(abs);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
throw new CliError(`No such file or directory: ${abs}`);
|
|
114
|
+
}
|
|
115
|
+
if (!stat.isDirectory())
|
|
116
|
+
return [abs];
|
|
117
|
+
const files = readdirSync(abs)
|
|
118
|
+
.filter((f) => f.endsWith(FLOWDOC_SUFFIX))
|
|
119
|
+
.sort()
|
|
120
|
+
.map((f) => join(abs, f));
|
|
121
|
+
if (files.length === 0) {
|
|
122
|
+
throw new CliError(`No *${FLOWDOC_SUFFIX} files in ${abs}`);
|
|
123
|
+
}
|
|
124
|
+
return files;
|
|
125
|
+
}
|
|
126
|
+
/** Reads and schema-validates every document a `<dir-or-file>` argument names. */
|
|
127
|
+
export function loadDocs(target) {
|
|
128
|
+
const validate = flowDocValidator();
|
|
129
|
+
const problems = [];
|
|
130
|
+
const loaded = [];
|
|
131
|
+
for (const path of resolveDocPaths(target)) {
|
|
132
|
+
let raw;
|
|
133
|
+
try {
|
|
134
|
+
raw = readFileSync(path, "utf8");
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
problems.push(`${path}: ${messageOf(error)}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
let parsed;
|
|
141
|
+
try {
|
|
142
|
+
parsed = JSON.parse(raw);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
problems.push(`${path}: invalid JSON: ${messageOf(error)}`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (!validate(parsed)) {
|
|
149
|
+
for (const problem of flowDocProblems(parsed)) {
|
|
150
|
+
problems.push(problem.startsWith("... and ") || isRuleProblem(problem)
|
|
151
|
+
? `${path}: ${problem}`
|
|
152
|
+
: `${path}: not a valid FlowDoc: ${problem}`);
|
|
153
|
+
}
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
loaded.push({ path, doc: parsed });
|
|
157
|
+
}
|
|
158
|
+
if (problems.length > 0) {
|
|
159
|
+
throw new CliError(`${String(problems.length)} problem(s):\n - ${problems.join("\n - ")}`);
|
|
160
|
+
}
|
|
161
|
+
return loaded;
|
|
162
|
+
}
|
|
163
|
+
/** Loads the one document a single-file argument names, refusing a directory. */
|
|
164
|
+
export function loadOneDoc(target, command) {
|
|
165
|
+
const abs = resolve(target);
|
|
166
|
+
let stat;
|
|
167
|
+
try {
|
|
168
|
+
stat = statSync(abs);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
throw new CliError(`No such file or directory: ${abs}`);
|
|
172
|
+
}
|
|
173
|
+
if (stat.isDirectory()) {
|
|
174
|
+
throw new CliError(`${command} takes a single FlowDoc file, not a directory: ${abs}`);
|
|
175
|
+
}
|
|
176
|
+
const [only] = loadDocs(abs);
|
|
177
|
+
if (only === undefined)
|
|
178
|
+
throw new CliError(`No FlowDoc loaded from ${abs}`);
|
|
179
|
+
return only;
|
|
180
|
+
}
|
|
181
|
+
/** Where a command writes when `--out` is absent: the directory of its input. */
|
|
182
|
+
export function defaultOutDir(target) {
|
|
183
|
+
const abs = resolve(target);
|
|
184
|
+
try {
|
|
185
|
+
return statSync(abs).isDirectory() ? abs : dirname(abs);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
throw new CliError(`No such file or directory: ${abs}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Reads a JSON file that must hold a flat string to string object: the resource
|
|
193
|
+
* map for `render` and the address map for `emit --target tf`.
|
|
194
|
+
*/
|
|
195
|
+
export function readStringMap(path, what) {
|
|
196
|
+
const abs = resolve(path);
|
|
197
|
+
let raw;
|
|
198
|
+
try {
|
|
199
|
+
raw = readFileSync(abs, "utf8");
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
throw new CliError(`No such file or directory: ${abs}`);
|
|
203
|
+
}
|
|
204
|
+
let parsed;
|
|
205
|
+
try {
|
|
206
|
+
parsed = JSON.parse(raw);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
throw new CliError(`${abs}: invalid JSON: ${messageOf(error)}`);
|
|
210
|
+
}
|
|
211
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
212
|
+
throw new CliError(`${abs}: the ${what} must be a JSON object of string to string.`);
|
|
213
|
+
}
|
|
214
|
+
const bad = Object.entries(parsed)
|
|
215
|
+
.filter(([, value]) => typeof value !== "string")
|
|
216
|
+
.map(([key]) => key)
|
|
217
|
+
.sort();
|
|
218
|
+
if (bad.length > 0) {
|
|
219
|
+
throw new CliError(`${abs}: the ${what} has non-string value(s) for: ${bad.join(", ")}`);
|
|
220
|
+
}
|
|
221
|
+
return parsed;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=docs.js.map
|
package/dist/docs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"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"}
|
package/dist/emit.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,IAAI,CAAC;AAEtC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE,CAiCrE"}
|
package/dist/emit.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// `flow-cli emit <dir> --target cdk|tf`.
|
|
6
|
+
//
|
|
7
|
+
// The two targets are not symmetric, because the two emitters are not.
|
|
8
|
+
//
|
|
9
|
+
// - tf is a real code generator: @flow-as-code/tf turns the document set into HCL plus
|
|
10
|
+
// .tftpl files. This command is a thin wrapper over `writeTf`, deliberately
|
|
11
|
+
// adding nothing of its own so the bytes it writes are exactly the bytes
|
|
12
|
+
// `emitTf` returns. src/cli.test.ts asserts that equality.
|
|
13
|
+
// - cdk is a library binding: FlowSet reads the FlowDoc directory itself at
|
|
14
|
+
// synth time, so there is nothing per-document to emit and what gets written
|
|
15
|
+
// is a stack scaffold with a TODO binder. See cdk-scaffold.ts.
|
|
16
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
17
|
+
import { join, resolve } from "node:path";
|
|
18
|
+
import { EmitTfError, writeTf } from "@flow-as-code/tf";
|
|
19
|
+
import { CDK_SCAFFOLD_FILE, cdkScaffoldForDirs } from "./cdk-scaffold.js";
|
|
20
|
+
import { defaultOutDir, loadDocs, readStringMap } from "./docs.js";
|
|
21
|
+
import { CliError } from "./errors.js";
|
|
22
|
+
const TARGETS = new Set(["cdk", "tf"]);
|
|
23
|
+
export function runEmit(input, options) {
|
|
24
|
+
if (!TARGETS.has(options.target)) {
|
|
25
|
+
throw new CliError(`Unknown --target "${options.target}". Use "cdk" or "tf".`);
|
|
26
|
+
}
|
|
27
|
+
if (options.target === "cdk" && options.addressMap !== undefined) {
|
|
28
|
+
throw new CliError("--address-map applies to --target tf only; the cdk target uses a binder.");
|
|
29
|
+
}
|
|
30
|
+
const docsDir = defaultOutDir(input);
|
|
31
|
+
const docs = loadDocs(input).map((l) => l.doc);
|
|
32
|
+
const outDir = resolve(options.out ?? docsDir);
|
|
33
|
+
mkdirSync(outDir, { recursive: true });
|
|
34
|
+
if (options.target === "tf") {
|
|
35
|
+
const addressMap = options.addressMap === undefined
|
|
36
|
+
? undefined
|
|
37
|
+
: readStringMap(options.addressMap, "address map");
|
|
38
|
+
let result;
|
|
39
|
+
try {
|
|
40
|
+
result = writeTf(docs, outDir, addressMap === undefined ? {} : { addressMap });
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof EmitTfError)
|
|
44
|
+
throw new CliError(error.message);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
return Object.keys(result.files)
|
|
48
|
+
.sort()
|
|
49
|
+
.map((file) => join(outDir, file));
|
|
50
|
+
}
|
|
51
|
+
const path = join(outDir, CDK_SCAFFOLD_FILE);
|
|
52
|
+
writeFileSync(path, cdkScaffoldForDirs({ docs, outDir, docsDir }), "utf8");
|
|
53
|
+
return [path];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=emit.js.map
|
package/dist/emit.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,yCAAyC;AACzC,EAAE;AACF,uEAAuE;AACvE,EAAE;AACF,uFAAuF;AACvF,8EAA8E;AAC9E,2EAA2E;AAC3E,6DAA6D;AAC7D,4EAA4E;AAC5E,+EAA+E;AAC/E,iEAAiE;AAEjE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAUvC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAE/C,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,OAAoB;IACzD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,QAAQ,CAAC,qBAAqB,OAAO,CAAC,MAAM,uBAAuB,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjE,MAAM,IAAI,QAAQ,CAAC,0EAA0E,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;IAC/C,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,UAAU,GACd,OAAO,CAAC,UAAU,KAAK,SAAS;YAC9B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,WAAW;gBAAE,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpE,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aAC7B,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,OAAO,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A failure with a message meant for the terminal, and the exit code to use.
|
|
3
|
+
* `cause` carries the error it was written from, for callers of the command
|
|
4
|
+
* functions; the terminal only ever sees the message.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CliError extends Error {
|
|
7
|
+
readonly exitCode: number;
|
|
8
|
+
constructor(message: string, exitCode?: number, options?: ErrorOptions);
|
|
9
|
+
}
|
|
10
|
+
/** Message of an unknown thrown value, without a stack trace. */
|
|
11
|
+
export declare function messageOf(error: unknown): string;
|
|
12
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,OAAO,CAAC,EAAE,YAAY;CAKlE;AAED,iEAAiE;AACjE,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// Terminal-facing errors. Every command surfaces failures as a CliError whose
|
|
6
|
+
// message is already written for a human: the offending path, the offending
|
|
7
|
+
// token, or the flag that was wrong, on stderr, with nothing else added.
|
|
8
|
+
/**
|
|
9
|
+
* A failure with a message meant for the terminal, and the exit code to use.
|
|
10
|
+
* `cause` carries the error it was written from, for callers of the command
|
|
11
|
+
* functions; the terminal only ever sees the message.
|
|
12
|
+
*/
|
|
13
|
+
export class CliError extends Error {
|
|
14
|
+
exitCode;
|
|
15
|
+
constructor(message, exitCode = 1, options) {
|
|
16
|
+
super(message, options);
|
|
17
|
+
this.name = "CliError";
|
|
18
|
+
this.exitCode = exitCode;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Message of an unknown thrown value, without a stack trace. */
|
|
22
|
+
export function messageOf(error) {
|
|
23
|
+
return error instanceof Error ? error.message : String(error);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,8EAA8E;AAC9E,4EAA4E;AAC5E,yEAAyE;AAEzE;;;;GAIG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,QAAQ,CAAS;IAE1B,YAAY,OAAe,EAAE,QAAQ,GAAG,CAAC,EAAE,OAAsB;QAC/D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
package/dist/export.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ExportFailure, FlowDoc } from "@flow-as-code/core";
|
|
2
|
+
import { type LiveClients } from "./aws.js";
|
|
3
|
+
export declare const TS_SUFFIX = ".flow.ts";
|
|
4
|
+
export interface ExportOptions {
|
|
5
|
+
instance: string;
|
|
6
|
+
out?: string;
|
|
7
|
+
/** commander's `--no-codegen` sets this false; absent means generate. */
|
|
8
|
+
codegen?: boolean;
|
|
9
|
+
onError?: string;
|
|
10
|
+
}
|
|
11
|
+
/** One document written to disk. */
|
|
12
|
+
export interface WrittenDoc {
|
|
13
|
+
name: string;
|
|
14
|
+
kind: FlowDoc["kind"];
|
|
15
|
+
/** Paths relative to the output directory, document first. */
|
|
16
|
+
files: string[];
|
|
17
|
+
/** True when the content came through the `$SAVED` alias (never published). */
|
|
18
|
+
saved: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ExportOutcome {
|
|
21
|
+
outDir: string;
|
|
22
|
+
written: WrittenDoc[];
|
|
23
|
+
failures: ExportFailure[];
|
|
24
|
+
warnings: string[];
|
|
25
|
+
}
|
|
26
|
+
export declare function runExport(options: ExportOptions, clients?: LiveClients): Promise<ExportOutcome>;
|
|
27
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,aAAa,EAAgB,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EAAE,KAAK,WAAW,EAAiC,MAAM,UAAU,CAAC;AAK3E,eAAO,MAAM,SAAS,aAAa,CAAC;AAEpC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+EAA+E;IAC/E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAyBD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,WAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CA0ExB"}
|
package/dist/export.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// `flow-cli export --instance <arn> [--out <dir>] [--no-codegen] [--on-error abort|collect]`.
|
|
6
|
+
//
|
|
7
|
+
// Reads every flow and module in a live instance through @flow-as-code/core's
|
|
8
|
+
// exportInstance and writes one `<name>.flowdoc.json` per document, plus
|
|
9
|
+
// `<name>.flow.ts` unless --no-codegen, into --out (default: the working
|
|
10
|
+
// directory). The name is the slug the exporter derives from the console name,
|
|
11
|
+
// which is also how `diff` finds the live counterpart of a local document.
|
|
12
|
+
//
|
|
13
|
+
// --on-error defaults to collect, not abort, because a fresh instance always
|
|
14
|
+
// holds the stock "Sample Lambda integration" flow, which calls a Lambda in an
|
|
15
|
+
// AWS-owned account that ListLambdaFunctions cannot return. That flow is an
|
|
16
|
+
// unknown-ARN hard error by design (packages/core/SPEC.md, Export), and
|
|
17
|
+
// aborting on it would make a first export of any new instance write nothing.
|
|
18
|
+
// Collect writes everything else and reports every failure at once; either
|
|
19
|
+
// mode exits 1 when any flow failed.
|
|
20
|
+
//
|
|
21
|
+
// Both halves of a pair are written the way `synth` and the studio write them:
|
|
22
|
+
// the document carries `meta.sourceHash` of the generated source, so the watch
|
|
23
|
+
// engine sees an exported pair as in sync rather than as a conflict. An
|
|
24
|
+
// existing `<name>.flow.ts` is read first so its `@keep` comments survive, as
|
|
25
|
+
// `codegen` does.
|
|
26
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
27
|
+
import { join, resolve } from "node:path";
|
|
28
|
+
import { codegen, collectInventory, exportInstance, serialize } from "@flow-as-code/core";
|
|
29
|
+
import { parseInstanceArn, SDK_CLIENTS } from "./aws.js";
|
|
30
|
+
import { FLOWDOC_SUFFIX } from "./docs.js";
|
|
31
|
+
import { CliError, messageOf } from "./errors.js";
|
|
32
|
+
import { GENERATOR, sha256Hex } from "./synth.js";
|
|
33
|
+
export const TS_SUFFIX = ".flow.ts";
|
|
34
|
+
const ON_ERROR = new Set(["abort", "collect"]);
|
|
35
|
+
/** Writes one exported document, and its source when asked. */
|
|
36
|
+
function writeExported(flow, outDir, withCode) {
|
|
37
|
+
const { doc } = flow;
|
|
38
|
+
const docFile = `${doc.name}${FLOWDOC_SUFFIX}`;
|
|
39
|
+
const files = [docFile];
|
|
40
|
+
let text;
|
|
41
|
+
if (withCode) {
|
|
42
|
+
const tsFile = `${doc.name}${TS_SUFFIX}`;
|
|
43
|
+
const tsPath = join(outDir, tsFile);
|
|
44
|
+
const previous = existsSync(tsPath) ? readFileSync(tsPath, "utf8") : undefined;
|
|
45
|
+
const source = codegen(doc, previous === undefined ? {} : { previous });
|
|
46
|
+
writeFileSync(tsPath, source, "utf8");
|
|
47
|
+
files.push(tsFile);
|
|
48
|
+
text = serialize({ ...doc, meta: { ...doc.meta, sourceHash: `sha256:${sha256Hex(source)}` } });
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
text = serialize(doc);
|
|
52
|
+
}
|
|
53
|
+
writeFileSync(join(outDir, docFile), text, "utf8");
|
|
54
|
+
return { name: doc.name, kind: doc.kind, files, saved: flow.saved === true };
|
|
55
|
+
}
|
|
56
|
+
export async function runExport(options, clients = SDK_CLIENTS) {
|
|
57
|
+
const onError = options.onError ?? "collect";
|
|
58
|
+
if (!ON_ERROR.has(onError)) {
|
|
59
|
+
throw new CliError(`Unknown --on-error "${onError}". Use "abort" or "collect".`);
|
|
60
|
+
}
|
|
61
|
+
const target = parseInstanceArn(options.instance);
|
|
62
|
+
const outDir = resolve(options.out ?? ".");
|
|
63
|
+
const withCode = options.codegen !== false;
|
|
64
|
+
const client = await clients.inventory(target);
|
|
65
|
+
// The inventory is listed on its own, apart from the flows: a refused list
|
|
66
|
+
// call, throttling, or the network failing there is not a flow failure, so
|
|
67
|
+
// --on-error has no say in it and the SDK's message is passed through as is.
|
|
68
|
+
let inventory;
|
|
69
|
+
try {
|
|
70
|
+
inventory = await collectInventory(client);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throw new CliError(messageOf(error), 1, { cause: error });
|
|
74
|
+
}
|
|
75
|
+
let result;
|
|
76
|
+
try {
|
|
77
|
+
result = await exportInstance(client, {
|
|
78
|
+
inventory,
|
|
79
|
+
onError: onError === "abort" ? "throw" : "collect",
|
|
80
|
+
generator: GENERATOR,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
// With the inventory in hand, exportInstance throws only for a flow, and
|
|
85
|
+
// only in abort mode; collect records every flow failure in `failures`.
|
|
86
|
+
throw new CliError(`export aborted (--on-error abort): ${messageOf(error)}`, 1, {
|
|
87
|
+
cause: error,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
mkdirSync(outDir, { recursive: true });
|
|
91
|
+
const failures = [...result.failures];
|
|
92
|
+
const written = [];
|
|
93
|
+
// Flow and module names are unique per kind, not across kinds, and both
|
|
94
|
+
// kinds write <name>.flowdoc.json. The second one is a failure, not a
|
|
95
|
+
// silent overwrite.
|
|
96
|
+
const claimed = new Map();
|
|
97
|
+
for (const flow of result.flows) {
|
|
98
|
+
const other = claimed.get(flow.doc.name);
|
|
99
|
+
if (other !== undefined) {
|
|
100
|
+
failures.push({
|
|
101
|
+
arn: flow.arn,
|
|
102
|
+
name: flow.sourceName,
|
|
103
|
+
reason: `a ${other.doc.kind} and a ${flow.doc.kind} both slug to "${flow.doc.name}"; ` +
|
|
104
|
+
`not written, ${other.doc.name}${FLOWDOC_SUFFIX} holds the ${other.doc.kind}`,
|
|
105
|
+
});
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
claimed.set(flow.doc.name, flow);
|
|
109
|
+
written.push(writeExported(flow, outDir, withCode));
|
|
110
|
+
}
|
|
111
|
+
for (const warning of result.warnings)
|
|
112
|
+
console.error(`warning: ${warning}`);
|
|
113
|
+
for (const doc of written) {
|
|
114
|
+
const tag = doc.saved ? `${doc.kind}, $SAVED` : doc.kind;
|
|
115
|
+
console.log(`${doc.name} (${tag}): ${doc.files.join(", ")}`);
|
|
116
|
+
}
|
|
117
|
+
for (const failure of failures) {
|
|
118
|
+
console.error(`failed: ${failure.name} (${failure.arn}): ${failure.reason}`);
|
|
119
|
+
}
|
|
120
|
+
console.log(`Exported ${String(written.length)} of ${String(written.length + failures.length)} to ${outDir}`);
|
|
121
|
+
if (failures.length > 0) {
|
|
122
|
+
throw new CliError(`${String(failures.length)} flow(s) could not be exported`);
|
|
123
|
+
}
|
|
124
|
+
return { outDir, written, failures, warnings: result.warnings };
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// Library entry. Importing this package must not run the CLI, so the commander
|
|
6
|
+
// program lives in ./bin.ts and nothing here has a side effect at load time.
|
|
7
|
+
// The three subpath exports (./synth, ./watch, ./bridge) are the public API and
|
|
8
|
+
// this module is their union; src/index.test.ts holds the two in step.
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
export * from "./synth.js";
|
|
11
|
+
export * from "./watch.js";
|
|
12
|
+
export * from "./bridge/server.js";
|
|
13
|
+
// Before the bin split this file was the CLI, so `node .../dist/index.js studio`
|
|
14
|
+
// still exists in scripts and in muscle memory. Left alone it now exits 0 having
|
|
15
|
+
// done nothing, which reads as success. Refuse instead, but only when this module
|
|
16
|
+
// is the process entry point: on the import path argv[1] is some other script (or
|
|
17
|
+
// undefined under `node -e`), the branch is not taken, and importing stays free of
|
|
18
|
+
// side effects.
|
|
19
|
+
if (process.argv[1] !== undefined && pathToFileURL(process.argv[1]).href === import.meta.url) {
|
|
20
|
+
process.stderr.write("flow-cli: this is the library entry and runs no commands. Run the CLI as dist/bin.js (or the installed flow-cli bin).\n");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,uEAAuE;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AAEnC,iFAAiF;AACjF,iFAAiF;AACjF,kFAAkF;AAClF,kFAAkF;AAClF,mFAAmF;AACnF,gBAAgB;AAChB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7F,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yHAAyH,CAC1H,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
package/dist/lint.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAalE"}
|
package/dist/lint.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// `flow-cli lint <dir-or-file>`.
|
|
6
|
+
//
|
|
7
|
+
// The whole document set goes to @flow-as-code/core's lint in ONE call. Rules receive
|
|
8
|
+
// `all` alongside `doc` (packages/core/src/lint/types.ts), and the ones
|
|
9
|
+
// that follow module references need the rest of the set to answer at all:
|
|
10
|
+
// linting file by file would silently downgrade module-depth-5 and every other
|
|
11
|
+
// cross-document rule to a no-op.
|
|
12
|
+
//
|
|
13
|
+
// Exit status is severity, not finding count: any `error` exits 1, warnings
|
|
14
|
+
// alone exit 0.
|
|
15
|
+
import { lint, toJson, toText } from "@flow-as-code/core";
|
|
16
|
+
import { loadDocs } from "./docs.js";
|
|
17
|
+
import { CliError } from "./errors.js";
|
|
18
|
+
const FORMATS = new Set(["text", "json"]);
|
|
19
|
+
export function runLint(target, options) {
|
|
20
|
+
const format = options.format ?? "text";
|
|
21
|
+
if (!FORMATS.has(format)) {
|
|
22
|
+
throw new CliError(`Unknown --format "${format}". Use "text" or "json".`);
|
|
23
|
+
}
|
|
24
|
+
const findings = lint(loadDocs(target).map((l) => l.doc));
|
|
25
|
+
process.stdout.write(format === "json" ? toJson(findings) : toText(findings));
|
|
26
|
+
const errors = findings.filter((f) => f.severity === "error").length;
|
|
27
|
+
if (errors > 0) {
|
|
28
|
+
throw new CliError(`lint failed: ${String(errors)} error-severity finding(s) in ${target}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=lint.js.map
|
package/dist/lint.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,iCAAiC;AACjC,EAAE;AACF,sFAAsF;AACtF,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,kCAAkC;AAClC,EAAE;AACF,4EAA4E;AAC5E,gBAAgB;AAEhB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQvC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAElD,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,OAAoB;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;IACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,QAAQ,CAAC,qBAAqB,MAAM,0BAA0B,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE9E,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACrE,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,iCAAiC,MAAM,EAAE,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,EAAE,CA8B1E"}
|