@akanjs/cli 2.1.2-rc.1 → 2.2.0-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.
- package/incrementalBuilder.proc.js +146 -48
- package/index.js +146 -52
- package/package.json +2 -2
|
@@ -20,8 +20,8 @@ import chalk from "chalk";
|
|
|
20
20
|
// pkgs/@akanjs/devkit/cloud/constants.ts
|
|
21
21
|
var basePath = `${Bun.env.HOME ?? Bun.env.USERPROFILE}/.akan`;
|
|
22
22
|
var configPath = `${basePath}/config.json`;
|
|
23
|
-
var akanCloudHost = process.env.
|
|
24
|
-
var akanCloudUrl = `${akanCloudHost}${process.env.
|
|
23
|
+
var akanCloudHost = process.env.USE_AKANJS_PKGS === "true" ? "http://localhost" : "https://cloud.akanjs.com";
|
|
24
|
+
var akanCloudUrl = `${akanCloudHost}${process.env.USE_AKANJS_PKGS === "true" ? ":8282" : ""}/api`;
|
|
25
25
|
var defaultHostConfig = {};
|
|
26
26
|
var defaultAkanGlobalConfig = {
|
|
27
27
|
cloudHost: {},
|
|
@@ -6228,7 +6228,9 @@ import { mkdir as mkdir5, rm, unlink } from "fs/promises";
|
|
|
6228
6228
|
import path21 from "path";
|
|
6229
6229
|
|
|
6230
6230
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
6231
|
+
import fs3 from "fs";
|
|
6231
6232
|
import path20 from "path";
|
|
6233
|
+
import ts5 from "typescript";
|
|
6232
6234
|
|
|
6233
6235
|
class PagesEntrySourceGenerator {
|
|
6234
6236
|
#pageEntries;
|
|
@@ -6257,8 +6259,9 @@ ${lines.join(`
|
|
|
6257
6259
|
const absPath = path20.resolve(moduleAbsPath);
|
|
6258
6260
|
return `import * as page${index} from ${JSON.stringify(absPath)};`;
|
|
6259
6261
|
});
|
|
6260
|
-
const entries = this.#pageEntries.map(({ key }, index) => {
|
|
6261
|
-
|
|
6262
|
+
const entries = this.#pageEntries.map(({ key, moduleAbsPath }, index) => {
|
|
6263
|
+
const isAsyncDefault = PagesEntrySourceGenerator.#hasAsyncDefaultExport(moduleAbsPath);
|
|
6264
|
+
return ` ${JSON.stringify(key)}: { loader: async () => page${index}, isAsyncDefault: ${isAsyncDefault} },`;
|
|
6262
6265
|
});
|
|
6263
6266
|
return `${imports.join(`
|
|
6264
6267
|
`)}
|
|
@@ -6268,6 +6271,63 @@ ${entries.join(`
|
|
|
6268
6271
|
};
|
|
6269
6272
|
`;
|
|
6270
6273
|
}
|
|
6274
|
+
static #hasAsyncDefaultExport(moduleAbsPath) {
|
|
6275
|
+
try {
|
|
6276
|
+
const source = fs3.readFileSync(path20.resolve(moduleAbsPath), "utf8");
|
|
6277
|
+
const sourceFile = ts5.createSourceFile(moduleAbsPath, source, ts5.ScriptTarget.Latest, true, PagesEntrySourceGenerator.#scriptKind(moduleAbsPath));
|
|
6278
|
+
return PagesEntrySourceGenerator.#sourceFileHasAsyncDefaultExport(sourceFile);
|
|
6279
|
+
} catch {
|
|
6280
|
+
return false;
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
static #sourceFileHasAsyncDefaultExport(sourceFile) {
|
|
6284
|
+
const asyncBindings = new Map;
|
|
6285
|
+
let defaultIdentifier = null;
|
|
6286
|
+
for (const statement of sourceFile.statements) {
|
|
6287
|
+
if (ts5.isFunctionDeclaration(statement)) {
|
|
6288
|
+
if (PagesEntrySourceGenerator.#hasModifier(statement, ts5.SyntaxKind.DefaultKeyword)) {
|
|
6289
|
+
return PagesEntrySourceGenerator.#hasModifier(statement, ts5.SyntaxKind.AsyncKeyword);
|
|
6290
|
+
}
|
|
6291
|
+
if (statement.name) {
|
|
6292
|
+
asyncBindings.set(statement.name.text, PagesEntrySourceGenerator.#hasModifier(statement, ts5.SyntaxKind.AsyncKeyword));
|
|
6293
|
+
}
|
|
6294
|
+
continue;
|
|
6295
|
+
}
|
|
6296
|
+
if (ts5.isVariableStatement(statement)) {
|
|
6297
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
6298
|
+
if (!ts5.isIdentifier(declaration.name))
|
|
6299
|
+
continue;
|
|
6300
|
+
asyncBindings.set(declaration.name.text, PagesEntrySourceGenerator.#isAsyncFunctionExpression(declaration.initializer));
|
|
6301
|
+
}
|
|
6302
|
+
continue;
|
|
6303
|
+
}
|
|
6304
|
+
if (ts5.isExportAssignment(statement)) {
|
|
6305
|
+
if (PagesEntrySourceGenerator.#isAsyncFunctionExpression(statement.expression))
|
|
6306
|
+
return true;
|
|
6307
|
+
if (ts5.isIdentifier(statement.expression))
|
|
6308
|
+
defaultIdentifier = statement.expression.text;
|
|
6309
|
+
continue;
|
|
6310
|
+
}
|
|
6311
|
+
if (ts5.isExportDeclaration(statement) && statement.exportClause && ts5.isNamedExports(statement.exportClause)) {
|
|
6312
|
+
const exportClause = statement.exportClause;
|
|
6313
|
+
for (const specifier of exportClause.elements) {
|
|
6314
|
+
if (specifier.name.text !== "default")
|
|
6315
|
+
continue;
|
|
6316
|
+
defaultIdentifier = specifier.propertyName?.text ?? specifier.name.text;
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6319
|
+
}
|
|
6320
|
+
return defaultIdentifier ? asyncBindings.get(defaultIdentifier) === true : false;
|
|
6321
|
+
}
|
|
6322
|
+
static #hasModifier(node, kind) {
|
|
6323
|
+
return ts5.canHaveModifiers(node) && (ts5.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
|
|
6324
|
+
}
|
|
6325
|
+
static #isAsyncFunctionExpression(node) {
|
|
6326
|
+
return Boolean(node && (ts5.isArrowFunction(node) || ts5.isFunctionExpression(node)) && PagesEntrySourceGenerator.#hasModifier(node, ts5.SyntaxKind.AsyncKeyword));
|
|
6327
|
+
}
|
|
6328
|
+
static #scriptKind(moduleAbsPath) {
|
|
6329
|
+
return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? ts5.ScriptKind.TSX : ts5.ScriptKind.TS;
|
|
6330
|
+
}
|
|
6271
6331
|
}
|
|
6272
6332
|
|
|
6273
6333
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
@@ -6403,6 +6463,13 @@ ${remainingAssets.join(`
|
|
|
6403
6463
|
jsFiles.push(jsPath);
|
|
6404
6464
|
return await Bun.file(jsPath).text();
|
|
6405
6465
|
});
|
|
6466
|
+
const bundledCss = (await Promise.all(cssFiles.map((cssFile) => Bun.file(cssFile).text().catch(() => "")))).filter(Boolean).join(`
|
|
6467
|
+
`);
|
|
6468
|
+
if (bundledCss) {
|
|
6469
|
+
const style = CsrArtifactBuilder.createInlineStyle(bundledCss);
|
|
6470
|
+
if (!next.includes(style))
|
|
6471
|
+
next = CsrArtifactBuilder.injectBeforeHeadEnd(next, style);
|
|
6472
|
+
}
|
|
6406
6473
|
if (cssAsset) {
|
|
6407
6474
|
const cssPath = path21.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
6408
6475
|
const css = await Bun.file(cssPath).text();
|
|
@@ -6881,7 +6948,7 @@ import {
|
|
|
6881
6948
|
} from "fontaine";
|
|
6882
6949
|
import { createFont, woff2 } from "fonteditor-core";
|
|
6883
6950
|
import subsetFont from "subset-font";
|
|
6884
|
-
import
|
|
6951
|
+
import ts6 from "typescript";
|
|
6885
6952
|
var FONT_URL_PREFIX = "/_akan/fonts";
|
|
6886
6953
|
var DEFAULT_FONT_SUBSETS = ["latin"];
|
|
6887
6954
|
|
|
@@ -6946,17 +7013,17 @@ class FontOptimizer {
|
|
|
6946
7013
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
6947
7014
|
}
|
|
6948
7015
|
#extractFontsExport(source, filePath) {
|
|
6949
|
-
const sourceFile =
|
|
7016
|
+
const sourceFile = ts6.createSourceFile(filePath, source, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TSX);
|
|
6950
7017
|
const fonts = [];
|
|
6951
7018
|
for (const statement of sourceFile.statements) {
|
|
6952
|
-
if (!
|
|
7019
|
+
if (!ts6.isVariableStatement(statement))
|
|
6953
7020
|
continue;
|
|
6954
|
-
const modifiers =
|
|
6955
|
-
const isExported = modifiers?.some((modifier) => modifier.kind ===
|
|
7021
|
+
const modifiers = ts6.canHaveModifiers(statement) ? ts6.getModifiers(statement) : undefined;
|
|
7022
|
+
const isExported = modifiers?.some((modifier) => modifier.kind === ts6.SyntaxKind.ExportKeyword) ?? false;
|
|
6956
7023
|
if (!isExported)
|
|
6957
7024
|
continue;
|
|
6958
7025
|
for (const declaration of statement.declarationList.declarations) {
|
|
6959
|
-
if (!
|
|
7026
|
+
if (!ts6.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
|
|
6960
7027
|
continue;
|
|
6961
7028
|
const value = declaration.initializer ? this.#literalToValue(declaration.initializer) : null;
|
|
6962
7029
|
if (Array.isArray(value)) {
|
|
@@ -6967,20 +7034,20 @@ class FontOptimizer {
|
|
|
6967
7034
|
return fonts;
|
|
6968
7035
|
}
|
|
6969
7036
|
#literalToValue(node) {
|
|
6970
|
-
if (
|
|
7037
|
+
if (ts6.isStringLiteralLike(node))
|
|
6971
7038
|
return node.text;
|
|
6972
|
-
if (
|
|
7039
|
+
if (ts6.isNumericLiteral(node))
|
|
6973
7040
|
return Number(node.text);
|
|
6974
|
-
if (node.kind ===
|
|
7041
|
+
if (node.kind === ts6.SyntaxKind.TrueKeyword)
|
|
6975
7042
|
return true;
|
|
6976
|
-
if (node.kind ===
|
|
7043
|
+
if (node.kind === ts6.SyntaxKind.FalseKeyword)
|
|
6977
7044
|
return false;
|
|
6978
|
-
if (
|
|
7045
|
+
if (ts6.isArrayLiteralExpression(node))
|
|
6979
7046
|
return node.elements.map((element) => this.#literalToValue(element));
|
|
6980
|
-
if (
|
|
7047
|
+
if (ts6.isObjectLiteralExpression(node)) {
|
|
6981
7048
|
const obj = {};
|
|
6982
7049
|
for (const prop of node.properties) {
|
|
6983
|
-
if (!
|
|
7050
|
+
if (!ts6.isPropertyAssignment(prop))
|
|
6984
7051
|
continue;
|
|
6985
7052
|
const name = this.#getPropertyName(prop.name);
|
|
6986
7053
|
if (!name)
|
|
@@ -6989,13 +7056,13 @@ class FontOptimizer {
|
|
|
6989
7056
|
}
|
|
6990
7057
|
return obj;
|
|
6991
7058
|
}
|
|
6992
|
-
if (
|
|
7059
|
+
if (ts6.isAsExpression(node) || ts6.isSatisfiesExpression(node) || ts6.isParenthesizedExpression(node)) {
|
|
6993
7060
|
return this.#literalToValue(node.expression);
|
|
6994
7061
|
}
|
|
6995
7062
|
return;
|
|
6996
7063
|
}
|
|
6997
7064
|
#getPropertyName(name) {
|
|
6998
|
-
if (
|
|
7065
|
+
if (ts6.isIdentifier(name) || ts6.isStringLiteral(name) || ts6.isNumericLiteral(name))
|
|
6999
7066
|
return name.text;
|
|
7000
7067
|
return null;
|
|
7001
7068
|
}
|
|
@@ -7295,7 +7362,7 @@ class HmrChangeClassifier {
|
|
|
7295
7362
|
}
|
|
7296
7363
|
}
|
|
7297
7364
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7298
|
-
import
|
|
7365
|
+
import fs4 from "fs";
|
|
7299
7366
|
import path26 from "path";
|
|
7300
7367
|
class HmrWatcher {
|
|
7301
7368
|
#roots;
|
|
@@ -7317,7 +7384,7 @@ class HmrWatcher {
|
|
|
7317
7384
|
start() {
|
|
7318
7385
|
for (const root of this.#roots) {
|
|
7319
7386
|
try {
|
|
7320
|
-
const w =
|
|
7387
|
+
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7321
7388
|
if (!filename)
|
|
7322
7389
|
return;
|
|
7323
7390
|
const abs = path26.resolve(root, filename.toString());
|
|
@@ -7612,7 +7679,7 @@ class PagesBundleBuilder {
|
|
|
7612
7679
|
}
|
|
7613
7680
|
}
|
|
7614
7681
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
7615
|
-
import
|
|
7682
|
+
import fs5 from "fs";
|
|
7616
7683
|
import path29 from "path";
|
|
7617
7684
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
7618
7685
|
var MIN_COMPRESS_BYTES = 1024;
|
|
@@ -7626,7 +7693,7 @@ async function precompressArtifacts(app) {
|
|
|
7626
7693
|
return result;
|
|
7627
7694
|
}
|
|
7628
7695
|
async function precompressRoot(root, result) {
|
|
7629
|
-
if (!
|
|
7696
|
+
if (!fs5.existsSync(root) || !fs5.statSync(root).isDirectory())
|
|
7630
7697
|
return;
|
|
7631
7698
|
const glob = new Bun.Glob("**/*");
|
|
7632
7699
|
for await (const filePath of glob.scan({ cwd: root, absolute: true })) {
|
|
@@ -7664,9 +7731,7 @@ function formatBytes(bytes) {
|
|
|
7664
7731
|
import path30 from "path";
|
|
7665
7732
|
import { optimize } from "@tailwindcss/node";
|
|
7666
7733
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
7667
|
-
|
|
7668
|
-
return cssText;
|
|
7669
|
-
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
|
|
7734
|
+
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
7670
7735
|
}
|
|
7671
7736
|
|
|
7672
7737
|
class SsrBaseArtifactBuilder {
|
|
@@ -7773,7 +7838,7 @@ ${preparedCssText}`).toString(36);
|
|
|
7773
7838
|
}
|
|
7774
7839
|
}
|
|
7775
7840
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
7776
|
-
import
|
|
7841
|
+
import fs6 from "fs";
|
|
7777
7842
|
import path31 from "path";
|
|
7778
7843
|
|
|
7779
7844
|
class WatchRootResolver {
|
|
@@ -7793,7 +7858,7 @@ class WatchRootResolver {
|
|
|
7793
7858
|
continue;
|
|
7794
7859
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
7795
7860
|
const resolved = path31.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
7796
|
-
if (
|
|
7861
|
+
if (fs6.existsSync(resolved))
|
|
7797
7862
|
set.add(resolved);
|
|
7798
7863
|
}
|
|
7799
7864
|
}
|
|
@@ -8616,10 +8681,11 @@ class CapacitorApp {
|
|
|
8616
8681
|
iosRootPath = "ios";
|
|
8617
8682
|
iosProjectPath = "ios/App";
|
|
8618
8683
|
androidRootPath = "android";
|
|
8684
|
+
androidAssetsPath = "android/app/src/main/assets";
|
|
8619
8685
|
constructor(app, target) {
|
|
8620
8686
|
this.app = app;
|
|
8621
8687
|
this.target = target;
|
|
8622
|
-
this.targetRootPath = path35.posix.join("mobile", this.target.name);
|
|
8688
|
+
this.targetRootPath = path35.posix.join(".akan", "mobile", this.target.name);
|
|
8623
8689
|
this.targetRoot = path35.join(this.app.cwdPath, this.targetRootPath);
|
|
8624
8690
|
this.targetWebRoot = path35.join(this.targetRoot, "www");
|
|
8625
8691
|
this.targetAssetRoot = path35.join(this.targetRoot, "assets");
|
|
@@ -8699,6 +8765,8 @@ class CapacitorApp {
|
|
|
8699
8765
|
await this.#applyLinks();
|
|
8700
8766
|
await this.project.commit();
|
|
8701
8767
|
await this.#generateAssets({ operation, env });
|
|
8768
|
+
await this.#ensureAndroidAssetsDir();
|
|
8769
|
+
await this.#ensureAndroidDebugKeystore();
|
|
8702
8770
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
8703
8771
|
}
|
|
8704
8772
|
async#updateAndroidBuildTypes() {
|
|
@@ -8746,12 +8814,40 @@ class CapacitorApp {
|
|
|
8746
8814
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
8747
8815
|
stdio: "inherit",
|
|
8748
8816
|
cwd: path35.join(this.app.cwdPath, this.androidRootPath),
|
|
8749
|
-
env: this.#commandEnv("release", env)
|
|
8817
|
+
env: await this.#commandEnv("release", env)
|
|
8750
8818
|
});
|
|
8751
8819
|
}
|
|
8752
8820
|
async openAndroid() {
|
|
8753
8821
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
8754
8822
|
}
|
|
8823
|
+
async#ensureAndroidAssetsDir() {
|
|
8824
|
+
await mkdir10(path35.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
8825
|
+
}
|
|
8826
|
+
async#ensureAndroidDebugKeystore() {
|
|
8827
|
+
const keystorePath = path35.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
8828
|
+
if (await Bun.file(keystorePath).exists())
|
|
8829
|
+
return;
|
|
8830
|
+
await this.#spawn("keytool", [
|
|
8831
|
+
"-genkeypair",
|
|
8832
|
+
"-v",
|
|
8833
|
+
"-keystore",
|
|
8834
|
+
keystorePath,
|
|
8835
|
+
"-storepass",
|
|
8836
|
+
"android",
|
|
8837
|
+
"-alias",
|
|
8838
|
+
"androiddebugkey",
|
|
8839
|
+
"-keypass",
|
|
8840
|
+
"android",
|
|
8841
|
+
"-keyalg",
|
|
8842
|
+
"RSA",
|
|
8843
|
+
"-keysize",
|
|
8844
|
+
"2048",
|
|
8845
|
+
"-validity",
|
|
8846
|
+
"10000",
|
|
8847
|
+
"-dname",
|
|
8848
|
+
"CN=Android Debug,O=Android,C=US"
|
|
8849
|
+
]);
|
|
8850
|
+
}
|
|
8755
8851
|
async syncAndroid(options = {}) {
|
|
8756
8852
|
await this.prepareWww();
|
|
8757
8853
|
await this.#prepareAndroid({ operation: "release", env: "debug", ...options });
|
|
@@ -8793,13 +8889,13 @@ class CapacitorApp {
|
|
|
8793
8889
|
await mkdir10(this.targetRoot, { recursive: true });
|
|
8794
8890
|
const appInfoPath = path35.relative(this.app.cwdPath, path35.join(this.app.cwdPath, "akan.app.json")).split(path35.sep).join("/");
|
|
8795
8891
|
const content = `import type { AppScanResult } from "akanjs";
|
|
8796
|
-
import { withBase } from "akanjs/capacitor.base.config";
|
|
8892
|
+
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
8797
8893
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
8798
8894
|
|
|
8799
8895
|
export default withBase(
|
|
8800
8896
|
(config, target) => ({
|
|
8801
8897
|
...config,
|
|
8802
|
-
webDir:
|
|
8898
|
+
webDir: \`.akan/mobile/\${target.name}/www\`,
|
|
8803
8899
|
android: {
|
|
8804
8900
|
...config.android,
|
|
8805
8901
|
path: "android",
|
|
@@ -8899,12 +8995,14 @@ export default withBase(
|
|
|
8899
8995
|
this.project.android.getAndroidManifest().injectFragment("activity", `<intent-filter android:autoVerify="true"><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:scheme="https" android:host="${host}" android:pathPrefix="${pathPrefix}" /></intent-filter>`);
|
|
8900
8996
|
}
|
|
8901
8997
|
}
|
|
8902
|
-
#commandEnv(operation, env) {
|
|
8998
|
+
async#commandEnv(operation, env) {
|
|
8999
|
+
const devPort = operation === "local" ? (await this.app.getDevPort()).toString() : undefined;
|
|
8903
9000
|
return this.app.getCommandEnv({
|
|
8904
9001
|
APP_OPERATION_MODE: operation,
|
|
8905
9002
|
AKAN_PUBLIC_OPERATION_MODE: env === "local" ? "local" : "cloud",
|
|
8906
9003
|
AKAN_PUBLIC_ENV: env,
|
|
8907
|
-
AKAN_MOBILE_TARGET: this.target.name
|
|
9004
|
+
AKAN_MOBILE_TARGET: this.target.name,
|
|
9005
|
+
...devPort ? { PORT: devPort, AKAN_PUBLIC_CLIENT_PORT: devPort, AKAN_PUBLIC_SERVER_PORT: devPort } : {}
|
|
8908
9006
|
});
|
|
8909
9007
|
}
|
|
8910
9008
|
async#spawn(command, args = [], options = {}) {
|
|
@@ -8913,7 +9011,7 @@ export default withBase(
|
|
|
8913
9011
|
async#spawnMobile(command, args = [], { operation, env }, options = {}) {
|
|
8914
9012
|
return await this.#spawn(command, args, {
|
|
8915
9013
|
...options,
|
|
8916
|
-
env: { ...this.#commandEnv(operation, env), ...options.env }
|
|
9014
|
+
env: { ...await this.#commandEnv(operation, env), ...options.env }
|
|
8917
9015
|
});
|
|
8918
9016
|
}
|
|
8919
9017
|
async addCamera() {
|
|
@@ -9773,7 +9871,7 @@ import yaml from "js-yaml";
|
|
|
9773
9871
|
// pkgs/@akanjs/devkit/getRelatedCnsts.ts
|
|
9774
9872
|
import { readFileSync as readFileSync4, realpathSync } from "fs";
|
|
9775
9873
|
import ora2 from "ora";
|
|
9776
|
-
import * as
|
|
9874
|
+
import * as ts7 from "typescript";
|
|
9777
9875
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
9778
9876
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
9779
9877
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
@@ -9806,10 +9904,10 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
9806
9904
|
return importSpecifiers;
|
|
9807
9905
|
};
|
|
9808
9906
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
9809
|
-
const configFile =
|
|
9810
|
-
return
|
|
9907
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path37) => {
|
|
9908
|
+
return ts7.sys.readFile(path37);
|
|
9811
9909
|
});
|
|
9812
|
-
return
|
|
9910
|
+
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
9813
9911
|
};
|
|
9814
9912
|
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
9815
9913
|
const allFilesToAnalyze = new Set([constantFilePath]);
|
|
@@ -9824,7 +9922,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9824
9922
|
for (const importPath of scanModuleSpecifiers(source, filePath, false)) {
|
|
9825
9923
|
if (!importPath.startsWith("."))
|
|
9826
9924
|
continue;
|
|
9827
|
-
const resolved =
|
|
9925
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, parsedConfig.options, ts7.sys).resolvedModule?.resolvedFileName;
|
|
9828
9926
|
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
9829
9927
|
allFilesToAnalyze.add(resolved);
|
|
9830
9928
|
collectImported(resolved);
|
|
@@ -9841,7 +9939,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9841
9939
|
var createTsProgram = (filePaths, options) => {
|
|
9842
9940
|
const spinner = ora2("Creating TypeScript program for all files...");
|
|
9843
9941
|
spinner.start();
|
|
9844
|
-
const program2 =
|
|
9942
|
+
const program2 = ts7.createProgram(Array.from(filePaths), options);
|
|
9845
9943
|
const checker = program2.getTypeChecker();
|
|
9846
9944
|
spinner.succeed("TypeScript program created.");
|
|
9847
9945
|
return {
|
|
@@ -9881,17 +9979,17 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9881
9979
|
function visit(node) {
|
|
9882
9980
|
if (!source)
|
|
9883
9981
|
return;
|
|
9884
|
-
if (
|
|
9982
|
+
if (ts7.isPropertyAccessExpression(node)) {
|
|
9885
9983
|
const left = node.expression;
|
|
9886
9984
|
const right = node.name;
|
|
9887
|
-
const { line } =
|
|
9888
|
-
if (
|
|
9985
|
+
const { line } = ts7.getLineAndCharacterOfPosition(source, node.getStart());
|
|
9986
|
+
if (ts7.isIdentifier(left) && sourceLines && sourceLines.length > line && sourceLines[line] && (sourceLines[line]?.includes(`@Field.Prop(() => ${left.text}.${right.text}`) || sourceLines[line].includes(`base.Filter(${left.text}.${right.text},`))) {
|
|
9889
9987
|
const symbol = getCachedSymbol(right);
|
|
9890
9988
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
9891
9989
|
const key = symbol.declarations[0]?.getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
9892
9990
|
const property = propertyMap.get(key);
|
|
9893
9991
|
const isScalar = symbol.declarations[0]?.getSourceFile().fileName.includes("_") ?? false;
|
|
9894
|
-
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${
|
|
9992
|
+
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${ts7.sys.getCurrentDirectory()}/`, "");
|
|
9895
9993
|
if (!symbolFilePath)
|
|
9896
9994
|
throw new Error(`No symbol file path found for ${left.text}.${right.text}`);
|
|
9897
9995
|
if (property) {
|
|
@@ -9915,10 +10013,10 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9915
10013
|
}
|
|
9916
10014
|
}
|
|
9917
10015
|
}
|
|
9918
|
-
} else if (
|
|
10016
|
+
} else if (ts7.isImportDeclaration(node) && ts7.isStringLiteral(node.moduleSpecifier)) {
|
|
9919
10017
|
const importPath = node.moduleSpecifier.text;
|
|
9920
10018
|
if (importPath.startsWith(".")) {
|
|
9921
|
-
const resolved =
|
|
10019
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts7.sys).resolvedModule?.resolvedFileName;
|
|
9922
10020
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
9923
10021
|
const property = propertyMap.get(moduleName);
|
|
9924
10022
|
const isScalar = importPath.includes("_");
|
|
@@ -9933,7 +10031,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9933
10031
|
}
|
|
9934
10032
|
}
|
|
9935
10033
|
}
|
|
9936
|
-
|
|
10034
|
+
ts7.forEachChild(node, visit);
|
|
9937
10035
|
}
|
|
9938
10036
|
visit(source);
|
|
9939
10037
|
}
|
package/index.js
CHANGED
|
@@ -18,8 +18,8 @@ import chalk from "chalk";
|
|
|
18
18
|
// pkgs/@akanjs/devkit/cloud/constants.ts
|
|
19
19
|
var basePath = `${Bun.env.HOME ?? Bun.env.USERPROFILE}/.akan`;
|
|
20
20
|
var configPath = `${basePath}/config.json`;
|
|
21
|
-
var akanCloudHost = process.env.
|
|
22
|
-
var akanCloudUrl = `${akanCloudHost}${process.env.
|
|
21
|
+
var akanCloudHost = process.env.USE_AKANJS_PKGS === "true" ? "http://localhost" : "https://cloud.akanjs.com";
|
|
22
|
+
var akanCloudUrl = `${akanCloudHost}${process.env.USE_AKANJS_PKGS === "true" ? ":8282" : ""}/api`;
|
|
23
23
|
var defaultHostConfig = {};
|
|
24
24
|
var defaultAkanGlobalConfig = {
|
|
25
25
|
cloudHost: {},
|
|
@@ -6226,7 +6226,9 @@ import { mkdir as mkdir5, rm, unlink } from "fs/promises";
|
|
|
6226
6226
|
import path21 from "path";
|
|
6227
6227
|
|
|
6228
6228
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
6229
|
+
import fs3 from "fs";
|
|
6229
6230
|
import path20 from "path";
|
|
6231
|
+
import ts5 from "typescript";
|
|
6230
6232
|
|
|
6231
6233
|
class PagesEntrySourceGenerator {
|
|
6232
6234
|
#pageEntries;
|
|
@@ -6255,8 +6257,9 @@ ${lines.join(`
|
|
|
6255
6257
|
const absPath = path20.resolve(moduleAbsPath);
|
|
6256
6258
|
return `import * as page${index} from ${JSON.stringify(absPath)};`;
|
|
6257
6259
|
});
|
|
6258
|
-
const entries = this.#pageEntries.map(({ key }, index) => {
|
|
6259
|
-
|
|
6260
|
+
const entries = this.#pageEntries.map(({ key, moduleAbsPath }, index) => {
|
|
6261
|
+
const isAsyncDefault = PagesEntrySourceGenerator.#hasAsyncDefaultExport(moduleAbsPath);
|
|
6262
|
+
return ` ${JSON.stringify(key)}: { loader: async () => page${index}, isAsyncDefault: ${isAsyncDefault} },`;
|
|
6260
6263
|
});
|
|
6261
6264
|
return `${imports.join(`
|
|
6262
6265
|
`)}
|
|
@@ -6266,6 +6269,63 @@ ${entries.join(`
|
|
|
6266
6269
|
};
|
|
6267
6270
|
`;
|
|
6268
6271
|
}
|
|
6272
|
+
static #hasAsyncDefaultExport(moduleAbsPath) {
|
|
6273
|
+
try {
|
|
6274
|
+
const source = fs3.readFileSync(path20.resolve(moduleAbsPath), "utf8");
|
|
6275
|
+
const sourceFile = ts5.createSourceFile(moduleAbsPath, source, ts5.ScriptTarget.Latest, true, PagesEntrySourceGenerator.#scriptKind(moduleAbsPath));
|
|
6276
|
+
return PagesEntrySourceGenerator.#sourceFileHasAsyncDefaultExport(sourceFile);
|
|
6277
|
+
} catch {
|
|
6278
|
+
return false;
|
|
6279
|
+
}
|
|
6280
|
+
}
|
|
6281
|
+
static #sourceFileHasAsyncDefaultExport(sourceFile) {
|
|
6282
|
+
const asyncBindings = new Map;
|
|
6283
|
+
let defaultIdentifier = null;
|
|
6284
|
+
for (const statement of sourceFile.statements) {
|
|
6285
|
+
if (ts5.isFunctionDeclaration(statement)) {
|
|
6286
|
+
if (PagesEntrySourceGenerator.#hasModifier(statement, ts5.SyntaxKind.DefaultKeyword)) {
|
|
6287
|
+
return PagesEntrySourceGenerator.#hasModifier(statement, ts5.SyntaxKind.AsyncKeyword);
|
|
6288
|
+
}
|
|
6289
|
+
if (statement.name) {
|
|
6290
|
+
asyncBindings.set(statement.name.text, PagesEntrySourceGenerator.#hasModifier(statement, ts5.SyntaxKind.AsyncKeyword));
|
|
6291
|
+
}
|
|
6292
|
+
continue;
|
|
6293
|
+
}
|
|
6294
|
+
if (ts5.isVariableStatement(statement)) {
|
|
6295
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
6296
|
+
if (!ts5.isIdentifier(declaration.name))
|
|
6297
|
+
continue;
|
|
6298
|
+
asyncBindings.set(declaration.name.text, PagesEntrySourceGenerator.#isAsyncFunctionExpression(declaration.initializer));
|
|
6299
|
+
}
|
|
6300
|
+
continue;
|
|
6301
|
+
}
|
|
6302
|
+
if (ts5.isExportAssignment(statement)) {
|
|
6303
|
+
if (PagesEntrySourceGenerator.#isAsyncFunctionExpression(statement.expression))
|
|
6304
|
+
return true;
|
|
6305
|
+
if (ts5.isIdentifier(statement.expression))
|
|
6306
|
+
defaultIdentifier = statement.expression.text;
|
|
6307
|
+
continue;
|
|
6308
|
+
}
|
|
6309
|
+
if (ts5.isExportDeclaration(statement) && statement.exportClause && ts5.isNamedExports(statement.exportClause)) {
|
|
6310
|
+
const exportClause = statement.exportClause;
|
|
6311
|
+
for (const specifier of exportClause.elements) {
|
|
6312
|
+
if (specifier.name.text !== "default")
|
|
6313
|
+
continue;
|
|
6314
|
+
defaultIdentifier = specifier.propertyName?.text ?? specifier.name.text;
|
|
6315
|
+
}
|
|
6316
|
+
}
|
|
6317
|
+
}
|
|
6318
|
+
return defaultIdentifier ? asyncBindings.get(defaultIdentifier) === true : false;
|
|
6319
|
+
}
|
|
6320
|
+
static #hasModifier(node, kind) {
|
|
6321
|
+
return ts5.canHaveModifiers(node) && (ts5.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
|
|
6322
|
+
}
|
|
6323
|
+
static #isAsyncFunctionExpression(node) {
|
|
6324
|
+
return Boolean(node && (ts5.isArrowFunction(node) || ts5.isFunctionExpression(node)) && PagesEntrySourceGenerator.#hasModifier(node, ts5.SyntaxKind.AsyncKeyword));
|
|
6325
|
+
}
|
|
6326
|
+
static #scriptKind(moduleAbsPath) {
|
|
6327
|
+
return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? ts5.ScriptKind.TSX : ts5.ScriptKind.TS;
|
|
6328
|
+
}
|
|
6269
6329
|
}
|
|
6270
6330
|
|
|
6271
6331
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
@@ -6401,6 +6461,13 @@ ${remainingAssets.join(`
|
|
|
6401
6461
|
jsFiles.push(jsPath);
|
|
6402
6462
|
return await Bun.file(jsPath).text();
|
|
6403
6463
|
});
|
|
6464
|
+
const bundledCss = (await Promise.all(cssFiles.map((cssFile) => Bun.file(cssFile).text().catch(() => "")))).filter(Boolean).join(`
|
|
6465
|
+
`);
|
|
6466
|
+
if (bundledCss) {
|
|
6467
|
+
const style = CsrArtifactBuilder.createInlineStyle(bundledCss);
|
|
6468
|
+
if (!next.includes(style))
|
|
6469
|
+
next = CsrArtifactBuilder.injectBeforeHeadEnd(next, style);
|
|
6470
|
+
}
|
|
6404
6471
|
if (cssAsset) {
|
|
6405
6472
|
const cssPath = path21.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
6406
6473
|
const css = await Bun.file(cssPath).text();
|
|
@@ -6879,7 +6946,7 @@ import {
|
|
|
6879
6946
|
} from "fontaine";
|
|
6880
6947
|
import { createFont, woff2 } from "fonteditor-core";
|
|
6881
6948
|
import subsetFont from "subset-font";
|
|
6882
|
-
import
|
|
6949
|
+
import ts6 from "typescript";
|
|
6883
6950
|
var FONT_URL_PREFIX = "/_akan/fonts";
|
|
6884
6951
|
var DEFAULT_FONT_SUBSETS = ["latin"];
|
|
6885
6952
|
|
|
@@ -6944,17 +7011,17 @@ class FontOptimizer {
|
|
|
6944
7011
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
6945
7012
|
}
|
|
6946
7013
|
#extractFontsExport(source, filePath) {
|
|
6947
|
-
const sourceFile =
|
|
7014
|
+
const sourceFile = ts6.createSourceFile(filePath, source, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TSX);
|
|
6948
7015
|
const fonts = [];
|
|
6949
7016
|
for (const statement of sourceFile.statements) {
|
|
6950
|
-
if (!
|
|
7017
|
+
if (!ts6.isVariableStatement(statement))
|
|
6951
7018
|
continue;
|
|
6952
|
-
const modifiers =
|
|
6953
|
-
const isExported = modifiers?.some((modifier) => modifier.kind ===
|
|
7019
|
+
const modifiers = ts6.canHaveModifiers(statement) ? ts6.getModifiers(statement) : undefined;
|
|
7020
|
+
const isExported = modifiers?.some((modifier) => modifier.kind === ts6.SyntaxKind.ExportKeyword) ?? false;
|
|
6954
7021
|
if (!isExported)
|
|
6955
7022
|
continue;
|
|
6956
7023
|
for (const declaration of statement.declarationList.declarations) {
|
|
6957
|
-
if (!
|
|
7024
|
+
if (!ts6.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
|
|
6958
7025
|
continue;
|
|
6959
7026
|
const value = declaration.initializer ? this.#literalToValue(declaration.initializer) : null;
|
|
6960
7027
|
if (Array.isArray(value)) {
|
|
@@ -6965,20 +7032,20 @@ class FontOptimizer {
|
|
|
6965
7032
|
return fonts;
|
|
6966
7033
|
}
|
|
6967
7034
|
#literalToValue(node) {
|
|
6968
|
-
if (
|
|
7035
|
+
if (ts6.isStringLiteralLike(node))
|
|
6969
7036
|
return node.text;
|
|
6970
|
-
if (
|
|
7037
|
+
if (ts6.isNumericLiteral(node))
|
|
6971
7038
|
return Number(node.text);
|
|
6972
|
-
if (node.kind ===
|
|
7039
|
+
if (node.kind === ts6.SyntaxKind.TrueKeyword)
|
|
6973
7040
|
return true;
|
|
6974
|
-
if (node.kind ===
|
|
7041
|
+
if (node.kind === ts6.SyntaxKind.FalseKeyword)
|
|
6975
7042
|
return false;
|
|
6976
|
-
if (
|
|
7043
|
+
if (ts6.isArrayLiteralExpression(node))
|
|
6977
7044
|
return node.elements.map((element) => this.#literalToValue(element));
|
|
6978
|
-
if (
|
|
7045
|
+
if (ts6.isObjectLiteralExpression(node)) {
|
|
6979
7046
|
const obj = {};
|
|
6980
7047
|
for (const prop of node.properties) {
|
|
6981
|
-
if (!
|
|
7048
|
+
if (!ts6.isPropertyAssignment(prop))
|
|
6982
7049
|
continue;
|
|
6983
7050
|
const name = this.#getPropertyName(prop.name);
|
|
6984
7051
|
if (!name)
|
|
@@ -6987,13 +7054,13 @@ class FontOptimizer {
|
|
|
6987
7054
|
}
|
|
6988
7055
|
return obj;
|
|
6989
7056
|
}
|
|
6990
|
-
if (
|
|
7057
|
+
if (ts6.isAsExpression(node) || ts6.isSatisfiesExpression(node) || ts6.isParenthesizedExpression(node)) {
|
|
6991
7058
|
return this.#literalToValue(node.expression);
|
|
6992
7059
|
}
|
|
6993
7060
|
return;
|
|
6994
7061
|
}
|
|
6995
7062
|
#getPropertyName(name) {
|
|
6996
|
-
if (
|
|
7063
|
+
if (ts6.isIdentifier(name) || ts6.isStringLiteral(name) || ts6.isNumericLiteral(name))
|
|
6997
7064
|
return name.text;
|
|
6998
7065
|
return null;
|
|
6999
7066
|
}
|
|
@@ -7293,7 +7360,7 @@ class HmrChangeClassifier {
|
|
|
7293
7360
|
}
|
|
7294
7361
|
}
|
|
7295
7362
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7296
|
-
import
|
|
7363
|
+
import fs4 from "fs";
|
|
7297
7364
|
import path26 from "path";
|
|
7298
7365
|
class HmrWatcher {
|
|
7299
7366
|
#roots;
|
|
@@ -7315,7 +7382,7 @@ class HmrWatcher {
|
|
|
7315
7382
|
start() {
|
|
7316
7383
|
for (const root of this.#roots) {
|
|
7317
7384
|
try {
|
|
7318
|
-
const w =
|
|
7385
|
+
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7319
7386
|
if (!filename)
|
|
7320
7387
|
return;
|
|
7321
7388
|
const abs = path26.resolve(root, filename.toString());
|
|
@@ -7610,7 +7677,7 @@ class PagesBundleBuilder {
|
|
|
7610
7677
|
}
|
|
7611
7678
|
}
|
|
7612
7679
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
7613
|
-
import
|
|
7680
|
+
import fs5 from "fs";
|
|
7614
7681
|
import path29 from "path";
|
|
7615
7682
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
7616
7683
|
var MIN_COMPRESS_BYTES = 1024;
|
|
@@ -7624,7 +7691,7 @@ async function precompressArtifacts(app) {
|
|
|
7624
7691
|
return result;
|
|
7625
7692
|
}
|
|
7626
7693
|
async function precompressRoot(root, result) {
|
|
7627
|
-
if (!
|
|
7694
|
+
if (!fs5.existsSync(root) || !fs5.statSync(root).isDirectory())
|
|
7628
7695
|
return;
|
|
7629
7696
|
const glob = new Bun.Glob("**/*");
|
|
7630
7697
|
for await (const filePath of glob.scan({ cwd: root, absolute: true })) {
|
|
@@ -7662,9 +7729,7 @@ function formatBytes(bytes) {
|
|
|
7662
7729
|
import path30 from "path";
|
|
7663
7730
|
import { optimize } from "@tailwindcss/node";
|
|
7664
7731
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
7665
|
-
|
|
7666
|
-
return cssText;
|
|
7667
|
-
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
|
|
7732
|
+
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
7668
7733
|
}
|
|
7669
7734
|
|
|
7670
7735
|
class SsrBaseArtifactBuilder {
|
|
@@ -7771,7 +7836,7 @@ ${preparedCssText}`).toString(36);
|
|
|
7771
7836
|
}
|
|
7772
7837
|
}
|
|
7773
7838
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
7774
|
-
import
|
|
7839
|
+
import fs6 from "fs";
|
|
7775
7840
|
import path31 from "path";
|
|
7776
7841
|
|
|
7777
7842
|
class WatchRootResolver {
|
|
@@ -7791,7 +7856,7 @@ class WatchRootResolver {
|
|
|
7791
7856
|
continue;
|
|
7792
7857
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
7793
7858
|
const resolved = path31.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
7794
|
-
if (
|
|
7859
|
+
if (fs6.existsSync(resolved))
|
|
7795
7860
|
set.add(resolved);
|
|
7796
7861
|
}
|
|
7797
7862
|
}
|
|
@@ -8614,10 +8679,11 @@ class CapacitorApp {
|
|
|
8614
8679
|
iosRootPath = "ios";
|
|
8615
8680
|
iosProjectPath = "ios/App";
|
|
8616
8681
|
androidRootPath = "android";
|
|
8682
|
+
androidAssetsPath = "android/app/src/main/assets";
|
|
8617
8683
|
constructor(app, target) {
|
|
8618
8684
|
this.app = app;
|
|
8619
8685
|
this.target = target;
|
|
8620
|
-
this.targetRootPath = path35.posix.join("mobile", this.target.name);
|
|
8686
|
+
this.targetRootPath = path35.posix.join(".akan", "mobile", this.target.name);
|
|
8621
8687
|
this.targetRoot = path35.join(this.app.cwdPath, this.targetRootPath);
|
|
8622
8688
|
this.targetWebRoot = path35.join(this.targetRoot, "www");
|
|
8623
8689
|
this.targetAssetRoot = path35.join(this.targetRoot, "assets");
|
|
@@ -8697,6 +8763,8 @@ class CapacitorApp {
|
|
|
8697
8763
|
await this.#applyLinks();
|
|
8698
8764
|
await this.project.commit();
|
|
8699
8765
|
await this.#generateAssets({ operation, env });
|
|
8766
|
+
await this.#ensureAndroidAssetsDir();
|
|
8767
|
+
await this.#ensureAndroidDebugKeystore();
|
|
8700
8768
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
8701
8769
|
}
|
|
8702
8770
|
async#updateAndroidBuildTypes() {
|
|
@@ -8744,12 +8812,40 @@ class CapacitorApp {
|
|
|
8744
8812
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
8745
8813
|
stdio: "inherit",
|
|
8746
8814
|
cwd: path35.join(this.app.cwdPath, this.androidRootPath),
|
|
8747
|
-
env: this.#commandEnv("release", env)
|
|
8815
|
+
env: await this.#commandEnv("release", env)
|
|
8748
8816
|
});
|
|
8749
8817
|
}
|
|
8750
8818
|
async openAndroid() {
|
|
8751
8819
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
8752
8820
|
}
|
|
8821
|
+
async#ensureAndroidAssetsDir() {
|
|
8822
|
+
await mkdir10(path35.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
8823
|
+
}
|
|
8824
|
+
async#ensureAndroidDebugKeystore() {
|
|
8825
|
+
const keystorePath = path35.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
8826
|
+
if (await Bun.file(keystorePath).exists())
|
|
8827
|
+
return;
|
|
8828
|
+
await this.#spawn("keytool", [
|
|
8829
|
+
"-genkeypair",
|
|
8830
|
+
"-v",
|
|
8831
|
+
"-keystore",
|
|
8832
|
+
keystorePath,
|
|
8833
|
+
"-storepass",
|
|
8834
|
+
"android",
|
|
8835
|
+
"-alias",
|
|
8836
|
+
"androiddebugkey",
|
|
8837
|
+
"-keypass",
|
|
8838
|
+
"android",
|
|
8839
|
+
"-keyalg",
|
|
8840
|
+
"RSA",
|
|
8841
|
+
"-keysize",
|
|
8842
|
+
"2048",
|
|
8843
|
+
"-validity",
|
|
8844
|
+
"10000",
|
|
8845
|
+
"-dname",
|
|
8846
|
+
"CN=Android Debug,O=Android,C=US"
|
|
8847
|
+
]);
|
|
8848
|
+
}
|
|
8753
8849
|
async syncAndroid(options = {}) {
|
|
8754
8850
|
await this.prepareWww();
|
|
8755
8851
|
await this.#prepareAndroid({ operation: "release", env: "debug", ...options });
|
|
@@ -8791,13 +8887,13 @@ class CapacitorApp {
|
|
|
8791
8887
|
await mkdir10(this.targetRoot, { recursive: true });
|
|
8792
8888
|
const appInfoPath = path35.relative(this.app.cwdPath, path35.join(this.app.cwdPath, "akan.app.json")).split(path35.sep).join("/");
|
|
8793
8889
|
const content = `import type { AppScanResult } from "akanjs";
|
|
8794
|
-
import { withBase } from "akanjs/capacitor.base.config";
|
|
8890
|
+
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
8795
8891
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
8796
8892
|
|
|
8797
8893
|
export default withBase(
|
|
8798
8894
|
(config, target) => ({
|
|
8799
8895
|
...config,
|
|
8800
|
-
webDir:
|
|
8896
|
+
webDir: \`.akan/mobile/\${target.name}/www\`,
|
|
8801
8897
|
android: {
|
|
8802
8898
|
...config.android,
|
|
8803
8899
|
path: "android",
|
|
@@ -8897,12 +8993,14 @@ export default withBase(
|
|
|
8897
8993
|
this.project.android.getAndroidManifest().injectFragment("activity", `<intent-filter android:autoVerify="true"><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:scheme="https" android:host="${host}" android:pathPrefix="${pathPrefix}" /></intent-filter>`);
|
|
8898
8994
|
}
|
|
8899
8995
|
}
|
|
8900
|
-
#commandEnv(operation, env) {
|
|
8996
|
+
async#commandEnv(operation, env) {
|
|
8997
|
+
const devPort = operation === "local" ? (await this.app.getDevPort()).toString() : undefined;
|
|
8901
8998
|
return this.app.getCommandEnv({
|
|
8902
8999
|
APP_OPERATION_MODE: operation,
|
|
8903
9000
|
AKAN_PUBLIC_OPERATION_MODE: env === "local" ? "local" : "cloud",
|
|
8904
9001
|
AKAN_PUBLIC_ENV: env,
|
|
8905
|
-
AKAN_MOBILE_TARGET: this.target.name
|
|
9002
|
+
AKAN_MOBILE_TARGET: this.target.name,
|
|
9003
|
+
...devPort ? { PORT: devPort, AKAN_PUBLIC_CLIENT_PORT: devPort, AKAN_PUBLIC_SERVER_PORT: devPort } : {}
|
|
8906
9004
|
});
|
|
8907
9005
|
}
|
|
8908
9006
|
async#spawn(command, args = [], options = {}) {
|
|
@@ -8911,7 +9009,7 @@ export default withBase(
|
|
|
8911
9009
|
async#spawnMobile(command, args = [], { operation, env }, options = {}) {
|
|
8912
9010
|
return await this.#spawn(command, args, {
|
|
8913
9011
|
...options,
|
|
8914
|
-
env: { ...this.#commandEnv(operation, env), ...options.env }
|
|
9012
|
+
env: { ...await this.#commandEnv(operation, env), ...options.env }
|
|
8915
9013
|
});
|
|
8916
9014
|
}
|
|
8917
9015
|
async addCamera() {
|
|
@@ -9771,7 +9869,7 @@ import yaml from "js-yaml";
|
|
|
9771
9869
|
// pkgs/@akanjs/devkit/getRelatedCnsts.ts
|
|
9772
9870
|
import { readFileSync as readFileSync4, realpathSync } from "fs";
|
|
9773
9871
|
import ora2 from "ora";
|
|
9774
|
-
import * as
|
|
9872
|
+
import * as ts7 from "typescript";
|
|
9775
9873
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
9776
9874
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
9777
9875
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
@@ -9804,10 +9902,10 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
9804
9902
|
return importSpecifiers;
|
|
9805
9903
|
};
|
|
9806
9904
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
9807
|
-
const configFile =
|
|
9808
|
-
return
|
|
9905
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path37) => {
|
|
9906
|
+
return ts7.sys.readFile(path37);
|
|
9809
9907
|
});
|
|
9810
|
-
return
|
|
9908
|
+
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
9811
9909
|
};
|
|
9812
9910
|
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
9813
9911
|
const allFilesToAnalyze = new Set([constantFilePath]);
|
|
@@ -9822,7 +9920,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9822
9920
|
for (const importPath of scanModuleSpecifiers(source, filePath, false)) {
|
|
9823
9921
|
if (!importPath.startsWith("."))
|
|
9824
9922
|
continue;
|
|
9825
|
-
const resolved =
|
|
9923
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, parsedConfig.options, ts7.sys).resolvedModule?.resolvedFileName;
|
|
9826
9924
|
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
9827
9925
|
allFilesToAnalyze.add(resolved);
|
|
9828
9926
|
collectImported(resolved);
|
|
@@ -9839,7 +9937,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9839
9937
|
var createTsProgram = (filePaths, options) => {
|
|
9840
9938
|
const spinner = ora2("Creating TypeScript program for all files...");
|
|
9841
9939
|
spinner.start();
|
|
9842
|
-
const program2 =
|
|
9940
|
+
const program2 = ts7.createProgram(Array.from(filePaths), options);
|
|
9843
9941
|
const checker = program2.getTypeChecker();
|
|
9844
9942
|
spinner.succeed("TypeScript program created.");
|
|
9845
9943
|
return {
|
|
@@ -9879,17 +9977,17 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9879
9977
|
function visit(node) {
|
|
9880
9978
|
if (!source)
|
|
9881
9979
|
return;
|
|
9882
|
-
if (
|
|
9980
|
+
if (ts7.isPropertyAccessExpression(node)) {
|
|
9883
9981
|
const left = node.expression;
|
|
9884
9982
|
const right = node.name;
|
|
9885
|
-
const { line } =
|
|
9886
|
-
if (
|
|
9983
|
+
const { line } = ts7.getLineAndCharacterOfPosition(source, node.getStart());
|
|
9984
|
+
if (ts7.isIdentifier(left) && sourceLines && sourceLines.length > line && sourceLines[line] && (sourceLines[line]?.includes(`@Field.Prop(() => ${left.text}.${right.text}`) || sourceLines[line].includes(`base.Filter(${left.text}.${right.text},`))) {
|
|
9887
9985
|
const symbol = getCachedSymbol(right);
|
|
9888
9986
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
9889
9987
|
const key = symbol.declarations[0]?.getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
9890
9988
|
const property = propertyMap.get(key);
|
|
9891
9989
|
const isScalar = symbol.declarations[0]?.getSourceFile().fileName.includes("_") ?? false;
|
|
9892
|
-
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${
|
|
9990
|
+
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${ts7.sys.getCurrentDirectory()}/`, "");
|
|
9893
9991
|
if (!symbolFilePath)
|
|
9894
9992
|
throw new Error(`No symbol file path found for ${left.text}.${right.text}`);
|
|
9895
9993
|
if (property) {
|
|
@@ -9913,10 +10011,10 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9913
10011
|
}
|
|
9914
10012
|
}
|
|
9915
10013
|
}
|
|
9916
|
-
} else if (
|
|
10014
|
+
} else if (ts7.isImportDeclaration(node) && ts7.isStringLiteral(node.moduleSpecifier)) {
|
|
9917
10015
|
const importPath = node.moduleSpecifier.text;
|
|
9918
10016
|
if (importPath.startsWith(".")) {
|
|
9919
|
-
const resolved =
|
|
10017
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts7.sys).resolvedModule?.resolvedFileName;
|
|
9920
10018
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
9921
10019
|
const property = propertyMap.get(moduleName);
|
|
9922
10020
|
const isScalar = importPath.includes("_");
|
|
@@ -9931,7 +10029,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9931
10029
|
}
|
|
9932
10030
|
}
|
|
9933
10031
|
}
|
|
9934
|
-
|
|
10032
|
+
ts7.forEachChild(node, visit);
|
|
9935
10033
|
}
|
|
9936
10034
|
visit(source);
|
|
9937
10035
|
}
|
|
@@ -10272,8 +10370,6 @@ class ApplicationRunner extends runner("application") {
|
|
|
10272
10370
|
const targets = await resolveMobileTargets(app, target);
|
|
10273
10371
|
if (operation === "release")
|
|
10274
10372
|
await this.#buildMobileCsr(app, env);
|
|
10275
|
-
else
|
|
10276
|
-
await this.start(app);
|
|
10277
10373
|
await this.#runMobileTargets(targets, async (mobileTarget2) => {
|
|
10278
10374
|
const capacitorApp2 = new CapacitorApp(app, mobileTarget2.config);
|
|
10279
10375
|
await capacitorApp2.runIos({ operation, env, regenerate });
|
|
@@ -10305,8 +10401,6 @@ class ApplicationRunner extends runner("application") {
|
|
|
10305
10401
|
const targets = await resolveMobileTargets(app, target);
|
|
10306
10402
|
if (operation === "release")
|
|
10307
10403
|
await this.#buildMobileCsr(app, env);
|
|
10308
|
-
else
|
|
10309
|
-
await this.start(app);
|
|
10310
10404
|
await this.#runMobileTargets(targets, async (mobileTarget2) => {
|
|
10311
10405
|
const capacitorApp2 = new CapacitorApp(app, mobileTarget2.config);
|
|
10312
10406
|
await capacitorApp2.runAndroid({ operation, env, regenerate });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0-rc.0",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@langchain/openai": "^1.4.6",
|
|
36
36
|
"@tailwindcss/node": "^4.3.0",
|
|
37
37
|
"@trapezedev/project": "^7.1.4",
|
|
38
|
-
"akanjs": "2.
|
|
38
|
+
"akanjs": "2.2.0-rc.0",
|
|
39
39
|
"chalk": "^5.6.2",
|
|
40
40
|
"commander": "^14.0.3",
|
|
41
41
|
"daisyui": "^5.5.20",
|