@akanjs/devkit 2.1.0-rc.6 → 2.1.0-rc.7

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.
@@ -1,4 +1,3 @@
1
- export { archs } from "akanjs";
2
1
  export type {
3
2
  AkanConfigFile,
4
3
  AkanMobileConfig,
@@ -21,3 +20,4 @@ export type {
21
20
  ScanResult,
22
21
  WorkspaceScanResult,
23
22
  } from "akanjs";
23
+ export { archs } from "akanjs";
@@ -51,23 +51,6 @@ const SSR_RENDER_EXTERNALS = [
51
51
  "react-server-dom-webpack/client.browser",
52
52
  ] as const;
53
53
 
54
- const TYPECHECK_WORKER_CODE = `
55
- import { TypeChecker } from "@akanjs/devkit";
56
-
57
- try {
58
- const configPath = process.env.AKAN_TYPECHECK_TSCONFIG;
59
- if (!configPath) throw new Error("AKAN_TYPECHECK_TSCONFIG is required");
60
- const result = TypeChecker.checkProject(configPath);
61
- if (result.errors.length > 0) {
62
- console.error(result.message);
63
- process.exit(1);
64
- }
65
- } catch (error) {
66
- console.error(error instanceof Error ? error.message : String(error));
67
- process.exit(1);
68
- }
69
- `;
70
-
71
54
  export class ApplicationBuildRunner {
72
55
  #app: App;
73
56
  #fast: boolean;
@@ -258,7 +241,8 @@ export class ApplicationBuildRunner {
258
241
  }
259
242
 
260
243
  async #checkProjectInChildProcess(tsconfigPath: string) {
261
- const proc = Bun.spawn([process.execPath, "--eval", TYPECHECK_WORKER_CODE], {
244
+ const entry = await this.#resolveTypecheckWorkerEntry();
245
+ const proc = Bun.spawn([process.execPath, entry], {
262
246
  cwd: this.#app.workspace.workspaceRoot,
263
247
  env: this.#app.getCommandEnv({
264
248
  AKAN_COMMAND_TYPE: "typecheck",
@@ -275,6 +259,17 @@ export class ApplicationBuildRunner {
275
259
  if (exitCode !== 0) throw new Error((stderr || stdout).trim() || `Typecheck failed with exit code ${exitCode}`);
276
260
  }
277
261
 
262
+ async #resolveTypecheckWorkerEntry() {
263
+ const candidates = [
264
+ path.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
265
+ path.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
266
+ path.join(import.meta.dir, "typecheck.proc.js"),
267
+ path.join(import.meta.dir, "typecheck.proc.ts"),
268
+ ];
269
+ for (const candidate of candidates) if (await Bun.file(candidate).exists()) return candidate;
270
+ throw new Error(`[cli] typecheck worker entry not found; looked in: ${candidates.join(", ")}`);
271
+ }
272
+
278
273
  async #buildOrThrow(label: string, config: Bun.BuildConfig): Promise<Bun.BuildOutput> {
279
274
  const result = await Bun.build(config);
280
275
  if (!result.success) throw new AggregateError(result.logs, `[${label}] Bun.build failed`);
package/capacitorApp.ts CHANGED
@@ -217,7 +217,7 @@ export class CapacitorApp {
217
217
  .split(path.sep)
218
218
  .join("/");
219
219
  const content = `import type { AppScanResult } from "akanjs";
220
- import { withBase } from "@akanjs/devkit/capacitor.base.config";
220
+ import { withBase } from "akanjs/capacitor.base.config";
221
221
  import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
222
222
 
223
223
  export default withBase(
@@ -120,12 +120,7 @@ export class CssImportResolver {
120
120
  }
121
121
 
122
122
  #resolutionBases(fromBase: string): string[] {
123
- return [
124
- fromBase,
125
- this.#workspaceRoot,
126
- path.dirname(Bun.main),
127
- path.resolve(path.dirname(Bun.main), "../.."),
128
- ];
123
+ return [fromBase, this.#workspaceRoot, path.dirname(Bun.main), path.resolve(path.dirname(Bun.main), "../..")];
129
124
  }
130
125
 
131
126
  #packageJsonCandidates(pkgName: string): string[] {
@@ -1,5 +1,4 @@
1
1
  import path from "node:path";
2
- import { Logger } from "akanjs/common";
3
2
  import {
4
3
  type App,
5
4
  AppExecutor,
@@ -16,6 +15,7 @@ import {
16
15
  WatchRootResolver,
17
16
  WorkspaceExecutor,
18
17
  } from "@akanjs/devkit";
18
+ import { Logger } from "akanjs/common";
19
19
  import type {
20
20
  BaseBuildArtifact,
21
21
  BuilderEvent,
@@ -6,6 +6,7 @@ JsModuleSource() as $source where {
6
6
  not $source <: or {
7
7
  r"\"\..*",
8
8
  r"\"akanjs.*",
9
+ r"\"@akanjs.*",
9
10
  r"\"@playwright.*",
10
11
  r"\"@radix-ui.*",
11
12
  r"\"@apps/.*",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/devkit",
3
- "version": "2.1.0-rc.6",
3
+ "version": "2.1.0-rc.7",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -23,11 +23,6 @@
23
23
  "default": "./index.ts"
24
24
  },
25
25
  "./package.json": "./package.json",
26
- "./capacitor.base.config": {
27
- "import": "./capacitor.base.config.ts",
28
- "types": "./capacitor.base.config.ts",
29
- "default": "./capacitor.base.config.ts"
30
- },
31
26
  "./*": "./*"
32
27
  },
33
28
  "dependencies": {
@@ -36,7 +31,7 @@
36
31
  "@langchain/deepseek": "^1.0.26",
37
32
  "@langchain/openai": "^1.4.6",
38
33
  "@trapezedev/project": "^7.1.4",
39
- "akanjs": "2.1.0-rc.5",
34
+ "akanjs": "2.1.0-rc.6",
40
35
  "chalk": "^5.6.2",
41
36
  "commander": "^14.0.3",
42
37
  "daisyui": "^5.5.20",
@@ -1,9 +1,9 @@
1
+ import { type AppExecutor, FileSys } from "@akanjs/devkit";
1
2
  import type { CapacitorConfig } from "@capacitor/cli";
2
3
  import { MobileProject } from "@trapezedev/project";
3
4
  import type { AndroidProject } from "@trapezedev/project/dist/android/project";
4
5
  import type { IosProject } from "@trapezedev/project/dist/ios/project";
5
6
  import { capitalize } from "akanjs/common";
6
- import { type AppExecutor, FileSys } from "@akanjs/devkit";
7
7
 
8
8
  import { FileEditor } from "./fileEditor";
9
9
 
@@ -0,0 +1,14 @@
1
+ import { TypeChecker } from "../typeChecker";
2
+
3
+ try {
4
+ const configPath = process.env.AKAN_TYPECHECK_TSCONFIG;
5
+ if (!configPath) throw new Error("AKAN_TYPECHECK_TSCONFIG is required");
6
+ const result = TypeChecker.checkProject(configPath);
7
+ if (result.errors.length > 0) {
8
+ console.error(result.message);
9
+ process.exit(1);
10
+ }
11
+ } catch (error) {
12
+ console.error(error instanceof Error ? error.message : String(error));
13
+ process.exit(1);
14
+ }
@@ -1,88 +0,0 @@
1
- import os from "node:os";
2
- import type { CapacitorConfig } from "@capacitor/cli";
3
- import type { AkanMobileTargetConfig, AppScanResult } from "akanjs";
4
-
5
- const getLocalIP = () => {
6
- const interfaces = os.networkInterfaces();
7
- for (const interfaceName in interfaces) {
8
- const iface = interfaces[interfaceName];
9
- if (!iface) continue;
10
- for (const alias of iface) {
11
- if (alias.family === "IPv4" && !alias.internal) return alias.address;
12
- }
13
- }
14
- return "127.0.0.1"; // fallback to localhost if no suitable IP found
15
- };
16
-
17
- const normalizeBasePath = (basePath: string | undefined) => basePath?.replace(/^\/+|\/+$/g, "");
18
-
19
- const routeBasePaths = (appInfo: AppScanResult) =>
20
- new Set(
21
- appInfo.routes
22
- .map((route) => route.replace(/^\.\//, "").split("/")[0])
23
- .filter((segment): segment is string => !!segment && !segment.startsWith("_") && !segment.startsWith("(")),
24
- );
25
-
26
- const resolveTarget = (appInfo: AppScanResult, targetName = process.env.AKAN_MOBILE_TARGET) => {
27
- const targets = appInfo.akanConfig.mobile.targets;
28
- if (!targets || Object.keys(targets).length === 0) throw new Error("Akan mobile target metadata is missing.");
29
- if (targetName) {
30
- const target = targets[targetName];
31
- if (!target) {
32
- const basePath = normalizeBasePath(targetName);
33
- const [template] = Object.values(targets);
34
- if (basePath && template && routeBasePaths(appInfo).has(basePath))
35
- return { ...template, name: basePath, basePath };
36
- throw new Error(`Akan mobile target '${targetName}' was not found.`);
37
- }
38
- return target;
39
- }
40
- const entries = Object.entries(targets);
41
- if (entries.length !== 1) throw new Error("AKAN_MOBILE_TARGET is required when multiple mobile targets exist.");
42
- return entries[0]?.[1] as AkanMobileTargetConfig;
43
- };
44
-
45
- const localCsrUrl = (ip: string, target: AkanMobileTargetConfig) => {
46
- const basePath = normalizeBasePath(target.basePath);
47
- const port = process.env.AKAN_PUBLIC_CLIENT_PORT ?? process.env.PORT ?? "8282";
48
- return `http://${ip}:${port}/${basePath ? `${basePath}` : ""}?csr=true`;
49
- };
50
-
51
- export const withBase = (
52
- configImp: (config: CapacitorConfig, target: AkanMobileTargetConfig) => CapacitorConfig = (config) => config,
53
- appData?: AppScanResult,
54
- targetName?: string,
55
- ) => {
56
- const ip = getLocalIP();
57
- const appInfo = appData;
58
- if (!appInfo) throw new Error("withBase requires apps/<app>/akan.app.json metadata.");
59
- const target = resolveTarget(appInfo, targetName);
60
- const baseConfig: CapacitorConfig = {
61
- ...target,
62
- appId: target.appId,
63
- appName: target.appName,
64
- webDir: "dist",
65
- server:
66
- process.env.APP_OPERATION_MODE !== "release"
67
- ? {
68
- androidScheme: "http",
69
- url: localCsrUrl(ip, target),
70
- cleartext: true,
71
- allowNavigation: [ip, "localhost"],
72
- }
73
- : {
74
- allowNavigation: ["*"],
75
- },
76
- plugins: {
77
- CapacitorCookies: { enabled: true },
78
- ...target.plugins,
79
- },
80
- android: {
81
- ...target.android,
82
- },
83
- ios: {
84
- ...target.ios,
85
- },
86
- };
87
- return configImp(baseConfig, target);
88
- };