@akanjs/devkit 3.1.0-rc.1 → 3.1.0-rc.11

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.
Files changed (138) hide show
  1. package/abstractDoc.ts +1 -1
  2. package/agentsIndex.test.ts +4 -1
  3. package/akanConfig/akanConfig.test.ts +51 -5
  4. package/akanConfig/akanConfig.ts +33 -14
  5. package/akanConfig/akanWorkspaceConfig.test.ts +6 -6
  6. package/akanConfig/akanWorkspaceConfig.ts +1 -1
  7. package/akanContext.ts +4 -4
  8. package/akanMcpContract.ts +1 -1
  9. package/applicationBuildRunner.test.ts +57 -2
  10. package/applicationBuildRunner.ts +15 -6
  11. package/artifact/implicitRootLayout.test.ts +2 -0
  12. package/artifact/implicitRootLayout.ts +1 -0
  13. package/biome.base.json +1 -11
  14. package/biomeBase.ts +1 -1
  15. package/cloud/cloudApi.ts +22 -15
  16. package/cloud/cloudHttpError.test.ts +32 -0
  17. package/cloud/cloudHttpError.ts +54 -0
  18. package/cloud/cloudUpdates.ts +138 -0
  19. package/cloud/configLock.ts +2 -1
  20. package/cloud/globalConfig.test.ts +17 -0
  21. package/cloud/globalConfig.ts +9 -2
  22. package/cloud/index.ts +3 -0
  23. package/cloud/pipelineSecrets.ts +114 -0
  24. package/cloud/updatePackUpload.test.ts +100 -45
  25. package/cloud/updatePackUpload.ts +38 -18
  26. package/codeAgent/agent/CodeAgentProxy.ts +2 -2
  27. package/codeAgent/agent/akanCodeModel.ts +1 -1
  28. package/codeAgent/agent/akanContextFiles.test.ts +3 -1
  29. package/codeAgent/tools/WebToolPack.ts +4 -4
  30. package/codeAgent/tools/akanCodePlugins.test.ts +20 -16
  31. package/commandDecorators/argMeta.ts +11 -2
  32. package/commandDecorators/command.ts +45 -10
  33. package/commandDecorators/commandBuilder.ts +6 -1
  34. package/commandDecorators/commandDecorators.test.ts +205 -4
  35. package/commandDecorators/exitCodeError.ts +15 -0
  36. package/commandDecorators/index.ts +1 -0
  37. package/createTunnel.test.ts +14 -0
  38. package/createTunnel.ts +3 -1
  39. package/dependencyScanner.ts +1 -1
  40. package/devkitUtils.test.ts +1 -1
  41. package/executors.test.ts +131 -3
  42. package/executors.ts +56 -36
  43. package/frontendBuild/autoImportSync.test.ts +3 -1
  44. package/frontendBuild/clientEntryDiscovery.ts +1 -1
  45. package/frontendBuild/csrArtifactBuilder.test.ts +30 -0
  46. package/frontendBuild/csrArtifactBuilder.ts +23 -4
  47. package/frontendBuild/csrDevPatcher.test.ts +4 -1
  48. package/frontendBuild/cssBlockParser.test.ts +123 -0
  49. package/frontendBuild/cssBlockParser.ts +132 -0
  50. package/frontendBuild/cssCompiler.test.ts +53 -0
  51. package/frontendBuild/cssCompiler.ts +8 -4
  52. package/frontendBuild/fontOptimizer.ts +2 -1
  53. package/frontendBuild/frontendBuild.test.ts +14 -0
  54. package/frontendBuild/hmrWatcher.ts +1 -1
  55. package/frontendBuild/pagesBundleBuilder.test.ts +98 -0
  56. package/frontendBuild/pagesBundleBuilder.ts +64 -9
  57. package/frontendBuild/routeClientBuilder.ts +1 -1
  58. package/frontendBuild/sourceMtimeIndex.test.ts +1 -1
  59. package/frontendBuild/themeValidator.test.ts +83 -2
  60. package/frontendBuild/themeValidator.ts +37 -15
  61. package/getRelatedCnsts.ts +2 -1
  62. package/incrementalBuilder/buildBatch.proc.ts +12 -7
  63. package/incrementalBuilder/incrementalBuilder.proc.test.ts +63 -0
  64. package/incrementalBuilder/incrementalBuilder.proc.ts +7 -5
  65. package/integration/devStabilityHarness.ts +5 -3
  66. package/lint/__fixtures__/no-deep-internal-import/bad.tsx +1 -0
  67. package/lint/__fixtures__/no-deep-internal-import/good.tsx +1 -0
  68. package/lint/__fixtures__/no-import-client-functions/bad.tsx +1 -0
  69. package/lint/__fixtures__/no-import-client-functions/good.tsx +1 -0
  70. package/lint/__fixtures__/no-import-client-in-server/bad.tsx +1 -0
  71. package/lint/__fixtures__/no-import-client-in-server/good.tsx +1 -0
  72. package/lint/__fixtures__/no-import-external-library/bad.tsx +1 -0
  73. package/lint/__fixtures__/no-import-external-library/good.tsx +1 -0
  74. package/lint/__fixtures__/no-import-external-library-in-test/bad.tsx +1 -0
  75. package/lint/__fixtures__/no-import-external-library-in-test/good.tsx +1 -0
  76. package/lint/__fixtures__/no-import-server-in-client/bad.tsx +1 -0
  77. package/lint/__fixtures__/no-import-server-in-client/good.tsx +1 -0
  78. package/lint/__fixtures__/no-init-fetch-in-client/store-file/bad.ts +1 -1
  79. package/lint/__fixtures__/no-static-in-object-light-model/bad.ts +2 -2
  80. package/mobile/desktopServerStage.test.ts +13 -0
  81. package/mobile/desktopServerStage.ts +5 -7
  82. package/mobile/index.ts +2 -0
  83. package/mobile/mobileTarget.ts +1 -2
  84. package/mobile/nativeApi.test.ts +26 -0
  85. package/mobile/nativeApi.ts +5 -2
  86. package/mobile/nativeApp.test.ts +135 -33
  87. package/mobile/nativeApp.ts +109 -73
  88. package/mobile/nativeConfig.test.ts +3 -0
  89. package/mobile/nativeConfig.ts +5 -3
  90. package/mobile/nativePublicEnv.test.ts +131 -0
  91. package/mobile/nativePublicEnv.ts +116 -0
  92. package/mobile/nativeWebDir.ts +3 -2
  93. package/mobile/serverBundleSecrets.test.ts +79 -0
  94. package/mobile/serverBundleSecrets.ts +60 -16
  95. package/mobile/updatePackFolder.test.ts +98 -0
  96. package/mobile/updatePackFolder.ts +131 -0
  97. package/mobile/updateUploader.test.ts +115 -22
  98. package/mobile/updateUploader.ts +77 -10
  99. package/package.json +20 -20
  100. package/piDependencyPins.test.ts +18 -19
  101. package/pipeline/PipelineCompiler.test.ts +157 -1
  102. package/pipeline/PipelineCompiler.ts +80 -46
  103. package/pipeline/PipelineDefinition.test.ts +9 -0
  104. package/pipeline/PipelineDefinition.ts +4 -3
  105. package/pipeline/PipelineDryRun.test.ts +27 -0
  106. package/pipeline/PipelineDryRun.ts +2 -2
  107. package/pipeline/PipelineInputReader.ts +157 -253
  108. package/pipeline/PipelineRules.ts +92 -0
  109. package/pipeline/index.ts +1 -0
  110. package/platformTest/LinuxDockerTarget.ts +2 -1
  111. package/platformTest/PlatformTestTarget.ts +7 -5
  112. package/platformTest/WindowsSshTarget.ts +2 -1
  113. package/qualityScanner.test.ts +5 -3
  114. package/qualityScanner.ts +1 -1
  115. package/recipeScanner.test.ts +9 -3
  116. package/scanInfo.ts +1 -1
  117. package/slicePlanner.ts +5 -3
  118. package/subspace.test.ts +90 -19
  119. package/subspace.ts +52 -500
  120. package/subspaceClone.ts +362 -0
  121. package/subspaceConfig.ts +1 -2
  122. package/subspaceReport.ts +162 -0
  123. package/testHelpers.ts +2 -0
  124. package/transforms/barrelImportsPlugin.ts +1 -1
  125. package/transforms/browserDirnamePlugin.test.ts +88 -0
  126. package/transforms/browserDirnamePlugin.ts +25 -0
  127. package/transforms/rscUseClientTransform.ts +2 -2
  128. package/transforms/serverEnvPlugin.test.ts +76 -0
  129. package/transforms/serverEnvPlugin.ts +9 -25
  130. package/transforms/serverEnvProfile.test.ts +189 -0
  131. package/transforms/serverEnvProfile.ts +324 -60
  132. package/transforms/transforms.test.ts +18 -2
  133. package/transforms/tsconfigPackageResolver.test.ts +9 -0
  134. package/typecheck/projectTypecheck.ts +6 -5
  135. package/types.ts +1 -0
  136. package/workflow/artifacts.ts +1 -1
  137. package/workflow/rolloutGate.test.ts +5 -1
  138. package/workflow/source.ts +2 -2
@@ -70,6 +70,15 @@ describe("PipelineDefinition", () => {
70
70
  );
71
71
  });
72
72
 
73
+ test("the workspace's apps are in code-point order, whatever the machine's locale", async () => {
74
+ await withWorkspace(
75
+ { "apps/api/akan.config.ts": "export default {};\n", "apps/Web/akan.config.ts": "export default {};\n" },
76
+ async (workspace) => {
77
+ expect((await PipelineDefinition.load(workspace, [])).workspaceApps).toEqual(["Web", "api"]);
78
+ },
79
+ );
80
+ });
81
+
73
82
  test("a config that cannot load is an error naming the file, never a silent default", async () => {
74
83
  await withWorkspace(
75
84
  {
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import type { AppPipelineConfig, WorkspacePipelineConfig } from "akanjs";
4
4
  import type { PipelineDiagnostic, PipelinePlanContext, PipelinePlanResult } from "akanjs/common";
5
+ import { toError } from "akanjs/common";
5
6
  import { AkanAppConfig, AkanWorkspaceConfig } from "../akanConfig";
6
7
  import { AppExecutor, type WorkspaceExecutor } from "../executors";
7
8
  import { FileSys } from "../fileSys";
@@ -44,7 +45,7 @@ export class PipelineDefinition {
44
45
  }
45
46
 
46
47
  async #load(apps: readonly string[]) {
47
- this.workspaceApps = (await this.#workspace.getApps()).sort((a, b) => a.localeCompare(b));
48
+ this.workspaceApps = (await this.#workspace.getApps()).sort();
48
49
  this.workspaceSource = await this.#loadWorkspace();
49
50
  for (const app of new Set(apps)) {
50
51
  if (!this.workspaceApps.includes(app)) continue;
@@ -68,7 +69,7 @@ export class PipelineDefinition {
68
69
  const targets = await resolveMobileTargets(AppExecutor.from(this.#workspace, app), "all");
69
70
  return { targets: targets.map(({ name, config }) => ({ name, updates: !!config.updates })) };
70
71
  } catch (error) {
71
- return { error: error instanceof Error ? error.message : String(error) };
72
+ return { error: toError(error).message };
72
73
  }
73
74
  }
74
75
 
@@ -105,7 +106,7 @@ export class PipelineDefinition {
105
106
  this.diagnostics.push({
106
107
  severity: "error",
107
108
  code: "pipeline.load.failed",
108
- message: `could not load: ${error instanceof Error ? error.message : String(error)}`,
109
+ message: `could not load: ${toError(error).message}`,
109
110
  file,
110
111
  path: null,
111
112
  });
@@ -76,6 +76,33 @@ describe("PipelineDryRun", () => {
76
76
  );
77
77
  });
78
78
 
79
+ test("a phase of one stage still names its app", () => {
80
+ const result = PipelineCompiler.compile({
81
+ context: { ...context, apps: ["web"] },
82
+ workspaceApps: ["web"],
83
+ workspace: {
84
+ file: "akan.config.ts",
85
+ sha256: sha,
86
+ pipeline: { after: [{ name: "E2E", matrix: "apps", sh: "bun run e2e" }] },
87
+ },
88
+ apps: new Map([["web", { file: "apps/web/akan.config.ts", sha256: sha, pipeline: null }]]),
89
+ akanVersion: "3.0.3",
90
+ });
91
+ expect(PipelineDryRun.render(result)).toBe(
92
+ [
93
+ "plan v1 · branch develop · env develop · trigger push · apps web",
94
+ "from akan.config.ts, apps/web/akan.config.ts (default)",
95
+ "",
96
+ "prepare (executor) checkout · env · install · plan",
97
+ "build build Build web action build",
98
+ "package docker Docker web action docker",
99
+ "deploy deploy Deploy → web (one at a time)",
100
+ "finish e2e E2E web bun run e2e",
101
+ "finish (executor) cleanup",
102
+ ].join("\n"),
103
+ );
104
+ });
105
+
79
106
  test("a failed plan prints its diagnostics", () => {
80
107
  const rendered = PipelineDryRun.render({
81
108
  ok: false,
@@ -6,7 +6,7 @@ import type {
6
6
  PipelinePlanStage,
7
7
  } from "akanjs/common";
8
8
 
9
- /** A plan as a person reads it: one line per phase in run order, the executor's own work included. Runs nothing. */
9
+ /** A plan as a person reads it: one line per phase in run order, the executor's own work included. */
10
10
  export class PipelineDryRun {
11
11
  static render(result: PipelinePlanResult) {
12
12
  const lines = result.ok ? PipelineDryRun.#plan(result.plan) : ["no plan: the definition has errors"];
@@ -61,7 +61,7 @@ export class PipelineDryRun {
61
61
  const command = stage?.steps
62
62
  .map((step) => (step.kind === "sh" ? step.name : `action ${step.action}`))
63
63
  .join(" · ");
64
- return [labels[0], command].filter((part) => part && part !== stage?.name).join(" ");
64
+ return [labels[0], command].filter((part) => part && part !== phase.name).join(" ");
65
65
  }
66
66
  return `‖ ${labels.join(" · ")}`;
67
67
  }