@akanjs/devkit 3.0.0 → 3.0.2-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.
Files changed (67) hide show
  1. package/CHANGELOG.md +1832 -0
  2. package/akanConfig/akanConfig.test.ts +3 -0
  3. package/akanConfig/akanConfig.ts +3 -1
  4. package/akanContext.ts +18 -1
  5. package/artifact/implicitRootLayout.test.ts +2 -1
  6. package/artifact/implicitRootLayout.ts +2 -1
  7. package/artifact/routeSeedIndex.test.ts +0 -14
  8. package/biome.base.json +12 -1
  9. package/commandDecorators/command.ts +3 -2
  10. package/commandDecorators/commandDecorators.test.ts +7 -0
  11. package/csrE2e/csrE2eHarness.fixture.ts +3 -2
  12. package/csrE2e/csrPageStack.e2e.test.ts +25 -3
  13. package/executors.test.ts +329 -4
  14. package/executors.ts +49 -47
  15. package/frontendBuild/csrArtifactBuilder.test.ts +34 -0
  16. package/frontendBuild/csrArtifactBuilder.ts +14 -8
  17. package/frontendBuild/csrDevModuleCompiler.ts +0 -1
  18. package/frontendBuild/csrDevResolver.ts +0 -2
  19. package/frontendBuild/devGeneratedIndexSync.test.ts +13 -1
  20. package/frontendBuild/devGeneratedIndexSync.ts +21 -4
  21. package/frontendBuild/frontendBuild.test.ts +1 -1
  22. package/frontendBuild/hmrWatcher.ts +6 -0
  23. package/integration/devStability.integration.test.ts +8 -5
  24. package/integration/devStabilityHarness.ts +2 -0
  25. package/jsonFormatter.test.ts +64 -0
  26. package/jsonFormatter.ts +78 -0
  27. package/lint/__fixtures__/README.md +12 -3
  28. package/lint/__fixtures__/no-double-brace-placeholder/bad.ts +22 -0
  29. package/lint/__fixtures__/no-double-brace-placeholder/fixture.json +1 -0
  30. package/lint/__fixtures__/no-double-brace-placeholder/good.ts +15 -0
  31. package/lint/__fixtures__/no-inline-color/bad.tsx +17 -0
  32. package/lint/__fixtures__/no-inline-color/good.tsx +13 -0
  33. package/lint/__fixtures__/no-static-in-object-light-model/bad.ts +43 -0
  34. package/lint/__fixtures__/no-static-in-object-light-model/fixture.json +1 -0
  35. package/lint/__fixtures__/no-static-in-object-light-model/good.ts +42 -0
  36. package/lint/__fixtures__/no-throw-raw-error/bad.tsx +8 -0
  37. package/lint/__fixtures__/no-throw-raw-error/good.tsx +8 -1
  38. package/lint/__fixtures__/no-unguarded-endpoint/bad.ts +20 -0
  39. package/lint/__fixtures__/no-unguarded-endpoint/fixture.json +1 -0
  40. package/lint/__fixtures__/no-unguarded-endpoint/good.ts +28 -0
  41. package/lint/__fixtures__/no-web-only-api-outside-webkit/bad.tsx +7 -7
  42. package/lint/gritRules.test.ts +23 -15
  43. package/lint/no-double-brace-placeholder.grit +15 -0
  44. package/lint/no-inline-color.grit +21 -5
  45. package/lint/no-static-in-object-light-model.grit +27 -0
  46. package/lint/no-throw-raw-error.grit +18 -33
  47. package/lint/no-unguarded-endpoint.grit +73 -0
  48. package/manifestDependencies.ts +65 -0
  49. package/mobile/desktopBin.test.ts +1 -1
  50. package/mobile/desktopServerStage.test.ts +7 -4
  51. package/mobile/nativeApp.test.ts +57 -8
  52. package/mobile/nativeApp.ts +27 -9
  53. package/mobile/nativeConfig.test.ts +26 -4
  54. package/mobile/nativeConfig.ts +19 -1
  55. package/package.json +2 -2
  56. package/platformTest/LinuxDockerTarget.ts +1 -1
  57. package/platformTest/PlatformTestTarget.ts +3 -1
  58. package/platformTest/WindowsSshTarget.ts +1 -1
  59. package/qualityScanner.test.ts +51 -0
  60. package/qualityScanner.ts +22 -1
  61. package/scanInfo.ts +14 -2
  62. package/subspace.test.ts +10 -1
  63. package/testHelpers.ts +17 -0
  64. package/transforms/transforms.test.ts +13 -0
  65. package/tsconfig.json +4 -15
  66. package/workspaceLayout.test.ts +24 -1
  67. package/workspaceLayout.ts +19 -2
@@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test";
2
2
  import {
3
3
  appRootAllowedDirs,
4
4
  appRootAllowedFiles,
5
+ facetIndexShadowOf,
5
6
  isAllowedLibFacetRootFile,
6
7
  isScannedRootEntry,
7
8
  libRootAllowedDirs,
@@ -34,7 +35,7 @@ describe("app root layout allowlist", () => {
34
35
  test("names what a Capacitor app kept in its root as a leftover, not an unknown entry", () => {
35
36
  for (const name of ["android", "ios", "mobile", "capacitor.config.ts", "capacitor.config.json"]) {
36
37
  expect(appRootAllowedFiles.has(name) || appRootAllowedDirs.has(name)).toBe(false);
37
- expect(rootEntryHintOf("app", name)).toContain(".akan/native/<target>");
38
+ expect(rootEntryHintOf("app", name)).toContain("dist/native/<app>/<target>");
38
39
  }
39
40
  expect(rootEntryHintOf("app", "base")).toBeNull();
40
41
  expect(rootEntryHintOf("lib", "ios")).toBeNull();
@@ -78,6 +79,28 @@ describe("lib root layout allowlist", () => {
78
79
  });
79
80
  });
80
81
 
82
+ describe("hand-written facet index", () => {
83
+ test("flags every index Bun resolves ahead of the generated barrel, at the root of each barrel facet", () => {
84
+ for (const facet of ["ui", "webkit", "srvkit", "common", "plugin"])
85
+ for (const filename of ["index.tsx", "index.jsx", "index.mts"])
86
+ expect(facetIndexShadowOf(`${facet}/${filename}`)).toContain(`shadows the generated ${facet}/index.ts`);
87
+ expect(facetIndexShadowOf("ui/index.tsx")).toContain("Delete it");
88
+ });
89
+
90
+ test("leaves the generated barrel, a folder namespace, and folders without a barrel alone", () => {
91
+ for (const relativePath of [
92
+ "ui/index.ts",
93
+ "ui/index.js",
94
+ "ui/Chat/index.tsx",
95
+ "ui/Chat/index_.tsx",
96
+ "page/index.tsx",
97
+ "lib/index.tsx",
98
+ "index.tsx",
99
+ ])
100
+ expect(facetIndexShadowOf(relativePath)).toBeNull();
101
+ });
102
+ });
103
+
81
104
  describe("lib facet root allowlist", () => {
82
105
  test("admits the generated support facets and a root signal test", () => {
83
106
  expect(isAllowedLibFacetRootFile("cnst.ts")).toBe(true);
@@ -84,7 +84,24 @@ const libFacetRootTestPattern = /^[A-Za-z][A-Za-z0-9_-]*\.signal\.(test|spec)\.(
84
84
  export const isAllowedLibFacetRootFile = (filename: string) =>
85
85
  libFacetRootAllowedFiles.has(filename) || libFacetRootTestPattern.test(filename);
86
86
 
87
- //* What a Capacitor app kept in its root. The native runtime generates its projects under `.akan/native/<target>`, so
87
+ export const barrelFacetDirs = ["ui", "webkit", "srvkit", "common", "plugin"] as const;
88
+
89
+ //* Bun resolves a folder import to `index.tsx`, `index.jsx` or `index.mts` ahead of `index.ts`, and TypeScript to
90
+ //* `index.ts` first, so one of these beside the generated barrel typechecks every name the barrel adds and serves none.
91
+ const barrelShadowingIndexFiles = new Set(["index.tsx", "index.jsx", "index.mts"]);
92
+
93
+ export const facetIndexShadowOf = (sysRelativePath: string) => {
94
+ const [facet, filename = "", ...nested] = sysRelativePath.split("/");
95
+ if (nested.length || !barrelShadowingIndexFiles.has(filename) || !barrelFacetDirs.some((dir) => dir === facet))
96
+ return null;
97
+ return (
98
+ `shadows the generated ${facet}/index.ts: Bun loads ${filename} and TypeScript checks index.ts, so a name only ` +
99
+ `the generated barrel exports typechecks and is undefined at runtime. Delete it, since the generated barrel ` +
100
+ `re-exports every file and folder in ${facet}/; a namespace it builds belongs in ${facet}/<Folder>/index.tsx`
101
+ );
102
+ };
103
+
104
+ //* What a Capacitor app kept in its root. The native runtime generates its projects under `dist/native/<app>/<target>`, so
88
105
  //* these are named as leftovers instead of as unknown entries.
89
106
  const retiredAppRootEntries = new Set([
90
107
  "android",
@@ -97,7 +114,7 @@ const retiredAppRootEntries = new Set([
97
114
 
98
115
  export const rootEntryHintOf = (type: SysType, name: string) =>
99
116
  type === "app" && retiredAppRootEntries.has(name)
100
- ? "a Capacitor-era entry; the native runtime generates its projects under .akan/native/<target>, so delete it"
117
+ ? "a Capacitor-era entry; the native runtime generates its projects under dist/native/<app>/<target>, so delete it"
101
118
  : null;
102
119
 
103
120
  // scanSync reads roots through `Bun.Glob("*")`, which skips dotfiles, so doctor skips them the same way.