@akanjs/cli 2.4.0-rc.9 → 2.4.1-rc.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/agent.command-h4afc69n.js +26 -0
- package/application.command-4ctkfdan.js +165 -0
- package/applicationBuildRunner-esa1kj7v.js +284 -0
- package/applicationReleasePackager-brvth6rs.js +245 -0
- package/capacitorApp-y0h6cgft.js +58 -0
- package/cloud.command-rpztn4fh.js +94 -0
- package/commandManifest.json +1 -0
- package/context.command-nqbtak4f.js +82 -0
- package/dependencyScanner-m4x5maek.js +9 -0
- package/guideline.command-ya0dh44f.js +356 -0
- package/incrementalBuilder.proc.js +89 -17394
- package/index-1xdrsbry.js +1447 -0
- package/index-45aj5ry0.js +990 -0
- package/index-5vvwc0cz.js +559 -0
- package/index-61keag0s.js +40 -0
- package/index-6pz1j0zj.js +62 -0
- package/index-73pr2cmy.js +534 -0
- package/index-76rn3g2c.js +76 -0
- package/index-85msc0wg.js +161 -0
- package/index-8pkbzj26.js +840 -0
- package/index-8rc0bm04.js +514 -0
- package/index-9sp6fsc5.js +1884 -0
- package/index-a6sbyy0b.js +2769 -0
- package/index-b0brjbp3.js +83 -0
- package/index-fgc8r6dj.js +33 -0
- package/index-h6ca6qg0.js +2777 -0
- package/index-hdqztm58.js +758 -0
- package/index-hwzpw9c1.js +202 -0
- package/index-pmm9e2jf.js +120 -0
- package/index-qaq13qk3.js +80 -0
- package/index-qhtr07v8.js +1072 -0
- package/index-r24hmh0q.js +4 -0
- package/index-ss469dec.js +11 -0
- package/index-swf4bmbg.js +25 -0
- package/index-w7fyqjrw.js +462 -0
- package/index-wnp7hwq7.js +193 -0
- package/index-wq8jwx8z.js +224 -0
- package/index-x53a5nya.js +301 -0
- package/index-xmc2w32q.js +4359 -0
- package/index-y3hdhy4p.js +229 -0
- package/index.js +54 -23340
- package/library.command-r15zdqvp.js +33 -0
- package/localRegistry.command-5tcahs3f.js +178 -0
- package/module.command-qrj3kmyz.js +54 -0
- package/package.command-r8sq5kzp.js +43 -0
- package/package.json +2 -2
- package/page.command-c6xdx0xm.js +24 -0
- package/primitive.command-pv9ssmtf.js +62 -0
- package/quality.command-es67wvdp.js +809 -0
- package/repair.command-677675vw.js +67 -0
- package/routeSourceValidator-wbhmbwpj.js +132 -0
- package/scalar.command-kabkd6wd.js +35 -0
- package/templates/app/page/_layout.tsx +19 -1
- package/templates/app/public/fonts/Pretendard-Black.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-Bold.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-ExtraBold.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-ExtraLight.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-Light.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-Medium.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-Regular.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-SemiBold.woff2 +0 -0
- package/templates/app/public/fonts/Pretendard-Thin.woff2 +0 -0
- package/templates/facetIndex/index.ts +1 -1
- package/typeChecker-kravn7ns.js +8 -0
- package/typecheck.proc.js +4 -194
- package/workflow.command-64r6cw0w.js +108 -0
- package/workspace.command-vrws0rgx.js +435 -0
- package/README.ko.md +0 -72
- package/README.md +0 -85
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
RepairRunner
|
|
4
|
+
} from "./index-85msc0wg.js";
|
|
5
|
+
import"./index-8rc0bm04.js";
|
|
6
|
+
import"./index-h6ca6qg0.js";
|
|
7
|
+
import {
|
|
8
|
+
Workspace,
|
|
9
|
+
command,
|
|
10
|
+
script
|
|
11
|
+
} from "./index-hdqztm58.js";
|
|
12
|
+
import"./index-a6sbyy0b.js";
|
|
13
|
+
import"./index-61keag0s.js";
|
|
14
|
+
import"./index-6pz1j0zj.js";
|
|
15
|
+
import"./index-r24hmh0q.js";
|
|
16
|
+
|
|
17
|
+
// pkgs/@akanjs/cli/repair/repair.script.ts
|
|
18
|
+
import { Logger } from "akanjs/common";
|
|
19
|
+
class RepairScript extends script("repair", [RepairRunner]) {
|
|
20
|
+
async repair(kind, {
|
|
21
|
+
workspace,
|
|
22
|
+
app = null,
|
|
23
|
+
module = null,
|
|
24
|
+
target = null,
|
|
25
|
+
format = "markdown"
|
|
26
|
+
}) {
|
|
27
|
+
Logger.rawLog(await this.repairRunner.repair(kind, {
|
|
28
|
+
workspace,
|
|
29
|
+
app,
|
|
30
|
+
module,
|
|
31
|
+
target,
|
|
32
|
+
format
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// pkgs/@akanjs/cli/repair/repair.command.ts
|
|
38
|
+
class RepairCommand extends command("repair", [RepairScript], ({ public: target }) => ({
|
|
39
|
+
repair: target({ desc: "Run a narrow Akan repair command and return a structured report" }).arg("kind", String, {
|
|
40
|
+
desc: "generated, format, imports, dictionary, or module-shape",
|
|
41
|
+
enum: ["generated", "format", "imports", "dictionary", "module-shape"]
|
|
42
|
+
}).with(Workspace).option("format", String, {
|
|
43
|
+
desc: "output format",
|
|
44
|
+
flag: "o",
|
|
45
|
+
default: "markdown",
|
|
46
|
+
enum: ["markdown", "json"]
|
|
47
|
+
}).option("app", String, {
|
|
48
|
+
desc: "target app or library for generated/dictionary/module-shape repair",
|
|
49
|
+
nullable: true
|
|
50
|
+
}).option("module", String, { desc: "target module for dictionary/module-shape repair", nullable: true }).option("target", String, {
|
|
51
|
+
flag: "t",
|
|
52
|
+
desc: "target app, library, or package for format/imports repair",
|
|
53
|
+
nullable: true
|
|
54
|
+
}).exec(async function(kind, workspace, format, app, module, targetName) {
|
|
55
|
+
await this.repairScript.repair(kind, {
|
|
56
|
+
workspace,
|
|
57
|
+
format,
|
|
58
|
+
app,
|
|
59
|
+
module,
|
|
60
|
+
target: targetName
|
|
61
|
+
});
|
|
62
|
+
})
|
|
63
|
+
})) {
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
RepairCommand
|
|
67
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import"./index-r24hmh0q.js";
|
|
3
|
+
|
|
4
|
+
// pkgs/@akanjs/devkit/routeSourceValidator.ts
|
|
5
|
+
import ts from "typescript";
|
|
6
|
+
|
|
7
|
+
class RouteSourceValidator {
|
|
8
|
+
static #pageExports = new Set([
|
|
9
|
+
"default",
|
|
10
|
+
"pageConfig",
|
|
11
|
+
"head",
|
|
12
|
+
"metadata",
|
|
13
|
+
"generateHead",
|
|
14
|
+
"generateMetadata",
|
|
15
|
+
"Loading"
|
|
16
|
+
]);
|
|
17
|
+
static #rootLayoutExports = new Set([
|
|
18
|
+
"default",
|
|
19
|
+
"pageConfig",
|
|
20
|
+
"head",
|
|
21
|
+
"metadata",
|
|
22
|
+
"generateHead",
|
|
23
|
+
"generateMetadata",
|
|
24
|
+
"fonts",
|
|
25
|
+
"manifest",
|
|
26
|
+
"theme",
|
|
27
|
+
"reconnect",
|
|
28
|
+
"layoutStyle",
|
|
29
|
+
"gaTrackingId",
|
|
30
|
+
"Loading",
|
|
31
|
+
"NotFound",
|
|
32
|
+
"Error"
|
|
33
|
+
]);
|
|
34
|
+
static #layoutExports = new Set([
|
|
35
|
+
"default",
|
|
36
|
+
"pageConfig",
|
|
37
|
+
"head",
|
|
38
|
+
"metadata",
|
|
39
|
+
"generateHead",
|
|
40
|
+
"generateMetadata",
|
|
41
|
+
"Loading",
|
|
42
|
+
"NotFound",
|
|
43
|
+
"Error"
|
|
44
|
+
]);
|
|
45
|
+
static validateRouteSourceExports(source, filePath, kind, options = {}) {
|
|
46
|
+
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
47
|
+
const allowed = kind === "page" ? RouteSourceValidator.#pageExports : options.rootLayout ? RouteSourceValidator.#rootLayoutExports : RouteSourceValidator.#layoutExports;
|
|
48
|
+
const exported = new Set;
|
|
49
|
+
const assertExport = (name) => {
|
|
50
|
+
if (!allowed.has(name)) {
|
|
51
|
+
throw new Error(`[route-convention] unsupported export "${name}" in ${filePath}`);
|
|
52
|
+
}
|
|
53
|
+
exported.add(name);
|
|
54
|
+
};
|
|
55
|
+
for (const statement of sourceFile.statements) {
|
|
56
|
+
if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement))
|
|
57
|
+
continue;
|
|
58
|
+
if (ts.isExportDeclaration(statement)) {
|
|
59
|
+
if (statement.isTypeOnly)
|
|
60
|
+
continue;
|
|
61
|
+
const clause = statement.exportClause;
|
|
62
|
+
if (!clause)
|
|
63
|
+
throw new Error(`[route-convention] export * is not allowed in route modules: ${filePath}`);
|
|
64
|
+
if (ts.isNamedExports(clause)) {
|
|
65
|
+
for (const element of clause.elements) {
|
|
66
|
+
if (element.isTypeOnly)
|
|
67
|
+
continue;
|
|
68
|
+
assertExport(element.name.text);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined;
|
|
74
|
+
const isExported = modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
|
|
75
|
+
if (!isExported)
|
|
76
|
+
continue;
|
|
77
|
+
const isDefault = modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) ?? false;
|
|
78
|
+
if (isDefault) {
|
|
79
|
+
assertExport("default");
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (ts.isVariableStatement(statement)) {
|
|
83
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
84
|
+
if (ts.isIdentifier(declaration.name))
|
|
85
|
+
assertExport(declaration.name.text);
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const name = statement.name;
|
|
90
|
+
if (name && ts.isIdentifier(name)) {
|
|
91
|
+
assertExport(name.text);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (exported.has("head") && exported.has("generateHead")) {
|
|
95
|
+
throw new Error(`[route-convention] head and generateHead cannot both be exported in ${filePath}`);
|
|
96
|
+
}
|
|
97
|
+
if (!options.rootLayout && (exported.has("head") || exported.has("generateHead")) && (exported.has("metadata") || exported.has("generateMetadata"))) {
|
|
98
|
+
throw new Error(`[route-convention] head/generateHead and metadata/generateMetadata cannot both be exported in ${filePath}`);
|
|
99
|
+
}
|
|
100
|
+
if (exported.has("metadata") && exported.has("generateMetadata")) {
|
|
101
|
+
throw new Error(`[route-convention] metadata and generateMetadata cannot both be exported in ${filePath}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
static validateOverridesSourceExports(source, filePath) {
|
|
105
|
+
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
106
|
+
const fail = (message) => {
|
|
107
|
+
throw new Error(`[route-convention] ${message}: ${filePath}`);
|
|
108
|
+
};
|
|
109
|
+
let defaultOverride = null;
|
|
110
|
+
for (const statement of sourceFile.statements) {
|
|
111
|
+
if (ts.isExpressionStatement(statement) && ts.isStringLiteral(statement.expression))
|
|
112
|
+
continue;
|
|
113
|
+
if (ts.isImportDeclaration(statement))
|
|
114
|
+
continue;
|
|
115
|
+
if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement))
|
|
116
|
+
continue;
|
|
117
|
+
if (ts.isExportAssignment(statement) && !statement.isExportEquals) {
|
|
118
|
+
defaultOverride = statement;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
fail(`_overrides.tsx may only contain imports and a single "export default override({ ... })"`);
|
|
122
|
+
}
|
|
123
|
+
if (!defaultOverride)
|
|
124
|
+
return fail(`_overrides.tsx must "export default override({ ... })"`);
|
|
125
|
+
const expression = defaultOverride.expression;
|
|
126
|
+
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "override")
|
|
127
|
+
fail(`_overrides.tsx default export must be a call to "override", e.g. "export default override({ Modal: BrandModal })"`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export {
|
|
131
|
+
RouteSourceValidator
|
|
132
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
ScalarScript
|
|
4
|
+
} from "./index-y3hdhy4p.js";
|
|
5
|
+
import"./index-ss469dec.js";
|
|
6
|
+
import"./index-qaq13qk3.js";
|
|
7
|
+
import {
|
|
8
|
+
renderPrimitiveReport
|
|
9
|
+
} from "./index-h6ca6qg0.js";
|
|
10
|
+
import"./index-5vvwc0cz.js";
|
|
11
|
+
import {
|
|
12
|
+
Sys,
|
|
13
|
+
command
|
|
14
|
+
} from "./index-hdqztm58.js";
|
|
15
|
+
import"./index-a6sbyy0b.js";
|
|
16
|
+
import"./index-61keag0s.js";
|
|
17
|
+
import"./index-6pz1j0zj.js";
|
|
18
|
+
import"./index-r24hmh0q.js";
|
|
19
|
+
|
|
20
|
+
// pkgs/@akanjs/cli/scalar/scalar.command.ts
|
|
21
|
+
import { Logger, lowerlize } from "akanjs/common";
|
|
22
|
+
class ScalarCommand extends command("scalar", [ScalarScript], ({ public: target }) => ({
|
|
23
|
+
createScalar: target({ desc: "Create a new scalar type (simple data model without DB)" }).arg("scalarName", String, { desc: "name of scalar" }).with(Sys).option("ai", Boolean, { default: false, desc: "use ai to create scalar" }).option("format", String, { flag: "o", desc: "output format", default: "markdown", enum: ["markdown", "json"] }).exec(async function(scalarName, sys, ai, format) {
|
|
24
|
+
const name = lowerlize(scalarName.replace(/ /g, ""));
|
|
25
|
+
const report = ai ? await this.scalarScript.createScalarWithAi(sys, name) : await this.scalarScript.createScalar(sys, name);
|
|
26
|
+
Logger.rawLog(renderPrimitiveReport(report, format));
|
|
27
|
+
}),
|
|
28
|
+
removeScalar: target({ desc: "Remove a scalar type from an app or library" }).arg("scalarName", String, { desc: "name of scalar" }).with(Sys).exec(async function(scalarName, sys) {
|
|
29
|
+
await this.scalarScript.removeScalar(sys, scalarName);
|
|
30
|
+
})
|
|
31
|
+
})) {
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
ScalarCommand
|
|
35
|
+
};
|
|
@@ -9,9 +9,27 @@ export default function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dic
|
|
|
9
9
|
filename: "_layout.tsx",
|
|
10
10
|
content: `
|
|
11
11
|
import "./styles.css";
|
|
12
|
-
import type { LayoutProps } from "akanjs/client";
|
|
12
|
+
import type { Font, LayoutProps } from "akanjs/client";
|
|
13
13
|
${isUsingShared ? "import { Auth } from '@shared/ui';" : ""}
|
|
14
14
|
|
|
15
|
+
export const fonts: Font[] = [
|
|
16
|
+
{
|
|
17
|
+
name: "pretendard",
|
|
18
|
+
default: true,
|
|
19
|
+
paths: [
|
|
20
|
+
{ src: "/fonts/Pretendard-Thin.woff2", weight: 100 },
|
|
21
|
+
{ src: "/fonts/Pretendard-ExtraLight.woff2", weight: 200 },
|
|
22
|
+
{ src: "/fonts/Pretendard-Light.woff2", weight: 300 },
|
|
23
|
+
{ src: "/fonts/Pretendard-Regular.woff2", weight: 400 },
|
|
24
|
+
{ src: "/fonts/Pretendard-Medium.woff2", weight: 500 },
|
|
25
|
+
{ src: "/fonts/Pretendard-SemiBold.woff2", weight: 600 },
|
|
26
|
+
{ src: "/fonts/Pretendard-Bold.woff2", weight: 700 },
|
|
27
|
+
{ src: "/fonts/Pretendard-ExtraBold.woff2", weight: 800 },
|
|
28
|
+
{ src: "/fonts/Pretendard-Black.woff2", weight: 900 },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
15
33
|
export const head = (
|
|
16
34
|
<>
|
|
17
35
|
<title>${dict.appName}</title>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/typecheck.proc.js
CHANGED
|
@@ -1,201 +1,11 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
2
|
+
import {
|
|
3
|
+
TypeChecker
|
|
4
|
+
} from "./index-wnp7hwq7.js";
|
|
5
|
+
import"./index-r24hmh0q.js";
|
|
3
6
|
|
|
4
7
|
// pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts
|
|
5
8
|
import { Logger } from "akanjs/common";
|
|
6
|
-
|
|
7
|
-
// pkgs/@akanjs/devkit/typeChecker.ts
|
|
8
|
-
import { readFileSync } from "fs";
|
|
9
|
-
import * as path from "path";
|
|
10
|
-
import chalk from "chalk";
|
|
11
|
-
import * as ts from "typescript";
|
|
12
|
-
|
|
13
|
-
class TypeChecker {
|
|
14
|
-
configPath;
|
|
15
|
-
configFile;
|
|
16
|
-
config;
|
|
17
|
-
constructor(executor) {
|
|
18
|
-
const configPath = this.#findConfigFile(executor.cwdPath);
|
|
19
|
-
if (!configPath)
|
|
20
|
-
throw new Error("No tsconfig.json found in the project");
|
|
21
|
-
this.configPath = configPath;
|
|
22
|
-
this.configFile = ts.readConfigFile(this.configPath, (fileName) => ts.sys.readFile(fileName));
|
|
23
|
-
const parsedConfig = ts.parseJsonConfigFileContent(this.configFile.config, ts.sys, path.dirname(this.configPath), undefined, this.configPath);
|
|
24
|
-
if (parsedConfig.errors.length > 0) {
|
|
25
|
-
const errorMessages = parsedConfig.errors.map((error) => ts.flattenDiagnosticMessageText(error.messageText, `
|
|
26
|
-
`)).join(`
|
|
27
|
-
`);
|
|
28
|
-
throw new Error(`Error parsing tsconfig.json:
|
|
29
|
-
${errorMessages}`);
|
|
30
|
-
}
|
|
31
|
-
this.config = parsedConfig;
|
|
32
|
-
}
|
|
33
|
-
#findConfigFile(searchPath) {
|
|
34
|
-
return ts.findConfigFile(searchPath, (fileName) => ts.sys.fileExists(fileName), "tsconfig.json");
|
|
35
|
-
}
|
|
36
|
-
check(filePath) {
|
|
37
|
-
const program = ts.createProgram([filePath], this.config.options);
|
|
38
|
-
const diagnostics = [
|
|
39
|
-
...program.getSemanticDiagnostics(),
|
|
40
|
-
...program.getSyntacticDiagnostics(),
|
|
41
|
-
...this.config.options.declaration ? program.getDeclarationDiagnostics() : []
|
|
42
|
-
];
|
|
43
|
-
const errors = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
|
|
44
|
-
const warnings = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Warning);
|
|
45
|
-
const fileDiagnostics = diagnostics.filter((diagnostic) => diagnostic.file?.fileName === filePath);
|
|
46
|
-
const fileErrors = fileDiagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
|
|
47
|
-
const fileWarnings = fileDiagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Warning);
|
|
48
|
-
return { diagnostics, errors, warnings, fileDiagnostics, fileErrors, fileWarnings };
|
|
49
|
-
}
|
|
50
|
-
formatDiagnostics(diagnostics) {
|
|
51
|
-
if (diagnostics.length === 0)
|
|
52
|
-
return chalk.bold("\u2705 No type errors found");
|
|
53
|
-
const output = [];
|
|
54
|
-
let errorCount = 0;
|
|
55
|
-
let warningCount = 0;
|
|
56
|
-
let suggestionCount = 0;
|
|
57
|
-
const diagnosticsByFile = new Map;
|
|
58
|
-
diagnostics.forEach((diagnostic) => {
|
|
59
|
-
if (diagnostic.category === ts.DiagnosticCategory.Error)
|
|
60
|
-
errorCount++;
|
|
61
|
-
else if (diagnostic.category === ts.DiagnosticCategory.Warning)
|
|
62
|
-
warningCount++;
|
|
63
|
-
else if (diagnostic.category === ts.DiagnosticCategory.Suggestion)
|
|
64
|
-
suggestionCount++;
|
|
65
|
-
if (diagnostic.file) {
|
|
66
|
-
const fileName = diagnostic.file.fileName;
|
|
67
|
-
if (!diagnosticsByFile.has(fileName))
|
|
68
|
-
diagnosticsByFile.set(fileName, []);
|
|
69
|
-
const fileDiagnostics = diagnosticsByFile.get(fileName);
|
|
70
|
-
if (fileDiagnostics)
|
|
71
|
-
fileDiagnostics.push(diagnostic);
|
|
72
|
-
} else {
|
|
73
|
-
if (!diagnosticsByFile.has(""))
|
|
74
|
-
diagnosticsByFile.set("", []);
|
|
75
|
-
const fileDiagnostics = diagnosticsByFile.get("");
|
|
76
|
-
if (fileDiagnostics)
|
|
77
|
-
fileDiagnostics.push(diagnostic);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
diagnosticsByFile.forEach((fileDiagnostics, fileName) => {
|
|
81
|
-
if (fileName)
|
|
82
|
-
output.push(`
|
|
83
|
-
${chalk.cyan(fileName)}`);
|
|
84
|
-
fileDiagnostics.forEach((diagnostic) => {
|
|
85
|
-
const categoryText = diagnostic.category === ts.DiagnosticCategory.Error ? "error" : diagnostic.category === ts.DiagnosticCategory.Warning ? "warning" : "suggestion";
|
|
86
|
-
const categoryColor = diagnostic.category === ts.DiagnosticCategory.Error ? chalk.red : diagnostic.category === ts.DiagnosticCategory.Warning ? chalk.yellow : chalk.blue;
|
|
87
|
-
const icon = diagnostic.category === ts.DiagnosticCategory.Error ? "\u274C" : diagnostic.category === ts.DiagnosticCategory.Warning ? "\u26A0\uFE0F" : "\uD83D\uDCA1";
|
|
88
|
-
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, `
|
|
89
|
-
`);
|
|
90
|
-
const tsCode = chalk.dim(`(TS${diagnostic.code})`);
|
|
91
|
-
if (diagnostic.file && diagnostic.start !== undefined) {
|
|
92
|
-
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
93
|
-
output.push(`
|
|
94
|
-
${icon} ${categoryColor(categoryText)}: ${message} ${tsCode}`);
|
|
95
|
-
output.push(` ${chalk.gray("at")} ${fileName}:${chalk.bold(`${line + 1}:${character + 1}`)}`);
|
|
96
|
-
const sourceLines = diagnostic.file.text.split(`
|
|
97
|
-
`);
|
|
98
|
-
if (line < sourceLines.length) {
|
|
99
|
-
const sourceLine = sourceLines[line];
|
|
100
|
-
const lineNumber = (line + 1).toString().padStart(5, " ");
|
|
101
|
-
output.push(`
|
|
102
|
-
${chalk.dim(`${lineNumber} |`)} ${sourceLine}`);
|
|
103
|
-
const underlinePrefix = " ".repeat(character);
|
|
104
|
-
const length = diagnostic.length ?? 1;
|
|
105
|
-
const underline = "~".repeat(Math.max(1, length));
|
|
106
|
-
output.push(`${chalk.dim(`${" ".repeat(lineNumber.length)} |`)} ${underlinePrefix}${categoryColor(underline)}`);
|
|
107
|
-
}
|
|
108
|
-
} else
|
|
109
|
-
output.push(`
|
|
110
|
-
${icon} ${categoryColor(categoryText)}: ${message} ${tsCode}`);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
const summary = [];
|
|
114
|
-
if (errorCount > 0)
|
|
115
|
-
summary.push(chalk.red(`${errorCount} error(s)`));
|
|
116
|
-
if (warningCount > 0)
|
|
117
|
-
summary.push(chalk.yellow(`${warningCount} warning(s)`));
|
|
118
|
-
if (suggestionCount > 0)
|
|
119
|
-
summary.push(chalk.blue(`${suggestionCount} suggestion(s)`));
|
|
120
|
-
return `
|
|
121
|
-
${summary.join(", ")} found${output.join(`
|
|
122
|
-
`)}`;
|
|
123
|
-
}
|
|
124
|
-
getDetailedDiagnostics(filePath) {
|
|
125
|
-
const { diagnostics } = this.check(filePath);
|
|
126
|
-
const sourceFile = ts.createSourceFile(filePath, readFileSync(filePath, "utf8"), ts.ScriptTarget.Latest, true);
|
|
127
|
-
const details = diagnostics.map((diagnostic) => {
|
|
128
|
-
if (diagnostic.file && diagnostic.start !== undefined) {
|
|
129
|
-
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
130
|
-
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, `
|
|
131
|
-
`);
|
|
132
|
-
const lines = sourceFile.text.split(`
|
|
133
|
-
`);
|
|
134
|
-
const codeSnippet = line < lines.length ? lines[line] : undefined;
|
|
135
|
-
return { line: line + 1, column: character + 1, message, code: diagnostic.code, codeSnippet };
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
line: 0,
|
|
139
|
-
column: 0,
|
|
140
|
-
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, `
|
|
141
|
-
`),
|
|
142
|
-
code: diagnostic.code
|
|
143
|
-
};
|
|
144
|
-
});
|
|
145
|
-
return { diagnostics, details };
|
|
146
|
-
}
|
|
147
|
-
hasNoTypeErrors(filePath) {
|
|
148
|
-
try {
|
|
149
|
-
const { diagnostics } = this.check(filePath);
|
|
150
|
-
return diagnostics.length === 0;
|
|
151
|
-
} catch (error) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
static checkProject(configPath) {
|
|
156
|
-
const parsedConfig = TypeChecker.parseConfig(configPath);
|
|
157
|
-
const host = ts.createIncrementalCompilerHost(parsedConfig.options);
|
|
158
|
-
const builderProgram = ts.createIncrementalProgram({
|
|
159
|
-
rootNames: parsedConfig.fileNames,
|
|
160
|
-
options: parsedConfig.options,
|
|
161
|
-
projectReferences: parsedConfig.projectReferences,
|
|
162
|
-
configFileParsingDiagnostics: parsedConfig.errors,
|
|
163
|
-
host
|
|
164
|
-
});
|
|
165
|
-
const program = builderProgram.getProgram();
|
|
166
|
-
const diagnostics = [...ts.getPreEmitDiagnostics(program), ...builderProgram.emit().diagnostics];
|
|
167
|
-
const errors = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
|
|
168
|
-
const warnings = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Warning);
|
|
169
|
-
return {
|
|
170
|
-
configPath,
|
|
171
|
-
diagnostics,
|
|
172
|
-
errors,
|
|
173
|
-
warnings,
|
|
174
|
-
message: TypeChecker.formatDiagnosticMessages(diagnostics)
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
static parseConfig(configPath) {
|
|
178
|
-
const configFile = ts.readConfigFile(configPath, (fileName) => ts.sys.readFile(fileName));
|
|
179
|
-
const configDiagnostics = configFile.error ? [configFile.error] : [];
|
|
180
|
-
if (!configFile.config) {
|
|
181
|
-
const message = TypeChecker.formatDiagnosticMessages(configDiagnostics);
|
|
182
|
-
throw new Error(message || `Error reading tsconfig.json: ${configPath}`);
|
|
183
|
-
}
|
|
184
|
-
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath), undefined, configPath);
|
|
185
|
-
if (parsedConfig.errors.length > 0)
|
|
186
|
-
throw new Error(TypeChecker.formatDiagnosticMessages(parsedConfig.errors));
|
|
187
|
-
return parsedConfig;
|
|
188
|
-
}
|
|
189
|
-
static formatDiagnosticMessages(diagnostics) {
|
|
190
|
-
return ts.formatDiagnosticsWithColorAndContext(diagnostics, {
|
|
191
|
-
getCanonicalFileName: (fileName) => fileName,
|
|
192
|
-
getCurrentDirectory: () => process.cwd(),
|
|
193
|
-
getNewLine: () => ts.sys.newLine
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts
|
|
199
9
|
try {
|
|
200
10
|
const filePath = process.env.AKAN_TYPECHECK_FILE;
|
|
201
11
|
if (filePath) {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
WorkflowRunner
|
|
4
|
+
} from "./index-45aj5ry0.js";
|
|
5
|
+
import {
|
|
6
|
+
ScalarScript
|
|
7
|
+
} from "./index-y3hdhy4p.js";
|
|
8
|
+
import {
|
|
9
|
+
PrimitiveScript
|
|
10
|
+
} from "./index-73pr2cmy.js";
|
|
11
|
+
import"./index-8rc0bm04.js";
|
|
12
|
+
import {
|
|
13
|
+
ModuleScript
|
|
14
|
+
} from "./index-8pkbzj26.js";
|
|
15
|
+
import"./index-swf4bmbg.js";
|
|
16
|
+
import"./index-ss469dec.js";
|
|
17
|
+
import"./index-qaq13qk3.js";
|
|
18
|
+
import {
|
|
19
|
+
createWorkflowStepRegistry
|
|
20
|
+
} from "./index-h6ca6qg0.js";
|
|
21
|
+
import"./index-5vvwc0cz.js";
|
|
22
|
+
import {
|
|
23
|
+
Workspace,
|
|
24
|
+
command,
|
|
25
|
+
script
|
|
26
|
+
} from "./index-hdqztm58.js";
|
|
27
|
+
import"./index-a6sbyy0b.js";
|
|
28
|
+
import"./index-61keag0s.js";
|
|
29
|
+
import"./index-6pz1j0zj.js";
|
|
30
|
+
import"./index-r24hmh0q.js";
|
|
31
|
+
|
|
32
|
+
// pkgs/@akanjs/cli/workflow/workflow.script.ts
|
|
33
|
+
import { Logger } from "akanjs/common";
|
|
34
|
+
class WorkflowScript extends script("workflow", [WorkflowRunner, ModuleScript, ScalarScript, PrimitiveScript]) {
|
|
35
|
+
async workflow(action, workflow, inputs, {
|
|
36
|
+
format = "markdown",
|
|
37
|
+
out = null,
|
|
38
|
+
dryRun = false,
|
|
39
|
+
workspace
|
|
40
|
+
} = {}) {
|
|
41
|
+
if (action === "list") {
|
|
42
|
+
Logger.rawLog(this.workflowRunner.list({ format }));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!workflow)
|
|
46
|
+
throw new Error(`Workflow name is required for "${action}".`);
|
|
47
|
+
if (action === "explain") {
|
|
48
|
+
Logger.rawLog(this.workflowRunner.explain(workflow, { format }));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (action === "plan") {
|
|
52
|
+
Logger.rawLog(await this.workflowRunner.plan(workflow, inputs, { format, out }));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (action === "apply") {
|
|
56
|
+
if (!workspace)
|
|
57
|
+
throw new Error("Workspace is required for workflow apply.");
|
|
58
|
+
Logger.rawLog(await this.workflowRunner.apply(workflow, {
|
|
59
|
+
dryRun,
|
|
60
|
+
format,
|
|
61
|
+
workspace,
|
|
62
|
+
registry: createWorkflowStepRegistry({
|
|
63
|
+
workspace,
|
|
64
|
+
createModule: (sys, module) => this.moduleScript.createModuleTemplate(sys, module),
|
|
65
|
+
createScalar: (sys, scalar) => this.scalarScript.createScalar(sys, scalar),
|
|
66
|
+
createUi: (input) => this.primitiveScript.createUi(workspace, input),
|
|
67
|
+
addField: (input) => this.primitiveScript.addField(workspace, input),
|
|
68
|
+
addEnumField: (input) => this.primitiveScript.addEnumField(workspace, input),
|
|
69
|
+
addMutation: (input) => this.primitiveScript.addMutation(workspace, input),
|
|
70
|
+
addSlice: (input) => this.primitiveScript.addSlice(workspace, input)
|
|
71
|
+
})
|
|
72
|
+
}));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (action === "validate") {
|
|
76
|
+
if (!workspace)
|
|
77
|
+
throw new Error("Workspace is required for workflow validate.");
|
|
78
|
+
Logger.rawLog(await this.workflowRunner.validate(workflow, { format, workspace }));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (action === "report") {
|
|
82
|
+
if (!workspace)
|
|
83
|
+
throw new Error("Workspace is required for workflow report.");
|
|
84
|
+
Logger.rawLog(await this.workflowRunner.report(workflow, { format, workspace }));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`Unknown workflow action: ${action}. Use list, explain, plan, apply, validate, or report.`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// pkgs/@akanjs/cli/workflow/workflow.command.ts
|
|
92
|
+
class WorkflowCommand extends command("workflow", [WorkflowScript], ({ public: target }) => ({
|
|
93
|
+
workflow: target({ desc: "List, explain, plan, apply, validate, or report Akan workflows" }).arg("action", String, {
|
|
94
|
+
desc: "list, explain, plan, apply, validate, or report",
|
|
95
|
+
enum: ["list", "explain", "plan", "apply", "validate", "report"]
|
|
96
|
+
}).arg("workflow", String, { desc: "workflow name, plan path, or run id", nullable: true }).with(Workspace).option("format", String, {
|
|
97
|
+
desc: "output format",
|
|
98
|
+
flag: "o",
|
|
99
|
+
default: "markdown",
|
|
100
|
+
enum: ["markdown", "json"]
|
|
101
|
+
}).option("out", String, { flag: "w", desc: "write workflow plan JSON to this path", nullable: true }).option("dryRun", Boolean, { flag: "r", desc: "show predicted apply report without writing files", default: false }).option("app", String, { desc: "target app or library name", nullable: true }).option("module", String, { desc: "target module name", nullable: true }).option("field", String, { desc: "field name", nullable: true }).option("type", String, { desc: "field type or scalar name", nullable: true }).option("values", String, { flag: "l", desc: "comma-separated values", nullable: true }).option("default", String, { desc: "default value", nullable: true }).option("scalar", String, { flag: "c", desc: "scalar name", nullable: true }).option("surface", String, { flag: "u", desc: "UI surface name", nullable: true }).option("mutation", String, { flag: "n", desc: "mutation name", nullable: true }).option("slice", String, { flag: "i", desc: "slice name", nullable: true }).exec(async function(action, workflow, workspace, format, out, dryRun, app, module, field, typeName, values, defaultValue, scalar, surface, mutation, slice) {
|
|
102
|
+
await this.workflowScript.workflow(action, workflow, { app, module, field, type: typeName, values, default: defaultValue, scalar, surface, mutation, slice }, { format, out, dryRun, workspace });
|
|
103
|
+
})
|
|
104
|
+
})) {
|
|
105
|
+
}
|
|
106
|
+
export {
|
|
107
|
+
WorkflowCommand
|
|
108
|
+
};
|