@akanjs/cli 3.0.0-alpha.7 → 3.0.0-alpha.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build-stamp +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/{abstractCompactor-e5yq60qz.js → abstractCompactor-20e0cwbs.js} +2 -2
- package/{agent.command-pggr92jj.js → agent.command-964bf8qg.js} +9 -7
- package/{application.command-692yap1d.js → application.command-n45n18sc.js} +8 -6
- package/{applicationBuildRunner-ha3y8ew8.js → applicationBuildRunner-af0wtspv.js} +19 -14
- package/{applicationReleasePackager-gg8ccbeh.js → applicationReleasePackager-93nzdfsy.js} +1 -1
- package/buildBatch.proc.js +7 -5
- package/{capacitorApp-p0z5yab2.js → capacitorApp-vnvnvdhf.js} +29 -27
- package/{cloud.command-wqfsyzv2.js → cloud.command-kx1bh5yq.js} +12 -10
- package/{context.command-9bxtdn0w.js → context.command-g1a65x6j.js} +17 -15
- package/{dependencyScanner-f6grrep3.js → dependencyScanner-rbs2407b.js} +1 -1
- package/getDirname-ka11hm7e.js +8 -0
- package/{guideline.command-nfqahxex.js → guideline.command-xphyhvwh.js} +8 -6
- package/guidelines/agentRule/agentRule.generate.json +31 -0
- package/guidelines/agentRule/agentRule.instruction.md +525 -0
- package/guidelines/conventions/conventions.generate.json +25 -0
- package/guidelines/conventions/conventions.instruction.md +1020 -0
- package/guidelines/cssRule/cssRule.instruction.md +7 -0
- package/guidelines/framework/framework.instruction.md +1 -0
- package/guidelines/mcpRule/mcpRule.generate.json +25 -0
- package/guidelines/mcpRule/mcpRule.instruction.md +220 -0
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +638 -0
- package/incrementalBuilder.proc.js +8 -6
- package/{index-azv0xjb5.js → index-0ngvvgry.js} +8 -4
- package/index-1577bej2.js +7 -0
- package/{index-p3f4q532.js → index-4rw4qhe6.js} +14 -13
- package/{index-bjpxzr6s.js → index-5vy2jzar.js} +1 -1
- package/{index-js368gk9.js → index-8gybxemv.js} +6 -6
- package/{index-qb61h0k7.js → index-abyjt72y.js} +333 -540
- package/{index-4hek879p.js → index-bqqts262.js} +1 -1
- package/{index-6rhabeev.js → index-e31ghfp5.js} +5 -3
- package/index-f39512t6.js +255 -0
- package/{index-5pmx7bkg.js → index-fahkq20v.js} +3 -3
- package/{index-xhgtkekh.js → index-hee7egtm.js} +1 -1
- package/{index-7myvn0f0.js → index-j37qq1f2.js} +1 -1
- package/{index-5dw57f0d.js → index-mkn5qagt.js} +14 -14
- package/{index-ztpw544k.js → index-nj3w0r34.js} +3 -3
- package/{index-vg0sj9nc.js → index-nkwmnqwn.js} +257 -97
- package/{index-a1e0j63x.js → index-p681w089.js} +15 -7
- package/{index-j9cxndc0.js → index-qnv0aqmm.js} +9 -6
- package/{index-w6wbb612.js → index-qt4nfr0n.js} +13 -13
- package/{index-bz2sfzzt.js → index-rb65xnw9.js} +4 -4
- package/{index-gex7c8kd.js → index-rbnpe8cp.js} +37 -6
- package/{index-0cj2zxbm.js → index-sh01r3pm.js} +1 -1
- package/{index-gmy45vz2.js → index-v5fdxdre.js} +4 -4
- package/{index-mssqn2sq.js → index-va15r8h5.js} +54 -15
- package/{index-vtj3zps1.js → index-yg3hxk2k.js} +8 -8
- package/{index-2c3e2xh8.js → index-ytaqtc04.js} +1 -1
- package/index.js +21 -19
- package/{library.command-md9715jz.js → library.command-rfpd27yv.js} +6 -4
- package/{localRegistry.command-exkbamyj.js → localRegistry.command-pyxfe0fs.js} +11 -9
- package/{module.command-w5aaddxk.js → module.command-qhaxad0p.js} +10 -8
- package/{package.command-yfkrcy0z.js → package.command-2k22q9nt.js} +6 -4
- package/package.json +4 -5
- package/{page.command-echbavp4.js → page.command-ymk9dqh4.js} +6 -4
- package/{primitive.command-9fbhspw2.js → primitive.command-9k45zpc1.js} +11 -9
- package/{quality.command-3pnt9yep.js → quality.command-bf6vkxe5.js} +192 -97
- package/{recipeScanner-tghkzrrt.js → recipeScanner-zrzev25x.js} +3 -3
- package/{repair.command-carj4vax.js → repair.command-egvvm6xf.js} +8 -6
- package/{routeSourceValidator-e4jmbfcx.js → routeSourceValidator-7fycdqyv.js} +1 -1
- package/{scalar.command-51ryzypc.js → scalar.command-bt1facyj.js} +9 -7
- package/templates/app/env/env.client.debug.ts.template +1 -5
- package/templates/app/env/env.client.develop.ts.template +1 -5
- package/templates/app/env/env.client.local.ts.template +1 -5
- package/templates/app/env/env.client.main.ts.template +1 -5
- package/templates/app/env/env.client.testing.ts.template +1 -5
- package/templates/app/env/env.client.type.ts +2 -6
- package/templates/app/env/env.server.debug.ts.template +1 -5
- package/templates/app/env/env.server.develop.ts.template +1 -5
- package/templates/app/env/env.server.local.ts.template +1 -5
- package/templates/app/env/env.server.main.ts.template +1 -5
- package/templates/app/main.ts +3 -1
- package/templates/app/page/styles.css.template +3 -3
- package/templates/appSample/srvkit/AuthGuard.ts +9 -5
- package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
- package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
- package/templates/crudPages/new/page.tsx +1 -1
- package/templates/crudSinglePage/page.tsx +1 -1
- package/templates/env/_env.server.type.ts +7 -5
- package/templates/lib/db.ts +1 -1
- package/templates/lib/dict.ts +1 -1
- package/templates/lib/sig.ts +1 -1
- package/templates/lib/srv.ts +6 -2
- package/templates/module/__Model__.Util.tsx +1 -1
- package/templates/module/__Model__.Zone.tsx +3 -5
- package/templates/workspaceRoot/AGENTS.md.template +0 -972
- package/templates/workspaceRoot/CLAUDE.md.template +19 -0
- package/templates/workspaceRoot/biome.json.template +4 -244
- package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +10 -14
- package/templates/workspaceRoot/docs/GENERATED.md.template +12 -10
- package/templates/workspaceRoot/package.json.template +1 -1
- package/{typeChecker-kravn7ns.js → typeChecker-g6bh0xfv.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/{workflow.command-91wmvm8k.js → workflow.command-v1n3wg7v.js} +16 -14
- package/{workspace.command-wa10mfd9.js → workspace.command-yvvqvhzz.js} +71 -52
- package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
- package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -34
- package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
- package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
- package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -18
- package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
- package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
- package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
- package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
- package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -19
- package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -62
- package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
- package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
- package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
- package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -99
- package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
- package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
- package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
- package/templates/workspaceRoot/.cursor/rules/ssr-first.mdc.template +0 -59
- package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
- /package/{index-r24hmh0q.js → index-yb2wsc7f.js} +0 -0
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getRootBoundarySegments,
|
|
4
|
+
isRootBoundarySegments
|
|
5
|
+
} from "./index-f39512t6.js";
|
|
2
6
|
import {
|
|
3
7
|
Spinner
|
|
4
8
|
} from "./index-mxvakhsm.js";
|
|
9
|
+
import {
|
|
10
|
+
getDirname
|
|
11
|
+
} from "./index-1577bej2.js";
|
|
5
12
|
import {
|
|
6
13
|
FileSys
|
|
7
14
|
} from "./index-67546d0j.js";
|
|
8
15
|
import {
|
|
9
16
|
__require
|
|
10
|
-
} from "./index-
|
|
17
|
+
} from "./index-yb2wsc7f.js";
|
|
11
18
|
|
|
12
19
|
// pkgs/@akanjs/devkit/executors.ts
|
|
13
20
|
import {
|
|
@@ -30,6 +37,7 @@ import path5 from "path";
|
|
|
30
37
|
import { pathToFileURL } from "url";
|
|
31
38
|
import {
|
|
32
39
|
capitalize,
|
|
40
|
+
getPageSourceFileViolation,
|
|
33
41
|
isRouteSourceFile,
|
|
34
42
|
Logger,
|
|
35
43
|
parseRouteModuleKey,
|
|
@@ -41,9 +49,24 @@ import chalk2 from "chalk";
|
|
|
41
49
|
|
|
42
50
|
// pkgs/@akanjs/devkit/agentsIndex.ts
|
|
43
51
|
var recipeScannerLoad = null;
|
|
44
|
-
var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-
|
|
52
|
+
var loadRecipeScanner = () => recipeScannerLoad ??= import("./recipeScanner-zrzev25x.js");
|
|
45
53
|
var AGENT_BLOCK_START = "<!-- akan:agent:start -->";
|
|
46
54
|
var AGENT_BLOCK_END = "<!-- akan:agent:end -->";
|
|
55
|
+
var AGENT_VERSION_PREFIX = "<!-- akan:agent:version ";
|
|
56
|
+
var stampBlockVersion = (block, version) => `${AGENT_VERSION_PREFIX}${version} -->
|
|
57
|
+
|
|
58
|
+
${block}`;
|
|
59
|
+
var extractBlockVersion = (content) => content.match(/<!-- akan:agent:version ([^\s]+) -->/)?.[1] ?? null;
|
|
60
|
+
var readDevkitVersion = async () => {
|
|
61
|
+
const { readFile } = await import("fs/promises");
|
|
62
|
+
const { getDirname: getDirname2 } = await import("./getDirname-ka11hm7e.js");
|
|
63
|
+
try {
|
|
64
|
+
const raw = await readFile(`${getDirname2(import.meta.url)}/package.json`, "utf-8");
|
|
65
|
+
return JSON.parse(raw).version ?? null;
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
47
70
|
var upsertAgentBlock = (existing, block) => {
|
|
48
71
|
const managed = `${AGENT_BLOCK_START}
|
|
49
72
|
${block}
|
|
@@ -137,9 +160,29 @@ ${AGENT_BLOCK_START}
|
|
|
137
160
|
${block}
|
|
138
161
|
${AGENT_BLOCK_END}
|
|
139
162
|
`;
|
|
163
|
+
var CLAUDE_COMMENT_RULE = `## Comments \u2014 Overrides Your Default
|
|
164
|
+
|
|
165
|
+
Write **no comments** unless the comment passes the test below. This is the rule agents break most often here, so it
|
|
166
|
+
is repeated outside the guide: a diff that adds a comment the test rejects is a diff to redo.
|
|
167
|
+
|
|
168
|
+
Before typing \`//\`, \`/*\`, or a doc block, ask \u2014 **does this sentence carry a fact that is nowhere in the code?**
|
|
169
|
+
|
|
170
|
+
- Restates the identifier, the signature, or the line under it \u2192 delete it.
|
|
171
|
+
- Labels a section (\`// helpers\`, \`// state\`) or narrates a step (\`// fetch the user\`, \`// then save\`) \u2192 delete it.
|
|
172
|
+
- JSDoc on an ordinary function, or a why/how preamble on ordinary logic \u2192 delete it.
|
|
173
|
+
- Explains the edit you just made, for whoever reads the diff \u2192 say it in your reply, not in the file.
|
|
174
|
+
- Names a vendor or protocol quirk, an infrastructure constraint, a library gotcha, security reasoning, a math
|
|
175
|
+
derivation, a domain field's business meaning, a state transition, or why an obvious alternative was rejected \u2192
|
|
176
|
+
keep it, one line.
|
|
177
|
+
|
|
178
|
+
That keep-list is exact \u2014 \`Comments\` in the guide is the full version. "It aids readability" and "this logic is
|
|
179
|
+
subtle" are not on it: rename or split the code instead. When you edit an existing file, match its density; if the
|
|
180
|
+
surrounding code carries none, your diff carries none.`;
|
|
140
181
|
var renderScopeClaudeMd = (scope) => `# ${scope.name} \u2014 Claude Code Guide
|
|
141
182
|
|
|
142
183
|
@AGENTS.md
|
|
184
|
+
|
|
185
|
+
${CLAUDE_COMMENT_RULE}
|
|
143
186
|
`;
|
|
144
187
|
|
|
145
188
|
// pkgs/@akanjs/devkit/akanConfig/akanConfig.ts
|
|
@@ -181,9 +224,8 @@ var DEFAULT_OPTIMIZE_IMPORTS = [
|
|
|
181
224
|
"react-icons/*"
|
|
182
225
|
];
|
|
183
226
|
var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
|
|
227
|
+
var DEFAULT_DOCKER_IMAGE = "oven/bun:1-slim";
|
|
184
228
|
var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
|
|
185
|
-
var NATIVE_RUNTIME_PACKAGES = ["sharp"];
|
|
186
|
-
var DEFAULT_BACKEND_RUNTIME_PACKAGES = ["croner"];
|
|
187
229
|
var MOBILE_RUNTIME_PACKAGES = [
|
|
188
230
|
"@capacitor/cli",
|
|
189
231
|
"@capacitor/core",
|
|
@@ -212,8 +254,6 @@ var DATABASE_MODE_RUNTIME_PACKAGES = {
|
|
|
212
254
|
};
|
|
213
255
|
var AKAN_RUNTIME_PACKAGES = new Set([
|
|
214
256
|
...SSR_RUNTIME_PACKAGES,
|
|
215
|
-
...NATIVE_RUNTIME_PACKAGES,
|
|
216
|
-
...DEFAULT_BACKEND_RUNTIME_PACKAGES,
|
|
217
257
|
...MOBILE_RUNTIME_PACKAGES,
|
|
218
258
|
...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat()
|
|
219
259
|
]);
|
|
@@ -228,7 +268,8 @@ var DEFAULT_AKAN_IMAGE_CONFIG = {
|
|
|
228
268
|
dangerouslyAllowSVG: false,
|
|
229
269
|
maximumRedirects: 3,
|
|
230
270
|
fetchTimeoutMs: 7000,
|
|
231
|
-
maxRemoteBytes: 25 * 1024 * 1024
|
|
271
|
+
maxRemoteBytes: 25 * 1024 * 1024,
|
|
272
|
+
maxConcurrency: 0
|
|
232
273
|
};
|
|
233
274
|
var normalizeIndexPath = (indexPath) => {
|
|
234
275
|
const normalized = indexPath?.trim();
|
|
@@ -275,12 +316,28 @@ var normalizeDeepLinks = (deepLinks) => {
|
|
|
275
316
|
...sha256CertFingerprints ? { android: { sha256CertFingerprints } } : {}
|
|
276
317
|
};
|
|
277
318
|
};
|
|
319
|
+
var emptyLibContributions = () => ({
|
|
320
|
+
externalLibs: [],
|
|
321
|
+
docker: { preRuns: [], postRuns: [] },
|
|
322
|
+
keepFonts: []
|
|
323
|
+
});
|
|
324
|
+
var normalizeKeepFonts = (keepFonts) => [
|
|
325
|
+
...new Set((keepFonts ?? []).map((glob) => glob.trim().replace(/^\/+/, "")).filter(Boolean))
|
|
326
|
+
];
|
|
327
|
+
var dedupeDockerRuns = (runs) => {
|
|
328
|
+
const byKey = new Map;
|
|
329
|
+
for (const run of runs)
|
|
330
|
+
byKey.set(typeof run === "string" ? run : JSON.stringify(run), run);
|
|
331
|
+
return [...byKey.values()];
|
|
332
|
+
};
|
|
278
333
|
|
|
279
334
|
class AkanAppConfig {
|
|
280
335
|
app;
|
|
281
336
|
rootPackageJson;
|
|
282
337
|
docker;
|
|
338
|
+
dockerfile;
|
|
283
339
|
defaultDatabaseMode;
|
|
340
|
+
web;
|
|
284
341
|
externalLibs;
|
|
285
342
|
barrelImports;
|
|
286
343
|
optimizeImports;
|
|
@@ -290,6 +347,7 @@ class AkanAppConfig {
|
|
|
290
347
|
mobile;
|
|
291
348
|
hasMobileConfig;
|
|
292
349
|
secrets;
|
|
350
|
+
assets;
|
|
293
351
|
syncPageLibs;
|
|
294
352
|
baseDevEnv;
|
|
295
353
|
libs;
|
|
@@ -298,7 +356,7 @@ class AkanAppConfig {
|
|
|
298
356
|
subRoutes = new Map;
|
|
299
357
|
basePaths = new Set;
|
|
300
358
|
branches = new Set(["debug", "develop", "main"]);
|
|
301
|
-
constructor(app, libs, rootPackageJson, config, baseDevEnv, plugins = []) {
|
|
359
|
+
constructor(app, libs, rootPackageJson, config, baseDevEnv, plugins = [], libContributions = emptyLibContributions()) {
|
|
302
360
|
this.app = app;
|
|
303
361
|
this.rootPackageJson = rootPackageJson;
|
|
304
362
|
this.libs = libs;
|
|
@@ -306,7 +364,7 @@ class AkanAppConfig {
|
|
|
306
364
|
this.plugins = plugins;
|
|
307
365
|
this.#applyRoutes(config?.routes);
|
|
308
366
|
this.defaultDatabaseMode = config?.defaultDatabaseMode ?? "single";
|
|
309
|
-
this.externalLibs = config?.externalLibs ?? [];
|
|
367
|
+
this.externalLibs = [...new Set([...config?.externalLibs ?? [], ...libContributions.externalLibs])];
|
|
310
368
|
this.barrelImports = [
|
|
311
369
|
...DEFAULT_BARREL_IMPORTS,
|
|
312
370
|
...WORKSPACE_BARREL_FACETS.map((facet) => `@apps/${app.name}/${facet}`),
|
|
@@ -320,10 +378,25 @@ class AkanAppConfig {
|
|
|
320
378
|
process.env.AKAN_PUBLIC_LOCALES = this.i18n.locales.join(",");
|
|
321
379
|
this.publicEnv = config?.publicEnv ?? [];
|
|
322
380
|
this.secrets = config?.secrets ?? [];
|
|
381
|
+
this.assets = {
|
|
382
|
+
pruneFonts: config?.assets?.pruneFonts ?? true,
|
|
383
|
+
keepFonts: [
|
|
384
|
+
...normalizeKeepFonts(config?.assets?.keepFonts),
|
|
385
|
+
...libContributions.keepFonts ?? []
|
|
386
|
+
]
|
|
387
|
+
};
|
|
323
388
|
this.syncPageLibs = config?.syncPageLibs ?? false;
|
|
324
389
|
this.hasMobileConfig = Boolean(config.mobile);
|
|
325
390
|
this.mobile = this.#resolveMobileConfig(config.mobile);
|
|
326
|
-
this.
|
|
391
|
+
this.web = this.#resolveWebConfig(config.web);
|
|
392
|
+
this.docker = AkanAppConfig.#resolveDocker(config.docker, libContributions.docker);
|
|
393
|
+
this.dockerfile = this.#makeDockerfile();
|
|
394
|
+
}
|
|
395
|
+
#resolveWebConfig(web) {
|
|
396
|
+
const resolved = typeof web === "object" ? { ssr: true, csr: web.csr } : { ssr: web ?? true, csr: web ?? true };
|
|
397
|
+
if (!resolved.csr && this.hasMobileConfig)
|
|
398
|
+
throw new Error(`apps/${this.app.name}/akan.config.ts turns the CSR bundle off but declares mobile targets; the Capacitor build ships that bundle. Drop the mobile section or leave CSR on.`);
|
|
399
|
+
return resolved;
|
|
327
400
|
}
|
|
328
401
|
#resolveMobileConfig(mobile) {
|
|
329
402
|
const {
|
|
@@ -433,23 +506,31 @@ class AkanAppConfig {
|
|
|
433
506
|
return archs.map((arch) => `FROM ${image[arch] ?? defaultImage} AS ${arch}`).join(`
|
|
434
507
|
`);
|
|
435
508
|
}
|
|
436
|
-
#
|
|
437
|
-
if (docker
|
|
438
|
-
return
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const
|
|
509
|
+
static #resolveDocker(docker, libDocker) {
|
|
510
|
+
if (typeof docker === "string")
|
|
511
|
+
return docker;
|
|
512
|
+
return {
|
|
513
|
+
image: docker?.image ?? DEFAULT_DOCKER_IMAGE,
|
|
514
|
+
preRuns: dedupeDockerRuns([...libDocker.preRuns, ...docker?.preRuns ?? []]),
|
|
515
|
+
postRuns: dedupeDockerRuns([...libDocker.postRuns, ...docker?.postRuns ?? []]),
|
|
516
|
+
command: docker?.command ?? ["bun", "main.js"]
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
#makeDockerfile() {
|
|
520
|
+
if (typeof this.docker === "string")
|
|
521
|
+
return this.docker;
|
|
522
|
+
const { image, preRuns, postRuns, command } = this.docker;
|
|
523
|
+
const preRunScripts = this.#getDockerRunScripts(preRuns);
|
|
524
|
+
const postRunScripts = this.#getDockerRunScripts(postRuns);
|
|
525
|
+
const imageScript = this.#getDockerImageScript(image, DEFAULT_DOCKER_IMAGE);
|
|
526
|
+
const webEnvLines = [
|
|
527
|
+
...this.web.ssr ? [] : ["ENV AKAN_SSR=false"],
|
|
528
|
+
...this.web.csr ? [] : ["ENV AKAN_CSR=false"]
|
|
529
|
+
].join(`
|
|
530
|
+
`);
|
|
531
|
+
return `${imageScript}
|
|
532
|
+
RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends ca-certificates tzdata && rm -rf /var/lib/apt/lists/*
|
|
450
533
|
RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
|
|
451
|
-
RUN apt-get update && apt-get upgrade -y
|
|
452
|
-
RUN apt-get install -y --no-install-recommends git redis build-essential python3 ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils udev ffmpeg
|
|
453
534
|
ARG TARGETARCH
|
|
454
535
|
${preRunScripts.join(`
|
|
455
536
|
`)}
|
|
@@ -470,15 +551,8 @@ ${this.basePaths.size ? `ENV AKAN_PUBLIC_BASE_PATHS=${[...this.basePaths].join("
|
|
|
470
551
|
ENV AKAN_PUBLIC_DEFAULT_LOCALE=${this.i18n.defaultLocale}
|
|
471
552
|
ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
|
|
472
553
|
ENV AKAN_PUBLIC_OPERATION_MODE=cloud
|
|
473
|
-
|
|
554
|
+
${webEnvLines}
|
|
474
555
|
CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
475
|
-
return {
|
|
476
|
-
content,
|
|
477
|
-
image: imageScript,
|
|
478
|
-
preRuns: docker.preRuns ?? [],
|
|
479
|
-
postRuns: docker.postRuns ?? [],
|
|
480
|
-
command
|
|
481
|
-
};
|
|
482
556
|
}
|
|
483
557
|
static #importGeneration = 0;
|
|
484
558
|
static async importConfigModule(cwdPath, { bustImportCache = false } = {}) {
|
|
@@ -495,7 +569,22 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
495
569
|
]);
|
|
496
570
|
const resolved = typeof configImp === "function" ? configImp(app) : configImp;
|
|
497
571
|
const { plugins, ...config } = resolved ?? {};
|
|
498
|
-
|
|
572
|
+
const libContributions = await AkanAppConfig.#collectLibContributions(app, libs, bustImportCache);
|
|
573
|
+
return new AkanAppConfig(app, libs, rootPackageJson, config, baseDevEnv, plugins ?? [], libContributions);
|
|
574
|
+
}
|
|
575
|
+
static async#collectLibContributions(app, libs, bustImportCache) {
|
|
576
|
+
const libConfigs = await Promise.all(libs.map(async (libName) => LibExecutor.from(app, libName).getConfig({ refresh: bustImportCache }).catch((error) => {
|
|
577
|
+
app.logger.warn(`Skipped libs/${libName}/akan.config.ts contributions: ${String(error)}`);
|
|
578
|
+
return null;
|
|
579
|
+
})));
|
|
580
|
+
return {
|
|
581
|
+
externalLibs: libConfigs.flatMap((libConfig) => libConfig?.externalLibs ?? []),
|
|
582
|
+
docker: {
|
|
583
|
+
preRuns: libConfigs.flatMap((libConfig) => libConfig?.docker.preRuns ?? []),
|
|
584
|
+
postRuns: libConfigs.flatMap((libConfig) => libConfig?.docker.postRuns ?? [])
|
|
585
|
+
},
|
|
586
|
+
keepFonts: libConfigs.flatMap((libConfig) => (libConfig?.assets.keepFonts ?? []).map((glob) => `libs/${libConfig?.lib.name}/${glob}`))
|
|
587
|
+
};
|
|
499
588
|
}
|
|
500
589
|
#resolveProductionDependencyVersion(lib) {
|
|
501
590
|
const rootVersion = this.rootPackageJson.dependencies?.[lib] ?? this.rootPackageJson.devDependencies?.[lib];
|
|
@@ -505,13 +594,7 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
505
594
|
return akanPackageJson.dependencies?.[lib] ?? akanPackageJson.peerDependencies?.[lib];
|
|
506
595
|
}
|
|
507
596
|
#getProductionRuntimePackages() {
|
|
508
|
-
return [
|
|
509
|
-
...this.externalLibs,
|
|
510
|
-
...SSR_RUNTIME_PACKAGES,
|
|
511
|
-
...NATIVE_RUNTIME_PACKAGES,
|
|
512
|
-
...DEFAULT_BACKEND_RUNTIME_PACKAGES,
|
|
513
|
-
...this.getDatabaseModeRuntimePackages()
|
|
514
|
-
];
|
|
597
|
+
return [...this.externalLibs, ...SSR_RUNTIME_PACKAGES, ...this.getDatabaseModeRuntimePackages()];
|
|
515
598
|
}
|
|
516
599
|
getDatabaseModeRuntimePackages(databaseMode = this.defaultDatabaseMode) {
|
|
517
600
|
return [...DATABASE_MODE_RUNTIME_PACKAGES[databaseMode]];
|
|
@@ -599,14 +682,18 @@ function mergeImageConfig(config = {}) {
|
|
|
599
682
|
class AkanLibConfig {
|
|
600
683
|
lib;
|
|
601
684
|
externalLibs;
|
|
685
|
+
docker;
|
|
686
|
+
assets;
|
|
602
687
|
plugins;
|
|
603
688
|
constructor(lib, config, plugins = []) {
|
|
604
689
|
this.lib = lib;
|
|
605
690
|
this.externalLibs = config?.externalLibs ?? [];
|
|
691
|
+
this.docker = { preRuns: config?.docker?.preRuns ?? [], postRuns: config?.docker?.postRuns ?? [] };
|
|
692
|
+
this.assets = { keepFonts: normalizeKeepFonts(config?.assets?.keepFonts) };
|
|
606
693
|
this.plugins = plugins;
|
|
607
694
|
}
|
|
608
|
-
static async from(lib) {
|
|
609
|
-
const
|
|
695
|
+
static async from(lib, { bustImportCache = false } = {}) {
|
|
696
|
+
const configImp = await AkanAppConfig.importConfigModule(lib.cwdPath, { bustImportCache });
|
|
610
697
|
const resolved = typeof configImp === "function" ? configImp(lib) : configImp;
|
|
611
698
|
const { plugins, ...config } = resolved ?? {};
|
|
612
699
|
return new AkanLibConfig(lib, config, plugins ?? []);
|
|
@@ -627,42 +714,47 @@ var decreaseBuildNum = async (app) => {
|
|
|
627
714
|
const akanConfigContent = akanConfig.replace(`buildNum: ${appConfig.mobile.buildNum}`, `buildNum: ${appConfig.mobile.buildNum - 1}`);
|
|
628
715
|
fs.writeFileSync(akanConfigPath, akanConfigContent);
|
|
629
716
|
};
|
|
630
|
-
// pkgs/@akanjs/devkit/getDirname.ts
|
|
631
|
-
import path2 from "path";
|
|
632
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
633
|
-
var getDirname = (url) => path2.dirname(fileURLToPath2(url));
|
|
634
|
-
|
|
635
717
|
// pkgs/@akanjs/devkit/linter.ts
|
|
636
718
|
import { spawn } from "child_process";
|
|
637
719
|
import { existsSync, readFileSync } from "fs";
|
|
638
|
-
import
|
|
720
|
+
import path2 from "path";
|
|
639
721
|
import chalk from "chalk";
|
|
722
|
+
var BIOME_CONFIG_FILES = ["biome.json", "biome.jsonc"];
|
|
640
723
|
|
|
641
724
|
class Linter {
|
|
642
725
|
lintRoot;
|
|
726
|
+
configPath;
|
|
643
727
|
#biomeBin;
|
|
644
728
|
constructor(cwdPath) {
|
|
645
729
|
this.lintRoot = this.#findBiomeRootPath(cwdPath);
|
|
646
|
-
|
|
730
|
+
this.configPath = Linter.#configPathIn(this.lintRoot) ?? path2.join(this.lintRoot, "biome.json");
|
|
731
|
+
const localBiomeBin = path2.join(this.lintRoot, "node_modules/.bin/biome");
|
|
647
732
|
this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
|
|
648
733
|
}
|
|
734
|
+
static #configPathIn(dir) {
|
|
735
|
+
for (const fileName of BIOME_CONFIG_FILES) {
|
|
736
|
+
const configPath = path2.join(dir, fileName);
|
|
737
|
+
if (existsSync(configPath))
|
|
738
|
+
return configPath;
|
|
739
|
+
}
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
649
742
|
#findBiomeRootPath(dir) {
|
|
650
|
-
|
|
651
|
-
if (existsSync(configPath))
|
|
743
|
+
if (Linter.#configPathIn(dir))
|
|
652
744
|
return dir;
|
|
653
|
-
const parentDir =
|
|
745
|
+
const parentDir = path2.dirname(dir);
|
|
654
746
|
if (parentDir === dir)
|
|
655
747
|
throw new Error(`biome.json not found from ${dir}`);
|
|
656
748
|
return this.#findBiomeRootPath(parentDir);
|
|
657
749
|
}
|
|
658
750
|
#toBiomePath(filePath) {
|
|
659
|
-
const relativePath =
|
|
660
|
-
if (!relativePath.startsWith("..") && !
|
|
751
|
+
const relativePath = path2.relative(this.lintRoot, filePath);
|
|
752
|
+
if (!relativePath.startsWith("..") && !path2.isAbsolute(relativePath))
|
|
661
753
|
return relativePath;
|
|
662
754
|
return filePath;
|
|
663
755
|
}
|
|
664
756
|
#resolveFilePath(filePath) {
|
|
665
|
-
return
|
|
757
|
+
return path2.isAbsolute(filePath) ? filePath : path2.join(this.lintRoot, filePath);
|
|
666
758
|
}
|
|
667
759
|
async#runBiome(args, input) {
|
|
668
760
|
return await new Promise((resolve, reject) => {
|
|
@@ -694,7 +786,7 @@ class Linter {
|
|
|
694
786
|
const diagnosticPath = diagnostic.location?.path;
|
|
695
787
|
if (!diagnosticPath)
|
|
696
788
|
return fallbackFilePath;
|
|
697
|
-
return
|
|
789
|
+
return path2.isAbsolute(diagnosticPath) ? diagnosticPath : path2.join(this.lintRoot, diagnosticPath);
|
|
698
790
|
}
|
|
699
791
|
#createLintMessage(diagnostic) {
|
|
700
792
|
const start = diagnostic.location?.start;
|
|
@@ -759,7 +851,7 @@ class Linter {
|
|
|
759
851
|
"--max-diagnostics=none",
|
|
760
852
|
"--no-errors-on-unmatched",
|
|
761
853
|
"--config-path",
|
|
762
|
-
|
|
854
|
+
this.configPath,
|
|
763
855
|
this.#toBiomePath(filePath)
|
|
764
856
|
]);
|
|
765
857
|
const report = this.#parseBiomeReport(stdout || stderr);
|
|
@@ -880,14 +972,7 @@ ${errorText}, ${warningText} found`];
|
|
|
880
972
|
if (!dryRun)
|
|
881
973
|
return await this.#checkFile(resolvedFilePath, { write: true });
|
|
882
974
|
const source = readFileSync(resolvedFilePath, "utf8");
|
|
883
|
-
const { stdout } = await this.#runBiome([
|
|
884
|
-
"check",
|
|
885
|
-
"--write",
|
|
886
|
-
"--config-path",
|
|
887
|
-
path3.join(this.lintRoot, "biome.json"),
|
|
888
|
-
"--stdin-file-path",
|
|
889
|
-
this.#toBiomePath(resolvedFilePath)
|
|
890
|
-
], source);
|
|
975
|
+
const { stdout } = await this.#runBiome(["check", "--write", "--config-path", this.configPath, "--stdin-file-path", this.#toBiomePath(resolvedFilePath)], source);
|
|
891
976
|
const lintResult = await this.lintFile(resolvedFilePath);
|
|
892
977
|
return { ...lintResult, fixed: stdout !== source, output: stdout };
|
|
893
978
|
}
|
|
@@ -895,7 +980,7 @@ ${errorText}, ${warningText} found`];
|
|
|
895
980
|
const resolvedFilePath = this.#resolveFilePath(filePath);
|
|
896
981
|
if (!existsSync(resolvedFilePath))
|
|
897
982
|
throw new Error(`File not found: ${filePath}`);
|
|
898
|
-
return JSON.parse(readFileSync(
|
|
983
|
+
return JSON.parse(readFileSync(this.configPath, "utf8"));
|
|
899
984
|
}
|
|
900
985
|
async getProblematicRules(filePath) {
|
|
901
986
|
const { results } = await this.lintFile(filePath);
|
|
@@ -910,6 +995,31 @@ ${errorText}, ${warningText} found`];
|
|
|
910
995
|
}
|
|
911
996
|
}
|
|
912
997
|
|
|
998
|
+
// pkgs/@akanjs/devkit/repoIdentity.ts
|
|
999
|
+
import { execFileSync } from "child_process";
|
|
1000
|
+
import path3 from "path";
|
|
1001
|
+
var resolved = new Map;
|
|
1002
|
+
var readRemoteName = (workspaceRoot) => {
|
|
1003
|
+
try {
|
|
1004
|
+
const url = execFileSync("git", ["config", "--get", "remote.origin.url"], {
|
|
1005
|
+
cwd: workspaceRoot,
|
|
1006
|
+
encoding: "utf-8",
|
|
1007
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1008
|
+
}).trim();
|
|
1009
|
+
return url.replace(/\.git$/, "").split(/[/:]/).pop() || null;
|
|
1010
|
+
} catch {
|
|
1011
|
+
return null;
|
|
1012
|
+
}
|
|
1013
|
+
};
|
|
1014
|
+
var resolveRepoName = (workspaceRoot) => {
|
|
1015
|
+
const cached = resolved.get(workspaceRoot);
|
|
1016
|
+
if (cached)
|
|
1017
|
+
return cached;
|
|
1018
|
+
const repoName = readRemoteName(workspaceRoot) ?? path3.basename(workspaceRoot);
|
|
1019
|
+
resolved.set(workspaceRoot, repoName);
|
|
1020
|
+
return repoName;
|
|
1021
|
+
};
|
|
1022
|
+
|
|
913
1023
|
// pkgs/@akanjs/devkit/scanInfo.ts
|
|
914
1024
|
import { rm } from "fs/promises";
|
|
915
1025
|
import path4 from "path";
|
|
@@ -946,6 +1056,34 @@ var appRootAllowedDirs = new Set([
|
|
|
946
1056
|
"ui",
|
|
947
1057
|
"webkit"
|
|
948
1058
|
]);
|
|
1059
|
+
var libRootAllowedFiles = new Set([
|
|
1060
|
+
"AGENTS.md",
|
|
1061
|
+
"CLAUDE.md",
|
|
1062
|
+
"README.md",
|
|
1063
|
+
"akan.config.ts",
|
|
1064
|
+
"akan.lib.json",
|
|
1065
|
+
"client.ts",
|
|
1066
|
+
"index.ts",
|
|
1067
|
+
"package.json",
|
|
1068
|
+
"server.ts",
|
|
1069
|
+
"tsconfig.json",
|
|
1070
|
+
"tsconfig.spec.json",
|
|
1071
|
+
"tsconfig.tsbuildinfo"
|
|
1072
|
+
]);
|
|
1073
|
+
var libRootAllowedDirs = new Set([
|
|
1074
|
+
"common",
|
|
1075
|
+
"env",
|
|
1076
|
+
"lib",
|
|
1077
|
+
"page",
|
|
1078
|
+
"plugin",
|
|
1079
|
+
"private",
|
|
1080
|
+
"public",
|
|
1081
|
+
"srvkit",
|
|
1082
|
+
"ui",
|
|
1083
|
+
"webkit"
|
|
1084
|
+
]);
|
|
1085
|
+
var rootAllowedFiles = { app: appRootAllowedFiles, lib: libRootAllowedFiles };
|
|
1086
|
+
var rootAllowedDirs = { app: appRootAllowedDirs, lib: libRootAllowedDirs };
|
|
949
1087
|
var libFacetRootAllowedFiles = new Set([
|
|
950
1088
|
"cnst.ts",
|
|
951
1089
|
"db.ts",
|
|
@@ -957,7 +1095,9 @@ var libFacetRootAllowedFiles = new Set([
|
|
|
957
1095
|
"useClient.ts",
|
|
958
1096
|
"useServer.ts"
|
|
959
1097
|
]);
|
|
960
|
-
var
|
|
1098
|
+
var libFacetRootTestPattern = /^[A-Za-z][A-Za-z0-9_-]*\.signal\.(test|spec)\.(ts|tsx)$/;
|
|
1099
|
+
var isAllowedLibFacetRootFile = (filename) => libFacetRootAllowedFiles.has(filename) || libFacetRootTestPattern.test(filename);
|
|
1100
|
+
var isScannedRootEntry = (type, name) => !name.startsWith(".") || rootAllowedDirs[type].has(name);
|
|
961
1101
|
|
|
962
1102
|
// pkgs/@akanjs/devkit/scanInfo.ts
|
|
963
1103
|
var databaseFileTypes = [
|
|
@@ -986,10 +1126,8 @@ var moduleUiFileTypes = {
|
|
|
986
1126
|
scalar: new Set(["Template", "Unit"])
|
|
987
1127
|
};
|
|
988
1128
|
var testFilePattern = /\.(test|spec)\.(ts|tsx)$/;
|
|
989
|
-
var
|
|
990
|
-
var createDependencyScanner = async (exec) => (await import("./dependencyScanner-f6grrep3.js")).TypeScriptDependencyScanner.from(exec);
|
|
1129
|
+
var createDependencyScanner = async (exec) => (await import("./dependencyScanner-rbs2407b.js")).TypeScriptDependencyScanner.from(exec);
|
|
991
1130
|
var isAllowedTestFile = (filename) => testFilePattern.test(filename);
|
|
992
|
-
var isAllowedLibRootFile = (filename) => libFacetRootAllowedFiles.has(filename) || rootSignalTestFilePattern.test(filename);
|
|
993
1131
|
var getScanPath = (exec, relativePath) => path4.posix.join(`${exec.type}s`, exec.name, relativePath.split(path4.sep).join("/"));
|
|
994
1132
|
async function clearGeneratedRootCapacitorConfigs(exec) {
|
|
995
1133
|
if (exec.type !== "app")
|
|
@@ -1006,17 +1144,20 @@ async function assertScanConvention(exec, libRoot) {
|
|
|
1006
1144
|
const addViolation = (relativePath, reason) => {
|
|
1007
1145
|
violations.push(`${getScanPath(exec, relativePath)}: ${reason}`);
|
|
1008
1146
|
};
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
});
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
});
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1147
|
+
const allowedRootFiles = rootAllowedFiles[exec.type];
|
|
1148
|
+
const allowedRootDirs = rootAllowedDirs[exec.type];
|
|
1149
|
+
const { files, dirs } = await exec.getFilesAndDirs(".");
|
|
1150
|
+
files.filter((filename) => !allowedRootFiles.has(filename)).forEach((filename) => {
|
|
1151
|
+
addViolation(filename, `unsupported ${exec.type} root file`);
|
|
1152
|
+
});
|
|
1153
|
+
dirs.filter((dirname) => !allowedRootDirs.has(dirname)).forEach((dirname) => {
|
|
1154
|
+
addViolation(dirname, `unsupported ${exec.type} root folder`);
|
|
1155
|
+
});
|
|
1156
|
+
if (exec.type === "lib")
|
|
1157
|
+
for (const { relativePath, reason } of await exec.getPageConventionViolations())
|
|
1158
|
+
addViolation(relativePath, reason);
|
|
1159
|
+
libRoot.files.filter((filename) => !isAllowedLibFacetRootFile(filename)).forEach((filename) => {
|
|
1160
|
+
addViolation(path4.join("lib", filename), "unsupported lib facet root file");
|
|
1020
1161
|
});
|
|
1021
1162
|
libRoot.dirs.filter((dirname) => dirname.startsWith("__") && !internalLibDirs.has(dirname)).forEach((dirname) => {
|
|
1022
1163
|
addViolation(path4.join("lib", dirname), "unsupported internal lib folder");
|
|
@@ -1196,12 +1337,11 @@ class ScanInfo {
|
|
|
1196
1337
|
})
|
|
1197
1338
|
]);
|
|
1198
1339
|
const routes = exec.type === "lib" ? [] : await exec.getPageKeys();
|
|
1199
|
-
const
|
|
1340
|
+
const common = {
|
|
1200
1341
|
name: exec.name,
|
|
1201
1342
|
type: exec.type,
|
|
1202
1343
|
repoName: exec.workspace.repoName,
|
|
1203
1344
|
serveDomain: WorkspaceExecutor.getBaseDevEnv(path4.join(exec.workspace.workspaceRoot, ".env")).serveDomain,
|
|
1204
|
-
akanConfig: akanConfig2,
|
|
1205
1345
|
files,
|
|
1206
1346
|
libDeps,
|
|
1207
1347
|
pkgDeps,
|
|
@@ -1209,6 +1349,7 @@ class ScanInfo {
|
|
|
1209
1349
|
devDependencies: npmDevDeps.filter((dep) => !isAkanFrameworkDependency(dep)),
|
|
1210
1350
|
routes
|
|
1211
1351
|
};
|
|
1352
|
+
const scanResult = akanConfig2 instanceof AkanAppConfig ? { ...common, akanConfig: akanConfig2 } : { ...common, akanConfig: akanConfig2 };
|
|
1212
1353
|
return scanResult;
|
|
1213
1354
|
}
|
|
1214
1355
|
constructor(scanResult) {
|
|
@@ -1634,7 +1775,7 @@ class Executor {
|
|
|
1634
1775
|
}));
|
|
1635
1776
|
});
|
|
1636
1777
|
proc.on("exit", (code, signal) => {
|
|
1637
|
-
if (
|
|
1778
|
+
if (code || signal)
|
|
1638
1779
|
reject(new CommandExecutionError({
|
|
1639
1780
|
command,
|
|
1640
1781
|
cwd,
|
|
@@ -1732,7 +1873,7 @@ class Executor {
|
|
|
1732
1873
|
}));
|
|
1733
1874
|
});
|
|
1734
1875
|
proc.on("exit", (code, signal) => {
|
|
1735
|
-
if (
|
|
1876
|
+
if (code || signal)
|
|
1736
1877
|
reject(new CommandExecutionError({
|
|
1737
1878
|
command: modulePath,
|
|
1738
1879
|
args,
|
|
@@ -1819,7 +1960,8 @@ class Executor {
|
|
|
1819
1960
|
const dir = path5.dirname(writePath);
|
|
1820
1961
|
if (!await FileSys.dirExists(dir))
|
|
1821
1962
|
await mkdir(dir, { recursive: true });
|
|
1822
|
-
let contentStr = typeof content === "string" ? content : JSON.stringify(content, null, 2)
|
|
1963
|
+
let contentStr = typeof content === "string" ? content : `${JSON.stringify(content, null, 2)}
|
|
1964
|
+
`;
|
|
1823
1965
|
if (await FileSys.fileExists(writePath)) {
|
|
1824
1966
|
const currentContent = await FileSys.readText(writePath);
|
|
1825
1967
|
if (currentContent === contentStr || !overwrite) {
|
|
@@ -2028,7 +2170,7 @@ class Executor {
|
|
|
2028
2170
|
return this._applyTemplate({ ...options, dict });
|
|
2029
2171
|
}
|
|
2030
2172
|
async getTypeChecker() {
|
|
2031
|
-
const { TypeChecker } = await import("./typeChecker-
|
|
2173
|
+
const { TypeChecker } = await import("./typeChecker-g6bh0xfv.js");
|
|
2032
2174
|
this.typeChecker ??= new TypeChecker(this);
|
|
2033
2175
|
return this.typeChecker;
|
|
2034
2176
|
}
|
|
@@ -2109,7 +2251,7 @@ class WorkspaceExecutor extends Executor {
|
|
|
2109
2251
|
static #execs = new Map;
|
|
2110
2252
|
static fromRoot({
|
|
2111
2253
|
workspaceRoot = process.cwd(),
|
|
2112
|
-
repoName =
|
|
2254
|
+
repoName = resolveRepoName(workspaceRoot)
|
|
2113
2255
|
} = {}) {
|
|
2114
2256
|
return WorkspaceExecutor.#execs.get(repoName) ?? new WorkspaceExecutor({ workspaceRoot, repoName });
|
|
2115
2257
|
}
|
|
@@ -2297,6 +2439,18 @@ class SysExecutor extends Executor {
|
|
|
2297
2439
|
const path6 = this.type === "app" ? `apps/${this.name}/lib` : `libs/${this.name}/lib`;
|
|
2298
2440
|
return await this.workspace.getDirInModule(path6, this.name);
|
|
2299
2441
|
}
|
|
2442
|
+
async getPageConventionViolations() {
|
|
2443
|
+
if (!await this.exists("page"))
|
|
2444
|
+
return [];
|
|
2445
|
+
const violations = [];
|
|
2446
|
+
for (const entry of await this.getAllFiles("**/*", { cwd: this.getPath("page") })) {
|
|
2447
|
+
const relativePath = entry.split(path5.sep).join("/");
|
|
2448
|
+
const reason = getPageSourceFileViolation(relativePath);
|
|
2449
|
+
if (reason)
|
|
2450
|
+
violations.push({ relativePath: `page/${relativePath}`, reason });
|
|
2451
|
+
}
|
|
2452
|
+
return violations;
|
|
2453
|
+
}
|
|
2300
2454
|
#scanInfo = null;
|
|
2301
2455
|
hasScanInfo() {
|
|
2302
2456
|
return this.#scanInfo !== null;
|
|
@@ -2485,7 +2639,7 @@ class SysExecutor extends Executor {
|
|
|
2485
2639
|
class AppExecutor extends SysExecutor {
|
|
2486
2640
|
static #routeSourceValidator = null;
|
|
2487
2641
|
static async#getRouteSourceValidator() {
|
|
2488
|
-
AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-
|
|
2642
|
+
AppExecutor.#routeSourceValidator ??= (await import("./routeSourceValidator-7fycdqyv.js")).RouteSourceValidator;
|
|
2489
2643
|
return AppExecutor.#routeSourceValidator;
|
|
2490
2644
|
}
|
|
2491
2645
|
dist;
|
|
@@ -2549,10 +2703,15 @@ class AppExecutor extends SysExecutor {
|
|
|
2549
2703
|
await Promise.all([this.dist.mkdir("private"), this.dist.mkdir("public")]);
|
|
2550
2704
|
await Promise.all([
|
|
2551
2705
|
this.cp("private", `${this.dist.cwdPath}/private`, { dereference: true }),
|
|
2552
|
-
this.cp("public", `${this.dist.cwdPath}/public`, { dereference: true })
|
|
2706
|
+
...akanConfig2.web.ssr ? [this.cp("public", `${this.dist.cwdPath}/public`, { dereference: true })] : []
|
|
2553
2707
|
]);
|
|
2554
|
-
} else
|
|
2708
|
+
} else {
|
|
2555
2709
|
await this.removeDir(".akan");
|
|
2710
|
+
if (!akanConfig2.web.ssr || !akanConfig2.web.csr)
|
|
2711
|
+
this.logger.verbose(`akan.config.ts disables web.${!akanConfig2.web.ssr ? "ssr" : "csr"}; \`akan start\` still serves it, \`akan build\` will not`);
|
|
2712
|
+
}
|
|
2713
|
+
if (type === "start")
|
|
2714
|
+
process.env.NODE_ENV = "development";
|
|
2556
2715
|
const devPort = type === "start" ? (await this.getDevPort()).toString() : undefined;
|
|
2557
2716
|
const env = this.getCommandEnv({
|
|
2558
2717
|
AKAN_COMMAND_TYPE: type,
|
|
@@ -2641,7 +2800,8 @@ class AppExecutor extends SysExecutor {
|
|
|
2641
2800
|
}
|
|
2642
2801
|
if (!owner)
|
|
2643
2802
|
owners.set(routeId, { absPath, fromLib });
|
|
2644
|
-
const
|
|
2803
|
+
const layoutSegments = getRootBoundarySegments(key);
|
|
2804
|
+
const isRootLayout = layoutSegments !== null && isRootBoundarySegments(layoutSegments, akanConfig2.basePaths);
|
|
2645
2805
|
const routeSource = await Bun.file(absPath).text();
|
|
2646
2806
|
const validator = await AppExecutor.#getRouteSourceValidator();
|
|
2647
2807
|
if (parsed.kind === "overrides")
|
|
@@ -2869,7 +3029,7 @@ class LibExecutor extends SysExecutor {
|
|
|
2869
3029
|
async getConfig({ refresh } = {}) {
|
|
2870
3030
|
if (this.#akanConfig && !refresh)
|
|
2871
3031
|
return this.#akanConfig;
|
|
2872
|
-
this.#akanConfig = await AkanLibConfig.from(this);
|
|
3032
|
+
this.#akanConfig = await AkanLibConfig.from(this, { bustImportCache: refresh });
|
|
2873
3033
|
return this.#akanConfig;
|
|
2874
3034
|
}
|
|
2875
3035
|
}
|
|
@@ -2966,7 +3126,7 @@ class PkgExecutor extends Executor {
|
|
|
2966
3126
|
default: "./index.ts"
|
|
2967
3127
|
}
|
|
2968
3128
|
},
|
|
2969
|
-
engines: { bun: ">=1.
|
|
3129
|
+
engines: { bun: ">=1.4.0" },
|
|
2970
3130
|
...dependencyMaps
|
|
2971
3131
|
};
|
|
2972
3132
|
await Promise.all([this.dist.writeJson("package.json", distPkgJson), this.writeJson("package.json", distPkgJson)]);
|
|
@@ -3009,4 +3169,4 @@ class ModuleExecutor extends Executor {
|
|
|
3009
3169
|
}
|
|
3010
3170
|
}
|
|
3011
3171
|
|
|
3012
|
-
export { AGENT_BLOCK_START, AGENT_BLOCK_END, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock,
|
|
3172
|
+
export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, isScannedRootEntry, CommandExecutionError, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
|