@akanjs/cli 2.3.11 → 2.3.12-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -721,6 +721,7 @@ var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
|
|
|
721
721
|
var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
|
|
722
722
|
var NATIVE_RUNTIME_PACKAGES = ["sharp"];
|
|
723
723
|
var DEFAULT_BACKEND_RUNTIME_PACKAGES = ["croner"];
|
|
724
|
+
var MOBILE_RUNTIME_PACKAGES = ["firebase"];
|
|
724
725
|
var DATABASE_MODE_RUNTIME_PACKAGES = {
|
|
725
726
|
single: [],
|
|
726
727
|
multiple: ["@libsql/client", "bullmq", "ioredis", "protobufjs"],
|
|
@@ -730,6 +731,7 @@ var AKAN_RUNTIME_PACKAGES = new Set([
|
|
|
730
731
|
...SSR_RUNTIME_PACKAGES,
|
|
731
732
|
...NATIVE_RUNTIME_PACKAGES,
|
|
732
733
|
...DEFAULT_BACKEND_RUNTIME_PACKAGES,
|
|
734
|
+
...MOBILE_RUNTIME_PACKAGES,
|
|
733
735
|
...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat()
|
|
734
736
|
]);
|
|
735
737
|
var DEFAULT_AKAN_IMAGE_CONFIG = {
|
|
@@ -1013,11 +1015,20 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
1013
1015
|
return [...DATABASE_MODE_RUNTIME_PACKAGES[databaseMode]];
|
|
1014
1016
|
}
|
|
1015
1017
|
getMissingDatabaseModeDependencySpecs(databaseMode = this.defaultDatabaseMode) {
|
|
1018
|
+
return this.#getMissingDependencySpecs(this.getDatabaseModeRuntimePackages(databaseMode));
|
|
1019
|
+
}
|
|
1020
|
+
getMobileRuntimePackages() {
|
|
1021
|
+
return [...MOBILE_RUNTIME_PACKAGES];
|
|
1022
|
+
}
|
|
1023
|
+
getMissingMobileDependencySpecs() {
|
|
1024
|
+
return this.#getMissingDependencySpecs(this.getMobileRuntimePackages());
|
|
1025
|
+
}
|
|
1026
|
+
#getMissingDependencySpecs(libs) {
|
|
1016
1027
|
const rootDependencies = {
|
|
1017
1028
|
...this.rootPackageJson.dependencies,
|
|
1018
1029
|
...this.rootPackageJson.devDependencies
|
|
1019
1030
|
};
|
|
1020
|
-
return
|
|
1031
|
+
return libs.filter((lib) => !rootDependencies[lib]).map((lib) => {
|
|
1021
1032
|
const version = this.#resolveProductionDependencyVersion(lib);
|
|
1022
1033
|
if (!version)
|
|
1023
1034
|
throw new Error(`Dependency ${lib} not found in package.json`);
|
|
@@ -11490,6 +11501,8 @@ import path28 from "path";
|
|
|
11490
11501
|
var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit"]);
|
|
11491
11502
|
var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
|
|
11492
11503
|
var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
11504
|
+
var FACET_PASCAL_CASE_RE = /^[A-Z][A-Za-z0-9]*$/;
|
|
11505
|
+
var FACET_CAMEL_CASE_RE = /^[a-z][A-Za-z0-9]*$/;
|
|
11493
11506
|
var MODULE_UI_TYPES = ["Template", "Unit", "Util", "View", "Zone"];
|
|
11494
11507
|
var SERVICE_UI_TYPES = ["Util", "Zone"];
|
|
11495
11508
|
var SCALAR_UI_TYPES = ["Template", "Unit"];
|
|
@@ -11586,18 +11599,20 @@ class DevGeneratedIndexSync {
|
|
|
11586
11599
|
return this.#moduleContent(path28.dirname(indexPath));
|
|
11587
11600
|
}
|
|
11588
11601
|
async#facetContent(dir) {
|
|
11602
|
+
const nameCasePattern = path28.basename(dir) === "ui" ? FACET_PASCAL_CASE_RE : FACET_CAMEL_CASE_RE;
|
|
11589
11603
|
const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
|
|
11590
11604
|
const exportNames = entries.flatMap((entry) => {
|
|
11591
11605
|
const name = entry.name;
|
|
11592
11606
|
if (name.startsWith("."))
|
|
11593
11607
|
return [];
|
|
11594
11608
|
if (entry.isDirectory())
|
|
11595
|
-
return [name];
|
|
11609
|
+
return nameCasePattern.test(name) ? [name] : [];
|
|
11596
11610
|
if (!entry.isFile())
|
|
11597
11611
|
return [];
|
|
11598
11612
|
if (!FACET_SOURCE_FILE_RE.test(name) || FACET_EXCLUDED_FILE_RE.test(name))
|
|
11599
11613
|
return [];
|
|
11600
|
-
|
|
11614
|
+
const exportName = name.replace(FACET_SOURCE_FILE_RE, "");
|
|
11615
|
+
return nameCasePattern.test(exportName) ? [exportName] : [];
|
|
11601
11616
|
}).sort();
|
|
11602
11617
|
if (exportNames.length === 0)
|
|
11603
11618
|
return null;
|
package/index.js
CHANGED
|
@@ -719,6 +719,7 @@ var WORKSPACE_BARREL_FACETS = ["ui", "webkit", "common", "client", "server"];
|
|
|
719
719
|
var SSR_RUNTIME_PACKAGES = ["react", "react-dom", "react-server-dom-webpack"];
|
|
720
720
|
var NATIVE_RUNTIME_PACKAGES = ["sharp"];
|
|
721
721
|
var DEFAULT_BACKEND_RUNTIME_PACKAGES = ["croner"];
|
|
722
|
+
var MOBILE_RUNTIME_PACKAGES = ["firebase"];
|
|
722
723
|
var DATABASE_MODE_RUNTIME_PACKAGES = {
|
|
723
724
|
single: [],
|
|
724
725
|
multiple: ["@libsql/client", "bullmq", "ioredis", "protobufjs"],
|
|
@@ -728,6 +729,7 @@ var AKAN_RUNTIME_PACKAGES = new Set([
|
|
|
728
729
|
...SSR_RUNTIME_PACKAGES,
|
|
729
730
|
...NATIVE_RUNTIME_PACKAGES,
|
|
730
731
|
...DEFAULT_BACKEND_RUNTIME_PACKAGES,
|
|
732
|
+
...MOBILE_RUNTIME_PACKAGES,
|
|
731
733
|
...Object.values(DATABASE_MODE_RUNTIME_PACKAGES).flat()
|
|
732
734
|
]);
|
|
733
735
|
var DEFAULT_AKAN_IMAGE_CONFIG = {
|
|
@@ -1011,11 +1013,20 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
|
|
|
1011
1013
|
return [...DATABASE_MODE_RUNTIME_PACKAGES[databaseMode]];
|
|
1012
1014
|
}
|
|
1013
1015
|
getMissingDatabaseModeDependencySpecs(databaseMode = this.defaultDatabaseMode) {
|
|
1016
|
+
return this.#getMissingDependencySpecs(this.getDatabaseModeRuntimePackages(databaseMode));
|
|
1017
|
+
}
|
|
1018
|
+
getMobileRuntimePackages() {
|
|
1019
|
+
return [...MOBILE_RUNTIME_PACKAGES];
|
|
1020
|
+
}
|
|
1021
|
+
getMissingMobileDependencySpecs() {
|
|
1022
|
+
return this.#getMissingDependencySpecs(this.getMobileRuntimePackages());
|
|
1023
|
+
}
|
|
1024
|
+
#getMissingDependencySpecs(libs) {
|
|
1014
1025
|
const rootDependencies = {
|
|
1015
1026
|
...this.rootPackageJson.dependencies,
|
|
1016
1027
|
...this.rootPackageJson.devDependencies
|
|
1017
1028
|
};
|
|
1018
|
-
return
|
|
1029
|
+
return libs.filter((lib) => !rootDependencies[lib]).map((lib) => {
|
|
1019
1030
|
const version = this.#resolveProductionDependencyVersion(lib);
|
|
1020
1031
|
if (!version)
|
|
1021
1032
|
throw new Error(`Dependency ${lib} not found in package.json`);
|
|
@@ -11488,6 +11499,8 @@ import path28 from "path";
|
|
|
11488
11499
|
var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit"]);
|
|
11489
11500
|
var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
|
|
11490
11501
|
var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
11502
|
+
var FACET_PASCAL_CASE_RE = /^[A-Z][A-Za-z0-9]*$/;
|
|
11503
|
+
var FACET_CAMEL_CASE_RE = /^[a-z][A-Za-z0-9]*$/;
|
|
11491
11504
|
var MODULE_UI_TYPES = ["Template", "Unit", "Util", "View", "Zone"];
|
|
11492
11505
|
var SERVICE_UI_TYPES = ["Util", "Zone"];
|
|
11493
11506
|
var SCALAR_UI_TYPES = ["Template", "Unit"];
|
|
@@ -11584,18 +11597,20 @@ class DevGeneratedIndexSync {
|
|
|
11584
11597
|
return this.#moduleContent(path28.dirname(indexPath));
|
|
11585
11598
|
}
|
|
11586
11599
|
async#facetContent(dir) {
|
|
11600
|
+
const nameCasePattern = path28.basename(dir) === "ui" ? FACET_PASCAL_CASE_RE : FACET_CAMEL_CASE_RE;
|
|
11587
11601
|
const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
|
|
11588
11602
|
const exportNames = entries.flatMap((entry) => {
|
|
11589
11603
|
const name = entry.name;
|
|
11590
11604
|
if (name.startsWith("."))
|
|
11591
11605
|
return [];
|
|
11592
11606
|
if (entry.isDirectory())
|
|
11593
|
-
return [name];
|
|
11607
|
+
return nameCasePattern.test(name) ? [name] : [];
|
|
11594
11608
|
if (!entry.isFile())
|
|
11595
11609
|
return [];
|
|
11596
11610
|
if (!FACET_SOURCE_FILE_RE.test(name) || FACET_EXCLUDED_FILE_RE.test(name))
|
|
11597
11611
|
return [];
|
|
11598
|
-
|
|
11612
|
+
const exportName = name.replace(FACET_SOURCE_FILE_RE, "");
|
|
11613
|
+
return nameCasePattern.test(exportName) ? [exportName] : [];
|
|
11599
11614
|
}).sort();
|
|
11600
11615
|
if (exportNames.length === 0)
|
|
11601
11616
|
return null;
|
|
@@ -17161,6 +17176,31 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
17161
17176
|
throw error;
|
|
17162
17177
|
}
|
|
17163
17178
|
}
|
|
17179
|
+
async confirmMobileDependencyInstall(installSpecs) {
|
|
17180
|
+
return await confirm3({
|
|
17181
|
+
message: [`Mobile builds require missing dependencies: ${installSpecs.join(", ")}.`, "Install them now?"].join(" "),
|
|
17182
|
+
default: true
|
|
17183
|
+
});
|
|
17184
|
+
}
|
|
17185
|
+
async syncMobileDependencies(app, akanConfig3) {
|
|
17186
|
+
const installSpecs = akanConfig3.getMissingMobileDependencySpecs();
|
|
17187
|
+
if (installSpecs.length === 0)
|
|
17188
|
+
return;
|
|
17189
|
+
const shouldInstall = await this.confirmMobileDependencyInstall(installSpecs);
|
|
17190
|
+
if (!shouldInstall)
|
|
17191
|
+
throw new Error(`Mobile builds require missing dependencies: ${installSpecs.join(", ")}.`);
|
|
17192
|
+
const spinner2 = app.workspace.spinning("Installing mobile dependencies...");
|
|
17193
|
+
try {
|
|
17194
|
+
await app.workspace.spawn("bun", ["add", ...installSpecs], {
|
|
17195
|
+
stdio: "inherit"
|
|
17196
|
+
});
|
|
17197
|
+
await app.workspace.getPackageJson({ refresh: true });
|
|
17198
|
+
spinner2.succeed("Installed mobile dependencies");
|
|
17199
|
+
} catch (error) {
|
|
17200
|
+
spinner2.fail("Failed to install mobile dependencies");
|
|
17201
|
+
throw error;
|
|
17202
|
+
}
|
|
17203
|
+
}
|
|
17164
17204
|
async createApplication(appName, workspace, { start = false, libs = [] } = {}) {
|
|
17165
17205
|
const spinner2 = workspace.spinning("Creating application...");
|
|
17166
17206
|
const app = await this.applicationRunner.createApplication(appName, workspace, libs);
|
|
@@ -17282,6 +17322,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
17282
17322
|
noAllowProvisioningUpdates = false
|
|
17283
17323
|
} = {}) {
|
|
17284
17324
|
await app.scanSync({ write });
|
|
17325
|
+
await this.syncMobileDependencies(app, await app.getConfig());
|
|
17285
17326
|
await this.applicationRunner.startIos(app, {
|
|
17286
17327
|
open,
|
|
17287
17328
|
operation,
|
|
@@ -17310,6 +17351,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
17310
17351
|
regenerate = false
|
|
17311
17352
|
} = {}) {
|
|
17312
17353
|
await app.scanSync({ write });
|
|
17354
|
+
await this.syncMobileDependencies(app, await app.getConfig());
|
|
17313
17355
|
await this.applicationRunner.startAndroid(app, {
|
|
17314
17356
|
open,
|
|
17315
17357
|
operation,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.12-rc.0",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@langchain/openai": "^1.4.6",
|
|
35
35
|
"@tailwindcss/node": "^4.3.0",
|
|
36
36
|
"@trapezedev/project": "^7.1.4",
|
|
37
|
-
"akanjs": "2.3.
|
|
37
|
+
"akanjs": "2.3.12-rc.0",
|
|
38
38
|
"chalk": "^5.6.2",
|
|
39
39
|
"commander": "^14.0.3",
|
|
40
40
|
"daisyui": "5.5.23",
|
|
@@ -12,18 +12,24 @@ interface Options {
|
|
|
12
12
|
|
|
13
13
|
const sourceFilePattern = /\.(ts|tsx)$/;
|
|
14
14
|
const excludedFilePattern = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
15
|
+
// `ui` exports PascalCase names only; `common`/`srvkit`/`webkit` export camelCase names only. Names with
|
|
16
|
+
// dots, underscores, or hyphens (e.g. `foo.helper`, `Globe_Dynamic`, `kebab-case`) match neither and are skipped.
|
|
17
|
+
const pascalCasePattern = /^[A-Z][A-Za-z0-9]*$/;
|
|
18
|
+
const camelCasePattern = /^[a-z][A-Za-z0-9]*$/;
|
|
19
|
+
const nameCasePatternForFacet = (facet: string) => (facet === "ui" ? pascalCasePattern : camelCasePattern);
|
|
15
20
|
|
|
16
21
|
export default async function getContent(scanInfo: AppInfo | LibInfo | null, dict: Dict = {}, options: Options = {}) {
|
|
17
22
|
const { exec, facet } = options;
|
|
18
23
|
if (!exec || !facet || !(await exec.exists(facet))) return null;
|
|
19
24
|
|
|
25
|
+
const nameCasePattern = nameCasePatternForFacet(facet);
|
|
20
26
|
const { files, dirs } = await exec.getFilesAndDirs(facet);
|
|
21
27
|
const exportNames = [
|
|
22
28
|
...files
|
|
23
29
|
.filter((filename) => sourceFilePattern.test(filename) && !excludedFilePattern.test(filename))
|
|
24
30
|
.map((filename) => filename.replace(sourceFilePattern, "")),
|
|
25
31
|
...dirs.filter((dirname) => !dirname.startsWith(".")),
|
|
26
|
-
].sort();
|
|
32
|
+
].filter((name) => nameCasePattern.test(name)).sort();
|
|
27
33
|
|
|
28
34
|
if (exportNames.length === 0) return null;
|
|
29
35
|
return {
|
|
@@ -9,5 +9,5 @@ alwaysApply: false
|
|
|
9
9
|
- Use Bun and ESM assumptions from the root `tsconfig.json`.
|
|
10
10
|
- Prefer path aliases over deep relative imports when crossing package boundaries.
|
|
11
11
|
- Use `akanjs/*` for framework facets, `@apps/*` for apps, `@libs/*` for shared libs, and `@contract/*` for contract code.
|
|
12
|
-
- Respect existing client/server entrypoints such as `@libs/shared/client`, `@libs/shared/server`, `@apps
|
|
12
|
+
- Respect existing client/server entrypoints such as `@libs/shared/client`, `@libs/shared/server`, `@apps/myapp/client`, and `@apps/myapp/server`.
|
|
13
13
|
- Let Biome organize imports instead of manually reshuffling unrelated imports.
|