@akanjs/cli 3.0.0-beta.2 → 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.
Files changed (187) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-awv258wb.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-1nqh35ez.js +1457 -0
  6. package/README.md +3 -0
  7. package/TunnelShare-scf4e4pd.js +9 -0
  8. package/{agent.command-d2gfxfck.js → agent.command-1s9ag7sb.js} +8 -9
  9. package/akanCode.js +102 -0
  10. package/{application.command-pj2m7584.js → application.command-49hwy6va.js} +51 -78
  11. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-ybyp97pv.js} +63 -64
  12. package/{applicationReleasePackager-4yasxwv9.js → applicationReleasePackager-esnrphw8.js} +40 -60
  13. package/buildBatch.proc.js +19 -24
  14. package/{capacitorApp-36rbr858.js → capacitorApp-1synz4en.js} +3 -4
  15. package/cloud.command-d7rqtzt9.js +94 -0
  16. package/cloud.script-bkbpcr96.js +19 -0
  17. package/code.command-nn48xzej.js +154 -0
  18. package/commandManifest.json +1 -1
  19. package/consoleToStderr-h5bryj94.js +7 -0
  20. package/context.command-s3mcmvpa.js +48 -0
  21. package/context.runner-k99nb5pk.js +21 -0
  22. package/{dependencyScanner-shs82ynp.js → dependencyScanner-ye2e6pdz.js} +2 -2
  23. package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
  24. package/fileSys-5ngz93ga.js +9 -0
  25. package/guideline.command-sct4qnt5.js +42 -0
  26. package/guidelines/agentRule/agentRule.instruction.md +206 -25
  27. package/guidelines/conventions/conventions.instruction.md +79 -24
  28. package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
  29. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  30. package/guidelines/queryRule/queryRule.instruction.md +17 -7
  31. package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
  32. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  33. package/guidelines/transportRule/transportRule.instruction.md +51 -0
  34. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
  35. package/incrementalBuilder.proc.js +31 -48
  36. package/{index-h7yw2z9n.js → index-0bq14vr1.js} +8 -14
  37. package/index-13ffe9wp.js +69 -0
  38. package/index-22d57v4c.js +266 -0
  39. package/{index-fz5q3gd7.js → index-31yr441d.js} +10 -17
  40. package/index-3hx1z96c.js +87 -0
  41. package/index-3sq321ak.js +53 -0
  42. package/{index-kcxmv48c.js → index-3t7g9e4r.js} +45 -79
  43. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  44. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  45. package/{index-259dsnz3.js → index-5pc1qrbv.js} +5 -8
  46. package/index-7md2g9vw.js +6 -0
  47. package/index-8mna0947.js +187 -0
  48. package/{index-zry5nz81.js → index-8sf7wmdr.js} +51 -30
  49. package/{index-2tv3fdx4.js → index-9d9bgcx4.js} +342 -765
  50. package/index-9dp031by.js +12 -0
  51. package/{index-ne2qy0nk.js → index-ahemdr5n.js} +12 -12
  52. package/{index-ws5e0j51.js → index-as7xmyz8.js} +40 -24
  53. package/index-axzjaqve.js +1118 -0
  54. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  55. package/index-c6eggbee.js +123 -0
  56. package/index-d2242ksy.js +99 -0
  57. package/{index-a64esmtb.js → index-ddxvdd1p.js} +169 -305
  58. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  59. package/{index-pnqbkf5p.js → index-dzf3r49a.js} +6 -2
  60. package/{index-w8kmx1b6.js → index-fgq75haa.js} +198 -290
  61. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  62. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  63. package/{index-wt7qrtd4.js → index-mxav6j3c.js} +93 -232
  64. package/{index-gyd220p2.js → index-myhc3c1j.js} +554 -577
  65. package/{index-600zhnve.js → index-nv5976x3.js} +56 -197
  66. package/index-p6pbz9n5.js +25 -0
  67. package/{index-4edzf1gr.js → index-przybvy5.js} +77 -150
  68. package/index-smme4r47.js +49 -0
  69. package/{index-mak3cd28.js → index-w2zdcw3k.js} +137 -255
  70. package/index-wa5jbxj1.js +760 -0
  71. package/{index-v0qh106m.js → index-ww4z397j.js} +527 -723
  72. package/{index-j9yhg404.js → index-xqjwd384.js} +4 -7
  73. package/{index-7737gxcp.js → index-xqpzbab5.js} +107 -241
  74. package/index-xsjh6nzh.js +2729 -0
  75. package/{index-ktb5njgy.js → index-ygn77a5w.js} +47 -99
  76. package/index-ztp3e73t.js +700 -0
  77. package/index.js +23 -22
  78. package/{library.command-nbsky672.js → library.command-1gx04jgn.js} +4 -5
  79. package/{localRegistry.command-yeq57wjr.js → localRegistry.command-zndxj1q6.js} +22 -42
  80. package/{module.command-29vqzrh8.js → module.command-3waddk95.js} +8 -11
  81. package/{package.command-axv0abmn.js → package.command-zrc7br1y.js} +6 -7
  82. package/package.json +14 -5
  83. package/{page.command-vs9s3zrh.js → page.command-vpjgardh.js} +4 -5
  84. package/{primitive.command-cbxmqbtc.js → primitive.command-sz84tk4t.js} +9 -22
  85. package/prompter-ptaa3nk0.js +8 -0
  86. package/{quality.command-gmbs7nws.js → quality.command-g869hafs.js} +203 -376
  87. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  88. package/{repair.command-bqsjptsj.js → repair.command-chsnjvvv.js} +11 -35
  89. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  90. package/{scalar.command-6k1vhe9s.js → scalar.command-2v21newx.js} +7 -10
  91. package/skills/akan-code/SKILL.md +130 -0
  92. package/skills/akan-debug/SKILL.md +42 -0
  93. package/skills/akan-deps/SKILL.md +50 -0
  94. package/skills/akan-err/SKILL.md +39 -0
  95. package/skills/akan-module/SKILL.md +45 -0
  96. package/skills/akan-scaffold/SKILL.md +76 -0
  97. package/skills/akan-scalar/SKILL.md +52 -0
  98. package/skills/akan-service/SKILL.md +34 -0
  99. package/skills/akan-store/SKILL.md +67 -0
  100. package/skills/akan-ui/SKILL.md +63 -0
  101. package/skills/akan-validate/SKILL.md +44 -0
  102. package/{subspace.command-fwjfcts7.js → subspace.command-ckcbwfp1.js} +138 -67
  103. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  104. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  105. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  106. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  107. package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
  108. package/templates/appSample/lib/task/task.signal.test.ts +15 -1
  109. package/templates/appSample/lib/task/task.signal.ts +1 -1
  110. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
  111. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
  112. package/templates/client.ts +7 -30
  113. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  114. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  115. package/templates/crudPages/new/page.tsx +2 -1
  116. package/templates/crudPages/page.tsx +2 -1
  117. package/templates/crudSinglePage/page.tsx +2 -1
  118. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  119. package/templates/lib/__lib/lib.document.ts +0 -2
  120. package/templates/lib/sig.ts +8 -30
  121. package/templates/localDev/docker-compose.yaml.template +3 -14
  122. package/templates/module/__model__.signal.ts +12 -4
  123. package/templates/pkgRoot/tsconfig.json.template +2 -7
  124. package/templates/server.ts +0 -2
  125. package/templates/service/__model__.abstract.md.template +8 -0
  126. package/tunnel.command-kd2yr4fx.js +129 -0
  127. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  128. package/typecheck.proc.js +1 -1
  129. package/workflow.command-44252cqv.js +79 -0
  130. package/{workspace.command-8s050m0h.js → workspace.command-fqcztt5p.js} +77 -109
  131. package/abstractCompactor-mjh5ppsq.js +0 -101
  132. package/cloud.command-jshwdq22.js +0 -93
  133. package/context.command-ez8a0zyz.js +0 -80
  134. package/devTuiView-c08ccbat.js +0 -9
  135. package/getDirname-dr3jz1xg.js +0 -7
  136. package/guideline.command-xmqwx8zm.js +0 -359
  137. package/guidelines/agentRule/agentRule.generate.json +0 -31
  138. package/guidelines/componentRule/componentRule.generate.json +0 -31
  139. package/guidelines/conventions/conventions.generate.json +0 -25
  140. package/guidelines/cssRule/cssRule.generate.json +0 -31
  141. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  142. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  143. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  144. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  145. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  146. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  147. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  148. package/guidelines/framework/framework.generate.json +0 -32
  149. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  150. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  151. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  152. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  153. package/guidelines/modelService/modelService.generate.json +0 -31
  154. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  155. package/guidelines/modelStore/modelStore.generate.json +0 -31
  156. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  157. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  158. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  159. package/guidelines/modelView/modelView.generate.json +0 -31
  160. package/guidelines/modelZone/modelZone.generate.json +0 -31
  161. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  162. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  163. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  164. package/guidelines/queryRule/queryRule.generate.json +0 -31
  165. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  166. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  167. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  168. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  169. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  170. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  171. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  172. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  173. package/guidelines/transportRule/transportRule.generate.json +0 -31
  174. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  175. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  176. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  177. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
  178. package/index-2hq52jq3.js +0 -465
  179. package/index-6wwzs1bc.js +0 -7
  180. package/index-8pm30m73.js +0 -841
  181. package/index-kn1h7p1x.js +0 -560
  182. package/index-meh558jy.js +0 -65
  183. package/index-rwg2aa4f.js +0 -229
  184. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  185. package/templates/module/__model__.abstract.md +0 -28
  186. package/templates/service/__model__.abstract.md +0 -28
  187. package/workflow.command-nwpcdc8p.js +0 -107
@@ -1,10 +1,8 @@
1
1
  // @bun
2
2
  import {
3
- FileSys
4
- } from "./index-q0y2jq9j.js";
5
- import {
6
- getDirname2
7
- } from "./index-6wwzs1bc.js";
3
+ getDirname2,
4
+ FileSys2
5
+ } from "./index-5b6tavv3.js";
8
6
 
9
7
  // pkgs/@akanjs/devkit/codegenLock.ts
10
8
  import { mkdir, open, readFile, rm, stat } from "fs/promises";
@@ -191,11 +189,12 @@ import {
191
189
  fork,
192
190
  spawn as spawn2
193
191
  } from "child_process";
194
- import { readFileSync as readFileSync2 } from "fs";
192
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
195
193
  import {
196
194
  copyFile,
197
195
  cp as cpEntry,
198
- mkdir as mkdir3,
196
+ lstat,
197
+ mkdir as mkdir2,
199
198
  readdir as readDirEntries,
200
199
  realpath,
201
200
  rm as rm3,
@@ -218,7 +217,7 @@ import chalk2 from "chalk";
218
217
 
219
218
  // pkgs/@akanjs/devkit/agentsIndex.ts
220
219
  var recipeScannerLoad = null;
221
- var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-fpagtgc1.js");
220
+ var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-4b69ybe0.js");
222
221
  var AGENT_BLOCK_START = "<!-- akan:agent:start -->";
223
222
  var AGENT_BLOCK_END = "<!-- akan:agent:end -->";
224
223
  var AGENT_VERSION_PREFIX = "<!-- akan:agent:version ";
@@ -228,7 +227,7 @@ ${block}`;
228
227
  var extractBlockVersion = (content) => content.match(/<!-- akan:agent:version ([^\s]+) -->/)?.[1] ?? null;
229
228
  var readDevkitVersion = async () => {
230
229
  const { readFile } = await import("fs/promises");
231
- const { getDirname } = await import("./getDirname-dr3jz1xg.js");
230
+ const { getDirname } = await import("./fileSys-5ngz93ga.js");
232
231
  try {
233
232
  const raw = await readFile(`${getDirname(import.meta.url)}/package.json`, "utf-8");
234
233
  return JSON.parse(raw).version ?? null;
@@ -358,7 +357,7 @@ ${CLAUDE_COMMENT_RULE}
358
357
  import fs from "fs";
359
358
  import path2 from "path";
360
359
  import { fileURLToPath } from "url";
361
- import { normalizeRoutePrefix } from "akanjs/base";
360
+ import { DatabaseModes, normalizeRoutePrefix } from "akanjs/base";
362
361
  import { resolveAkanI18nConfig } from "akanjs/common";
363
362
 
364
363
  // pkgs/@akanjs/devkit/akanConfig/types.ts
@@ -367,32 +366,11 @@ import { archs } from "akanjs";
367
366
  // pkgs/@akanjs/devkit/akanConfig/akanConfig.ts
368
367
  var DEFAULT_BARREL_IMPORTS = ["akanjs/webkit", "akanjs/common", "akanjs/ui", "akanjs/server"];
369
368
  var DEFAULT_OPTIMIZE_IMPORTS = [
370
- "lucide-react",
371
- "date-fns",
372
- "lodash-es",
373
- "ramda",
374
- "antd",
375
- "react-bootstrap",
376
- "ahooks",
377
- "@ant-design/icons",
378
- "@headlessui/react",
379
- "@headlessui-float/react",
380
- "@heroicons/react/20/solid",
381
- "@heroicons/react/24/solid",
382
- "@heroicons/react/24/outline",
383
- "@visx/visx",
384
- "@tremor/react",
385
- "rxjs",
386
- "@mui/material",
387
- "@mui/icons-material",
388
- "recharts",
389
- "react-use",
390
- "@material-ui/core",
391
- "@material-ui/icons",
392
- "@tabler/icons-react",
393
- "mui-core",
394
- "react-icons/*"
395
- ];
369
+ "lucide-react date-fns lodash-es ramda antd react-bootstrap ahooks @ant-design/icons @headlessui/react",
370
+ "@headlessui-float/react @heroicons/react/20/solid @heroicons/react/24/solid @heroicons/react/24/outline",
371
+ "@visx/visx @tremor/react rxjs @mui/material @mui/icons-material recharts react-use @material-ui/core",
372
+ "@material-ui/icons @tabler/icons-react mui-core react-icons/*"
373
+ ].flatMap((line) => line.split(" "));
396
374
  var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
397
375
  var DEFAULT_DOCKER_IMAGE = "oven/bun:1-slim";
398
376
  var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
@@ -404,29 +382,9 @@ var MOBILE_RUNTIME_PACKAGES = [
404
382
  "@capacitor/assets"
405
383
  ];
406
384
  var MOBILE_APP_CAPACITOR_PLUGINS = [
407
- "@capacitor/app",
408
- "@capacitor/browser",
409
- "@capacitor/camera",
410
- "@capacitor/core",
411
- "@capacitor/device",
412
- "@capacitor/geolocation",
413
- "@capacitor/haptics",
414
- "@capacitor/inappbrowser",
415
- "@capacitor/keyboard",
416
- "@capacitor/preferences",
417
- "@capacitor/push-notifications",
385
+ ..."app browser camera core device geolocation haptics inappbrowser keyboard preferences push-notifications".split(" ").map((name) => `@capacitor/${name}`),
418
386
  "capacitor-plugin-safe-area"
419
387
  ];
420
- var DATABASE_MODE_RUNTIME_PACKAGES = {
421
- single: [],
422
- multiple: ["@libsql/client", "bullmq", "ioredis", "protobufjs"],
423
- cluster: ["bullmq", "ioredis", "postgres", "protobufjs"]
424
- };
425
- var AKAN_RUNTIME_PACKAGES = new Set([
426
- ...SSR_RUNTIME_PACKAGES,
427
- ...MOBILE_RUNTIME_PACKAGES,
428
- ...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat()
429
- ]);
430
388
  var DEFAULT_AKAN_IMAGE_CONFIG = {
431
389
  deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
432
390
  imageSizes: [32, 48, 64, 96, 128, 256, 384],
@@ -506,7 +464,7 @@ class AkanAppConfig {
506
464
  rootPackageJson;
507
465
  docker;
508
466
  dockerfile;
509
- defaultDatabaseMode;
467
+ database;
510
468
  web;
511
469
  externalLibs;
512
470
  barrelImports;
@@ -534,7 +492,7 @@ class AkanAppConfig {
534
492
  this.baseDevEnv = baseDevEnv;
535
493
  this.plugins = plugins;
536
494
  this.#applyRoutes(config?.routes);
537
- this.defaultDatabaseMode = config?.defaultDatabaseMode ?? "single";
495
+ this.database = AkanAppConfig.#database(app, config);
538
496
  this.externalLibs = [...new Set([...config?.externalLibs ?? [], ...libContributions.externalLibs])];
539
497
  this.barrelImports = [
540
498
  ...DEFAULT_BARREL_IMPORTS,
@@ -641,22 +599,15 @@ class AkanAppConfig {
641
599
  }
642
600
  #applyRoutes(routes = []) {
643
601
  for (const route of routes) {
644
- if (route.basePath) {
645
- const basePath = route.basePath.replace(/^\/+|\/+$/g, "");
602
+ const basePath = route.basePath ? route.basePath.replace(/^\/+|\/+$/g, "") : null;
603
+ if (basePath !== null)
646
604
  this.basePaths.add(basePath);
647
- const domains = this.subRoutes.getOrInsert(basePath, new Set);
648
- Object.keys(route.domains).forEach((branch) => void this.branches.add(branch));
649
- Object.values(route.domains).flat().forEach((domain) => {
650
- if (domain)
651
- domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
652
- });
653
- } else {
654
- Object.keys(route.domains).forEach((branch) => void this.branches.add(branch));
655
- Object.values(route.domains).flat().forEach((domain) => {
656
- if (domain)
657
- this.domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
658
- });
659
- }
605
+ const domains = basePath !== null ? this.subRoutes.getOrInsert(basePath, new Set) : this.domains;
606
+ for (const branch of Object.keys(route.domains))
607
+ this.branches.add(branch);
608
+ for (const domain of Object.values(route.domains).flat())
609
+ if (domain)
610
+ domains.add(domain.toLowerCase().replace(/:\d+$/, ""));
660
611
  }
661
612
  const appName = this.app.name.toLowerCase();
662
613
  const serveDomain = this.baseDevEnv.serveDomain.toLowerCase();
@@ -730,6 +681,7 @@ ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
730
681
  ENV AKAN_PUBLIC_API_PREFIX=${this.api.prefix}
731
682
  ENV AKAN_PUBLIC_WS_PREFIX=${this.api.websocketPrefix}
732
683
  ENV AKAN_PUBLIC_OPERATION_MODE=cloud
684
+ ENV AKAN_DATABASE_MODES=${this.database.modes.join(",")}
733
685
  ENV AKAN_LOG_TO_FILE=0
734
686
  ${webEnvLines}
735
687
  CMD [${command.map((c) => `"${c}"`).join(",")}]`;
@@ -771,17 +723,36 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
771
723
  if (rootVersion)
772
724
  return rootVersion;
773
725
  const akanPackageJson = getAkanPackageJson();
774
- return akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
726
+ const version = akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
727
+ if (!version)
728
+ throw new Error(`Dependency ${lib} not found in package.json`);
729
+ return version;
775
730
  }
776
731
  #getProductionRuntimePackages() {
777
- return [...this.externalLibs, ...SSR_RUNTIME_PACKAGES, ...this.getDatabaseModeRuntimePackages()];
732
+ return [
733
+ ...this.externalLibs,
734
+ ...SSR_RUNTIME_PACKAGES,
735
+ ...this.database.modes.flatMap((mode) => this.getDatabaseModeRuntimePackages(mode))
736
+ ];
778
737
  }
779
- getDatabaseModeRuntimePackages(databaseMode = this.defaultDatabaseMode) {
780
- return [...DATABASE_MODE_RUNTIME_PACKAGES[databaseMode]];
738
+ getDatabaseModeRuntimePackages(databaseMode) {
739
+ return [...DatabaseModes.drivers[databaseMode]];
781
740
  }
782
- getMissingDatabaseModeDependencySpecs(databaseMode = this.defaultDatabaseMode) {
741
+ getMissingDatabaseModeDependencySpecs(databaseMode) {
783
742
  return this.#getMissingDependencySpecs(this.getDatabaseModeRuntimePackages(databaseMode));
784
743
  }
744
+ resolveDatabaseMode() {
745
+ return DatabaseModes.resolve({
746
+ requested: process.env.AKAN_DATABASE_MODE,
747
+ declared: this.database.modes.join(","),
748
+ local: true
749
+ });
750
+ }
751
+ static #database(app, config) {
752
+ const declared = config?.database?.modes?.filter((mode) => !!mode);
753
+ const modes = declared?.length ? declared : ["single"];
754
+ return { modes: DatabaseModes.parseList(modes.join(","), `database.modes in apps/${app.name}/akan.config.ts`) };
755
+ }
785
756
  getMobileRuntimePackages() {
786
757
  return [...new Set([...MOBILE_RUNTIME_PACKAGES, ...MOBILE_APP_CAPACITOR_PLUGINS])];
787
758
  }
@@ -796,12 +767,10 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
796
767
  ...this.rootPackageJson.dependencies,
797
768
  ...this.rootPackageJson.devDependencies
798
769
  };
799
- return libs.filter((lib) => !rootDependencies[lib]).map((lib) => {
800
- const version = this.#resolveProductionDependencyVersion(lib);
801
- if (!version)
802
- throw new Error(`Dependency ${lib} not found in package.json`);
803
- return `${lib}@${version}`;
804
- });
770
+ return libs.filter((lib) => !rootDependencies[lib]).map((lib) => `${lib}@${this.#resolveProductionDependencyVersion(lib)}`);
771
+ }
772
+ get akanVersion() {
773
+ return getAkanPackageJson().version;
805
774
  }
806
775
  getProductionPackageJson(data = {}) {
807
776
  return {
@@ -809,12 +778,10 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
809
778
  description: this.app.name,
810
779
  version: "1.0.0",
811
780
  main: "./main.js",
812
- dependencies: Object.fromEntries([...new Set(this.#getProductionRuntimePackages())].map((lib) => {
813
- const version = this.#resolveProductionDependencyVersion(lib);
814
- if (!version)
815
- throw new Error(`Dependency ${lib} not found in package.json`);
816
- return [lib, version];
817
- })),
781
+ dependencies: Object.fromEntries([...new Set(this.#getProductionRuntimePackages())].map((lib) => [
782
+ lib,
783
+ this.#resolveProductionDependencyVersion(lib)
784
+ ])),
818
785
  ...data
819
786
  };
820
787
  }
@@ -880,22 +847,15 @@ class AkanLibConfig {
880
847
  }
881
848
  }
882
849
  //! need to refactor
883
- var increaseBuildNum = async (app) => {
884
- const appConfig = await AkanAppConfig.from(app);
885
- const akanConfigPath = path2.join(app.cwdPath, "akan.config.ts");
886
- const akanConfig = fs.readFileSync(akanConfigPath, "utf8");
887
- const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum + 1}`);
888
- fs.writeFileSync(akanConfigPath, akanConfigContent);
889
- };
890
- var decreaseBuildNum = async (app) => {
891
- const appConfig = await AkanAppConfig.from(app);
850
+ var shiftBuildNum = async (app, delta) => {
851
+ const { buildNum } = (await AkanAppConfig.from(app)).mobile;
892
852
  const akanConfigPath = path2.join(app.cwdPath, "akan.config.ts");
893
853
  const akanConfig = fs.readFileSync(akanConfigPath, "utf8");
894
- const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum - 1}`);
895
- fs.writeFileSync(akanConfigPath, akanConfigContent);
854
+ fs.writeFileSync(akanConfigPath, akanConfig.replace(`buildNum: ${buildNum}`, `buildNum: ${buildNum + delta}`));
896
855
  };
856
+ var increaseBuildNum = async (app) => await shiftBuildNum(app, 1);
857
+ var decreaseBuildNum = async (app) => await shiftBuildNum(app, -1);
897
858
  // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
898
- import { mkdir as mkdir2 } from "fs/promises";
899
859
  import path4 from "path";
900
860
 
901
861
  // pkgs/@akanjs/devkit/transforms/asyncDefaultExportDetector.ts
@@ -912,7 +872,7 @@ class AsyncDefaultExportDetector {
912
872
  try {
913
873
  const typescript = await AsyncDefaultExportDetector.#loadTypescript();
914
874
  const source = fs2.readFileSync(path3.resolve(moduleAbsPath), "utf8");
915
- const sourceFile = typescript.createSourceFile(moduleAbsPath, source, typescript.ScriptTarget.Latest, true, AsyncDefaultExportDetector.#scriptKind(typescript, moduleAbsPath));
875
+ const sourceFile = typescript.createSourceFile(moduleAbsPath, source, typescript.ScriptTarget.Latest, true, /\.[tj]sx$/.test(moduleAbsPath) ? typescript.ScriptKind.TSX : typescript.ScriptKind.TS);
916
876
  return new AsyncDefaultExportDetector(typescript).detectInSourceFile(sourceFile);
917
877
  } catch {
918
878
  return false;
@@ -954,8 +914,7 @@ class AsyncDefaultExportDetector {
954
914
  continue;
955
915
  }
956
916
  if (ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
957
- const exportClause = statement.exportClause;
958
- for (const specifier of exportClause.elements) {
917
+ for (const specifier of statement.exportClause.elements) {
959
918
  if (specifier.name.text !== "default")
960
919
  continue;
961
920
  defaultIdentifier = specifier.propertyName?.text ?? specifier.name.text;
@@ -972,29 +931,25 @@ class AsyncDefaultExportDetector {
972
931
  const ts = this.#ts;
973
932
  return Boolean(node && (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) && this.#hasModifier(node, ts.SyntaxKind.AsyncKeyword));
974
933
  }
975
- static #scriptKind(typescript, moduleAbsPath) {
976
- return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? typescript.ScriptKind.TSX : typescript.ScriptKind.TS;
977
- }
978
934
  }
979
935
 
980
936
  // pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
981
937
  var LAYOUT_KEY_RE = /^\.\/(.+\/)?_layout\.(tsx|ts|jsx|js)$/;
982
- async function appHasStModule(appCwdPath) {
983
- return Bun.file(path4.join(appCwdPath, "lib", "st.ts")).exists();
984
- }
985
938
  var IMPLICIT_LAYOUT_DIR = path4.join(".akan", "generated", "root-layouts");
986
939
  var IMPLICIT_DICT_DIR = path4.join(".akan", "generated", "dict");
987
940
  var IMPLICIT_OVERRIDES_DIR = path4.join(".akan", "generated", "overrides");
988
941
  var OVERRIDES_KEY_RE = /^\.\/(.+\/)?_overrides\.(tsx|ts|jsx|js)$/;
942
+ var importSpecifier = (fromAbsPath, toAbsPath) => {
943
+ const rel = path4.relative(path4.dirname(fromAbsPath), toAbsPath).split(path4.sep).join("/");
944
+ return rel.startsWith(".") ? rel : `./${rel}`;
945
+ };
989
946
  async function writeGeneratedOverridesLayoutFile(opts) {
990
947
  const filename = `${opts.key.replace(/^\.\//, "").replace(/[^a-zA-Z0-9]+/g, "_")}.tsx`;
991
948
  const absPath = path4.join(path4.resolve(opts.appCwdPath), IMPLICIT_OVERRIDES_DIR, filename);
992
- const userRel = path4.relative(path4.dirname(absPath), opts.userAbsPath).split(path4.sep).join("/");
993
- const userSpecifier = userRel.startsWith(".") ? userRel : `./${userRel}`;
994
949
  const source = `"use client";
995
950
  import { UiOverrideProvider } from "akanjs/ui";
996
951
  import { createElement, type ReactNode } from "react";
997
- import value from ${JSON.stringify(userSpecifier)};
952
+ import value from ${JSON.stringify(importSpecifier(absPath, opts.userAbsPath))};
998
953
 
999
954
  export default function AkanUiOverridesLayout({ children }: { children?: ReactNode }) {
1000
955
  return createElement(UiOverrideProvider, { value }, children);
@@ -1019,9 +974,6 @@ function implicitRootLayoutAbsPath(appCwdPath, segments) {
1019
974
  const filename = segments.length ? `${segments.join("__")}__root_layout.tsx` : "__root_layout.tsx";
1020
975
  return path4.join(path4.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
1021
976
  }
1022
- function implicitDictionaryMacroAbsPath(appCwdPath) {
1023
- return path4.join(path4.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
1024
- }
1025
977
  function isRootBoundarySegments(segments, basePaths) {
1026
978
  const firstVisibleIndex = segments.findIndex((segment) => !/^\(.+\)$/.test(segment));
1027
979
  if (firstVisibleIndex === -1)
@@ -1047,10 +999,8 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
1047
999
  segments
1048
1000
  });
1049
1001
  }
1050
- const hasExplicitRootBoundary = [...boundaries.values()].some((boundary) => boundary.segments.length === 0);
1051
- if (!hasExplicitRootBoundary && boundaries.size === 0) {
1002
+ if (boundaries.size === 0)
1052
1003
  boundaries.set("", { sourceKey: null, sourceAbsPath: null, segments: [] });
1053
- }
1054
1004
  return [...boundaries.values()].sort((a, b) => a.segments.join("/").localeCompare(b.segments.join("/")));
1055
1005
  }
1056
1006
  function hasAncestorRootBoundary(boundary, boundaries) {
@@ -1063,10 +1013,6 @@ function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
1063
1013
  });
1064
1014
  return rootLayoutKey ? path4.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
1065
1015
  }
1066
- function routePrefixForSegments(segments) {
1067
- const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
1068
- return visible[0] ?? null;
1069
- }
1070
1016
  async function assertEnvClientConvention(appCwdPath, appName) {
1071
1017
  const envPath = path4.join(appCwdPath, "env", "env.client.ts");
1072
1018
  if (!await Bun.file(envPath).exists()) {
@@ -1074,8 +1020,7 @@ async function assertEnvClientConvention(appCwdPath, appName) {
1074
1020
  }
1075
1021
  }
1076
1022
  async function writeGeneratedDictionaryMacroFile(appCwdPath, appName) {
1077
- const absPath = implicitDictionaryMacroAbsPath(appCwdPath);
1078
- await mkdir2(path4.dirname(absPath), { recursive: true });
1023
+ const absPath = path4.join(path4.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
1079
1024
  await Bun.write(absPath, `import { getAllDictionary } from "@apps/${appName}/lib/dict" with { type: "macro" };
1080
1025
 
1081
1026
  export const allDictionary = getAllDictionary();
@@ -1086,14 +1031,10 @@ async function writeGeneratedRootLayoutFile(opts) {
1086
1031
  await assertEnvClientConvention(opts.appCwdPath, opts.appName);
1087
1032
  const dictMacroAbsPath = opts.includeSystemProvider ? await writeGeneratedDictionaryMacroFile(opts.appCwdPath, opts.appName) : null;
1088
1033
  const absPath = implicitRootLayoutAbsPath(opts.appCwdPath, opts.boundary.segments);
1089
- await mkdir2(path4.dirname(absPath), { recursive: true });
1090
- const dictMacroRel = dictMacroAbsPath ? path4.relative(path4.dirname(absPath), dictMacroAbsPath).split(path4.sep).join("/") : null;
1091
- const dictMacroSpecifier = dictMacroRel ? dictMacroRel.startsWith(".") ? dictMacroRel : `./${dictMacroRel}` : null;
1092
- const sourceRel = opts.boundary.sourceAbsPath ? path4.relative(path4.dirname(absPath), opts.boundary.sourceAbsPath).split(path4.sep).join("/") : null;
1093
- const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
1034
+ const dictMacroSpecifier = dictMacroAbsPath ? importSpecifier(absPath, dictMacroAbsPath) : null;
1035
+ const sourceSpecifier = opts.boundary.sourceAbsPath ? importSpecifier(absPath, opts.boundary.sourceAbsPath) : null;
1094
1036
  const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
1095
- const inheritedSourceRel = inheritedSourceAbsPath ? path4.relative(path4.dirname(absPath), inheritedSourceAbsPath).split(path4.sep).join("/") : null;
1096
- const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
1037
+ const inheritedSourceSpecifier = inheritedSourceAbsPath ? importSpecifier(absPath, inheritedSourceAbsPath) : null;
1097
1038
  const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
1098
1039
  void st;
1099
1040
  ` : `import "@apps/${opts.appName}/client";
@@ -1103,7 +1044,7 @@ void st;
1103
1044
  const inheritedLayout = resolveRouteModule(inheritedModule as never, ${JSON.stringify(inheritedLabel)}).module as LayoutModule;
1104
1045
  ` : `const inheritedLayout: LayoutModule = {};
1105
1046
  `;
1106
- const prefix = routePrefixForSegments(opts.boundary.segments);
1047
+ const prefix = opts.boundary.segments.find((segment) => !/^\(.+\)$/.test(segment)) ?? null;
1107
1048
  const userLabel = opts.boundary.sourceAbsPath ? path4.relative(opts.appCwdPath, opts.boundary.sourceAbsPath) : "";
1108
1049
  const userImport = sourceSpecifier ? `import * as userModule from ${JSON.stringify(sourceSpecifier)};
1109
1050
  const userLayout = resolveRouteModule(userModule as never, ${JSON.stringify(userLabel)}).module as LayoutModule;
@@ -1121,6 +1062,19 @@ const userLayout: LayoutModule = {};
1121
1062
  ` : "";
1122
1063
  const layoutChild = isAsyncUserLayout ? "{layout}" : userLayoutElement;
1123
1064
  const layoutReturn = isAsyncUserLayout ? "layout" : userLayoutElement;
1065
+ const layoutExports = `export async function generateHead(props: PageProps) {
1066
+ if (userLayout.generateHead) return userLayout.generateHead(props);
1067
+ if (userLayout.head !== undefined) return userLayout.head;
1068
+ if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
1069
+ return inheritedLayout.head;
1070
+ }
1071
+
1072
+ export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1073
+ export const Error = userLayout.Error ?? inheritedLayout.Error;
1074
+ export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
1075
+
1076
+ ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
1077
+ ${layoutBinding} return `;
1124
1078
  const source = opts.includeSystemProvider ? `import type { LayoutModule, LayoutProps, PageProps } from "akanjs/client";
1125
1079
  import { loadFonts, resolveRouteModule } from "akanjs/client";
1126
1080
  import type { ReactNode } from "react";
@@ -1134,26 +1088,7 @@ if (defaultFonts.length > 1) throw new Error("[route-convention] only one defaul
1134
1088
  const defaultFont = defaultFonts[0];
1135
1089
  const defaultFontClassName = defaultFont ? (defaultFont.className ?? \`font-\${defaultFont.name}\`) : undefined;
1136
1090
 
1137
- export async function generateHead(props: PageProps) {
1138
- if (userLayout.generateHead) return userLayout.generateHead(props);
1139
- if (userLayout.head !== undefined) return userLayout.head;
1140
- if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
1141
- return inheritedLayout.head;
1142
- }
1143
-
1144
- export async function generateMetadata(props: PageProps) {
1145
- if (userLayout.generateMetadata) return userLayout.generateMetadata(props);
1146
- if (userLayout.metadata !== undefined) return userLayout.metadata;
1147
- if (inheritedLayout.generateMetadata) return inheritedLayout.generateMetadata(props);
1148
- return inheritedLayout.metadata;
1149
- }
1150
-
1151
- export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1152
- export const Error = userLayout.Error ?? inheritedLayout.Error;
1153
- export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
1154
-
1155
- ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
1156
- ${layoutBinding} return (
1091
+ ${layoutExports}(
1157
1092
  <System.Provider
1158
1093
  of={GeneratedLayout as never}
1159
1094
  appName=${JSON.stringify(opts.appName)}
@@ -1164,7 +1099,6 @@ ${layoutBinding} return (
1164
1099
  theme={userLayout.theme ?? inheritedLayout.theme}
1165
1100
  fonts={loadFonts(userFonts)}
1166
1101
  className={defaultFontClassName}
1167
- gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
1168
1102
  layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
1169
1103
  reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
1170
1104
  wsConnect={userLayout.wsConnect ?? inheritedLayout.wsConnect ?? true}
@@ -1178,26 +1112,7 @@ ${layoutBinding} return (
1178
1112
  import { resolveRouteModule } from "akanjs/client";
1179
1113
  import type { ReactNode } from "react";
1180
1114
  ${inheritedImport}${userImport}
1181
- export async function generateHead(props: PageProps) {
1182
- if (userLayout.generateHead) return userLayout.generateHead(props);
1183
- if (userLayout.head !== undefined) return userLayout.head;
1184
- if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
1185
- return inheritedLayout.head;
1186
- }
1187
-
1188
- export async function generateMetadata(props: PageProps) {
1189
- if (userLayout.generateMetadata) return userLayout.generateMetadata(props);
1190
- if (userLayout.metadata !== undefined) return userLayout.metadata;
1191
- if (inheritedLayout.generateMetadata) return inheritedLayout.generateMetadata(props);
1192
- return inheritedLayout.metadata;
1193
- }
1194
-
1195
- export const NotFound = userLayout.NotFound ?? inheritedLayout.NotFound;
1196
- export const Error = userLayout.Error ?? inheritedLayout.Error;
1197
- export const pageConfig = userLayout.pageConfig ?? inheritedLayout.pageConfig;
1198
-
1199
- ${layoutSignature}({ children, params, searchParams }: LayoutProps) {
1200
- ${layoutBinding} return ${layoutReturn};
1115
+ ${layoutExports}${layoutReturn};
1201
1116
  }
1202
1117
  `;
1203
1118
  await Bun.write(absPath, source);
@@ -1205,7 +1120,7 @@ ${layoutBinding} return ${layoutReturn};
1205
1120
  }
1206
1121
  async function resolveSsrPageEntries(opts) {
1207
1122
  const absPageDir = path4.resolve(opts.appCwdPath, "page");
1208
- const hasSt = await appHasStModule(opts.appCwdPath);
1123
+ const hasSt = await Bun.file(path4.join(opts.appCwdPath, "lib", "st.ts")).exists();
1209
1124
  const basePaths = opts.basePaths ?? [];
1210
1125
  const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
1211
1126
  const rootBoundaries = findRootBoundaries(opts.pageKeys, opts.appCwdPath, basePaths);
@@ -1237,9 +1152,7 @@ async function resolveSsrPageEntries(opts) {
1237
1152
  }),
1238
1153
  seedAbsPaths: [...new Set([boundary.sourceAbsPath, rootSourceAbsPath].filter((absPath) => absPath !== null))]
1239
1154
  })));
1240
- const entries = [...base, ...generated];
1241
- entries.sort((a, b) => a.key.localeCompare(b.key));
1242
- return entries;
1155
+ return [...base, ...generated].sort((a, b) => a.key.localeCompare(b.key));
1243
1156
  }
1244
1157
  async function resolveSsrPageEntriesForApp(app, pageKeys) {
1245
1158
  const config = await app.getConfig();
@@ -1299,15 +1212,24 @@ var asBiomeReport = (candidate) => {
1299
1212
  }
1300
1213
  };
1301
1214
  var BIOME_CONFIG_FILES = ["biome.json", "biome.jsonc"];
1215
+ var emptyResult = (filePath) => ({
1216
+ filePath,
1217
+ messages: [],
1218
+ errorCount: 0,
1219
+ warningCount: 0,
1220
+ fixableErrorCount: 0,
1221
+ fixableWarningCount: 0
1222
+ });
1302
1223
 
1303
1224
  class Linter {
1225
+ static biomeBinName = process.platform === "win32" ? "biome.exe" : "biome";
1304
1226
  lintRoot;
1305
1227
  configPath;
1306
1228
  #biomeBin;
1307
1229
  constructor(cwdPath) {
1308
1230
  this.lintRoot = this.#findBiomeRootPath(cwdPath);
1309
1231
  this.configPath = Linter.#configPathIn(this.lintRoot) ?? path5.join(this.lintRoot, "biome.json");
1310
- const localBiomeBin = path5.join(this.lintRoot, "node_modules/.bin/biome");
1232
+ const localBiomeBin = path5.join(this.lintRoot, "node_modules", ".bin", Linter.biomeBinName);
1311
1233
  this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
1312
1234
  }
1313
1235
  static #configPathIn(dir) {
@@ -1379,14 +1301,7 @@ class Linter {
1379
1301
  if (diagnostic.severity !== "error" && diagnostic.severity !== "warning")
1380
1302
  continue;
1381
1303
  const diagnosticFilePath = this.#diagnosticFilePath(diagnostic, filePath);
1382
- const result = resultsByPath.get(diagnosticFilePath) ?? {
1383
- filePath: diagnosticFilePath,
1384
- messages: [],
1385
- errorCount: 0,
1386
- warningCount: 0,
1387
- fixableErrorCount: 0,
1388
- fixableWarningCount: 0
1389
- };
1304
+ const result = resultsByPath.get(diagnosticFilePath) ?? emptyResult(diagnosticFilePath);
1390
1305
  const message = this.#createLintMessage(diagnostic);
1391
1306
  result.messages.push(message);
1392
1307
  if (message.severity === 2)
@@ -1396,14 +1311,7 @@ class Linter {
1396
1311
  resultsByPath.set(diagnosticFilePath, result);
1397
1312
  }
1398
1313
  return [
1399
- resultsByPath.get(filePath) ?? {
1400
- filePath,
1401
- messages: [],
1402
- errorCount: 0,
1403
- warningCount: 0,
1404
- fixableErrorCount: 0,
1405
- fixableWarningCount: 0
1406
- },
1314
+ resultsByPath.get(filePath) ?? emptyResult(filePath),
1407
1315
  ...[...resultsByPath.entries()].filter(([resultPath]) => resultPath !== filePath).map(([, result]) => result)
1408
1316
  ];
1409
1317
  }
@@ -1513,12 +1421,7 @@ ${errorText}, ${warningText} found`];
1513
1421
  warningCount: acc.warningCount + result.warningCount,
1514
1422
  fixableErrorCount: acc.fixableErrorCount + result.fixableErrorCount,
1515
1423
  fixableWarningCount: acc.fixableWarningCount + result.fixableWarningCount
1516
- }), {
1517
- errorCount: 0,
1518
- warningCount: 0,
1519
- fixableErrorCount: 0,
1520
- fixableWarningCount: 0
1521
- });
1424
+ }), { errorCount: 0, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0 });
1522
1425
  return { results, details, stats };
1523
1426
  }
1524
1427
  async hasNoLintErrors(filePath) {
@@ -1576,12 +1479,9 @@ ${errorText}, ${warningText} found`];
1576
1479
  async getProblematicRules(filePath) {
1577
1480
  const { results } = await this.lintFile(filePath);
1578
1481
  const ruleCounts = {};
1579
- results.forEach((result) => {
1580
- result.messages.forEach((message) => {
1581
- if (message.ruleId)
1582
- ruleCounts[message.ruleId] = (ruleCounts[message.ruleId] || 0) + 1;
1583
- });
1584
- });
1482
+ for (const message of results.flatMap((result) => result.messages))
1483
+ if (message.ruleId)
1484
+ ruleCounts[message.ruleId] = (ruleCounts[message.ruleId] || 0) + 1;
1585
1485
  return ruleCounts;
1586
1486
  }
1587
1487
  }
@@ -1691,10 +1591,8 @@ var isAllowedLibFacetRootFile = (filename) => libFacetRootAllowedFiles.has(filen
1691
1591
  var isScannedRootEntry = (type, name) => !name.startsWith(".") || rootAllowedDirs[type].has(name);
1692
1592
 
1693
1593
  // pkgs/@akanjs/devkit/scanInfo.ts
1694
- var databaseFileTypes = [
1695
- "constant",
1594
+ var serviceFileTypes = [
1696
1595
  "dictionary",
1697
- "document",
1698
1596
  "service",
1699
1597
  "signal",
1700
1598
  "store",
@@ -1704,6 +1602,9 @@ var databaseFileTypes = [
1704
1602
  "view",
1705
1603
  "zone"
1706
1604
  ];
1605
+ var databaseFileTypes = ["constant", "dictionary", "document", ...serviceFileTypes.slice(1)];
1606
+ var uiFileTypes = new Set(["template", "unit", "util", "view", "zone"]);
1607
+ var fileTypeOf = (filename) => databaseFileTypes.find((type) => filename.endsWith(uiFileTypes.has(type) ? `.${type[0].toUpperCase()}${type.slice(1)}.tsx` : `.${type}.ts`));
1707
1608
  var generatedRootCapacitorConfigFiles = ["capacitor.config.js", "capacitor.config.json"];
1708
1609
  var internalLibDirs = new Set(["__lib", "__scalar"]);
1709
1610
  var moduleNonUiFileTypes = {
@@ -1716,9 +1617,7 @@ var moduleUiFileTypes = {
1716
1617
  service: new Set(["Util", "Zone"]),
1717
1618
  scalar: new Set(["Template", "Unit"])
1718
1619
  };
1719
- var testFilePattern = /\.(test|spec)\.(ts|tsx)$/;
1720
- var createDependencyScanner = async (exec) => (await import("./dependencyScanner-shs82ynp.js")).TypeScriptDependencyScanner.from(exec);
1721
- var isAllowedTestFile = (filename) => testFilePattern.test(filename);
1620
+ var createDependencyScanner = async (exec) => (await import("./dependencyScanner-ye2e6pdz.js")).TypeScriptDependencyScanner.from(exec);
1722
1621
  var getScanPath = (exec, relativePath) => path7.posix.join(`${exec.type}s`, exec.name, relativePath.split(path7.sep).join("/"));
1723
1622
  async function clearGeneratedRootCapacitorConfigs(exec) {
1724
1623
  if (exec.type !== "app")
@@ -1738,21 +1637,21 @@ async function assertScanConvention(exec, libRoot) {
1738
1637
  const allowedRootFiles = rootAllowedFiles[exec.type];
1739
1638
  const allowedRootDirs = rootAllowedDirs[exec.type];
1740
1639
  const { files, dirs } = await exec.getFilesAndDirs(".");
1741
- files.filter((filename) => !allowedRootFiles.has(filename)).forEach((filename) => {
1742
- addViolation(filename, `unsupported ${exec.type} root file`);
1743
- });
1744
- dirs.filter((dirname) => !allowedRootDirs.has(dirname)).forEach((dirname) => {
1745
- addViolation(dirname, `unsupported ${exec.type} root folder`);
1746
- });
1640
+ for (const filename of files)
1641
+ if (!allowedRootFiles.has(filename))
1642
+ addViolation(filename, `unsupported ${exec.type} root file`);
1643
+ for (const dirname of dirs)
1644
+ if (!allowedRootDirs.has(dirname))
1645
+ addViolation(dirname, `unsupported ${exec.type} root folder`);
1747
1646
  if (exec.type === "lib")
1748
1647
  for (const { relativePath, reason } of await exec.getPageConventionViolations())
1749
1648
  addViolation(relativePath, reason);
1750
- libRoot.files.filter((filename) => !isAllowedLibFacetRootFile(filename)).forEach((filename) => {
1751
- addViolation(path7.join("lib", filename), "unsupported lib facet root file");
1752
- });
1753
- libRoot.dirs.filter((dirname) => dirname.startsWith("__") && !internalLibDirs.has(dirname)).forEach((dirname) => {
1754
- addViolation(path7.join("lib", dirname), "unsupported internal lib folder");
1755
- });
1649
+ for (const filename of libRoot.files)
1650
+ if (!isAllowedLibFacetRootFile(filename))
1651
+ addViolation(path7.join("lib", filename), "unsupported lib facet root file");
1652
+ for (const dirname of libRoot.dirs)
1653
+ if (dirname.startsWith("__") && !internalLibDirs.has(dirname))
1654
+ addViolation(path7.join("lib", dirname), "unsupported internal lib folder");
1756
1655
  const databaseDirs = libRoot.dirs.filter((dirname) => !dirname.startsWith("_"));
1757
1656
  const serviceDirs = libRoot.dirs.filter((dirname) => dirname.startsWith("_") && !dirname.startsWith("__"));
1758
1657
  const scalarDirs = await exec.readdir("lib/__scalar");
@@ -1774,38 +1673,25 @@ async function validateModuleFiles(exec, violations, kind, modulePath) {
1774
1673
  violations.push(`${getScanPath(exec, path7.join(modulePath, dirname))}: unsupported module folder`);
1775
1674
  });
1776
1675
  const uiModuleName = moduleName[0].toUpperCase() + moduleName.slice(1);
1777
- files.forEach((filename) => {
1778
- const filePath = path7.join(modulePath, filename);
1779
- if (filename === "index.ts" || filename === "index.tsx" || isAllowedTestFile(filename))
1780
- return;
1676
+ for (const filename of files) {
1677
+ const scanPath = getScanPath(exec, path7.join(modulePath, filename));
1678
+ if (filename === "index.ts" || filename === "index.tsx" || /\.(test|spec)\.(ts|tsx)$/.test(filename))
1679
+ continue;
1781
1680
  if (filename === `${moduleName}.abstract.md`)
1782
- return;
1681
+ continue;
1783
1682
  const uiMatch = filename.match(/^([A-Z][A-Za-z0-9]+)\.([A-Z][A-Za-z0-9]*)\.tsx$/);
1784
- if (uiMatch) {
1785
- const fileModuleName = uiMatch[1];
1786
- const fileType = uiMatch[2];
1787
- if (fileModuleName !== uiModuleName) {
1788
- violations.push(`${getScanPath(exec, filePath)}: module name mismatch: expected '${uiModuleName}', got '${fileModuleName}'`);
1789
- }
1790
- if (!moduleUiFileTypes[kind].has(fileType)) {
1791
- violations.push(`${getScanPath(exec, filePath)}: unsupported ${kind} UI file`);
1792
- }
1793
- return;
1794
- }
1795
- const nonUiMatch = filename.match(/^([a-z][a-zA-Z0-9]*)\.([a-z][a-z0-9]*)\.ts$/);
1796
- if (nonUiMatch) {
1797
- const fileModuleName = nonUiMatch[1];
1798
- const fileType = nonUiMatch[2];
1799
- if (fileModuleName !== moduleName) {
1800
- violations.push(`${getScanPath(exec, filePath)}: module name mismatch: expected '${moduleName}', got '${fileModuleName}'`);
1801
- }
1802
- if (!moduleNonUiFileTypes[kind].has(fileType)) {
1803
- violations.push(`${getScanPath(exec, filePath)}: unsupported ${kind} file`);
1804
- }
1805
- return;
1683
+ const match = uiMatch ?? filename.match(/^([a-z][a-zA-Z0-9]*)\.([a-z][a-z0-9]*)\.ts$/);
1684
+ if (!match) {
1685
+ violations.push(`${scanPath}: unsupported module file`);
1686
+ continue;
1806
1687
  }
1807
- violations.push(`${getScanPath(exec, filePath)}: unsupported module file`);
1808
- });
1688
+ const [, fileModuleName, fileType] = match;
1689
+ const expectedName = uiMatch ? uiModuleName : moduleName;
1690
+ if (fileModuleName !== expectedName)
1691
+ violations.push(`${scanPath}: module name mismatch: expected '${expectedName}', got '${fileModuleName}'`);
1692
+ if (!(uiMatch ? moduleUiFileTypes : moduleNonUiFileTypes)[kind].has(fileType))
1693
+ violations.push(`${scanPath}: unsupported ${kind}${uiMatch ? " UI" : ""} file`);
1694
+ }
1809
1695
  }
1810
1696
 
1811
1697
  class ScanInfo {
@@ -1853,79 +1739,17 @@ class ScanInfo {
1853
1739
  } else
1854
1740
  databaseDirs.push(name);
1855
1741
  });
1742
+ const collect = async (dir, name, kind) => {
1743
+ for (const filename of await exec.readdir(dir)) {
1744
+ const type = fileTypeOf(filename);
1745
+ if (type)
1746
+ files[type][kind]?.push(name);
1747
+ }
1748
+ };
1856
1749
  await Promise.all([
1857
- ...databaseDirs.map(async (name) => {
1858
- const filenames = await exec.readdir(path7.join("lib", name));
1859
- filenames.forEach((filename) => {
1860
- if (filename.endsWith(".constant.ts"))
1861
- files.constant.databases.push(name);
1862
- else if (filename.endsWith(".dictionary.ts"))
1863
- files.dictionary.databases.push(name);
1864
- else if (filename.endsWith(".document.ts"))
1865
- files.document.databases.push(name);
1866
- else if (filename.endsWith(".service.ts"))
1867
- files.service.databases.push(name);
1868
- else if (filename.endsWith(".signal.ts"))
1869
- files.signal.databases.push(name);
1870
- else if (filename.endsWith(".store.ts"))
1871
- files.store.databases.push(name);
1872
- else if (filename.endsWith(".Template.tsx"))
1873
- files.template.databases.push(name);
1874
- else if (filename.endsWith(".Unit.tsx"))
1875
- files.unit.databases.push(name);
1876
- else if (filename.endsWith(".Util.tsx"))
1877
- files.util.databases.push(name);
1878
- else if (filename.endsWith(".View.tsx"))
1879
- files.view.databases.push(name);
1880
- else if (filename.endsWith(".Zone.tsx"))
1881
- files.zone.databases.push(name);
1882
- });
1883
- }),
1884
- ...serviceDirs.map(async (dirname) => {
1885
- const name = dirname.slice(1);
1886
- const filenames = await exec.readdir(path7.join("lib", dirname));
1887
- filenames.forEach((filename) => {
1888
- if (filename.endsWith(".dictionary.ts"))
1889
- files.dictionary.services.push(name);
1890
- else if (filename.endsWith(".service.ts"))
1891
- files.service.services.push(name);
1892
- else if (filename.endsWith(".signal.ts"))
1893
- files.signal.services.push(name);
1894
- else if (filename.endsWith(".store.ts"))
1895
- files.store.services.push(name);
1896
- else if (filename.endsWith(".Template.tsx"))
1897
- files.template.services.push(name);
1898
- else if (filename.endsWith(".Unit.tsx"))
1899
- files.unit.services.push(name);
1900
- else if (filename.endsWith(".Util.tsx"))
1901
- files.util.services.push(name);
1902
- else if (filename.endsWith(".View.tsx"))
1903
- files.view.services.push(name);
1904
- else if (filename.endsWith(".Zone.tsx"))
1905
- files.zone.services.push(name);
1906
- });
1907
- }),
1908
- ...scalarDirs.map(async (name) => {
1909
- const filenames = await exec.readdir(path7.join("lib/__scalar", name));
1910
- filenames.forEach((filename) => {
1911
- if (filename.endsWith(".constant.ts"))
1912
- files.constant.scalars.push(name);
1913
- else if (filename.endsWith(".dictionary.ts"))
1914
- files.dictionary.scalars.push(name);
1915
- else if (filename.endsWith(".document.ts"))
1916
- files.document.scalars.push(name);
1917
- else if (filename.endsWith(".Template.tsx"))
1918
- files.template.scalars.push(name);
1919
- else if (filename.endsWith(".Unit.tsx"))
1920
- files.unit.scalars.push(name);
1921
- else if (filename.endsWith(".Util.tsx"))
1922
- files.util.scalars.push(name);
1923
- else if (filename.endsWith(".View.tsx"))
1924
- files.view.scalars.push(name);
1925
- else if (filename.endsWith(".Zone.tsx"))
1926
- files.zone.scalars.push(name);
1927
- });
1928
- })
1750
+ ...databaseDirs.map((name) => collect(path7.join("lib", name), name, "databases")),
1751
+ ...serviceDirs.map((dirname) => collect(path7.join("lib", dirname), dirname.slice(1), "services")),
1752
+ ...scalarDirs.map((name) => collect(path7.join("lib/__scalar", name), name, "scalars"))
1929
1753
  ]);
1930
1754
  const routes = exec.type === "lib" ? [] : await exec.getPageKeys();
1931
1755
  const common = {
@@ -1946,31 +1770,14 @@ class ScanInfo {
1946
1770
  constructor(scanResult) {
1947
1771
  this.name = scanResult.name;
1948
1772
  this.scanResult = scanResult;
1949
- Object.entries(scanResult.files).forEach(([_key, value]) => {
1950
- const key = _key;
1951
- const { databases, services, scalars } = value;
1952
- databases.forEach((modelName) => {
1953
- const model = this.database.get(modelName) ?? new Set;
1954
- model.add(key);
1955
- this.database.set(modelName, model);
1956
- this.file[key].all.add(modelName);
1957
- this.file[key].databases.add(modelName);
1958
- });
1959
- services?.forEach((serviceName) => {
1960
- const service = this.service.get(serviceName) ?? new Set;
1961
- service.add(key);
1962
- this.service.set(serviceName, service);
1963
- this.file[key].all.add(serviceName);
1964
- this.file[key].services.add(serviceName);
1965
- });
1966
- scalars?.forEach((scalarName) => {
1967
- const scalar = this.scalar.get(scalarName) ?? new Set;
1968
- scalar.add(key);
1969
- this.scalar.set(scalarName, scalar);
1970
- this.file[key].all.add(scalarName);
1971
- this.file[key].scalars.add(scalarName);
1972
- });
1973
- });
1773
+ const modulesOf = { databases: this.database, services: this.service, scalars: this.scalar };
1774
+ for (const [key, groups] of Object.entries(scanResult.files))
1775
+ for (const kind of ["databases", "services", "scalars"])
1776
+ for (const name of groups[kind] ?? []) {
1777
+ modulesOf[kind].set(name, (modulesOf[kind].get(name) ?? new Set).add(key));
1778
+ this.file[key].all.add(name);
1779
+ this.file[key][kind].add(name);
1780
+ }
1974
1781
  }
1975
1782
  getScanResult() {
1976
1783
  return this.scanResult;
@@ -1984,6 +1791,28 @@ class ScanInfo {
1984
1791
  getScalarModules() {
1985
1792
  return [...this.scalar.keys()];
1986
1793
  }
1794
+ #sortedLibs = null;
1795
+ sortedLibs(libDeps) {
1796
+ if (this.#sortedLibs)
1797
+ return this.#sortedLibs;
1798
+ const libIndices = LibInfo.getSortedLibIndices();
1799
+ this.#sortedLibs = libDeps.sort((libNameA, libNameB) => {
1800
+ const indexA = libIndices.get(libNameA);
1801
+ const indexB = libIndices.get(libNameB);
1802
+ if (indexA === undefined || indexB === undefined)
1803
+ throw new Error(`LibInfo not found: ${libNameA} or ${libNameB}`);
1804
+ return indexA - indexB;
1805
+ });
1806
+ return this.#sortedLibs;
1807
+ }
1808
+ sortedLibInfos(libDeps) {
1809
+ return new Map(this.sortedLibs(libDeps).map((libName) => {
1810
+ const libInfo = LibInfo.libInfos.get(libName);
1811
+ if (!libInfo)
1812
+ throw new Error(`LibInfo not found: ${libName}`);
1813
+ return [libName, libInfo];
1814
+ }));
1815
+ }
1987
1816
  }
1988
1817
  var isAkanFrameworkDependency = (dep) => dep === "akanjs" || dep.startsWith("akanjs/");
1989
1818
 
@@ -2033,30 +1862,11 @@ class AppInfo extends ScanInfo {
2033
1862
  }));
2034
1863
  return [...libSet];
2035
1864
  }
2036
- #sortedLibs = null;
2037
- #getSortedLibs() {
2038
- if (this.#sortedLibs)
2039
- return this.#sortedLibs;
2040
- const libIndices = LibInfo.getSortedLibIndices();
2041
- this.#sortedLibs = this.libDeps.sort((libNameA, libNameB) => {
2042
- const indexA = libIndices.get(libNameA);
2043
- const indexB = libIndices.get(libNameB);
2044
- if (indexA === undefined || indexB === undefined)
2045
- throw new Error(`LibInfo not found: ${libNameA} or ${libNameB}`);
2046
- return indexA - indexB;
2047
- });
2048
- return this.#sortedLibs;
2049
- }
2050
1865
  getLibs() {
2051
- return this.#getSortedLibs();
1866
+ return this.sortedLibs(this.libDeps);
2052
1867
  }
2053
1868
  getLibInfos() {
2054
- return new Map(this.#getSortedLibs().map((libName) => {
2055
- const libInfo = LibInfo.libInfos.get(libName);
2056
- if (!libInfo)
2057
- throw new Error(`LibInfo not found: ${libName}`);
2058
- return [libName, libInfo];
2059
- }));
1869
+ return this.sortedLibInfos(this.libDeps);
2060
1870
  }
2061
1871
  }
2062
1872
 
@@ -2096,38 +1906,18 @@ class LibInfo extends ScanInfo {
2096
1906
  getScanResult() {
2097
1907
  return this.scanResult;
2098
1908
  }
2099
- #sortedLibs = null;
2100
- #getSortedLibs() {
2101
- if (this.#sortedLibs)
2102
- return this.#sortedLibs;
2103
- const libs = LibInfo.getSortedLibIndices();
2104
- this.#sortedLibs = this.scanResult.libDeps.sort((libNameA, libNameB) => {
2105
- const indexA = libs.get(libNameA);
2106
- const indexB = libs.get(libNameB);
2107
- if (indexA === undefined || indexB === undefined)
2108
- throw new Error(`LibInfo not found: ${libNameA} or ${libNameB}`);
2109
- return indexA - indexB;
2110
- });
2111
- return this.#sortedLibs;
2112
- }
2113
1909
  getLibs() {
2114
- return this.#getSortedLibs();
1910
+ return this.sortedLibs(this.scanResult.libDeps);
2115
1911
  }
2116
1912
  getLibInfo(libName) {
2117
1913
  if (!this.getScanResult().libDeps.includes(libName))
2118
1914
  return;
2119
- const libSet = new Set(this.#getSortedLibs());
2120
- if (!libSet.has(libName))
1915
+ if (!this.getLibs().includes(libName))
2121
1916
  throw new Error(`LibInfo is invalid: ${libName}`);
2122
1917
  return LibInfo.libInfos.get(libName);
2123
1918
  }
2124
1919
  getLibInfos() {
2125
- return new Map(this.#getSortedLibs().map((libName) => {
2126
- const libInfo = LibInfo.libInfos.get(libName);
2127
- if (!libInfo)
2128
- throw new Error(`LibInfo not found: ${libName}`);
2129
- return [libName, libInfo];
2130
- }));
1920
+ return this.sortedLibInfos(this.scanResult.libDeps);
2131
1921
  }
2132
1922
  }
2133
1923
 
@@ -2139,18 +1929,14 @@ class PkgInfo {
2139
1929
  const [tsconfig, rootPackageJson] = await Promise.all([exec.getTsConfig(), exec.workspace.getPackageJson()]);
2140
1930
  const scanner = await createDependencyScanner(exec);
2141
1931
  const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
2142
- const pkgPathSet = new Set(Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path) => tsconfig.compilerOptions.paths?.[path]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path) => path.replace("/*", "")));
1932
+ const workspacePathOf = (resolve) => resolve.replace(/^\.\//, "");
1933
+ const pkgPathSet = new Set(Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path) => tsconfig.compilerOptions.paths?.[path]?.some((resolve) => workspacePathOf(resolve).startsWith("pkgs/"))).map((path) => path.replace("/*", "")));
2143
1934
  const [npmDepSet, pkgPathDepSet] = await scanner.getImportSets([npmSet, pkgPathSet]);
2144
1935
  const pkgDeps = [...pkgPathDepSet].map((path) => {
2145
1936
  const pathSplitLength = path.split("/").length;
2146
- return (tsconfig.compilerOptions.paths?.[path]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
1937
+ return workspacePathOf(tsconfig.compilerOptions.paths?.[path]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
2147
1938
  }).filter((pkg) => pkg !== exec.name);
2148
- const pkgScanResult = {
2149
- name: exec.name,
2150
- pkgDeps,
2151
- dependencies: [...npmDepSet]
2152
- };
2153
- return pkgScanResult;
1939
+ return { name: exec.name, pkgDeps, dependencies: [...npmDepSet] };
2154
1940
  }
2155
1941
  static #pkgInfos = new Map;
2156
1942
  static async fromExecutor(exec, options = {}) {
@@ -2188,17 +1974,9 @@ class WorkspaceInfo {
2188
1974
  return existingWorkspaceInfo;
2189
1975
  const [appNames, libNames, pkgNames] = await Promise.all([exec.getApps(), exec.getLibs(), exec.getPkgs()]);
2190
1976
  const [appInfos, libInfos, pkgInfos] = await Promise.all([
2191
- Promise.all(appNames.map(async (appName) => {
2192
- const app = AppExecutor.from(exec, appName);
2193
- return await app.scan();
2194
- })),
2195
- Promise.all(libNames.map(async (libName) => {
2196
- const lib = LibExecutor.from(exec, libName);
2197
- return await lib.scan();
2198
- })),
2199
- Promise.all(pkgNames.map(async (pkgName) => {
2200
- return await PkgExecutor.from(exec, pkgName).scan();
2201
- }))
1977
+ Promise.all(appNames.map(async (appName) => await AppExecutor.from(exec, appName).scan())),
1978
+ Promise.all(libNames.map(async (libName) => await LibExecutor.from(exec, libName).scan())),
1979
+ Promise.all(pkgNames.map(async (pkgName) => await PkgExecutor.from(exec, pkgName).scan()))
2202
1980
  ]);
2203
1981
  const workspaceInfo = new WorkspaceInfo(new Map(appInfos.map((app) => [app.exec.name, app])), new Map(libInfos.map((lib) => [lib.exec.name, lib])), new Map(pkgInfos.map((pkg) => [pkg.exec.name, pkg])));
2204
1982
  WorkspaceInfo.#workspaceInfos.set(exec.name, workspaceInfo);
@@ -2207,40 +1985,9 @@ class WorkspaceInfo {
2207
1985
  }
2208
1986
 
2209
1987
  // pkgs/@akanjs/devkit/executors.ts
2210
- var staticTemplateFileExtensions = new Set([
2211
- ".avif",
2212
- ".bmp",
2213
- ".cjs",
2214
- ".css",
2215
- ".eot",
2216
- ".gif",
2217
- ".html",
2218
- ".ico",
2219
- ".jpeg",
2220
- ".jpg",
2221
- ".js",
2222
- ".json",
2223
- ".map",
2224
- ".md",
2225
- ".mjs",
2226
- ".mp3",
2227
- ".mp4",
2228
- ".ogg",
2229
- ".otf",
2230
- ".pdf",
2231
- ".png",
2232
- ".svg",
2233
- ".ttf",
2234
- ".txt",
2235
- ".wasm",
2236
- ".wav",
2237
- ".webm",
2238
- ".webp",
2239
- ".woff",
2240
- ".woff2",
2241
- ".xml"
2242
- ]);
2243
- var formatCommandArg = (value) => /^[\w@%+=:,./-]+$/.test(value) ? value : JSON.stringify(value);
1988
+ var staticTemplateFileExtensions = new Set(".avif .bmp .cjs .css .eot .gif .html .ico .jpeg .jpg .js .json .map .md .mjs .mp3 .mp4 .ogg .otf .pdf .png .svg".split(" ").concat(".ttf .txt .wasm .wav .webm .webp .woff .woff2 .xml".split(" ")));
1989
+ var plainCommandArgPattern = process.platform === "win32" ? /^[\w@%+=:,./\\-]+$/ : /^[\w@%+=:,./-]+$/;
1990
+ var formatCommandArg = (value) => plainCommandArgPattern.test(value) ? value : JSON.stringify(value);
2244
1991
  var formatCommandForDisplay = (command, args = []) => [command, ...args].map(formatCommandArg).join(" ");
2245
1992
 
2246
1993
  class CommandExecutionError extends Error {
@@ -2314,6 +2061,10 @@ var parseEnvFile = (envPath) => {
2314
2061
  }
2315
2062
  return env;
2316
2063
  };
2064
+ var withCapitalizedDict = (dict = {}) => ({
2065
+ ...dict,
2066
+ ...Object.fromEntries(Object.entries(dict).map(([key, value]) => [capitalize(key), capitalize(value)]))
2067
+ });
2317
2068
 
2318
2069
  class Executor {
2319
2070
  static verbose = false;
@@ -2340,144 +2091,51 @@ class Executor {
2340
2091
  #stderr(data) {
2341
2092
  Logger2.raw(chalk2.red(data.toString()));
2342
2093
  }
2343
- exec(command, options = {}) {
2344
- const cwd = options.cwd?.toString() ?? this.cwdPath;
2345
- const proc = exec(command, { cwd: this.cwdPath, ...options });
2094
+ #settle(proc, target, { onClose = false, keepLogs = false, redStderr = false } = {}) {
2346
2095
  let stdout = "";
2347
2096
  let stderr = "";
2348
2097
  proc.stdout?.on("data", (data) => {
2349
2098
  stdout += data.toString();
2099
+ if (keepLogs)
2100
+ this.logs.push(data.toString());
2350
2101
  this.#stdout(data);
2351
2102
  });
2352
2103
  proc.stderr?.on("data", (data) => {
2353
2104
  stderr += data.toString();
2354
- this.#stdout(data);
2105
+ if (keepLogs)
2106
+ this.logs.push(data.toString());
2107
+ if (redStderr)
2108
+ this.#stderr(data);
2109
+ else
2110
+ this.#stdout(data);
2355
2111
  });
2356
2112
  return new Promise((resolve, reject) => {
2357
- proc.on("error", (error) => {
2358
- reject(new CommandExecutionError({
2359
- command,
2360
- cwd,
2361
- code: null,
2362
- signal: null,
2363
- stdout,
2364
- stderr,
2365
- cause: error
2366
- }));
2367
- });
2368
- proc.on("exit", (code, signal) => {
2369
- if (code || signal)
2370
- reject(new CommandExecutionError({
2371
- command,
2372
- cwd,
2373
- code,
2374
- signal,
2375
- stdout,
2376
- stderr
2377
- }));
2113
+ proc.on("error", (cause) => reject(new CommandExecutionError({ ...target, code: null, signal: null, stdout, stderr, cause })));
2114
+ proc.on(onClose ? "close" : "exit", (code, signal) => {
2115
+ if ((onClose ? code !== 0 : code) || signal)
2116
+ reject(new CommandExecutionError({ ...target, code, signal, stdout, stderr }));
2378
2117
  else
2379
- resolve({ code, signal });
2118
+ resolve({ code, signal, stdout });
2380
2119
  });
2381
2120
  });
2382
2121
  }
2122
+ exec(command, options = {}) {
2123
+ const target = { command, cwd: options.cwd?.toString() ?? this.cwdPath };
2124
+ const proc = exec(command, { cwd: this.cwdPath, ...options });
2125
+ return this.#settle(proc, target).then(({ code, signal }) => ({ code, signal }));
2126
+ }
2383
2127
  spawn(command, args = [], options = {}) {
2384
- const cwd = options.cwd?.toString() ?? this.cwdPath;
2385
- const proc = spawn2(command, args, {
2386
- cwd: this.cwdPath,
2387
- ...options
2388
- });
2389
- let stdout = "";
2390
- let stderr = "";
2391
- proc.stdout?.on("data", (data) => {
2392
- stdout += data.toString();
2393
- this.logs.push(data.toString());
2394
- this.#stdout(data);
2395
- });
2396
- proc.stderr?.on("data", (data) => {
2397
- stderr += data.toString();
2398
- this.logs.push(data.toString());
2399
- this.#stdout(data);
2400
- });
2401
- return new Promise((resolve, reject) => {
2402
- proc.on("error", (error) => {
2403
- reject(new CommandExecutionError({
2404
- command,
2405
- args,
2406
- cwd,
2407
- code: null,
2408
- signal: null,
2409
- stdout,
2410
- stderr,
2411
- cause: error
2412
- }));
2413
- });
2414
- proc.on("close", (code, signal) => {
2415
- if (code !== 0 || signal)
2416
- reject(new CommandExecutionError({
2417
- command,
2418
- args,
2419
- cwd,
2420
- code,
2421
- signal,
2422
- stdout,
2423
- stderr
2424
- }));
2425
- else
2426
- resolve(stdout);
2427
- });
2428
- });
2128
+ const target = { command, args, cwd: options.cwd?.toString() ?? this.cwdPath };
2129
+ const proc = spawn2(command, args, { cwd: this.cwdPath, ...options });
2130
+ return this.#settle(proc, target, { onClose: true, keepLogs: true }).then(({ stdout }) => stdout);
2429
2131
  }
2430
2132
  spawnSync(command, args = [], options = {}) {
2431
- const proc = spawn2(command, args, {
2432
- cwd: this.cwdPath,
2433
- ...options
2434
- });
2435
- return proc;
2133
+ return spawn2(command, args, { cwd: this.cwdPath, ...options });
2436
2134
  }
2437
2135
  fork(modulePath, args = [], options = {}) {
2438
- const cwd = options.cwd?.toString() ?? this.cwdPath;
2439
- const proc = fork(modulePath, args, {
2440
- cwd: this.cwdPath,
2441
- ...options
2442
- });
2443
- let stdout = "";
2444
- let stderr = "";
2445
- proc.stdout?.on("data", (data) => {
2446
- stdout += data.toString();
2447
- this.#stdout(data);
2448
- });
2449
- proc.stderr?.on("data", (data) => {
2450
- stderr += data.toString();
2451
- this.#stderr(data);
2452
- });
2453
- return new Promise((resolve, reject) => {
2454
- proc.on("error", (error) => {
2455
- reject(new CommandExecutionError({
2456
- command: modulePath,
2457
- args,
2458
- cwd,
2459
- code: null,
2460
- signal: null,
2461
- stdout,
2462
- stderr,
2463
- cause: error
2464
- }));
2465
- });
2466
- proc.on("exit", (code, signal) => {
2467
- if (code || signal)
2468
- reject(new CommandExecutionError({
2469
- command: modulePath,
2470
- args,
2471
- cwd,
2472
- code,
2473
- signal,
2474
- stdout,
2475
- stderr
2476
- }));
2477
- else
2478
- resolve({ code, signal });
2479
- });
2480
- });
2136
+ const target = { command: modulePath, args, cwd: options.cwd?.toString() ?? this.cwdPath };
2137
+ const proc = fork(modulePath, args, { cwd: this.cwdPath, ...options });
2138
+ return this.#settle(proc, target, { redStderr: true }).then(({ code, signal }) => ({ code, signal }));
2481
2139
  }
2482
2140
  getPath(filePath) {
2483
2141
  if (path8.isAbsolute(filePath))
@@ -2501,8 +2159,8 @@ class Executor {
2501
2159
  }
2502
2160
  async mkdir(dirPath) {
2503
2161
  const writePath = this.getPath(dirPath);
2504
- if (!await FileSys.dirExists(writePath))
2505
- await mkdir3(writePath, { recursive: true });
2162
+ if (!await FileSys2.dirExists(writePath))
2163
+ await mkdir2(writePath, { recursive: true });
2506
2164
  this.logger.verbose(`Make directory ${writePath}`);
2507
2165
  return this;
2508
2166
  }
@@ -2521,27 +2179,25 @@ class Executor {
2521
2179
  }
2522
2180
  async getFilesAndDirs(dirPath) {
2523
2181
  const fullDirPath = this.getPath(dirPath);
2524
- const fileGlob = new Bun.Glob("*");
2525
- const files = Array.from(fileGlob.scanSync({ cwd: fullDirPath, onlyFiles: true }));
2526
- const dirGlob = new Bun.Glob("*");
2527
- const allEntries = Array.from(dirGlob.scanSync({ cwd: fullDirPath, onlyFiles: false }));
2182
+ const glob = new Bun.Glob("*");
2183
+ const files = Array.from(glob.scanSync({ cwd: fullDirPath, onlyFiles: true }));
2184
+ const allEntries = Array.from(glob.scanSync({ cwd: fullDirPath, onlyFiles: false }));
2528
2185
  const dirs = allEntries.filter((entry) => !files.includes(entry));
2529
2186
  return { files, dirs };
2530
2187
  }
2531
2188
  async exists(filePath) {
2532
- const readPath = this.getPath(filePath);
2533
- return await FileSys.exists(readPath);
2189
+ return await FileSys2.exists(this.getPath(filePath));
2534
2190
  }
2535
2191
  async remove(filePath) {
2536
2192
  const readPath = this.getPath(filePath);
2537
- if (await FileSys.fileExists(readPath))
2538
- await FileSys.delete(readPath);
2193
+ if (await FileSys2.fileExists(readPath))
2194
+ await FileSys2.delete(readPath);
2539
2195
  this.logger.verbose(`Remove file ${readPath}`);
2540
2196
  return this;
2541
2197
  }
2542
2198
  async removeDir(dirPath) {
2543
2199
  const readPath = path8.join(this.getPath(dirPath), ".");
2544
- if (await FileSys.entryExists(readPath))
2200
+ if (await FileSys2.entryExists(readPath))
2545
2201
  await rm3(readPath, { recursive: true, force: true });
2546
2202
  this.logger.verbose(`Remove directory ${readPath}`);
2547
2203
  return this;
@@ -2549,22 +2205,22 @@ class Executor {
2549
2205
  async writeFile(filePath, content, { overwrite = true, silent = false } = {}) {
2550
2206
  const writePath = this.getPath(filePath);
2551
2207
  const dir = path8.dirname(writePath);
2552
- if (!await FileSys.dirExists(dir))
2553
- await mkdir3(dir, { recursive: true });
2208
+ if (!await FileSys2.dirExists(dir))
2209
+ await mkdir2(dir, { recursive: true });
2554
2210
  let contentStr = typeof content === "string" ? content : `${JSON.stringify(content, null, 2)}
2555
2211
  `;
2556
- if (await FileSys.fileExists(writePath)) {
2557
- const currentContent = await FileSys.readText(writePath);
2212
+ if (await FileSys2.fileExists(writePath)) {
2213
+ const currentContent = await FileSys2.readText(writePath);
2558
2214
  if (currentContent === contentStr || !overwrite) {
2559
2215
  this.logger.verbose(`File ${writePath} is unchanged`);
2560
2216
  contentStr = currentContent;
2561
2217
  } else {
2562
- await FileSys.writeText(writePath, contentStr);
2218
+ await FileSys2.writeText(writePath, contentStr);
2563
2219
  if (Logger2.isVerbose())
2564
2220
  this.logger.rawLog(chalk2.yellow(`File Update: ${filePath}`));
2565
2221
  }
2566
2222
  } else {
2567
- await FileSys.writeText(writePath, contentStr);
2223
+ await FileSys2.writeText(writePath, contentStr);
2568
2224
  if (!silent)
2569
2225
  this.logger.rawLog(chalk2.green(`File Create: ${filePath}`));
2570
2226
  }
@@ -2579,22 +2235,20 @@ class Executor {
2579
2235
  return { filePath, content };
2580
2236
  }
2581
2237
  async readFile(filePath) {
2582
- const readPath = this.getPath(filePath);
2583
- return await FileSys.readText(readPath);
2238
+ return await FileSys2.readText(this.getPath(filePath));
2584
2239
  }
2585
2240
  async readJson(filePath) {
2586
- const readPath = this.getPath(filePath);
2587
- return await FileSys.readJson(readPath);
2241
+ return await FileSys2.readJson(this.getPath(filePath));
2588
2242
  }
2589
2243
  async cp(srcPath, destPath, { dereference = false } = {}) {
2590
2244
  const src = this.getPath(srcPath);
2591
2245
  const dest = this.getPath(destPath);
2592
- if (!await FileSys.exists(src))
2246
+ if (!await FileSys2.exists(src))
2593
2247
  return;
2594
2248
  const isDirectory = (await stat2(src)).isDirectory();
2595
- if (!await FileSys.exists(dest) && isDirectory)
2596
- await mkdir3(dest, { recursive: true });
2597
- if (dereference)
2249
+ if (!await FileSys2.exists(dest) && isDirectory)
2250
+ await mkdir2(dest, { recursive: true });
2251
+ if (dereference || process.platform === "win32")
2598
2252
  await cpEntry(src, dest, { recursive: isDirectory, dereference: true, force: true });
2599
2253
  else
2600
2254
  await $`cp -r ${src}${isDirectory ? "/." : ""} ${dest}`;
@@ -2618,19 +2272,10 @@ class Executor {
2618
2272
  async getTsConfig(pathname = "tsconfig.json", { refresh } = {}) {
2619
2273
  if (this.#tsconfig && !refresh)
2620
2274
  return this.#tsconfig;
2621
- const tsconfig = await this.readJson(pathname);
2275
+ let tsconfig = await this.readJson(pathname);
2622
2276
  if (tsconfig.extends) {
2623
- const extendsTsconfig = await this.getTsConfig(tsconfig.extends);
2624
- const result = {
2625
- ...extendsTsconfig,
2626
- ...tsconfig,
2627
- compilerOptions: {
2628
- ...extendsTsconfig.compilerOptions,
2629
- ...tsconfig.compilerOptions
2630
- }
2631
- };
2632
- this.#tsconfig = result;
2633
- return result;
2277
+ const base = await this.getTsConfig(tsconfig.extends, { refresh });
2278
+ tsconfig = { ...base, ...tsconfig, compilerOptions: { ...base.compilerOptions, ...tsconfig.compilerOptions } };
2634
2279
  }
2635
2280
  this.#tsconfig = tsconfig;
2636
2281
  return tsconfig;
@@ -2666,6 +2311,7 @@ class Executor {
2666
2311
  scanInfo,
2667
2312
  overwrite = true
2668
2313
  }, dict = {}, options = {}) {
2314
+ const convertPath = (target) => Object.entries(dict).reduce((converted, [key, value]) => converted.replace(new RegExp(`__${key}__`, "g"), value), target);
2669
2315
  if (targetPath.endsWith(".ts") || targetPath.endsWith(".tsx")) {
2670
2316
  const getContent = await import(templatePath);
2671
2317
  const result = await getContent.default(scanInfo ?? null, dict, options);
@@ -2673,24 +2319,21 @@ class Executor {
2673
2319
  return null;
2674
2320
  const filename = typeof result === "object" ? result.filename : path8.basename(targetPath).replace(".js", ".ts");
2675
2321
  const content = typeof result === "object" ? result.content : result;
2676
- const dirname = path8.dirname(targetPath);
2677
- const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), `${dirname}/${filename}`);
2322
+ const convertedTargetPath = convertPath(`${path8.dirname(targetPath)}/${filename}`);
2678
2323
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2679
2324
  return this.writeFile(convertedTargetPath, content, { overwrite });
2680
2325
  } else if (targetPath.endsWith(".template")) {
2681
- const content = await FileSys.readText(templatePath);
2682
- const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), targetPath.slice(0, -9));
2326
+ const content = await FileSys2.readText(templatePath);
2327
+ const convertedTargetPath = convertPath(targetPath.slice(0, -9));
2683
2328
  const convertedContent = Object.entries(dict).reduce((data, [key, value]) => data.replace(new RegExp(`<%= ${key} %>`, "g"), value), content);
2684
2329
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2685
- return this.writeFile(convertedTargetPath, convertedContent, {
2686
- overwrite
2687
- });
2330
+ return this.writeFile(convertedTargetPath, convertedContent, { overwrite });
2688
2331
  } else if (staticTemplateFileExtensions.has(path8.extname(targetPath).toLowerCase())) {
2689
- const convertedTargetPath = Object.entries(dict).reduce((path, [key, value]) => path.replace(new RegExp(`__${key}__`, "g"), value), targetPath);
2332
+ const convertedTargetPath = convertPath(targetPath);
2690
2333
  const writePath = this.getPath(convertedTargetPath);
2691
2334
  const dirname = path8.dirname(writePath);
2692
- if (!await FileSys.dirExists(dirname))
2693
- await mkdir3(dirname, { recursive: true });
2335
+ if (!await FileSys2.dirExists(dirname))
2336
+ await mkdir2(dirname, { recursive: true });
2694
2337
  await copyFile(templatePath, writePath);
2695
2338
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2696
2339
  return { filePath: writePath, content: "" };
@@ -2707,12 +2350,10 @@ class Executor {
2707
2350
  }) {
2708
2351
  const templateRoot = await this.#resolveTemplateRoot();
2709
2352
  const templatePath = `${templateRoot}${template ? `/${template}` : ""}`;
2710
- const prefixTemplatePath = templatePath;
2711
- if ((await stat2(prefixTemplatePath)).isFile()) {
2712
- const filename = path8.basename(prefixTemplatePath);
2353
+ if ((await stat2(templatePath)).isFile()) {
2713
2354
  const fileContent = await this.#applyTemplateFile({
2714
- templatePath: prefixTemplatePath,
2715
- targetPath: path8.join(basePath, filename),
2355
+ templatePath,
2356
+ targetPath: path8.join(basePath, path8.basename(templatePath)),
2716
2357
  scanInfo,
2717
2358
  overwrite
2718
2359
  }, dict, options);
@@ -2748,17 +2389,13 @@ class Executor {
2748
2389
  path8.resolve(getDirname2(import.meta.url), "../cli/templates")
2749
2390
  ];
2750
2391
  for (const candidate of candidates) {
2751
- if (await FileSys.dirExists(candidate))
2392
+ if (await FileSys2.dirExists(candidate))
2752
2393
  return candidate;
2753
2394
  }
2754
2395
  return candidates[0];
2755
2396
  }
2756
2397
  async applyTemplate(options) {
2757
- const dict = {
2758
- ...options.dict ?? {},
2759
- ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [capitalize(key), capitalize(value)]))
2760
- };
2761
- const fileContents = await this._applyTemplate({ ...options, dict });
2398
+ const fileContents = await this._applyTemplate({ ...options, dict: withCapitalizedDict(options.dict) });
2762
2399
  await this.#formatAppliedTemplate(fileContents);
2763
2400
  return fileContents;
2764
2401
  }
@@ -2775,7 +2412,7 @@ class Executor {
2775
2412
  }
2776
2413
  }
2777
2414
  async getTypeChecker() {
2778
- const { TypeChecker } = await import("./typeChecker-3xgrzc2v.js");
2415
+ const { TypeChecker } = await import("./typeChecker-px49mezc.js");
2779
2416
  this.typeChecker ??= new TypeChecker(this);
2780
2417
  return this.typeChecker;
2781
2418
  }
@@ -2853,12 +2490,11 @@ class WorkspaceExecutor extends Executor {
2853
2490
  this.workspaceRoot = workspaceRoot;
2854
2491
  this.repoName = repoName;
2855
2492
  }
2856
- static #execs = new Map;
2857
2493
  static fromRoot({
2858
2494
  workspaceRoot = process.cwd(),
2859
2495
  repoName = resolveRepoName(workspaceRoot)
2860
2496
  } = {}) {
2861
- return WorkspaceExecutor.#execs.get(repoName) ?? new WorkspaceExecutor({ workspaceRoot, repoName });
2497
+ return new WorkspaceExecutor({ workspaceRoot, repoName });
2862
2498
  }
2863
2499
  static getBaseDevEnv(envPath) {
2864
2500
  const sourceEnv = envPath ? { ...process.env, ...parseEnvFile(envPath) } : process.env;
@@ -2897,13 +2533,9 @@ class WorkspaceExecutor extends Executor {
2897
2533
  return await WorkspaceInfo.fromExecutor(this);
2898
2534
  }
2899
2535
  async getApps() {
2900
- if (!await FileSys.dirExists(`${this.workspaceRoot}/apps`))
2901
- return [];
2902
2536
  return await this.#getDirHasFile(`${this.workspaceRoot}/apps`, "akan.config.ts");
2903
2537
  }
2904
2538
  async getLibs() {
2905
- if (!await FileSys.dirExists(`${this.workspaceRoot}/libs`))
2906
- return [];
2907
2539
  return await this.#getDirHasFile(`${this.workspaceRoot}/libs`, "akan.config.ts");
2908
2540
  }
2909
2541
  async getSyss() {
@@ -2911,8 +2543,6 @@ class WorkspaceExecutor extends Executor {
2911
2543
  return [appNames, libNames];
2912
2544
  }
2913
2545
  async getPkgs() {
2914
- if (!await FileSys.dirExists(`${this.workspaceRoot}/pkgs`))
2915
- return [];
2916
2546
  return await this.#getDirHasFile(`${this.workspaceRoot}/pkgs`, "package.json");
2917
2547
  }
2918
2548
  async getExecs() {
@@ -2977,6 +2607,8 @@ class WorkspaceExecutor extends Executor {
2977
2607
  return stdout.split("\x00").filter((file) => !!file).sort();
2978
2608
  }
2979
2609
  async#getDirHasFile(basePath, targetFilename) {
2610
+ if (!await FileSys2.dirExists(basePath))
2611
+ return [];
2980
2612
  const AVOID_DIRS = ["node_modules", "dist", "public", "webkit"];
2981
2613
  const getDirs = async (dirname, maxDepth = 3, results = [], prefix = "") => {
2982
2614
  const dirs = await this.readdir(dirname);
@@ -2984,8 +2616,8 @@ class WorkspaceExecutor extends Executor {
2984
2616
  if (AVOID_DIRS.includes(dir))
2985
2617
  return;
2986
2618
  const dirPath = path8.join(dirname, dir);
2987
- if (await FileSys.dirExists(dirPath)) {
2988
- const hasTargetFile = await FileSys.fileExists(path8.join(dirPath, targetFilename));
2619
+ if (await FileSys2.dirExists(dirPath)) {
2620
+ const hasTargetFile = await FileSys2.fileExists(path8.join(dirPath, targetFilename));
2989
2621
  if (hasTargetFile)
2990
2622
  results.push(`${prefix}${dir}`);
2991
2623
  if (maxDepth > 0)
@@ -2994,39 +2626,25 @@ class WorkspaceExecutor extends Executor {
2994
2626
  }));
2995
2627
  return results;
2996
2628
  };
2997
- return await getDirs(basePath);
2629
+ return (await getDirs(basePath)).sort((a, b) => a.localeCompare(b));
2998
2630
  }
2999
- async getScalarConstantFiles() {
2631
+ async#fromEverySys(read) {
3000
2632
  const [appNames, libNames] = await this.getSyss();
3001
- const scalarConstantExampleFiles = [
3002
- ...(await Promise.all(appNames.map((appName) => AppExecutor.from(this, appName).getScalarConstantFiles()))).flat(),
3003
- ...(await Promise.all(libNames.map((libName) => LibExecutor.from(this, libName).getScalarConstantFiles()))).flat()
3004
- ];
3005
- return scalarConstantExampleFiles;
2633
+ const fromApps = await Promise.all(appNames.map((appName) => read(AppExecutor.from(this, appName))));
2634
+ const fromLibs = await Promise.all(libNames.map((libName) => read(LibExecutor.from(this, libName))));
2635
+ return [...fromApps.flat(), ...fromLibs.flat()];
2636
+ }
2637
+ async getScalarConstantFiles() {
2638
+ return await this.#fromEverySys((sys) => sys.getScalarConstantFiles());
3006
2639
  }
3007
2640
  async getConstantFiles() {
3008
- const [appNames, libNames] = await this.getSyss();
3009
- const moduleConstantExampleFiles = [
3010
- ...(await Promise.all(appNames.map((appName) => AppExecutor.from(this, appName).getConstantFiles()))).flat(),
3011
- ...(await Promise.all(libNames.map((libName) => LibExecutor.from(this, libName).getConstantFiles()))).flat()
3012
- ];
3013
- return moduleConstantExampleFiles;
2641
+ return await this.#fromEverySys((sys) => sys.getConstantFiles());
3014
2642
  }
3015
2643
  async getDictionaryFiles() {
3016
- const [appNames, libNames] = await this.getSyss();
3017
- const moduleDictionaryExampleFiles = [
3018
- ...(await Promise.all(appNames.map((appName) => AppExecutor.from(this, appName).getDictionaryFiles()))).flat(),
3019
- ...(await Promise.all(libNames.map((libName) => LibExecutor.from(this, libName).getDictionaryFiles()))).flat()
3020
- ];
3021
- return moduleDictionaryExampleFiles;
2644
+ return await this.#fromEverySys((sys) => sys.getDictionaryFiles());
3022
2645
  }
3023
2646
  async getViewFiles() {
3024
- const [appNames, libNames] = await this.getSyss();
3025
- const viewExampleFiles = [
3026
- ...(await Promise.all(appNames.map((appName) => AppExecutor.from(this, appName).getViewsSourceCode()))).flat(),
3027
- ...(await Promise.all(libNames.map((libName) => LibExecutor.from(this, libName).getViewsSourceCode()))).flat()
3028
- ];
3029
- return viewExampleFiles;
2647
+ return await this.#fromEverySys((sys) => sys.getViewsSourceCode());
3030
2648
  }
3031
2649
  }
3032
2650
  var scanFacetDirs = ["ui", "webkit", "srvkit", "common", "plugin"];
@@ -3090,24 +2708,11 @@ class SysExecutor extends Executor {
3090
2708
  scanInfo,
3091
2709
  options: { exec: this, facet }
3092
2710
  })),
3093
- ...scanInfo.getDatabaseModules().map((model) => this._applyTemplate({
3094
- basePath: `lib/${model}`,
3095
- template: "moduleRoot",
3096
- scanInfo,
3097
- dict: { model, Model: capitalize(model) }
3098
- })),
3099
- ...scanInfo.getServiceModules().map((model) => this._applyTemplate({
3100
- basePath: `lib/_${model}`,
3101
- template: "moduleRoot",
3102
- scanInfo,
3103
- dict: { model, Model: capitalize(model) }
3104
- })),
3105
- ...scanInfo.getScalarModules().map((model) => this._applyTemplate({
3106
- basePath: `lib/__scalar/${model}`,
3107
- template: "moduleRoot",
3108
- scanInfo,
3109
- dict: { model, Model: capitalize(model) }
3110
- }))
2711
+ ...[
2712
+ ...scanInfo.getDatabaseModules().map((model) => [model, `lib/${model}`]),
2713
+ ...scanInfo.getServiceModules().map((model) => [model, `lib/_${model}`]),
2714
+ ...scanInfo.getScalarModules().map((model) => [model, `lib/__scalar/${model}`])
2715
+ ].map(([model, basePath]) => this._applyTemplate({ basePath, template: "moduleRoot", scanInfo, dict: { model, Model: capitalize(model) } }))
3111
2716
  ];
3112
2717
  }
3113
2718
  async scan({
@@ -3174,40 +2779,38 @@ class SysExecutor extends Executor {
3174
2779
  return { filePath, content };
3175
2780
  }
3176
2781
  async getDatabaseModules() {
3177
- const databaseModules = (await this.readdir("lib")).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) => Bun.file(`${this.cwdPath}/lib/${name}/${name}.constant.ts`).exists());
3178
- return databaseModules;
2782
+ return (await this.readdir("lib")).filter((name) => !name.startsWith("_") && !name.endsWith(".ts")).filter((name) => existsSync2(`${this.cwdPath}/lib/${name}/${name}.constant.ts`));
3179
2783
  }
3180
2784
  async getServiceModules() {
3181
- const serviceModules = (await this.readdir("lib")).filter((name) => name.startsWith("_") && !name.startsWith("__")).filter((name) => Bun.file(`${this.cwdPath}/lib/${name}/${name}.service.ts`).exists());
3182
- return serviceModules;
2785
+ return (await this.readdir("lib")).filter((name) => name.startsWith("_") && !name.startsWith("__")).filter((name) => existsSync2(`${this.cwdPath}/lib/${name}/${name.slice(1)}.service.ts`));
3183
2786
  }
3184
2787
  async getScalarModules() {
3185
- const scalarModules = (await this.readdir("lib/__scalar")).filter((name) => !name.startsWith("_")).filter((name) => Bun.file(`${this.cwdPath}/lib/__scalar/${name}/${name}.constant.ts`).exists());
3186
- return scalarModules;
2788
+ return (await this.readdir("lib/__scalar")).filter((name) => !name.startsWith("_")).filter((name) => existsSync2(`${this.cwdPath}/lib/__scalar/${name}/${name}.constant.ts`));
2789
+ }
2790
+ async#getComponentModules(role) {
2791
+ return (await this.readdir("lib")).filter((name) => !name.startsWith("_") && !name.endsWith(".ts")).filter((name) => existsSync2(`${this.cwdPath}/lib/${name}/${capitalize(name)}.${role}.tsx`));
2792
+ }
2793
+ async#getComponentSources(role) {
2794
+ const modules = await this.#getComponentModules(role);
2795
+ return Promise.all(modules.map((name) => this.getLocalFile(`lib/${name}/${capitalize(name)}.${role}.tsx`)));
3187
2796
  }
3188
2797
  async getViewComponents() {
3189
- const viewComponents = (await this.readdir("lib")).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) => Bun.file(`${this.cwdPath}/lib/${name}/${capitalize(name)}.View.tsx`).exists());
3190
- return viewComponents;
2798
+ return await this.#getComponentModules("View");
3191
2799
  }
3192
2800
  async getUnitComponents() {
3193
- const unitComponents = (await this.readdir("lib")).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) => Bun.file(`${this.cwdPath}/lib/${name}/${capitalize(name)}.Unit.tsx`).exists());
3194
- return unitComponents;
2801
+ return await this.#getComponentModules("Unit");
3195
2802
  }
3196
2803
  async getTemplateComponents() {
3197
- const templateComponents = (await this.readdir("lib")).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) => Bun.file(`${this.cwdPath}/lib/${name}/${capitalize(name)}.Template.tsx`).exists());
3198
- return templateComponents;
2804
+ return await this.#getComponentModules("Template");
3199
2805
  }
3200
2806
  async getViewsSourceCode() {
3201
- const viewComponents = await this.getViewComponents();
3202
- return Promise.all(viewComponents.map((viewComponent) => this.getLocalFile(`lib/${viewComponent}/${capitalize(viewComponent)}.View.tsx`)));
2807
+ return await this.#getComponentSources("View");
3203
2808
  }
3204
2809
  async getUnitsSourceCode() {
3205
- const unitComponents = await this.getUnitComponents();
3206
- return Promise.all(unitComponents.map((unitComponent) => this.getLocalFile(`lib/${unitComponent}/${capitalize(unitComponent)}.Unit.tsx`)));
2810
+ return await this.#getComponentSources("Unit");
3207
2811
  }
3208
2812
  async getTemplatesSourceCode() {
3209
- const templateComponents = await this.getTemplateComponents();
3210
- return Promise.all(templateComponents.map((templateComponent) => this.getLocalFile(`lib/${templateComponent}/${capitalize(templateComponent)}.Template.tsx`)));
2813
+ return await this.#getComponentSources("Template");
3211
2814
  }
3212
2815
  async getScalarConstantFiles() {
3213
2816
  const scalarModules = await this.getScalarModules();
@@ -3215,7 +2818,7 @@ class SysExecutor extends Executor {
3215
2818
  }
3216
2819
  async getScalarDictionaryFiles() {
3217
2820
  const scalarModules = await this.getScalarModules();
3218
- return Promise.all(scalarModules.map((scalarModule) => this.getLocalFile(`lib/${scalarModule}/${scalarModule}.dictionary.ts`)));
2821
+ return Promise.all(scalarModules.map((scalarModule) => this.getLocalFile(`lib/__scalar/${scalarModule}/${scalarModule}.dictionary.ts`)));
3219
2822
  }
3220
2823
  async getConstantFiles() {
3221
2824
  const modules = await this.getModules();
@@ -3237,16 +2840,8 @@ class SysExecutor extends Executor {
3237
2840
  return Promise.all(modules.map((module) => this.getLocalFile(`lib/${module}/${module}.dictionary.ts`)));
3238
2841
  }
3239
2842
  async applyTemplate(options) {
3240
- const dict = {
3241
- ...options.dict ?? {},
3242
- ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [capitalize(key), capitalize(value)]))
3243
- };
3244
2843
  const scanInfo = await this.scan();
3245
- const fileContents = await this._applyTemplate({
3246
- ...options,
3247
- scanInfo,
3248
- dict
3249
- });
2844
+ const fileContents = await this._applyTemplate({ ...options, scanInfo, dict: withCapitalizedDict(options.dict) });
3250
2845
  await this.scan();
3251
2846
  return fileContents;
3252
2847
  }
@@ -3255,7 +2850,7 @@ class SysExecutor extends Executor {
3255
2850
  class AppExecutor extends SysExecutor {
3256
2851
  static #routeSourceValidator = null;
3257
2852
  static async#getRouteSourceValidator() {
3258
- AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-apyqw7wk.js")).RouteSourceValidator;
2853
+ AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-7ycnfz0e.js")).RouteSourceValidator;
3259
2854
  return AppExecutor.#routeSourceValidator;
3260
2855
  }
3261
2856
  dist;
@@ -3264,15 +2859,8 @@ class AppExecutor extends SysExecutor {
3264
2859
  super({ workspace, name, type: "app" });
3265
2860
  this.dist = new Executor(`dist/${name}`, `${this.workspace.workspaceRoot}/dist/apps/${name}`);
3266
2861
  }
3267
- static #execs = new Map;
3268
2862
  static from(executor, name) {
3269
- const exec = AppExecutor.#execs.get(name);
3270
- if (exec)
3271
- return exec;
3272
- else if (executor instanceof WorkspaceExecutor)
3273
- return new AppExecutor({ workspace: executor, name });
3274
- else
3275
- return new AppExecutor({ workspace: executor.workspace, name });
2863
+ return new AppExecutor({ workspace: executor instanceof WorkspaceExecutor ? executor : executor.workspace, name });
3276
2864
  }
3277
2865
  getEnv() {
3278
2866
  return WorkspaceExecutor.getBaseDevEnv().env;
@@ -3288,10 +2876,8 @@ class AppExecutor extends SysExecutor {
3288
2876
  return basePort + appIndex + portOffset;
3289
2877
  }
3290
2878
  getCommandEnv(env = {}) {
3291
- const basePort = 8282;
3292
- const portOffset = WorkspaceExecutor.getBaseDevEnv().portOffset;
3293
- const PORT = (basePort + portOffset).toString();
3294
- const AKAN_PUBLIC_SERVER_PORT = portOffset ? (8282 + portOffset).toString() : undefined;
2879
+ const { portOffset } = WorkspaceExecutor.getBaseDevEnv();
2880
+ const PORT = (8282 + portOffset).toString();
3295
2881
  return {
3296
2882
  ...process.env,
3297
2883
  AKAN_PUBLIC_APP_NAME: this.name,
@@ -3299,18 +2885,24 @@ class AppExecutor extends SysExecutor {
3299
2885
  NODE_NO_WARNINGS: "1",
3300
2886
  PORT,
3301
2887
  AKAN_PUBLIC_CLIENT_PORT: PORT,
3302
- ...AKAN_PUBLIC_SERVER_PORT ? { AKAN_PUBLIC_SERVER_PORT } : {},
2888
+ ...portOffset ? { AKAN_PUBLIC_SERVER_PORT: PORT } : {},
3303
2889
  ...env
3304
2890
  };
3305
2891
  }
2892
+ async getDatabaseModeEnv() {
2893
+ const akanConfig = await this.getConfig();
2894
+ return {
2895
+ AKAN_DATABASE_MODE: akanConfig.resolveDatabaseMode(),
2896
+ AKAN_DATABASE_MODES: akanConfig.database.modes.join(",")
2897
+ };
2898
+ }
3306
2899
  async prepareCommand(type) {
3307
2900
  const akanConfig = await this.getConfig();
3308
- const databaseMode = process.env.AKAN_DATABASE_MODE ?? akanConfig.defaultDatabaseMode ?? "single";
3309
2901
  const routeEnv = {
3310
2902
  AKAN_PUBLIC_BASE_PATHS: [...akanConfig.basePaths].join(","),
3311
2903
  AKAN_PUBLIC_API_PREFIX: akanConfig.api.prefix,
3312
2904
  AKAN_PUBLIC_WS_PREFIX: akanConfig.api.websocketPrefix,
3313
- AKAN_DATABASE_MODE: databaseMode
2905
+ ...await this.getDatabaseModeEnv()
3314
2906
  };
3315
2907
  Object.assign(process.env, routeEnv);
3316
2908
  if (type === "build") {
@@ -3339,6 +2931,8 @@ class AppExecutor extends SysExecutor {
3339
2931
  const buildEnv = { ...env };
3340
2932
  delete buildEnv.AKAN_PUBLIC_CLIENT_PORT;
3341
2933
  delete buildEnv.AKAN_PUBLIC_SERVER_PORT;
2934
+ delete buildEnv.AKAN_PUBLIC_OPERATION_MODE;
2935
+ delete process.env.AKAN_PUBLIC_OPERATION_MODE;
3342
2936
  Object.assign(process.env, buildEnv);
3343
2937
  }
3344
2938
  return { env };
@@ -3348,16 +2942,7 @@ class AppExecutor extends SysExecutor {
3348
2942
  if (this.#publicEnv)
3349
2943
  return this.#publicEnv;
3350
2944
  const searchPatterns = [...patterns, "AKAN_PUBLIC_*"];
3351
- const regexes = searchPatterns.map((pattern) => {
3352
- let body = "";
3353
- for (const ch of pattern) {
3354
- if (ch === "*")
3355
- body += ".*";
3356
- else
3357
- body += ch.replace(/[.+^${}()|[\]\\?]/g, "\\$&");
3358
- }
3359
- return new RegExp(`^${body}$`);
3360
- });
2945
+ const regexes = searchPatterns.map((pattern) => new RegExp(`^${pattern.split("*").map((part) => part.replace(/[.+^${}()|[\]\\?]/g, "\\$&")).join(".*")}$`));
3361
2946
  const publicEnv = {};
3362
2947
  for (const [k, v] of Object.entries(process.env)) {
3363
2948
  if (typeof v !== "string")
@@ -3386,8 +2971,10 @@ class AppExecutor extends SysExecutor {
3386
2971
  const owners = new Map;
3387
2972
  const devOnlyKeys = new Set;
3388
2973
  const devOnlyDirs = [];
3389
- for (const root of await this.getPageRoots()) {
3390
- if (!await FileSys.dirExists(root.dir))
2974
+ const pageRoots = await this.getPageRoots();
2975
+ const libKeyPrefixes = pageRoots.map((root) => root.keyPrefix).filter(Boolean);
2976
+ for (const root of pageRoots) {
2977
+ if (!await FileSys2.dirExists(root.dir))
3391
2978
  continue;
3392
2979
  for await (const rel of glob.scan({
3393
2980
  cwd: root.dir,
@@ -3398,6 +2985,8 @@ class AppExecutor extends SysExecutor {
3398
2985
  if (segments.some((s) => s === "node_modules"))
3399
2986
  continue;
3400
2987
  const posix = `${root.keyPrefix}${segments.join("/")}`;
2988
+ if (!root.keyPrefix && libKeyPrefixes.some((prefix) => posix.startsWith(prefix)))
2989
+ continue;
3401
2990
  const absPath = path8.join(root.dir, ...segments);
3402
2991
  validatePageSourceFile(posix, { filePath: absPath });
3403
2992
  if (!isRouteSourceFile(posix))
@@ -3462,7 +3051,7 @@ class AppExecutor extends SysExecutor {
3462
3051
  const entries = await readDirEntries(libsDir).catch(() => []);
3463
3052
  for (const entry of entries.sort()) {
3464
3053
  const dir = `${libsDir}/${entry}`;
3465
- if (!await FileSys.dirExists(dir))
3054
+ if (!await FileSys2.dirExists(dir))
3466
3055
  continue;
3467
3056
  roots.push({ dir, realDir: await realpath(dir), keyPrefix: `${parent}${AppExecutor.#pageLibsDir}/${entry}/` });
3468
3057
  }
@@ -3487,7 +3076,8 @@ class AppExecutor extends SysExecutor {
3487
3076
  return entries.map((entry) => `${parent}${AppExecutor.#pageLibsDir}/${entry}/`);
3488
3077
  }))).flat();
3489
3078
  const wanted = parents.flatMap((parent) => libs.map((lib) => `${parent}${AppExecutor.#pageLibsDir}/(${lib})/`));
3490
- if (linked.sort().join(",") === wanted.sort().join(","))
3079
+ const isLink = async (key) => (await lstat(`${this.cwdPath}/page/${key.slice(0, -1)}`).catch(() => null))?.isSymbolicLink() ?? false;
3080
+ if (linked.sort().join(",") === wanted.sort().join(",") && (await Promise.all(linked.map(isLink))).every(Boolean))
3491
3081
  return false;
3492
3082
  await Promise.all(parents.map((parent) => this.removeDir(`${this.cwdPath}/page/${parent}${AppExecutor.#pageLibsDir}`)));
3493
3083
  for (const parent of parents) {
@@ -3503,7 +3093,7 @@ class AppExecutor extends SysExecutor {
3503
3093
  async#resolvePageLibs(syncPageLibs, libDeps) {
3504
3094
  if (!syncPageLibs)
3505
3095
  return [];
3506
- const hasPageDir = async (lib) => await FileSys.dirExists(`${this.workspace.workspaceRoot}/libs/${lib}/page`);
3096
+ const hasPageDir = async (lib) => await FileSys2.dirExists(`${this.workspace.workspaceRoot}/libs/${lib}/page`);
3507
3097
  if (syncPageLibs === true) {
3508
3098
  const libs = [];
3509
3099
  for (const lib of libDeps)
@@ -3543,7 +3133,7 @@ class AppExecutor extends SysExecutor {
3543
3133
  } catch (error) {
3544
3134
  if (!isWindows)
3545
3135
  throw error;
3546
- await mkdir3(linkPath, { recursive: true });
3136
+ await mkdir2(linkPath, { recursive: true });
3547
3137
  await cpEntry(targetPath, linkPath, { recursive: true, dereference: true, force: true });
3548
3138
  }
3549
3139
  }
@@ -3575,13 +3165,14 @@ class AppExecutor extends SysExecutor {
3575
3165
  appPath: this.cwdPath,
3576
3166
  executor: this,
3577
3167
  getPath: (rel) => this.getPath(rel),
3578
- fileExists: (rel) => FileSys.fileExists(this.getPath(rel)),
3168
+ fileExists: (rel) => FileSys2.fileExists(this.getPath(rel)),
3169
+ readFile: (rel) => this.readFile(rel),
3579
3170
  writeFile: async (rel, content, opts) => {
3580
3171
  await this.writeFile(rel, content, opts);
3581
3172
  },
3582
3173
  readEnvClient: async () => {
3583
3174
  const envClientPath = path8.join(this.cwdPath, "env", "env.client.ts");
3584
- if (!await FileSys.fileExists(envClientPath))
3175
+ if (!await FileSys2.fileExists(envClientPath))
3585
3176
  return null;
3586
3177
  try {
3587
3178
  const envUrl = pathToFileURL(envClientPath);
@@ -3637,15 +3228,8 @@ class LibExecutor extends SysExecutor {
3637
3228
  super({ workspace, name, type: "lib" });
3638
3229
  this.dist = new Executor(`dist/${name}`, `${this.workspace.workspaceRoot}/dist/libs/${name}`);
3639
3230
  }
3640
- static #execs = new Map;
3641
3231
  static from(executor, name) {
3642
- const exec = LibExecutor.#execs.get(name);
3643
- if (exec)
3644
- return exec;
3645
- else if (executor instanceof WorkspaceExecutor)
3646
- return new LibExecutor({ workspace: executor, name });
3647
- else
3648
- return new LibExecutor({ workspace: executor.workspace, name });
3232
+ return new LibExecutor({ workspace: executor instanceof WorkspaceExecutor ? executor : executor.workspace, name });
3649
3233
  }
3650
3234
  #akanConfig = null;
3651
3235
  async getConfig({ refresh } = {}) {
@@ -3668,9 +3252,7 @@ class PkgExecutor extends Executor {
3668
3252
  this.dist = new Executor(`dist/${name}`, `${this.workspace.workspaceRoot}/dist/pkgs/${name}`);
3669
3253
  }
3670
3254
  static from(executor, name) {
3671
- if (executor instanceof WorkspaceExecutor)
3672
- return new PkgExecutor({ workspace: executor, name });
3673
- return new PkgExecutor({ workspace: executor.workspace, name });
3255
+ return new PkgExecutor({ workspace: executor instanceof WorkspaceExecutor ? executor : executor.workspace, name });
3674
3256
  }
3675
3257
  #scanInfo = null;
3676
3258
  async scan({ refresh } = {}) {
@@ -3688,6 +3270,9 @@ class PkgExecutor extends Executor {
3688
3270
  const rootVersion = rootDeps[dep];
3689
3271
  if (rootVersion)
3690
3272
  return rootVersion;
3273
+ const overrideVersion = rootPackageJson.overrides?.[dep];
3274
+ if (typeof overrideVersion === "string")
3275
+ return overrideVersion;
3691
3276
  try {
3692
3277
  const packageJsonPath = `pkgs/${dep}/package.json`;
3693
3278
  if (!await Bun.file(path8.join(this.workspace.workspaceRoot, packageJsonPath)).exists())
@@ -3713,16 +3298,8 @@ class PkgExecutor extends Executor {
3713
3298
  }
3714
3299
  if (missingDeps.length > 0)
3715
3300
  throw new Error(`Missing dependency versions in root package.json: ${missingDeps.join(", ")}`);
3716
- const toDependencyEntries = (names) => names.map((dep) => {
3717
- const version = dependencyVersions.get(dep);
3718
- if (!version)
3719
- throw new Error(`Missing dependency versions in root package.json: ${dep}`);
3720
- return [dep, version];
3721
- });
3722
- return {
3723
- dependencies: Object.fromEntries(toDependencyEntries(dependencyNames)),
3724
- devDependencies: Object.fromEntries(toDependencyEntries(devDependencyNames))
3725
- };
3301
+ const toDependencyMap = (names) => Object.fromEntries(names.map((dep) => [dep, dependencyVersions.get(dep)]));
3302
+ return { dependencies: toDependencyMap(dependencyNames), devDependencies: toDependencyMap(devDependencyNames) };
3726
3303
  }
3727
3304
  async updatePackageJsonDependencies(dependencies = [], devDependencies = []) {
3728
3305
  const [rootPackageJson, pkgJson] = await Promise.all([this.workspace.getPackageJson(), this.getPackageJson()]);
@@ -3791,4 +3368,4 @@ class ModuleExecutor extends Executor {
3791
3368
  }
3792
3369
  }
3793
3370
 
3794
- export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, isScannedRootEntry, AppInfo, Spinner, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
3371
+ export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, Linter, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, isScannedRootEntry, AppInfo, Spinner, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };