@akanjs/devkit 3.0.0-beta.19 → 3.0.0-beta.20
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/abstractDoc.test.ts +6 -15
- package/abstractDoc.ts +1 -4
- package/agentsIndex.test.ts +4 -7
- package/agentsIndex.ts +6 -22
- package/akanApp/BackendImportGraph.test.ts +8 -22
- package/akanApp/BackendImportGraph.ts +1 -20
- package/akanApp/akanApp.host.test.ts +1 -3
- package/akanApp/akanApp.host.ts +64 -250
- package/akanApp/devHostPolicy.test.ts +10 -34
- package/akanApp/devHostPolicy.ts +12 -98
- package/akanConfig/akanConfig.test.ts +30 -39
- package/akanConfig/akanConfig.ts +40 -136
- package/akanContext.ts +106 -159
- package/akanMcpContract.ts +28 -73
- package/appSelectionMemory.ts +1 -4
- package/applicationBuildReporter.ts +37 -5
- package/applicationBuildRunner.ts +25 -59
- package/applicationReleasePackager.ts +24 -44
- package/applicationTestPreload.ts +3 -12
- package/artifact/implicitRootLayout.test.ts +3 -19
- package/artifact/implicitRootLayout.ts +34 -91
- package/artifact/routeSeedIndex.ts +11 -44
- package/biomeBase.ts +2 -5
- package/capacitorApp.test.ts +4 -14
- package/capacitorApp.ts +86 -235
- package/cloud/cloudApi.test.ts +202 -0
- package/cloud/cloudApi.ts +33 -57
- package/cloud/configLock.test.ts +64 -0
- package/cloud/configLock.ts +96 -0
- package/cloud/constants.ts +3 -2
- package/cloud/globalConfig.ts +64 -31
- package/codeAgent/agent/AkanCodeServices.ts +15 -57
- package/codeAgent/agent/AkanContextFiles.ts +5 -28
- package/codeAgent/agent/CodeAgent.ts +33 -108
- package/codeAgent/agent/CodeAgentAsks.ts +7 -30
- package/codeAgent/agent/CodeAgentEventMapper.ts +9 -52
- package/codeAgent/agent/CodeAgentGate.ts +8 -34
- package/codeAgent/agent/CodeAgentProxy.ts +4 -13
- package/codeAgent/agent/CodeAgentRpcHost.ts +3 -16
- package/codeAgent/agent/CodeAgentRpcListener.ts +2 -10
- package/codeAgent/agent/CodeAgentStreamPrinter.ts +4 -15
- package/codeAgent/agent/CodeAgentSuspended.ts +1 -8
- package/codeAgent/agent/CodeAgentUi.ts +2 -7
- package/codeAgent/agent/CodeMailbox.ts +7 -34
- package/codeAgent/agent/CodeSessionFork.ts +4 -19
- package/codeAgent/agent/CodeSessionIndex.ts +5 -31
- package/codeAgent/agent/SubagentPool.ts +48 -58
- package/codeAgent/agent/akanCodeModel.ts +5 -39
- package/codeAgent/agent/akanCodePaths.ts +4 -24
- package/codeAgent/agent/akanContextFiles.test.ts +0 -2
- package/codeAgent/agent/akanSystemPrompt.ts +1 -9
- package/codeAgent/agent/codeAgent.test.ts +178 -0
- package/codeAgent/agent/codeAgentContract.test.ts +5 -28
- package/codeAgent/agent/codeMailbox.test.ts +0 -4
- package/codeAgent/agent/codeSessionFork.test.ts +0 -2
- package/codeAgent/agent/codeSessionIndex.test.ts +9 -4
- package/codeAgent/agent/consoleToStderr.ts +2 -12
- package/codeAgent/agent/jsonLines.ts +29 -0
- package/codeAgent/agent/stringArg.ts +5 -0
- package/codeAgent/feedback/DevLogFeedback.ts +3 -18
- package/codeAgent/feedback/PreviewChrome.ts +5 -29
- package/codeAgent/feedback/PreviewFeedback.ts +2 -9
- package/codeAgent/feedback/PreviewView.ts +3 -15
- package/codeAgent/feedback/TurnFeedback.ts +2 -17
- package/codeAgent/feedback/VerifyFeedback.ts +1 -7
- package/codeAgent/feedback/previewChrome.test.ts +1 -1
- package/codeAgent/index.ts +2 -10
- package/codeAgent/skills/akan-code/SKILL.md +12 -4
- package/codeAgent/tools/AkanCli.ts +4 -16
- package/codeAgent/tools/AkanCodePlugins.ts +21 -43
- package/codeAgent/tools/AkanEditScope.ts +2 -12
- package/codeAgent/tools/AkanEnvKeys.ts +3 -11
- package/codeAgent/tools/AkanToolPack.ts +6 -28
- package/codeAgent/tools/AkanVerifier.ts +1 -8
- package/codeAgent/tools/AskToolPack.ts +3 -15
- package/codeAgent/tools/MailToolPack.ts +0 -9
- package/codeAgent/tools/McpClient.ts +3 -24
- package/codeAgent/tools/McpOAuth.ts +6 -41
- package/codeAgent/tools/McpOAuthLoopback.ts +2 -15
- package/codeAgent/tools/McpServerConfig.ts +7 -26
- package/codeAgent/tools/McpSignIn.ts +46 -49
- package/codeAgent/tools/McpTokenStore.ts +6 -17
- package/codeAgent/tools/McpToolPack.ts +107 -35
- package/codeAgent/tools/SessionToolPack.ts +1 -11
- package/codeAgent/tools/WebToolPack.ts +1 -7
- package/codeAgent/tools/akanCodePlugins.test.ts +231 -63
- package/codeAgent/tools/askToolPack.test.ts +0 -3
- package/codeAgent/tools/mcpOAuth.test.ts +315 -27
- package/codeAgent/tools/mcpServerConfig.test.ts +21 -14
- package/codegenLock.test.ts +4 -13
- package/codegenLock.ts +3 -17
- package/commandDecorators/argMeta.ts +1 -5
- package/commandDecorators/camelToKebabCase.ts +1 -0
- package/commandDecorators/command.ts +44 -102
- package/commandDecorators/commandBuilder.ts +30 -61
- package/commandDecorators/commandDecorators.test.ts +1 -9
- package/commandDecorators/dependencyBuilder.ts +10 -1
- package/commandDecorators/helpFormatter.ts +66 -144
- package/commandDecorators/index.ts +0 -2
- package/commandDecorators/targetMeta.ts +9 -7
- package/createTunnel.ts +7 -14
- package/dependencyScanner.test.ts +4 -16
- package/dependencyScanner.ts +27 -78
- package/devkitUtils.test.ts +47 -19
- package/executors.test.ts +114 -60
- package/executors.ts +165 -484
- package/fileEditor.ts +9 -37
- package/{getDirname.test.ts → fileSys.test.ts} +1 -1
- package/fileSys.ts +6 -8
- package/formSetterScanner.ts +3 -16
- package/frontendBuild/allRoutesBuilder.ts +7 -21
- package/frontendBuild/autoImportSync.test.ts +14 -38
- package/frontendBuild/autoImportSync.ts +15 -67
- package/frontendBuild/buildRouteClient.test.ts +10 -36
- package/frontendBuild/bundleDefine.ts +12 -0
- package/frontendBuild/clientBuildTypes.ts +5 -36
- package/frontendBuild/clientEntriesBundler.ts +9 -40
- package/frontendBuild/clientEntryDiscovery.ts +6 -41
- package/frontendBuild/csrArtifactBuilder.ts +6 -25
- package/frontendBuild/cssCandidateCache.test.ts +0 -6
- package/frontendBuild/cssCandidateCache.ts +6 -41
- package/frontendBuild/cssCompiler.ts +29 -78
- package/frontendBuild/cssImportResolver.ts +5 -18
- package/frontendBuild/devChangePlanner.ts +7 -10
- package/frontendBuild/devGeneratedIndexSync.test.ts +12 -27
- package/frontendBuild/devGeneratedIndexSync.ts +1 -4
- package/frontendBuild/fontOptimizer.test.ts +5 -13
- package/frontendBuild/fontOptimizer.ts +15 -72
- package/frontendBuild/fontPruner.test.ts +5 -10
- package/frontendBuild/fontPruner.ts +5 -20
- package/frontendBuild/frontendBuild.test.ts +27 -52
- package/frontendBuild/hmrChangeClassifier.ts +2 -2
- package/frontendBuild/hmrWatcher.test.ts +7 -31
- package/frontendBuild/hmrWatcher.ts +14 -71
- package/frontendBuild/pagesBundleBuilder.ts +4 -29
- package/frontendBuild/precompressArtifacts.ts +5 -18
- package/frontendBuild/routeClientBuilder.ts +7 -47
- package/frontendBuild/routesManifestArtifactSerializer.ts +5 -36
- package/frontendBuild/sourceMtimeIndex.test.ts +37 -94
- package/frontendBuild/sourceMtimeIndex.ts +19 -130
- package/frontendBuild/ssrBaseArtifactBuilder.ts +2 -8
- package/frontendBuild/styleContract.ts +1 -8
- package/frontendBuild/themeValidator.ts +4 -26
- package/frontendBuild/watchRootResolver.test.ts +23 -42
- package/frontendBuild/watchRootResolver.ts +5 -27
- package/getRelatedCnsts.ts +12 -92
- package/incrementalBuilder/buildBatch.proc.ts +22 -57
- package/incrementalBuilder/buildBatchProtocol.ts +8 -36
- package/incrementalBuilder/buildBatchRunner.test.ts +34 -0
- package/incrementalBuilder/buildBatchRunner.ts +10 -31
- package/incrementalBuilder/builderChannel.test.ts +24 -49
- package/incrementalBuilder/builderChannel.ts +6 -37
- package/incrementalBuilder/builderRequestRouter.test.ts +0 -8
- package/incrementalBuilder/builderRequestRouter.ts +5 -24
- package/incrementalBuilder/devWatchBatch.test.ts +14 -18
- package/incrementalBuilder/incrementalBuilder.host.test.ts +18 -55
- package/incrementalBuilder/incrementalBuilder.host.ts +18 -76
- package/incrementalBuilder/incrementalBuilder.proc.test.ts +81 -0
- package/incrementalBuilder/incrementalBuilder.proc.ts +48 -161
- package/index.ts +3 -15
- package/integration/devResourceProbe.ts +50 -56
- package/integration/devStability.integration.test.ts +47 -194
- package/integration/devStabilityHarness.test.ts +9 -29
- package/integration/devStabilityHarness.ts +65 -330
- package/integration/ssrMemoryProbe.ts +41 -167
- package/libSource.test.ts +4 -15
- package/libSource.ts +19 -31
- package/lint/gritRules.test.ts +6 -23
- package/linter.test.ts +1 -2
- package/linter.ts +22 -115
- package/mobile/mobileTarget.ts +14 -13
- package/package.json +2 -2
- package/packageExports.test.ts +3 -18
- package/packageExportsMap.ts +3 -19
- package/piDependencyPins.test.ts +3 -14
- package/platformTest/IdleWatchedProcess.test.ts +5 -13
- package/platformTest/IdleWatchedProcess.ts +1 -5
- package/platformTest/LinuxDockerTarget.ts +20 -35
- package/platformTest/PlatformTestRun.test.ts +5 -9
- package/platformTest/PlatformTestTarget.ts +24 -2
- package/platformTest/TestSnapshot.test.ts +6 -14
- package/platformTest/TestSnapshot.ts +1 -5
- package/platformTest/WindowsSshTarget.ts +6 -22
- package/prompter.ts +3 -6
- package/qualityScanner.test.ts +6 -24
- package/qualityScanner.ts +196 -284
- package/recipeScanner.test.ts +7 -12
- package/recipeScanner.ts +9 -38
- package/repoIdentity.ts +2 -9
- package/routeSourceValidator.ts +7 -30
- package/scanInfo.ts +82 -214
- package/selectModel.ts +1 -2
- package/semver.ts +3 -5
- package/slicePlanner.test.ts +6 -24
- package/slicePlanner.ts +11 -32
- package/spinner.test.ts +3 -8
- package/spinner.ts +4 -16
- package/sshTunnel.ts +1 -6
- package/ssrScanner.test.ts +1 -6
- package/ssrScanner.ts +103 -113
- package/subspace.test.ts +6 -25
- package/subspace.ts +31 -109
- package/subspaceConfig.ts +3 -11
- package/testHelpers.ts +49 -34
- package/transforms/asyncDefaultExportDetector.ts +3 -11
- package/transforms/barrelAnalyzer.ts +43 -135
- package/transforms/barrelImportsPlugin.ts +38 -175
- package/transforms/externalizeFrameworkPlugin.test.ts +39 -118
- package/transforms/externalizeFrameworkPlugin.ts +13 -87
- package/transforms/moduleSyntax.ts +32 -0
- package/transforms/rscUseClientTransform.ts +35 -20
- package/transforms/transforms.test.ts +153 -44
- package/transforms/tsconfigPackageResolver.test.ts +6 -24
- package/transforms/useClientBundlePlugin.ts +2 -22
- package/typeChecker.ts +7 -63
- package/uploadRelease.ts +10 -25
- package/workflow/artifacts.ts +18 -0
- package/workflow/executor.test.ts +1 -12
- package/workflow/executor.ts +85 -146
- package/workflow/index.ts +0 -1
- package/workflow/moduleIndex.test.ts +4 -15
- package/workflow/moduleIndex.ts +9 -49
- package/workflow/plan.ts +18 -25
- package/workflow/render.ts +80 -96
- package/workflow/source.ts +33 -56
- package/workflow/sourceAst.ts +50 -0
- package/workspaceLayout.ts +4 -19
- package/commandDecorators/commandMeta.ts +0 -7
- package/commandDecorators/types.ts +0 -10
- package/getDirname.ts +0 -4
- package/local/optimize-resource/ipcprobe/child.ts +0 -1
- package/local/optimize-resource/ipcprobe/parent.ts +0 -11
- package/workflow/primitive.ts +0 -59
package/executors.test.ts
CHANGED
|
@@ -1,25 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { lstat, mkdir,
|
|
3
|
-
import os from "node:os";
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { lstat, mkdir, readFile, readlink, rm, stat, writeFile } from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { AkanAppConfig } from "./akanConfig";
|
|
6
5
|
import { AppExecutor, CommandExecutionError, Executor, PkgExecutor, WorkspaceExecutor } from "./executors";
|
|
7
6
|
import { AppInfo } from "./scanInfo";
|
|
7
|
+
import { isolateEnv, tempDirs, writeJson, writeText } from "./testHelpers";
|
|
8
8
|
import type { PackageJson } from "./types";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const makeTempRoot = async () => {
|
|
14
|
-
const root = await mkdtemp(path.join(os.tmpdir(), "akan-devkit-"));
|
|
15
|
-
tempRoots.push(root);
|
|
16
|
-
return root;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const writeJson = async (filePath: string, value: object) => {
|
|
20
|
-
await mkdir(path.dirname(filePath), { recursive: true });
|
|
21
|
-
await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
22
|
-
};
|
|
10
|
+
isolateEnv();
|
|
11
|
+
const makeTempRoot = tempDirs("akan-devkit-");
|
|
23
12
|
|
|
24
13
|
const PAGE_SOURCE = "export default function Page() {\n return null;\n}\n";
|
|
25
14
|
|
|
@@ -39,49 +28,34 @@ const rootPackageJson = (extra: Partial<PackageJson> = {}): PackageJson => ({
|
|
|
39
28
|
...extra,
|
|
40
29
|
});
|
|
41
30
|
|
|
42
|
-
beforeEach(() => {
|
|
43
|
-
process.env = { ...originalEnv };
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
afterEach(async () => {
|
|
47
|
-
process.env = { ...originalEnv };
|
|
48
|
-
await Promise.all(tempRoots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
|
|
49
|
-
});
|
|
50
|
-
|
|
51
31
|
describe("Executor filesystem helpers", () => {
|
|
52
32
|
test("reports command failures with command context and captured output", async () => {
|
|
53
33
|
const root = await makeTempRoot();
|
|
54
34
|
const exec = new Executor("fixture", root);
|
|
55
35
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
} catch (caught) {
|
|
60
|
-
error = caught;
|
|
61
|
-
}
|
|
62
|
-
|
|
36
|
+
const error = await exec
|
|
37
|
+
.spawn(process.execPath, ["--eval", "console.error('spawn failed'); process.exit(7)"])
|
|
38
|
+
.catch((caught: unknown) => caught);
|
|
63
39
|
expect(error).toBeInstanceOf(CommandExecutionError);
|
|
64
|
-
|
|
65
|
-
expect(
|
|
66
|
-
expect(
|
|
67
|
-
expect(
|
|
40
|
+
const { message } = error as CommandExecutionError;
|
|
41
|
+
expect(message).toContain(`Command failed: ${process.execPath}`);
|
|
42
|
+
expect(message).toContain(`cwd: ${root}`);
|
|
43
|
+
expect(message).toContain("exit code: 7");
|
|
44
|
+
expect(message).toContain("spawn failed");
|
|
68
45
|
});
|
|
69
46
|
|
|
70
47
|
test("reports inherited stdio command failures with a fallback message", async () => {
|
|
71
48
|
const root = await makeTempRoot();
|
|
72
49
|
const exec = new Executor("fixture", root);
|
|
73
50
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
} catch (caught) {
|
|
78
|
-
error = caught;
|
|
79
|
-
}
|
|
80
|
-
|
|
51
|
+
const error = await exec
|
|
52
|
+
.spawn(process.execPath, ["--eval", "process.exit(3)"], { stdio: "inherit" })
|
|
53
|
+
.catch((caught: unknown) => caught);
|
|
81
54
|
expect(error).toBeInstanceOf(CommandExecutionError);
|
|
82
|
-
|
|
83
|
-
expect(
|
|
84
|
-
expect(
|
|
55
|
+
const { message } = error as CommandExecutionError;
|
|
56
|
+
expect(message).toContain(`Command failed: ${process.execPath}`);
|
|
57
|
+
expect(message).toContain(`cwd: ${root}`);
|
|
58
|
+
expect(message).toContain("exit code: 3");
|
|
85
59
|
});
|
|
86
60
|
|
|
87
61
|
test("resolves paths and reads/writes files relative to cwd", async () => {
|
|
@@ -105,6 +79,31 @@ describe("Executor filesystem helpers", () => {
|
|
|
105
79
|
expect(entries.dirs).toContain("nested");
|
|
106
80
|
});
|
|
107
81
|
|
|
82
|
+
test("a refreshed tsconfig re-reads the config it extends", async () => {
|
|
83
|
+
const root = await makeTempRoot();
|
|
84
|
+
const appDir = path.join(root, "apps/demo");
|
|
85
|
+
await writeJson(path.join(root, "tsconfig.json"), {
|
|
86
|
+
compilerOptions: { target: "es2022", paths: { "@libs/*": ["libs/*"] } },
|
|
87
|
+
});
|
|
88
|
+
await writeJson(path.join(appDir, "tsconfig.json"), {
|
|
89
|
+
extends: "../../tsconfig.json",
|
|
90
|
+
compilerOptions: { target: "esnext" },
|
|
91
|
+
references: [{ path: "../shared" }],
|
|
92
|
+
});
|
|
93
|
+
const exec = new Executor("fixture", appDir);
|
|
94
|
+
expect(await exec.getTsConfig()).toEqual({
|
|
95
|
+
extends: "../../tsconfig.json",
|
|
96
|
+
compilerOptions: { target: "esnext", paths: { "@libs/*": ["libs/*"] } },
|
|
97
|
+
references: [{ path: "../shared" }],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await writeJson(path.join(root, "tsconfig.json"), { compilerOptions: { target: "es2020" } });
|
|
101
|
+
await writeJson(path.join(appDir, "tsconfig.json"), { extends: "../../tsconfig.json", compilerOptions: {} });
|
|
102
|
+
const refreshed = { extends: "../../tsconfig.json", compilerOptions: { target: "es2020" } };
|
|
103
|
+
expect(await exec.getTsConfig("tsconfig.json", { refresh: true })).toEqual(refreshed);
|
|
104
|
+
expect(await new Executor("fixture", appDir).getTsConfig()).toEqual(refreshed);
|
|
105
|
+
});
|
|
106
|
+
|
|
108
107
|
test("applies CLI template files with dictionary replacement and overwrite control", async () => {
|
|
109
108
|
const root = await makeTempRoot();
|
|
110
109
|
const exec = new Executor("fixture", root);
|
|
@@ -128,9 +127,7 @@ describe("Executor filesystem helpers", () => {
|
|
|
128
127
|
});
|
|
129
128
|
|
|
130
129
|
test("hands every scaffolded TypeScript file to the formatter, and nothing else", async () => {
|
|
131
|
-
// A template
|
|
132
|
-
// named Task and wrong for Zoo — and unsorted imports fail `biome check`. So the scaffold is formatted
|
|
133
|
-
// on the way out, or it is red for most model names whatever the template says.
|
|
130
|
+
// A template cannot sort imports that depend on the model name, and unsorted imports fail `biome check`.
|
|
134
131
|
const root = await makeTempRoot();
|
|
135
132
|
const exec = new Executor("fixture", root);
|
|
136
133
|
const formatted: string[] = [];
|
|
@@ -152,8 +149,7 @@ describe("Executor filesystem helpers", () => {
|
|
|
152
149
|
});
|
|
153
150
|
|
|
154
151
|
test("a formatter that cannot run does not fail the scaffold", async () => {
|
|
155
|
-
//
|
|
156
|
-
// no config above the target. An unformatted file is a lint fix; a failed scaffold is not.
|
|
152
|
+
// create-akan-workspace scaffolds before `bun install`, so Biome may be absent; a lint fix beats a failed scaffold.
|
|
157
153
|
const root = await makeTempRoot();
|
|
158
154
|
const exec = new Executor("fixture", root);
|
|
159
155
|
exec.getLinter = () => {
|
|
@@ -191,8 +187,7 @@ describe("Executor filesystem helpers", () => {
|
|
|
191
187
|
"AI Development Guide",
|
|
192
188
|
);
|
|
193
189
|
expect(await readFile(path.join(root, "workspace/docs/GENERATED.md"), "utf8")).toContain("Generated Akan Files");
|
|
194
|
-
// Rules
|
|
195
|
-
// existing workspace on `bun update` — the workspace file only extends it and scopes its own files.
|
|
190
|
+
// Rules live in the package's base config, so a framework release reaches an existing workspace on `bun update`.
|
|
196
191
|
expect(await readFile(path.join(root, "workspace/biome.json"), "utf8")).toContain(
|
|
197
192
|
'"extends": ["@akanjs/devkit/biome.base.json"]',
|
|
198
193
|
);
|
|
@@ -323,8 +318,7 @@ describe("Workspace and app executor environment contracts", () => {
|
|
|
323
318
|
expect(prepared.env.AKAN_PUBLIC_BASE_PATHS).toBe("admin");
|
|
324
319
|
expect(prepared.env.AKAN_DATABASE_MODE).toBe("single");
|
|
325
320
|
expect(prepared.env.AKAN_DATABASE_MODES).toBe("single");
|
|
326
|
-
// Bundling
|
|
327
|
-
// dev port published here would be baked into the artifact and outrank the PORT the container is run with.
|
|
321
|
+
// Bundling bakes each AKAN_PUBLIC_* into a literal, so a dev port published here would outrank the container PORT.
|
|
328
322
|
expect(process.env.AKAN_PUBLIC_APP_NAME).toBe("demo");
|
|
329
323
|
expect(process.env.AKAN_PUBLIC_CLIENT_PORT).toBeUndefined();
|
|
330
324
|
expect(process.env.AKAN_PUBLIC_SERVER_PORT).toBeUndefined();
|
|
@@ -460,7 +454,6 @@ describe("Workspace and app executor environment contracts", () => {
|
|
|
460
454
|
});
|
|
461
455
|
|
|
462
456
|
describe("syncAssets", () => {
|
|
463
|
-
// `AppExecutor.from` memoises by name, so each test needs a name no other test has used.
|
|
464
457
|
const makeAppWithLibAssets = async (appName: string) => {
|
|
465
458
|
const root = await makeTempRoot();
|
|
466
459
|
process.env.AKAN_PUBLIC_REPO_NAME = "repo";
|
|
@@ -535,7 +528,6 @@ describe("Workspace and app executor environment contracts", () => {
|
|
|
535
528
|
});
|
|
536
529
|
|
|
537
530
|
describe("devOnly routes", () => {
|
|
538
|
-
// `AppExecutor.from` memoises by name, so each test needs a name no other test has used.
|
|
539
531
|
const makeAppWithRoutes = async (appName: string, routes: Record<string, string>) => {
|
|
540
532
|
const root = await makeTempRoot();
|
|
541
533
|
process.env.AKAN_PUBLIC_REPO_NAME = "repo";
|
|
@@ -629,7 +621,6 @@ describe("Workspace and app executor environment contracts", () => {
|
|
|
629
621
|
await mkdir(path.join(root, "apps", name), { recursive: true });
|
|
630
622
|
await writeFile(path.join(root, "apps", name, "akan.config.ts"), "export default {};\n");
|
|
631
623
|
}
|
|
632
|
-
// `AppExecutor.from` memoises by name, so each test needs names no other test has used.
|
|
633
624
|
return new WorkspaceExecutor({ workspaceRoot: root, repoName: "repo" });
|
|
634
625
|
};
|
|
635
626
|
|
|
@@ -645,8 +636,7 @@ describe("Workspace and app executor environment contracts", () => {
|
|
|
645
636
|
const app = AppExecutor.from(workspace, "drift-b");
|
|
646
637
|
expect(await app.getDevPort()).toBe(8282);
|
|
647
638
|
|
|
648
|
-
// Sorts ahead of `drift-b`, so the same app
|
|
649
|
-
// recomputes this on every restart.
|
|
639
|
+
// Sorts ahead of `drift-b`, so the same app gets another port — and a dev host recomputes it on each restart.
|
|
650
640
|
await mkdir(path.join(workspace.workspaceRoot, "apps/drift-a"), { recursive: true });
|
|
651
641
|
await writeFile(path.join(workspace.workspaceRoot, "apps/drift-a/akan.config.ts"), "export default {};\n");
|
|
652
642
|
|
|
@@ -957,3 +947,67 @@ describe("scan info construction", () => {
|
|
|
957
947
|
expect(info.file.document.scalars.has("money")).toBe(true);
|
|
958
948
|
});
|
|
959
949
|
});
|
|
950
|
+
|
|
951
|
+
describe("WorkspaceExecutor listing", () => {
|
|
952
|
+
test("lists apps, libs and pkgs in name order", async () => {
|
|
953
|
+
const root = await makeTempRoot();
|
|
954
|
+
for (const app of ["zeta", "alpha", "mid"]) await writeText(path.join(root, "apps", app, "akan.config.ts"), "");
|
|
955
|
+
for (const lib of ["util", "shared"]) await writeText(path.join(root, "libs", lib, "akan.config.ts"), "");
|
|
956
|
+
for (const pkg of ["zeta-tool", "@sample/tool", "akanjs"])
|
|
957
|
+
await writeJson(path.join(root, "pkgs", pkg, "package.json"), { name: pkg });
|
|
958
|
+
|
|
959
|
+
const workspace = new WorkspaceExecutor({ workspaceRoot: root, repoName: "repo" });
|
|
960
|
+
expect(await workspace.getExecs()).toEqual([
|
|
961
|
+
["alpha", "mid", "zeta"],
|
|
962
|
+
["shared", "util"],
|
|
963
|
+
["@sample/tool", "akanjs", "zeta-tool"],
|
|
964
|
+
]);
|
|
965
|
+
});
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
describe("SysExecutor module listing", () => {
|
|
969
|
+
test("lists only the module folders that hold the module's own file", async () => {
|
|
970
|
+
const root = await makeTempRoot();
|
|
971
|
+
const lib = path.join(root, "apps/modlist/lib");
|
|
972
|
+
for (const file of [
|
|
973
|
+
"cnst.ts",
|
|
974
|
+
"post/post.constant.ts",
|
|
975
|
+
"post/Post.View.tsx",
|
|
976
|
+
"post/Post.Unit.tsx",
|
|
977
|
+
"draft/draft.document.ts",
|
|
978
|
+
"_auth/auth.service.ts",
|
|
979
|
+
"_notes/notes.md",
|
|
980
|
+
"__scalar/money/money.constant.ts",
|
|
981
|
+
"__scalar/stale/stale.dictionary.ts",
|
|
982
|
+
])
|
|
983
|
+
await writeText(path.join(lib, file), "export {};\n");
|
|
984
|
+
|
|
985
|
+
const workspace = new WorkspaceExecutor({ workspaceRoot: root, repoName: "repo" });
|
|
986
|
+
const app = AppExecutor.from(workspace, "modlist");
|
|
987
|
+
expect(await app.getDatabaseModules()).toEqual(["post"]);
|
|
988
|
+
expect(await app.getServiceModules()).toEqual(["_auth"]);
|
|
989
|
+
expect(await app.getScalarModules()).toEqual(["money"]);
|
|
990
|
+
expect(await app.getViewComponents()).toEqual(["post"]);
|
|
991
|
+
expect(await app.getUnitComponents()).toEqual(["post"]);
|
|
992
|
+
expect(await app.getTemplateComponents()).toEqual([]);
|
|
993
|
+
expect((await app.getViewsSourceCode()).map(({ filePath }) => filePath)).toEqual([
|
|
994
|
+
"apps/modlist/lib/post/Post.View.tsx",
|
|
995
|
+
]);
|
|
996
|
+
expect((await app.getScalarConstantFiles()).map(({ filePath }) => filePath)).toEqual([
|
|
997
|
+
"apps/modlist/lib/__scalar/money/money.constant.ts",
|
|
998
|
+
]);
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
test("reads scalar dictionaries from the scalar folder", async () => {
|
|
1002
|
+
const root = await makeTempRoot();
|
|
1003
|
+
const scalarDir = path.join(root, "apps/scalardict/lib/__scalar/money");
|
|
1004
|
+
await writeText(path.join(scalarDir, "money.constant.ts"), "export {};\n");
|
|
1005
|
+
await writeText(path.join(scalarDir, "money.dictionary.ts"), "export const money = {};\n");
|
|
1006
|
+
|
|
1007
|
+
const workspace = new WorkspaceExecutor({ workspaceRoot: root, repoName: "repo" });
|
|
1008
|
+
const app = AppExecutor.from(workspace, "scalardict");
|
|
1009
|
+
expect(await app.getScalarDictionaryFiles()).toEqual([
|
|
1010
|
+
{ filePath: "apps/scalardict/lib/__scalar/money/money.dictionary.ts", content: "export const money = {};\n" },
|
|
1011
|
+
]);
|
|
1012
|
+
});
|
|
1013
|
+
});
|