@fazelstudio/floe 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/LICENSE +21 -0
- package/dist/src/cli/check.d.ts +14 -0
- package/dist/src/cli/check.d.ts.map +1 -0
- package/dist/src/cli/check.js +88 -0
- package/dist/src/cli/check.js.map +1 -0
- package/dist/src/cli/format.d.ts +9 -0
- package/dist/src/cli/format.d.ts.map +1 -0
- package/dist/src/cli/format.js +114 -0
- package/dist/src/cli/format.js.map +1 -0
- package/dist/src/cli/main.d.ts +19 -0
- package/dist/src/cli/main.d.ts.map +1 -0
- package/dist/src/cli/main.js +207 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/render.d.ts +7 -0
- package/dist/src/cli/render.d.ts.map +1 -0
- package/dist/src/cli/render.js +90 -0
- package/dist/src/cli/render.js.map +1 -0
- package/dist/src/diagnostics.d.ts +32 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +4 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/index.d.ts +40 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +64 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/language/completion.d.ts +6 -0
- package/dist/src/language/completion.d.ts.map +1 -0
- package/dist/src/language/completion.js +363 -0
- package/dist/src/language/completion.js.map +1 -0
- package/dist/src/language/definitions.d.ts +9 -0
- package/dist/src/language/definitions.d.ts.map +1 -0
- package/dist/src/language/definitions.js +70 -0
- package/dist/src/language/definitions.js.map +1 -0
- package/dist/src/language/diagnosticsService.d.ts +14 -0
- package/dist/src/language/diagnosticsService.d.ts.map +1 -0
- package/dist/src/language/diagnosticsService.js +37 -0
- package/dist/src/language/diagnosticsService.js.map +1 -0
- package/dist/src/language/folding.d.ts +8 -0
- package/dist/src/language/folding.d.ts.map +1 -0
- package/dist/src/language/folding.js +58 -0
- package/dist/src/language/folding.js.map +1 -0
- package/dist/src/language/formatting.d.ts +5 -0
- package/dist/src/language/formatting.d.ts.map +1 -0
- package/dist/src/language/formatting.js +274 -0
- package/dist/src/language/formatting.js.map +1 -0
- package/dist/src/language/highlighting.d.ts +9 -0
- package/dist/src/language/highlighting.d.ts.map +1 -0
- package/dist/src/language/highlighting.js +74 -0
- package/dist/src/language/highlighting.js.map +1 -0
- package/dist/src/language/hover.d.ts +6 -0
- package/dist/src/language/hover.d.ts.map +1 -0
- package/dist/src/language/hover.js +197 -0
- package/dist/src/language/hover.js.map +1 -0
- package/dist/src/language/indentation.d.ts +15 -0
- package/dist/src/language/indentation.d.ts.map +1 -0
- package/dist/src/language/indentation.js +97 -0
- package/dist/src/language/indentation.js.map +1 -0
- package/dist/src/language/index.d.ts +54 -0
- package/dist/src/language/index.d.ts.map +1 -0
- package/dist/src/language/index.js +85 -0
- package/dist/src/language/index.js.map +1 -0
- package/dist/src/language/references.d.ts +12 -0
- package/dist/src/language/references.d.ts.map +1 -0
- package/dist/src/language/references.js +35 -0
- package/dist/src/language/references.js.map +1 -0
- package/dist/src/language/rename.d.ts +18 -0
- package/dist/src/language/rename.d.ts.map +1 -0
- package/dist/src/language/rename.js +53 -0
- package/dist/src/language/rename.js.map +1 -0
- package/dist/src/language/semanticModel.d.ts +21 -0
- package/dist/src/language/semanticModel.d.ts.map +1 -0
- package/dist/src/language/semanticModel.js +43 -0
- package/dist/src/language/semanticModel.js.map +1 -0
- package/dist/src/language/symbols.d.ts +9 -0
- package/dist/src/language/symbols.d.ts.map +1 -0
- package/dist/src/language/symbols.js +160 -0
- package/dist/src/language/symbols.js.map +1 -0
- package/dist/src/language/types.d.ts +49 -0
- package/dist/src/language/types.d.ts.map +1 -0
- package/dist/src/language/types.js +2 -0
- package/dist/src/language/types.js.map +1 -0
- package/dist/src/language/utils.d.ts +24 -0
- package/dist/src/language/utils.d.ts.map +1 -0
- package/dist/src/language/utils.js +154 -0
- package/dist/src/language/utils.js.map +1 -0
- package/dist/src/layout/dagre.d.ts +13 -0
- package/dist/src/layout/dagre.d.ts.map +1 -0
- package/dist/src/layout/dagre.js +229 -0
- package/dist/src/layout/dagre.js.map +1 -0
- package/dist/src/layout/index.d.ts +15 -0
- package/dist/src/layout/index.d.ts.map +1 -0
- package/dist/src/layout/index.js +22 -0
- package/dist/src/layout/index.js.map +1 -0
- package/dist/src/layout/simple.d.ts +20 -0
- package/dist/src/layout/simple.d.ts.map +1 -0
- package/dist/src/layout/simple.js +674 -0
- package/dist/src/layout/simple.js.map +1 -0
- package/dist/src/layout/types.d.ts +65 -0
- package/dist/src/layout/types.d.ts.map +1 -0
- package/dist/src/layout/types.js +2 -0
- package/dist/src/layout/types.js.map +1 -0
- package/dist/src/lexer.d.ts +25 -0
- package/dist/src/lexer.d.ts.map +1 -0
- package/dist/src/lexer.js +280 -0
- package/dist/src/lexer.js.map +1 -0
- package/dist/src/lsp/documents.d.ts +24 -0
- package/dist/src/lsp/documents.d.ts.map +1 -0
- package/dist/src/lsp/documents.js +97 -0
- package/dist/src/lsp/documents.js.map +1 -0
- package/dist/src/lsp/server.d.ts +70 -0
- package/dist/src/lsp/server.d.ts.map +1 -0
- package/dist/src/lsp/server.js +623 -0
- package/dist/src/lsp/server.js.map +1 -0
- package/dist/src/lsp/utils.d.ts +47 -0
- package/dist/src/lsp/utils.d.ts.map +1 -0
- package/dist/src/lsp/utils.js +142 -0
- package/dist/src/lsp/utils.js.map +1 -0
- package/dist/src/parser.d.ts +106 -0
- package/dist/src/parser.d.ts.map +1 -0
- package/dist/src/parser.js +1018 -0
- package/dist/src/parser.js.map +1 -0
- package/dist/src/pipeline.d.ts +51 -0
- package/dist/src/pipeline.d.ts.map +1 -0
- package/dist/src/pipeline.js +65 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/range.d.ts +24 -0
- package/dist/src/range.d.ts.map +1 -0
- package/dist/src/range.js +20 -0
- package/dist/src/range.js.map +1 -0
- package/dist/src/render/index.d.ts +3 -0
- package/dist/src/render/index.d.ts.map +1 -0
- package/dist/src/render/index.js +3 -0
- package/dist/src/render/index.js.map +1 -0
- package/dist/src/render/shapes.d.ts +20 -0
- package/dist/src/render/shapes.d.ts.map +1 -0
- package/dist/src/render/shapes.js +110 -0
- package/dist/src/render/shapes.js.map +1 -0
- package/dist/src/render/svg.d.ts +19 -0
- package/dist/src/render/svg.d.ts.map +1 -0
- package/dist/src/render/svg.js +227 -0
- package/dist/src/render/svg.js.map +1 -0
- package/dist/src/security/url.d.ts +7 -0
- package/dist/src/security/url.d.ts.map +1 -0
- package/dist/src/security/url.js +27 -0
- package/dist/src/security/url.js.map +1 -0
- package/dist/src/types.d.ts +111 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +16 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/validator.d.ts +47 -0
- package/dist/src/validator.d.ts.map +1 -0
- package/dist/src/validator.js +235 -0
- package/dist/src/validator.js.map +1 -0
- package/package.json +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zulfazli (Fazelllyyy) <zulfazlilsm@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Diagnostic } from "../diagnostics.js";
|
|
2
|
+
export interface CheckOptions {
|
|
3
|
+
json?: boolean;
|
|
4
|
+
quiet?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface CheckResult {
|
|
7
|
+
file: string;
|
|
8
|
+
diagnostics: Diagnostic[];
|
|
9
|
+
hasErrors: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function formatDiagnostic(file: string, d: Diagnostic): string;
|
|
12
|
+
export declare function checkFile(filePath: string, opts?: CheckOptions): CheckResult;
|
|
13
|
+
export declare function runCheck(files: string[], opts?: CheckOptions): number;
|
|
14
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/cli/check.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAGpE;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,WAAW,CAWhF;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CA6DzE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { parseFloe } from "../index.js";
|
|
4
|
+
export function formatDiagnostic(file, d) {
|
|
5
|
+
const { line, column } = d.range.start;
|
|
6
|
+
return `${file}:${line}:${column} ${d.code} ${d.severity} ${d.message}`;
|
|
7
|
+
}
|
|
8
|
+
export function checkFile(filePath, opts = {}) {
|
|
9
|
+
let source;
|
|
10
|
+
try {
|
|
11
|
+
source = fs.readFileSync(filePath, "utf-8");
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
15
|
+
throw new Error(`Cannot read file '${filePath}': ${msg}`);
|
|
16
|
+
}
|
|
17
|
+
const { diagnostics } = parseFloe(source);
|
|
18
|
+
const hasErrors = diagnostics.some((d) => d.severity === "error");
|
|
19
|
+
return { file: filePath, diagnostics, hasErrors };
|
|
20
|
+
}
|
|
21
|
+
export function runCheck(files, opts = {}) {
|
|
22
|
+
if (files.length === 0) {
|
|
23
|
+
console.error("floe check: no input files");
|
|
24
|
+
console.error("Usage: floe check <file.floe> [--json]");
|
|
25
|
+
return 2;
|
|
26
|
+
}
|
|
27
|
+
let overallHasErrors = false;
|
|
28
|
+
let overallOutput = [];
|
|
29
|
+
for (const f of files) {
|
|
30
|
+
const resolved = path.resolve(f);
|
|
31
|
+
if (!fs.existsSync(resolved)) {
|
|
32
|
+
console.error(`floe check: file not found: ${f}`);
|
|
33
|
+
return 2;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const result = checkFile(resolved, opts);
|
|
37
|
+
overallOutput.push(result);
|
|
38
|
+
if (result.hasErrors)
|
|
39
|
+
overallHasErrors = true;
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
43
|
+
console.error(msg);
|
|
44
|
+
return 2;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (opts.json) {
|
|
48
|
+
const jsonOut = overallOutput.map((r) => ({
|
|
49
|
+
file: path.relative(process.cwd(), r.file),
|
|
50
|
+
diagnostics: r.diagnostics.map((d) => ({
|
|
51
|
+
code: d.code,
|
|
52
|
+
severity: d.severity,
|
|
53
|
+
message: d.message,
|
|
54
|
+
range: d.range,
|
|
55
|
+
})),
|
|
56
|
+
hasErrors: r.hasErrors,
|
|
57
|
+
}));
|
|
58
|
+
console.log(JSON.stringify(jsonOut, null, 2));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
for (const r of overallOutput) {
|
|
62
|
+
const rel = path.relative(process.cwd(), r.file);
|
|
63
|
+
if (r.diagnostics.length === 0) {
|
|
64
|
+
if (!opts.quiet)
|
|
65
|
+
console.log(`✔ ${rel}: OK`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const errCount = r.diagnostics.filter((d) => d.severity === "error").length;
|
|
69
|
+
const warnCount = r.diagnostics.filter((d) => d.severity === "warning").length;
|
|
70
|
+
if (!opts.quiet) {
|
|
71
|
+
if (errCount > 0)
|
|
72
|
+
console.error(`✖ ${rel}: ${errCount} error(s)${warnCount ? `, ${warnCount} warning(s)` : ""}`);
|
|
73
|
+
else
|
|
74
|
+
console.log(`✔ ${rel}: ${warnCount} warning(s)`);
|
|
75
|
+
}
|
|
76
|
+
for (const d of r.diagnostics) {
|
|
77
|
+
const line = formatDiagnostic(rel, d);
|
|
78
|
+
if (d.severity === "error")
|
|
79
|
+
console.error(line);
|
|
80
|
+
else
|
|
81
|
+
console.log(line);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return overallHasErrors ? 1 : 0;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/cli/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAcxC,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,CAAa;IAC1D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;IACvC,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAqB,EAAE;IACjE,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAClE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAe,EAAE,OAAqB,EAAE;IAC/D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,aAAa,GAAkB,EAAE,CAAC;IAEtC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACzC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,MAAM,CAAC,SAAS;gBAAE,gBAAgB,GAAG,IAAI,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;YAC1C,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;YACH,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACjD,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,IAAI,CAAC,KAAK;oBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;gBAC5E,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;gBAC/E,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBAChB,IAAI,QAAQ,GAAG,CAAC;wBAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,QAAQ,YAAY,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;;wBAC5G,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,SAAS,aAAa,CAAC,CAAC;gBACxD,CAAC;gBACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBACtC,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO;wBAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;;wBAC3C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface FormatOptions {
|
|
2
|
+
write?: boolean;
|
|
3
|
+
check?: boolean;
|
|
4
|
+
stdout?: boolean;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function runFormat(files: string[], opts?: FormatOptions): number;
|
|
8
|
+
export declare function checkIsFormatted(source: string): boolean;
|
|
9
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/cli/format.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAyG3E;AAGD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { format, isFormatted } from "../language/formatting.js";
|
|
4
|
+
import { parseFloe } from "../index.js";
|
|
5
|
+
export function runFormat(files, opts = {}) {
|
|
6
|
+
if (files.length === 0) {
|
|
7
|
+
console.error("floe format: no input files");
|
|
8
|
+
console.error("Usage: floe format <file.floe> [--write] [--check]");
|
|
9
|
+
return 2;
|
|
10
|
+
}
|
|
11
|
+
// Mutually exclusive: --write and --check should not both be set? Allow but prioritize check?
|
|
12
|
+
if (opts.write && opts.check) {
|
|
13
|
+
console.error("floe format: --write and --check are mutually exclusive");
|
|
14
|
+
return 2;
|
|
15
|
+
}
|
|
16
|
+
let hasUnformatted = false;
|
|
17
|
+
let hasErrors = false;
|
|
18
|
+
for (const f of files) {
|
|
19
|
+
const resolved = path.resolve(f);
|
|
20
|
+
if (!fs.existsSync(resolved)) {
|
|
21
|
+
console.error(`floe format: file not found: ${f}`);
|
|
22
|
+
return 2;
|
|
23
|
+
}
|
|
24
|
+
let source;
|
|
25
|
+
try {
|
|
26
|
+
source = fs.readFileSync(resolved, "utf-8");
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
30
|
+
console.error(`Cannot read file '${f}': ${msg}`);
|
|
31
|
+
return 2;
|
|
32
|
+
}
|
|
33
|
+
// Validate that format never throws on malformed input (security: no crash)
|
|
34
|
+
let formatted;
|
|
35
|
+
try {
|
|
36
|
+
formatted = format(source);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
40
|
+
console.error(`floe format: internal error formatting '${f}': ${msg}`);
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
const needsFormat = source !== formatted;
|
|
44
|
+
if (opts.check) {
|
|
45
|
+
if (needsFormat) {
|
|
46
|
+
hasUnformatted = true;
|
|
47
|
+
const rel = path.relative(process.cwd(), resolved);
|
|
48
|
+
if (opts.json) {
|
|
49
|
+
// json output for check mode
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.error(`✖ ${rel}: not formatted`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (!opts.json) {
|
|
57
|
+
const rel = path.relative(process.cwd(), resolved);
|
|
58
|
+
// quiet on success? Only print if not json?
|
|
59
|
+
// For CI, we want quiet success. So no output unless not formatted.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (opts.write) {
|
|
65
|
+
if (needsFormat) {
|
|
66
|
+
try {
|
|
67
|
+
fs.writeFileSync(resolved, formatted, "utf-8");
|
|
68
|
+
const rel = path.relative(process.cwd(), resolved);
|
|
69
|
+
if (!opts.json)
|
|
70
|
+
console.log(`formatted ${rel}`);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
74
|
+
console.error(`Cannot write file '${f}': ${msg}`);
|
|
75
|
+
return 2;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Already formatted, no write
|
|
80
|
+
if (!opts.json) {
|
|
81
|
+
// no output? Could be verbose
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
// Default: stdout (scriptable). If multiple files, separate with header?
|
|
87
|
+
if (files.length === 1) {
|
|
88
|
+
// Single file -> raw formatted to stdout
|
|
89
|
+
process.stdout.write(formatted);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const rel = path.relative(process.cwd(), resolved);
|
|
93
|
+
// For multiple files to stdout, add filename header for scriptability? But spec says scriptable, so we should output each?
|
|
94
|
+
// We'll output with header comment per file for clarity, but that would break piping.
|
|
95
|
+
// Instead, if multiple files and stdout mode, we print each file's formatted content separated by newline and header to stderr
|
|
96
|
+
console.error(`== ${rel} ==`);
|
|
97
|
+
process.stdout.write(formatted);
|
|
98
|
+
if (!formatted.endsWith("\n"))
|
|
99
|
+
process.stdout.write("\n");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (opts.check) {
|
|
103
|
+
return hasUnformatted ? 1 : 0;
|
|
104
|
+
}
|
|
105
|
+
// For write/stdout, exit 0 unless there were read errors (already returned)
|
|
106
|
+
// Should we exit 1 if original file had parse errors? Formatting should still succeed but maybe warn.
|
|
107
|
+
// We keep exit 0 for formatting success, to allow CI to use --check for validation.
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
// For testing: check if file is formatted
|
|
111
|
+
export function checkIsFormatted(source) {
|
|
112
|
+
return isFormatted(source);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/cli/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Floe CLI
|
|
4
|
+
* Commands:
|
|
5
|
+
* floe check <file.floe> [--json] [--quiet]
|
|
6
|
+
* floe format <file.floe> [--write] [--check]
|
|
7
|
+
* floe render <file.floe> [-o output.svg]
|
|
8
|
+
* floe lsp [--stdio] (starts LSP server)
|
|
9
|
+
*
|
|
10
|
+
* Keep CLI behavior scriptable for CI with appropriate exit codes:
|
|
11
|
+
* 0 success
|
|
12
|
+
* 1 validation / check failure
|
|
13
|
+
* 2 usage / file not found error
|
|
14
|
+
*
|
|
15
|
+
* Treat .floe files as untrusted: never eval, ensure SVG cannot execute code.
|
|
16
|
+
* This CLI never uses eval and delegates to safe core.
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Floe CLI
|
|
4
|
+
* Commands:
|
|
5
|
+
* floe check <file.floe> [--json] [--quiet]
|
|
6
|
+
* floe format <file.floe> [--write] [--check]
|
|
7
|
+
* floe render <file.floe> [-o output.svg]
|
|
8
|
+
* floe lsp [--stdio] (starts LSP server)
|
|
9
|
+
*
|
|
10
|
+
* Keep CLI behavior scriptable for CI with appropriate exit codes:
|
|
11
|
+
* 0 success
|
|
12
|
+
* 1 validation / check failure
|
|
13
|
+
* 2 usage / file not found error
|
|
14
|
+
*
|
|
15
|
+
* Treat .floe files as untrusted: never eval, ensure SVG cannot execute code.
|
|
16
|
+
* This CLI never uses eval and delegates to safe core.
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from "node:fs";
|
|
19
|
+
import * as path from "node:path";
|
|
20
|
+
import { runCheck } from "./check.js";
|
|
21
|
+
import { runFormat } from "./format.js";
|
|
22
|
+
import { runRender } from "./render.js";
|
|
23
|
+
const VERSION = "1.0.0";
|
|
24
|
+
function printHelp() {
|
|
25
|
+
console.log(`Floe ${VERSION} — diagram DSL
|
|
26
|
+
|
|
27
|
+
Usage:
|
|
28
|
+
floe <command> [options] <file...>
|
|
29
|
+
|
|
30
|
+
Commands:
|
|
31
|
+
check Validate a .floe file and print diagnostics
|
|
32
|
+
format Format file using canonical formatter
|
|
33
|
+
render Produce SVG output
|
|
34
|
+
lsp Start Language Server (stdio)
|
|
35
|
+
help Show this help
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
-h, --help Show help
|
|
39
|
+
-v, --version Show version
|
|
40
|
+
|
|
41
|
+
Check:
|
|
42
|
+
floe check diagram.floe [--json] [--quiet]
|
|
43
|
+
--json Output diagnostics as JSON
|
|
44
|
+
--quiet Suppress OK messages
|
|
45
|
+
|
|
46
|
+
Format:
|
|
47
|
+
floe format diagram.floe [--write] [--check]
|
|
48
|
+
--write Overwrite file in place
|
|
49
|
+
--check Exit 1 if file not formatted (for CI)
|
|
50
|
+
(default: print formatted content to stdout)
|
|
51
|
+
|
|
52
|
+
Render:
|
|
53
|
+
floe render diagram.floe [-o output.svg]
|
|
54
|
+
-o, --output <file> Write SVG to file (default: stdout)
|
|
55
|
+
|
|
56
|
+
LSP:
|
|
57
|
+
floe lsp [--stdio]
|
|
58
|
+
Starts LSP server over stdio (for editor integration)
|
|
59
|
+
|
|
60
|
+
Exit codes:
|
|
61
|
+
0 success
|
|
62
|
+
1 validation error / not formatted / render had errors
|
|
63
|
+
2 usage or file error
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
floe check diagram.floe
|
|
67
|
+
floe format diagram.floe --write
|
|
68
|
+
floe render diagram.floe -o diagram.svg
|
|
69
|
+
floe lsp
|
|
70
|
+
|
|
71
|
+
Docs: SPEC.md
|
|
72
|
+
`);
|
|
73
|
+
}
|
|
74
|
+
function printVersion() {
|
|
75
|
+
console.log(VERSION);
|
|
76
|
+
}
|
|
77
|
+
function parseArgs(argv) {
|
|
78
|
+
const args = argv.slice(2);
|
|
79
|
+
if (args.length === 0)
|
|
80
|
+
return { files: [], opts: {} };
|
|
81
|
+
// Handle global flags
|
|
82
|
+
if (args[0] === "--help" || args[0] === "-h" || args[0] === "help") {
|
|
83
|
+
return { command: "help", files: [], opts: {} };
|
|
84
|
+
}
|
|
85
|
+
if (args[0] === "--version" || args[0] === "-v" || args[0] === "version") {
|
|
86
|
+
return { command: "version", files: [], opts: {} };
|
|
87
|
+
}
|
|
88
|
+
const command = args[0];
|
|
89
|
+
const rest = args.slice(1);
|
|
90
|
+
const files = [];
|
|
91
|
+
const opts = {};
|
|
92
|
+
let i = 0;
|
|
93
|
+
while (i < rest.length) {
|
|
94
|
+
const a = rest[i];
|
|
95
|
+
if (a === "--json") {
|
|
96
|
+
opts.json = true;
|
|
97
|
+
i++;
|
|
98
|
+
}
|
|
99
|
+
else if (a === "--quiet" || a === "-q") {
|
|
100
|
+
opts.quiet = true;
|
|
101
|
+
i++;
|
|
102
|
+
}
|
|
103
|
+
else if (a === "--write" || a === "-w") {
|
|
104
|
+
opts.write = true;
|
|
105
|
+
i++;
|
|
106
|
+
}
|
|
107
|
+
else if (a === "--check" || a === "-c") {
|
|
108
|
+
opts.check = true;
|
|
109
|
+
i++;
|
|
110
|
+
}
|
|
111
|
+
else if (a === "--stdio") {
|
|
112
|
+
opts.stdio = true;
|
|
113
|
+
i++;
|
|
114
|
+
}
|
|
115
|
+
else if (a === "-o" || a === "--output") {
|
|
116
|
+
const next = rest[i + 1];
|
|
117
|
+
if (!next) {
|
|
118
|
+
console.error(`floe ${command}: missing value for ${a}`);
|
|
119
|
+
process.exit(2);
|
|
120
|
+
}
|
|
121
|
+
opts.output = next;
|
|
122
|
+
i += 2;
|
|
123
|
+
}
|
|
124
|
+
else if (a === "--help" || a === "-h") {
|
|
125
|
+
opts.help = true;
|
|
126
|
+
i++;
|
|
127
|
+
}
|
|
128
|
+
else if (a === "--version" || a === "-v") {
|
|
129
|
+
opts.version = true;
|
|
130
|
+
i++;
|
|
131
|
+
}
|
|
132
|
+
else if (a.startsWith("-")) {
|
|
133
|
+
console.error(`floe ${command}: unknown option ${a}`);
|
|
134
|
+
console.error(`Run 'floe ${command} --help' for usage.`);
|
|
135
|
+
process.exit(2);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
files.push(a);
|
|
139
|
+
i++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { command, files, opts };
|
|
143
|
+
}
|
|
144
|
+
async function main() {
|
|
145
|
+
const { command, files, opts } = parseArgs(process.argv);
|
|
146
|
+
if (!command) {
|
|
147
|
+
printHelp();
|
|
148
|
+
process.exit(2);
|
|
149
|
+
}
|
|
150
|
+
if (command === "help") {
|
|
151
|
+
printHelp();
|
|
152
|
+
process.exit(0);
|
|
153
|
+
}
|
|
154
|
+
if (command === "version") {
|
|
155
|
+
printVersion();
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
// Allow help per command
|
|
159
|
+
if (opts.help) {
|
|
160
|
+
printHelp();
|
|
161
|
+
process.exit(0);
|
|
162
|
+
}
|
|
163
|
+
if (opts.version) {
|
|
164
|
+
printVersion();
|
|
165
|
+
process.exit(0);
|
|
166
|
+
}
|
|
167
|
+
let exitCode = 0;
|
|
168
|
+
switch (command) {
|
|
169
|
+
case "check": {
|
|
170
|
+
exitCode = runCheck(files, { json: !!opts.json, quiet: !!opts.quiet });
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case "format": {
|
|
174
|
+
exitCode = runFormat(files, { write: !!opts.write, check: !!opts.check, json: !!opts.json });
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "render": {
|
|
178
|
+
exitCode = runRender(files, { output: opts.output, json: !!opts.json });
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
case "lsp":
|
|
182
|
+
case "lsp-server": {
|
|
183
|
+
// Start LSP server
|
|
184
|
+
// Dynamic import to avoid loading LSP code unless needed (keeps core Node/browser separation)
|
|
185
|
+
const { startLspServer } = await import("../lsp/server.js");
|
|
186
|
+
await startLspServer({ stdio: true });
|
|
187
|
+
// startLspServer runs indefinitely until shutdown
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
default: {
|
|
191
|
+
console.error(`floe: unknown command '${command}'`);
|
|
192
|
+
console.error("Run 'floe --help' for usage.");
|
|
193
|
+
process.exit(2);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
process.exit(exitCode);
|
|
197
|
+
}
|
|
198
|
+
// Ensure unhandled errors are reported with exit 1 (no crash with empty exit)
|
|
199
|
+
main().catch((e) => {
|
|
200
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
201
|
+
console.error(`floe: internal error: ${msg}`);
|
|
202
|
+
// Do not print stack for user-facing errors unless debug? Keep simple
|
|
203
|
+
if (process.env.FLOE_DEBUG)
|
|
204
|
+
console.error(e instanceof Error ? e.stack : "");
|
|
205
|
+
process.exit(1);
|
|
206
|
+
});
|
|
207
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/cli/render.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAmF3E"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { parseFloe } from "../index.js";
|
|
4
|
+
import { renderFloe } from "../pipeline.js";
|
|
5
|
+
export function runRender(files, opts = {}) {
|
|
6
|
+
if (files.length === 0) {
|
|
7
|
+
console.error("floe render: no input files");
|
|
8
|
+
console.error("Usage: floe render <file.floe> [-o <output.svg>]");
|
|
9
|
+
return 2;
|
|
10
|
+
}
|
|
11
|
+
if (files.length > 1 && opts.output) {
|
|
12
|
+
console.error("floe render: -o/--output can only be used with a single input file");
|
|
13
|
+
return 2;
|
|
14
|
+
}
|
|
15
|
+
let hadErrors = false;
|
|
16
|
+
for (const f of files) {
|
|
17
|
+
const resolved = path.resolve(f);
|
|
18
|
+
if (!fs.existsSync(resolved)) {
|
|
19
|
+
console.error(`floe render: file not found: ${f}`);
|
|
20
|
+
return 2;
|
|
21
|
+
}
|
|
22
|
+
let source;
|
|
23
|
+
try {
|
|
24
|
+
source = fs.readFileSync(resolved, "utf-8");
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
28
|
+
console.error(`Cannot read file '${f}': ${msg}`);
|
|
29
|
+
return 2;
|
|
30
|
+
}
|
|
31
|
+
// Parse to check diagnostics but still render best-effort (per spec: never crash)
|
|
32
|
+
let svg;
|
|
33
|
+
let hasParseErrors = false;
|
|
34
|
+
try {
|
|
35
|
+
const parseResult = parseFloe(source);
|
|
36
|
+
hasParseErrors = parseResult.diagnostics.some((d) => d.severity === "error");
|
|
37
|
+
if (hasParseErrors)
|
|
38
|
+
hadErrors = true;
|
|
39
|
+
// Render via pipeline (deterministic, never throws on malformed input)
|
|
40
|
+
const result = renderFloe(source);
|
|
41
|
+
svg = result.svg;
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
45
|
+
console.error(`floe render: failed to render '${f}': ${msg}`);
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
// Security: ensure svg is properly escaped (render already does) and not containing executable vectors
|
|
49
|
+
// We do not inject any untrusted content as raw; svg is derived via escaped paths.
|
|
50
|
+
if (opts.output) {
|
|
51
|
+
const outPath = path.resolve(opts.output);
|
|
52
|
+
try {
|
|
53
|
+
// Ensure directory exists
|
|
54
|
+
const dir = path.dirname(outPath);
|
|
55
|
+
if (!fs.existsSync(dir))
|
|
56
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
57
|
+
fs.writeFileSync(outPath, svg, "utf-8");
|
|
58
|
+
const rel = path.relative(process.cwd(), outPath);
|
|
59
|
+
if (!opts.json)
|
|
60
|
+
console.log(`rendered ${path.relative(process.cwd(), resolved)} -> ${rel}`);
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64
|
+
console.error(`Cannot write output '${opts.output}': ${msg}`);
|
|
65
|
+
return 2;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// stdout (scriptable)
|
|
70
|
+
// If json mode? Not needed but we support emitting svg via stdout only.
|
|
71
|
+
// Print svg to stdout; warnings to stderr
|
|
72
|
+
if (hasParseErrors && !opts.json) {
|
|
73
|
+
const rel = path.relative(process.cwd(), resolved);
|
|
74
|
+
console.error(`warning: ${rel} has parse errors, rendered best-effort SVG`);
|
|
75
|
+
}
|
|
76
|
+
process.stdout.write(svg);
|
|
77
|
+
if (!svg.endsWith("\n"))
|
|
78
|
+
process.stdout.write("\n");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// For CI: exit 1 if any file had parse errors? Or 0 still? Spec says appropriate exit codes and scriptable.
|
|
82
|
+
// We will exit 1 if any input had errors, to allow CI to fail on invalid diagrams, but still produce SVG.
|
|
83
|
+
// This is useful: `floe render` can be used in CI to validate rendering.
|
|
84
|
+
// If caller wants to ignore errors, they can check SVG existence anyway.
|
|
85
|
+
// We make decision: if any file had errors, exit 1, else 0. But produce SVG regardless.
|
|
86
|
+
// For scriptable use, they can do `floe render good.floe || echo failed`
|
|
87
|
+
// Document this behavior.
|
|
88
|
+
return hadErrors ? 1 : 0;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/cli/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Range } from "./range.js";
|
|
2
|
+
/**
|
|
3
|
+
* Diagnostic severity
|
|
4
|
+
*/
|
|
5
|
+
export type Severity = "error" | "warning" | "info";
|
|
6
|
+
/**
|
|
7
|
+
* Stable diagnostic codes
|
|
8
|
+
*
|
|
9
|
+
* E001 - invalid direction
|
|
10
|
+
* E002 - invalid identifier
|
|
11
|
+
* E003 - duplicate node declaration
|
|
12
|
+
* E004 - duplicate direction declaration
|
|
13
|
+
* E005 - malformed statement / unexpected token
|
|
14
|
+
* E006 - missing / incomplete statement
|
|
15
|
+
* E007 - invalid character
|
|
16
|
+
* E008 - invalid node type
|
|
17
|
+
* E009 - missing edge target
|
|
18
|
+
* E010 - empty label
|
|
19
|
+
* E011 - duplicate group declaration
|
|
20
|
+
* E012 - unclosed group / missing brace
|
|
21
|
+
* E013 - invalid metadata declaration
|
|
22
|
+
* E014 - invalid annotation or link (unknown target, empty text)
|
|
23
|
+
*/
|
|
24
|
+
export type DiagnosticCode = "E001" | "E002" | "E003" | "E004" | "E005" | "E006" | "E007" | "E008" | "E009" | "E010" | "E011" | "E012" | "E013" | "E014";
|
|
25
|
+
export interface Diagnostic {
|
|
26
|
+
severity: Severity;
|
|
27
|
+
code: DiagnosticCode;
|
|
28
|
+
message: string;
|
|
29
|
+
range: Range;
|
|
30
|
+
}
|
|
31
|
+
export declare function diag(severity: Severity, code: DiagnosticCode, message: string, range: Range): Diagnostic;
|
|
32
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|