@akanjs/cli 2.1.2-rc.0 → 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 +147 -48
- package/index.js +147 -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: {},
|
|
@@ -230,6 +230,7 @@ class CloudApi {
|
|
|
230
230
|
async downloadEnv(devProjectId) {
|
|
231
231
|
const localPath = `${this.#workspace.workspaceRoot}/local/env.tar`;
|
|
232
232
|
await this.#api.getFile(`/downloadEnv/${devProjectId}`, localPath);
|
|
233
|
+
return localPath;
|
|
233
234
|
}
|
|
234
235
|
async getRemoteAuthToken(remoteId) {
|
|
235
236
|
try {
|
|
@@ -6227,7 +6228,9 @@ import { mkdir as mkdir5, rm, unlink } from "fs/promises";
|
|
|
6227
6228
|
import path21 from "path";
|
|
6228
6229
|
|
|
6229
6230
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
6231
|
+
import fs3 from "fs";
|
|
6230
6232
|
import path20 from "path";
|
|
6233
|
+
import ts5 from "typescript";
|
|
6231
6234
|
|
|
6232
6235
|
class PagesEntrySourceGenerator {
|
|
6233
6236
|
#pageEntries;
|
|
@@ -6256,8 +6259,9 @@ ${lines.join(`
|
|
|
6256
6259
|
const absPath = path20.resolve(moduleAbsPath);
|
|
6257
6260
|
return `import * as page${index} from ${JSON.stringify(absPath)};`;
|
|
6258
6261
|
});
|
|
6259
|
-
const entries = this.#pageEntries.map(({ key }, index) => {
|
|
6260
|
-
|
|
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} },`;
|
|
6261
6265
|
});
|
|
6262
6266
|
return `${imports.join(`
|
|
6263
6267
|
`)}
|
|
@@ -6267,6 +6271,63 @@ ${entries.join(`
|
|
|
6267
6271
|
};
|
|
6268
6272
|
`;
|
|
6269
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
|
+
}
|
|
6270
6331
|
}
|
|
6271
6332
|
|
|
6272
6333
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
@@ -6402,6 +6463,13 @@ ${remainingAssets.join(`
|
|
|
6402
6463
|
jsFiles.push(jsPath);
|
|
6403
6464
|
return await Bun.file(jsPath).text();
|
|
6404
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
|
+
}
|
|
6405
6473
|
if (cssAsset) {
|
|
6406
6474
|
const cssPath = path21.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
6407
6475
|
const css = await Bun.file(cssPath).text();
|
|
@@ -6880,7 +6948,7 @@ import {
|
|
|
6880
6948
|
} from "fontaine";
|
|
6881
6949
|
import { createFont, woff2 } from "fonteditor-core";
|
|
6882
6950
|
import subsetFont from "subset-font";
|
|
6883
|
-
import
|
|
6951
|
+
import ts6 from "typescript";
|
|
6884
6952
|
var FONT_URL_PREFIX = "/_akan/fonts";
|
|
6885
6953
|
var DEFAULT_FONT_SUBSETS = ["latin"];
|
|
6886
6954
|
|
|
@@ -6945,17 +7013,17 @@ class FontOptimizer {
|
|
|
6945
7013
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
6946
7014
|
}
|
|
6947
7015
|
#extractFontsExport(source, filePath) {
|
|
6948
|
-
const sourceFile =
|
|
7016
|
+
const sourceFile = ts6.createSourceFile(filePath, source, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TSX);
|
|
6949
7017
|
const fonts = [];
|
|
6950
7018
|
for (const statement of sourceFile.statements) {
|
|
6951
|
-
if (!
|
|
7019
|
+
if (!ts6.isVariableStatement(statement))
|
|
6952
7020
|
continue;
|
|
6953
|
-
const modifiers =
|
|
6954
|
-
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;
|
|
6955
7023
|
if (!isExported)
|
|
6956
7024
|
continue;
|
|
6957
7025
|
for (const declaration of statement.declarationList.declarations) {
|
|
6958
|
-
if (!
|
|
7026
|
+
if (!ts6.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
|
|
6959
7027
|
continue;
|
|
6960
7028
|
const value = declaration.initializer ? this.#literalToValue(declaration.initializer) : null;
|
|
6961
7029
|
if (Array.isArray(value)) {
|
|
@@ -6966,20 +7034,20 @@ class FontOptimizer {
|
|
|
6966
7034
|
return fonts;
|
|
6967
7035
|
}
|
|
6968
7036
|
#literalToValue(node) {
|
|
6969
|
-
if (
|
|
7037
|
+
if (ts6.isStringLiteralLike(node))
|
|
6970
7038
|
return node.text;
|
|
6971
|
-
if (
|
|
7039
|
+
if (ts6.isNumericLiteral(node))
|
|
6972
7040
|
return Number(node.text);
|
|
6973
|
-
if (node.kind ===
|
|
7041
|
+
if (node.kind === ts6.SyntaxKind.TrueKeyword)
|
|
6974
7042
|
return true;
|
|
6975
|
-
if (node.kind ===
|
|
7043
|
+
if (node.kind === ts6.SyntaxKind.FalseKeyword)
|
|
6976
7044
|
return false;
|
|
6977
|
-
if (
|
|
7045
|
+
if (ts6.isArrayLiteralExpression(node))
|
|
6978
7046
|
return node.elements.map((element) => this.#literalToValue(element));
|
|
6979
|
-
if (
|
|
7047
|
+
if (ts6.isObjectLiteralExpression(node)) {
|
|
6980
7048
|
const obj = {};
|
|
6981
7049
|
for (const prop of node.properties) {
|
|
6982
|
-
if (!
|
|
7050
|
+
if (!ts6.isPropertyAssignment(prop))
|
|
6983
7051
|
continue;
|
|
6984
7052
|
const name = this.#getPropertyName(prop.name);
|
|
6985
7053
|
if (!name)
|
|
@@ -6988,13 +7056,13 @@ class FontOptimizer {
|
|
|
6988
7056
|
}
|
|
6989
7057
|
return obj;
|
|
6990
7058
|
}
|
|
6991
|
-
if (
|
|
7059
|
+
if (ts6.isAsExpression(node) || ts6.isSatisfiesExpression(node) || ts6.isParenthesizedExpression(node)) {
|
|
6992
7060
|
return this.#literalToValue(node.expression);
|
|
6993
7061
|
}
|
|
6994
7062
|
return;
|
|
6995
7063
|
}
|
|
6996
7064
|
#getPropertyName(name) {
|
|
6997
|
-
if (
|
|
7065
|
+
if (ts6.isIdentifier(name) || ts6.isStringLiteral(name) || ts6.isNumericLiteral(name))
|
|
6998
7066
|
return name.text;
|
|
6999
7067
|
return null;
|
|
7000
7068
|
}
|
|
@@ -7294,7 +7362,7 @@ class HmrChangeClassifier {
|
|
|
7294
7362
|
}
|
|
7295
7363
|
}
|
|
7296
7364
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7297
|
-
import
|
|
7365
|
+
import fs4 from "fs";
|
|
7298
7366
|
import path26 from "path";
|
|
7299
7367
|
class HmrWatcher {
|
|
7300
7368
|
#roots;
|
|
@@ -7316,7 +7384,7 @@ class HmrWatcher {
|
|
|
7316
7384
|
start() {
|
|
7317
7385
|
for (const root of this.#roots) {
|
|
7318
7386
|
try {
|
|
7319
|
-
const w =
|
|
7387
|
+
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7320
7388
|
if (!filename)
|
|
7321
7389
|
return;
|
|
7322
7390
|
const abs = path26.resolve(root, filename.toString());
|
|
@@ -7611,7 +7679,7 @@ class PagesBundleBuilder {
|
|
|
7611
7679
|
}
|
|
7612
7680
|
}
|
|
7613
7681
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
7614
|
-
import
|
|
7682
|
+
import fs5 from "fs";
|
|
7615
7683
|
import path29 from "path";
|
|
7616
7684
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
7617
7685
|
var MIN_COMPRESS_BYTES = 1024;
|
|
@@ -7625,7 +7693,7 @@ async function precompressArtifacts(app) {
|
|
|
7625
7693
|
return result;
|
|
7626
7694
|
}
|
|
7627
7695
|
async function precompressRoot(root, result) {
|
|
7628
|
-
if (!
|
|
7696
|
+
if (!fs5.existsSync(root) || !fs5.statSync(root).isDirectory())
|
|
7629
7697
|
return;
|
|
7630
7698
|
const glob = new Bun.Glob("**/*");
|
|
7631
7699
|
for await (const filePath of glob.scan({ cwd: root, absolute: true })) {
|
|
@@ -7663,9 +7731,7 @@ function formatBytes(bytes) {
|
|
|
7663
7731
|
import path30 from "path";
|
|
7664
7732
|
import { optimize } from "@tailwindcss/node";
|
|
7665
7733
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
7666
|
-
|
|
7667
|
-
return cssText;
|
|
7668
|
-
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
|
|
7734
|
+
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
7669
7735
|
}
|
|
7670
7736
|
|
|
7671
7737
|
class SsrBaseArtifactBuilder {
|
|
@@ -7772,7 +7838,7 @@ ${preparedCssText}`).toString(36);
|
|
|
7772
7838
|
}
|
|
7773
7839
|
}
|
|
7774
7840
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
7775
|
-
import
|
|
7841
|
+
import fs6 from "fs";
|
|
7776
7842
|
import path31 from "path";
|
|
7777
7843
|
|
|
7778
7844
|
class WatchRootResolver {
|
|
@@ -7792,7 +7858,7 @@ class WatchRootResolver {
|
|
|
7792
7858
|
continue;
|
|
7793
7859
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
7794
7860
|
const resolved = path31.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
7795
|
-
if (
|
|
7861
|
+
if (fs6.existsSync(resolved))
|
|
7796
7862
|
set.add(resolved);
|
|
7797
7863
|
}
|
|
7798
7864
|
}
|
|
@@ -8615,10 +8681,11 @@ class CapacitorApp {
|
|
|
8615
8681
|
iosRootPath = "ios";
|
|
8616
8682
|
iosProjectPath = "ios/App";
|
|
8617
8683
|
androidRootPath = "android";
|
|
8684
|
+
androidAssetsPath = "android/app/src/main/assets";
|
|
8618
8685
|
constructor(app, target) {
|
|
8619
8686
|
this.app = app;
|
|
8620
8687
|
this.target = target;
|
|
8621
|
-
this.targetRootPath = path35.posix.join("mobile", this.target.name);
|
|
8688
|
+
this.targetRootPath = path35.posix.join(".akan", "mobile", this.target.name);
|
|
8622
8689
|
this.targetRoot = path35.join(this.app.cwdPath, this.targetRootPath);
|
|
8623
8690
|
this.targetWebRoot = path35.join(this.targetRoot, "www");
|
|
8624
8691
|
this.targetAssetRoot = path35.join(this.targetRoot, "assets");
|
|
@@ -8698,6 +8765,8 @@ class CapacitorApp {
|
|
|
8698
8765
|
await this.#applyLinks();
|
|
8699
8766
|
await this.project.commit();
|
|
8700
8767
|
await this.#generateAssets({ operation, env });
|
|
8768
|
+
await this.#ensureAndroidAssetsDir();
|
|
8769
|
+
await this.#ensureAndroidDebugKeystore();
|
|
8701
8770
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
8702
8771
|
}
|
|
8703
8772
|
async#updateAndroidBuildTypes() {
|
|
@@ -8745,12 +8814,40 @@ class CapacitorApp {
|
|
|
8745
8814
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
8746
8815
|
stdio: "inherit",
|
|
8747
8816
|
cwd: path35.join(this.app.cwdPath, this.androidRootPath),
|
|
8748
|
-
env: this.#commandEnv("release", env)
|
|
8817
|
+
env: await this.#commandEnv("release", env)
|
|
8749
8818
|
});
|
|
8750
8819
|
}
|
|
8751
8820
|
async openAndroid() {
|
|
8752
8821
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
8753
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
|
+
}
|
|
8754
8851
|
async syncAndroid(options = {}) {
|
|
8755
8852
|
await this.prepareWww();
|
|
8756
8853
|
await this.#prepareAndroid({ operation: "release", env: "debug", ...options });
|
|
@@ -8792,13 +8889,13 @@ class CapacitorApp {
|
|
|
8792
8889
|
await mkdir10(this.targetRoot, { recursive: true });
|
|
8793
8890
|
const appInfoPath = path35.relative(this.app.cwdPath, path35.join(this.app.cwdPath, "akan.app.json")).split(path35.sep).join("/");
|
|
8794
8891
|
const content = `import type { AppScanResult } from "akanjs";
|
|
8795
|
-
import { withBase } from "akanjs/capacitor.base.config";
|
|
8892
|
+
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
8796
8893
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
8797
8894
|
|
|
8798
8895
|
export default withBase(
|
|
8799
8896
|
(config, target) => ({
|
|
8800
8897
|
...config,
|
|
8801
|
-
webDir:
|
|
8898
|
+
webDir: \`.akan/mobile/\${target.name}/www\`,
|
|
8802
8899
|
android: {
|
|
8803
8900
|
...config.android,
|
|
8804
8901
|
path: "android",
|
|
@@ -8898,12 +8995,14 @@ export default withBase(
|
|
|
8898
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>`);
|
|
8899
8996
|
}
|
|
8900
8997
|
}
|
|
8901
|
-
#commandEnv(operation, env) {
|
|
8998
|
+
async#commandEnv(operation, env) {
|
|
8999
|
+
const devPort = operation === "local" ? (await this.app.getDevPort()).toString() : undefined;
|
|
8902
9000
|
return this.app.getCommandEnv({
|
|
8903
9001
|
APP_OPERATION_MODE: operation,
|
|
8904
9002
|
AKAN_PUBLIC_OPERATION_MODE: env === "local" ? "local" : "cloud",
|
|
8905
9003
|
AKAN_PUBLIC_ENV: env,
|
|
8906
|
-
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 } : {}
|
|
8907
9006
|
});
|
|
8908
9007
|
}
|
|
8909
9008
|
async#spawn(command, args = [], options = {}) {
|
|
@@ -8912,7 +9011,7 @@ export default withBase(
|
|
|
8912
9011
|
async#spawnMobile(command, args = [], { operation, env }, options = {}) {
|
|
8913
9012
|
return await this.#spawn(command, args, {
|
|
8914
9013
|
...options,
|
|
8915
|
-
env: { ...this.#commandEnv(operation, env), ...options.env }
|
|
9014
|
+
env: { ...await this.#commandEnv(operation, env), ...options.env }
|
|
8916
9015
|
});
|
|
8917
9016
|
}
|
|
8918
9017
|
async addCamera() {
|
|
@@ -9772,7 +9871,7 @@ import yaml from "js-yaml";
|
|
|
9772
9871
|
// pkgs/@akanjs/devkit/getRelatedCnsts.ts
|
|
9773
9872
|
import { readFileSync as readFileSync4, realpathSync } from "fs";
|
|
9774
9873
|
import ora2 from "ora";
|
|
9775
|
-
import * as
|
|
9874
|
+
import * as ts7 from "typescript";
|
|
9776
9875
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
9777
9876
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
9778
9877
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
@@ -9805,10 +9904,10 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
9805
9904
|
return importSpecifiers;
|
|
9806
9905
|
};
|
|
9807
9906
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
9808
|
-
const configFile =
|
|
9809
|
-
return
|
|
9907
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path37) => {
|
|
9908
|
+
return ts7.sys.readFile(path37);
|
|
9810
9909
|
});
|
|
9811
|
-
return
|
|
9910
|
+
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
9812
9911
|
};
|
|
9813
9912
|
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
9814
9913
|
const allFilesToAnalyze = new Set([constantFilePath]);
|
|
@@ -9823,7 +9922,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9823
9922
|
for (const importPath of scanModuleSpecifiers(source, filePath, false)) {
|
|
9824
9923
|
if (!importPath.startsWith("."))
|
|
9825
9924
|
continue;
|
|
9826
|
-
const resolved =
|
|
9925
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, parsedConfig.options, ts7.sys).resolvedModule?.resolvedFileName;
|
|
9827
9926
|
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
9828
9927
|
allFilesToAnalyze.add(resolved);
|
|
9829
9928
|
collectImported(resolved);
|
|
@@ -9840,7 +9939,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9840
9939
|
var createTsProgram = (filePaths, options) => {
|
|
9841
9940
|
const spinner = ora2("Creating TypeScript program for all files...");
|
|
9842
9941
|
spinner.start();
|
|
9843
|
-
const program2 =
|
|
9942
|
+
const program2 = ts7.createProgram(Array.from(filePaths), options);
|
|
9844
9943
|
const checker = program2.getTypeChecker();
|
|
9845
9944
|
spinner.succeed("TypeScript program created.");
|
|
9846
9945
|
return {
|
|
@@ -9880,17 +9979,17 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9880
9979
|
function visit(node) {
|
|
9881
9980
|
if (!source)
|
|
9882
9981
|
return;
|
|
9883
|
-
if (
|
|
9982
|
+
if (ts7.isPropertyAccessExpression(node)) {
|
|
9884
9983
|
const left = node.expression;
|
|
9885
9984
|
const right = node.name;
|
|
9886
|
-
const { line } =
|
|
9887
|
-
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},`))) {
|
|
9888
9987
|
const symbol = getCachedSymbol(right);
|
|
9889
9988
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
9890
9989
|
const key = symbol.declarations[0]?.getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
9891
9990
|
const property = propertyMap.get(key);
|
|
9892
9991
|
const isScalar = symbol.declarations[0]?.getSourceFile().fileName.includes("_") ?? false;
|
|
9893
|
-
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${
|
|
9992
|
+
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${ts7.sys.getCurrentDirectory()}/`, "");
|
|
9894
9993
|
if (!symbolFilePath)
|
|
9895
9994
|
throw new Error(`No symbol file path found for ${left.text}.${right.text}`);
|
|
9896
9995
|
if (property) {
|
|
@@ -9914,10 +10013,10 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9914
10013
|
}
|
|
9915
10014
|
}
|
|
9916
10015
|
}
|
|
9917
|
-
} else if (
|
|
10016
|
+
} else if (ts7.isImportDeclaration(node) && ts7.isStringLiteral(node.moduleSpecifier)) {
|
|
9918
10017
|
const importPath = node.moduleSpecifier.text;
|
|
9919
10018
|
if (importPath.startsWith(".")) {
|
|
9920
|
-
const resolved =
|
|
10019
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts7.sys).resolvedModule?.resolvedFileName;
|
|
9921
10020
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
9922
10021
|
const property = propertyMap.get(moduleName);
|
|
9923
10022
|
const isScalar = importPath.includes("_");
|
|
@@ -9932,7 +10031,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9932
10031
|
}
|
|
9933
10032
|
}
|
|
9934
10033
|
}
|
|
9935
|
-
|
|
10034
|
+
ts7.forEachChild(node, visit);
|
|
9936
10035
|
}
|
|
9937
10036
|
visit(source);
|
|
9938
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: {},
|
|
@@ -228,6 +228,7 @@ class CloudApi {
|
|
|
228
228
|
async downloadEnv(devProjectId) {
|
|
229
229
|
const localPath = `${this.#workspace.workspaceRoot}/local/env.tar`;
|
|
230
230
|
await this.#api.getFile(`/downloadEnv/${devProjectId}`, localPath);
|
|
231
|
+
return localPath;
|
|
231
232
|
}
|
|
232
233
|
async getRemoteAuthToken(remoteId) {
|
|
233
234
|
try {
|
|
@@ -6225,7 +6226,9 @@ import { mkdir as mkdir5, rm, unlink } from "fs/promises";
|
|
|
6225
6226
|
import path21 from "path";
|
|
6226
6227
|
|
|
6227
6228
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
6229
|
+
import fs3 from "fs";
|
|
6228
6230
|
import path20 from "path";
|
|
6231
|
+
import ts5 from "typescript";
|
|
6229
6232
|
|
|
6230
6233
|
class PagesEntrySourceGenerator {
|
|
6231
6234
|
#pageEntries;
|
|
@@ -6254,8 +6257,9 @@ ${lines.join(`
|
|
|
6254
6257
|
const absPath = path20.resolve(moduleAbsPath);
|
|
6255
6258
|
return `import * as page${index} from ${JSON.stringify(absPath)};`;
|
|
6256
6259
|
});
|
|
6257
|
-
const entries = this.#pageEntries.map(({ key }, index) => {
|
|
6258
|
-
|
|
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} },`;
|
|
6259
6263
|
});
|
|
6260
6264
|
return `${imports.join(`
|
|
6261
6265
|
`)}
|
|
@@ -6265,6 +6269,63 @@ ${entries.join(`
|
|
|
6265
6269
|
};
|
|
6266
6270
|
`;
|
|
6267
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
|
+
}
|
|
6268
6329
|
}
|
|
6269
6330
|
|
|
6270
6331
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
@@ -6400,6 +6461,13 @@ ${remainingAssets.join(`
|
|
|
6400
6461
|
jsFiles.push(jsPath);
|
|
6401
6462
|
return await Bun.file(jsPath).text();
|
|
6402
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
|
+
}
|
|
6403
6471
|
if (cssAsset) {
|
|
6404
6472
|
const cssPath = path21.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
6405
6473
|
const css = await Bun.file(cssPath).text();
|
|
@@ -6878,7 +6946,7 @@ import {
|
|
|
6878
6946
|
} from "fontaine";
|
|
6879
6947
|
import { createFont, woff2 } from "fonteditor-core";
|
|
6880
6948
|
import subsetFont from "subset-font";
|
|
6881
|
-
import
|
|
6949
|
+
import ts6 from "typescript";
|
|
6882
6950
|
var FONT_URL_PREFIX = "/_akan/fonts";
|
|
6883
6951
|
var DEFAULT_FONT_SUBSETS = ["latin"];
|
|
6884
6952
|
|
|
@@ -6943,17 +7011,17 @@ class FontOptimizer {
|
|
|
6943
7011
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
6944
7012
|
}
|
|
6945
7013
|
#extractFontsExport(source, filePath) {
|
|
6946
|
-
const sourceFile =
|
|
7014
|
+
const sourceFile = ts6.createSourceFile(filePath, source, ts6.ScriptTarget.Latest, true, ts6.ScriptKind.TSX);
|
|
6947
7015
|
const fonts = [];
|
|
6948
7016
|
for (const statement of sourceFile.statements) {
|
|
6949
|
-
if (!
|
|
7017
|
+
if (!ts6.isVariableStatement(statement))
|
|
6950
7018
|
continue;
|
|
6951
|
-
const modifiers =
|
|
6952
|
-
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;
|
|
6953
7021
|
if (!isExported)
|
|
6954
7022
|
continue;
|
|
6955
7023
|
for (const declaration of statement.declarationList.declarations) {
|
|
6956
|
-
if (!
|
|
7024
|
+
if (!ts6.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
|
|
6957
7025
|
continue;
|
|
6958
7026
|
const value = declaration.initializer ? this.#literalToValue(declaration.initializer) : null;
|
|
6959
7027
|
if (Array.isArray(value)) {
|
|
@@ -6964,20 +7032,20 @@ class FontOptimizer {
|
|
|
6964
7032
|
return fonts;
|
|
6965
7033
|
}
|
|
6966
7034
|
#literalToValue(node) {
|
|
6967
|
-
if (
|
|
7035
|
+
if (ts6.isStringLiteralLike(node))
|
|
6968
7036
|
return node.text;
|
|
6969
|
-
if (
|
|
7037
|
+
if (ts6.isNumericLiteral(node))
|
|
6970
7038
|
return Number(node.text);
|
|
6971
|
-
if (node.kind ===
|
|
7039
|
+
if (node.kind === ts6.SyntaxKind.TrueKeyword)
|
|
6972
7040
|
return true;
|
|
6973
|
-
if (node.kind ===
|
|
7041
|
+
if (node.kind === ts6.SyntaxKind.FalseKeyword)
|
|
6974
7042
|
return false;
|
|
6975
|
-
if (
|
|
7043
|
+
if (ts6.isArrayLiteralExpression(node))
|
|
6976
7044
|
return node.elements.map((element) => this.#literalToValue(element));
|
|
6977
|
-
if (
|
|
7045
|
+
if (ts6.isObjectLiteralExpression(node)) {
|
|
6978
7046
|
const obj = {};
|
|
6979
7047
|
for (const prop of node.properties) {
|
|
6980
|
-
if (!
|
|
7048
|
+
if (!ts6.isPropertyAssignment(prop))
|
|
6981
7049
|
continue;
|
|
6982
7050
|
const name = this.#getPropertyName(prop.name);
|
|
6983
7051
|
if (!name)
|
|
@@ -6986,13 +7054,13 @@ class FontOptimizer {
|
|
|
6986
7054
|
}
|
|
6987
7055
|
return obj;
|
|
6988
7056
|
}
|
|
6989
|
-
if (
|
|
7057
|
+
if (ts6.isAsExpression(node) || ts6.isSatisfiesExpression(node) || ts6.isParenthesizedExpression(node)) {
|
|
6990
7058
|
return this.#literalToValue(node.expression);
|
|
6991
7059
|
}
|
|
6992
7060
|
return;
|
|
6993
7061
|
}
|
|
6994
7062
|
#getPropertyName(name) {
|
|
6995
|
-
if (
|
|
7063
|
+
if (ts6.isIdentifier(name) || ts6.isStringLiteral(name) || ts6.isNumericLiteral(name))
|
|
6996
7064
|
return name.text;
|
|
6997
7065
|
return null;
|
|
6998
7066
|
}
|
|
@@ -7292,7 +7360,7 @@ class HmrChangeClassifier {
|
|
|
7292
7360
|
}
|
|
7293
7361
|
}
|
|
7294
7362
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7295
|
-
import
|
|
7363
|
+
import fs4 from "fs";
|
|
7296
7364
|
import path26 from "path";
|
|
7297
7365
|
class HmrWatcher {
|
|
7298
7366
|
#roots;
|
|
@@ -7314,7 +7382,7 @@ class HmrWatcher {
|
|
|
7314
7382
|
start() {
|
|
7315
7383
|
for (const root of this.#roots) {
|
|
7316
7384
|
try {
|
|
7317
|
-
const w =
|
|
7385
|
+
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7318
7386
|
if (!filename)
|
|
7319
7387
|
return;
|
|
7320
7388
|
const abs = path26.resolve(root, filename.toString());
|
|
@@ -7609,7 +7677,7 @@ class PagesBundleBuilder {
|
|
|
7609
7677
|
}
|
|
7610
7678
|
}
|
|
7611
7679
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
7612
|
-
import
|
|
7680
|
+
import fs5 from "fs";
|
|
7613
7681
|
import path29 from "path";
|
|
7614
7682
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
7615
7683
|
var MIN_COMPRESS_BYTES = 1024;
|
|
@@ -7623,7 +7691,7 @@ async function precompressArtifacts(app) {
|
|
|
7623
7691
|
return result;
|
|
7624
7692
|
}
|
|
7625
7693
|
async function precompressRoot(root, result) {
|
|
7626
|
-
if (!
|
|
7694
|
+
if (!fs5.existsSync(root) || !fs5.statSync(root).isDirectory())
|
|
7627
7695
|
return;
|
|
7628
7696
|
const glob = new Bun.Glob("**/*");
|
|
7629
7697
|
for await (const filePath of glob.scan({ cwd: root, absolute: true })) {
|
|
@@ -7661,9 +7729,7 @@ function formatBytes(bytes) {
|
|
|
7661
7729
|
import path30 from "path";
|
|
7662
7730
|
import { optimize } from "@tailwindcss/node";
|
|
7663
7731
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
7664
|
-
|
|
7665
|
-
return cssText;
|
|
7666
|
-
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
|
|
7732
|
+
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
7667
7733
|
}
|
|
7668
7734
|
|
|
7669
7735
|
class SsrBaseArtifactBuilder {
|
|
@@ -7770,7 +7836,7 @@ ${preparedCssText}`).toString(36);
|
|
|
7770
7836
|
}
|
|
7771
7837
|
}
|
|
7772
7838
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
7773
|
-
import
|
|
7839
|
+
import fs6 from "fs";
|
|
7774
7840
|
import path31 from "path";
|
|
7775
7841
|
|
|
7776
7842
|
class WatchRootResolver {
|
|
@@ -7790,7 +7856,7 @@ class WatchRootResolver {
|
|
|
7790
7856
|
continue;
|
|
7791
7857
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
7792
7858
|
const resolved = path31.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
7793
|
-
if (
|
|
7859
|
+
if (fs6.existsSync(resolved))
|
|
7794
7860
|
set.add(resolved);
|
|
7795
7861
|
}
|
|
7796
7862
|
}
|
|
@@ -8613,10 +8679,11 @@ class CapacitorApp {
|
|
|
8613
8679
|
iosRootPath = "ios";
|
|
8614
8680
|
iosProjectPath = "ios/App";
|
|
8615
8681
|
androidRootPath = "android";
|
|
8682
|
+
androidAssetsPath = "android/app/src/main/assets";
|
|
8616
8683
|
constructor(app, target) {
|
|
8617
8684
|
this.app = app;
|
|
8618
8685
|
this.target = target;
|
|
8619
|
-
this.targetRootPath = path35.posix.join("mobile", this.target.name);
|
|
8686
|
+
this.targetRootPath = path35.posix.join(".akan", "mobile", this.target.name);
|
|
8620
8687
|
this.targetRoot = path35.join(this.app.cwdPath, this.targetRootPath);
|
|
8621
8688
|
this.targetWebRoot = path35.join(this.targetRoot, "www");
|
|
8622
8689
|
this.targetAssetRoot = path35.join(this.targetRoot, "assets");
|
|
@@ -8696,6 +8763,8 @@ class CapacitorApp {
|
|
|
8696
8763
|
await this.#applyLinks();
|
|
8697
8764
|
await this.project.commit();
|
|
8698
8765
|
await this.#generateAssets({ operation, env });
|
|
8766
|
+
await this.#ensureAndroidAssetsDir();
|
|
8767
|
+
await this.#ensureAndroidDebugKeystore();
|
|
8699
8768
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
8700
8769
|
}
|
|
8701
8770
|
async#updateAndroidBuildTypes() {
|
|
@@ -8743,12 +8812,40 @@ class CapacitorApp {
|
|
|
8743
8812
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
8744
8813
|
stdio: "inherit",
|
|
8745
8814
|
cwd: path35.join(this.app.cwdPath, this.androidRootPath),
|
|
8746
|
-
env: this.#commandEnv("release", env)
|
|
8815
|
+
env: await this.#commandEnv("release", env)
|
|
8747
8816
|
});
|
|
8748
8817
|
}
|
|
8749
8818
|
async openAndroid() {
|
|
8750
8819
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
8751
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
|
+
}
|
|
8752
8849
|
async syncAndroid(options = {}) {
|
|
8753
8850
|
await this.prepareWww();
|
|
8754
8851
|
await this.#prepareAndroid({ operation: "release", env: "debug", ...options });
|
|
@@ -8790,13 +8887,13 @@ class CapacitorApp {
|
|
|
8790
8887
|
await mkdir10(this.targetRoot, { recursive: true });
|
|
8791
8888
|
const appInfoPath = path35.relative(this.app.cwdPath, path35.join(this.app.cwdPath, "akan.app.json")).split(path35.sep).join("/");
|
|
8792
8889
|
const content = `import type { AppScanResult } from "akanjs";
|
|
8793
|
-
import { withBase } from "akanjs/capacitor.base.config";
|
|
8890
|
+
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
8794
8891
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
8795
8892
|
|
|
8796
8893
|
export default withBase(
|
|
8797
8894
|
(config, target) => ({
|
|
8798
8895
|
...config,
|
|
8799
|
-
webDir:
|
|
8896
|
+
webDir: \`.akan/mobile/\${target.name}/www\`,
|
|
8800
8897
|
android: {
|
|
8801
8898
|
...config.android,
|
|
8802
8899
|
path: "android",
|
|
@@ -8896,12 +8993,14 @@ export default withBase(
|
|
|
8896
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>`);
|
|
8897
8994
|
}
|
|
8898
8995
|
}
|
|
8899
|
-
#commandEnv(operation, env) {
|
|
8996
|
+
async#commandEnv(operation, env) {
|
|
8997
|
+
const devPort = operation === "local" ? (await this.app.getDevPort()).toString() : undefined;
|
|
8900
8998
|
return this.app.getCommandEnv({
|
|
8901
8999
|
APP_OPERATION_MODE: operation,
|
|
8902
9000
|
AKAN_PUBLIC_OPERATION_MODE: env === "local" ? "local" : "cloud",
|
|
8903
9001
|
AKAN_PUBLIC_ENV: env,
|
|
8904
|
-
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 } : {}
|
|
8905
9004
|
});
|
|
8906
9005
|
}
|
|
8907
9006
|
async#spawn(command, args = [], options = {}) {
|
|
@@ -8910,7 +9009,7 @@ export default withBase(
|
|
|
8910
9009
|
async#spawnMobile(command, args = [], { operation, env }, options = {}) {
|
|
8911
9010
|
return await this.#spawn(command, args, {
|
|
8912
9011
|
...options,
|
|
8913
|
-
env: { ...this.#commandEnv(operation, env), ...options.env }
|
|
9012
|
+
env: { ...await this.#commandEnv(operation, env), ...options.env }
|
|
8914
9013
|
});
|
|
8915
9014
|
}
|
|
8916
9015
|
async addCamera() {
|
|
@@ -9770,7 +9869,7 @@ import yaml from "js-yaml";
|
|
|
9770
9869
|
// pkgs/@akanjs/devkit/getRelatedCnsts.ts
|
|
9771
9870
|
import { readFileSync as readFileSync4, realpathSync } from "fs";
|
|
9772
9871
|
import ora2 from "ora";
|
|
9773
|
-
import * as
|
|
9872
|
+
import * as ts7 from "typescript";
|
|
9774
9873
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
9775
9874
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
9776
9875
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
@@ -9803,10 +9902,10 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
9803
9902
|
return importSpecifiers;
|
|
9804
9903
|
};
|
|
9805
9904
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
9806
|
-
const configFile =
|
|
9807
|
-
return
|
|
9905
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path37) => {
|
|
9906
|
+
return ts7.sys.readFile(path37);
|
|
9808
9907
|
});
|
|
9809
|
-
return
|
|
9908
|
+
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
9810
9909
|
};
|
|
9811
9910
|
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
9812
9911
|
const allFilesToAnalyze = new Set([constantFilePath]);
|
|
@@ -9821,7 +9920,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9821
9920
|
for (const importPath of scanModuleSpecifiers(source, filePath, false)) {
|
|
9822
9921
|
if (!importPath.startsWith("."))
|
|
9823
9922
|
continue;
|
|
9824
|
-
const resolved =
|
|
9923
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, parsedConfig.options, ts7.sys).resolvedModule?.resolvedFileName;
|
|
9825
9924
|
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
9826
9925
|
allFilesToAnalyze.add(resolved);
|
|
9827
9926
|
collectImported(resolved);
|
|
@@ -9838,7 +9937,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
9838
9937
|
var createTsProgram = (filePaths, options) => {
|
|
9839
9938
|
const spinner = ora2("Creating TypeScript program for all files...");
|
|
9840
9939
|
spinner.start();
|
|
9841
|
-
const program2 =
|
|
9940
|
+
const program2 = ts7.createProgram(Array.from(filePaths), options);
|
|
9842
9941
|
const checker = program2.getTypeChecker();
|
|
9843
9942
|
spinner.succeed("TypeScript program created.");
|
|
9844
9943
|
return {
|
|
@@ -9878,17 +9977,17 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9878
9977
|
function visit(node) {
|
|
9879
9978
|
if (!source)
|
|
9880
9979
|
return;
|
|
9881
|
-
if (
|
|
9980
|
+
if (ts7.isPropertyAccessExpression(node)) {
|
|
9882
9981
|
const left = node.expression;
|
|
9883
9982
|
const right = node.name;
|
|
9884
|
-
const { line } =
|
|
9885
|
-
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},`))) {
|
|
9886
9985
|
const symbol = getCachedSymbol(right);
|
|
9887
9986
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
9888
9987
|
const key = symbol.declarations[0]?.getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
9889
9988
|
const property = propertyMap.get(key);
|
|
9890
9989
|
const isScalar = symbol.declarations[0]?.getSourceFile().fileName.includes("_") ?? false;
|
|
9891
|
-
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${
|
|
9990
|
+
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${ts7.sys.getCurrentDirectory()}/`, "");
|
|
9892
9991
|
if (!symbolFilePath)
|
|
9893
9992
|
throw new Error(`No symbol file path found for ${left.text}.${right.text}`);
|
|
9894
9993
|
if (property) {
|
|
@@ -9912,10 +10011,10 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9912
10011
|
}
|
|
9913
10012
|
}
|
|
9914
10013
|
}
|
|
9915
|
-
} else if (
|
|
10014
|
+
} else if (ts7.isImportDeclaration(node) && ts7.isStringLiteral(node.moduleSpecifier)) {
|
|
9916
10015
|
const importPath = node.moduleSpecifier.text;
|
|
9917
10016
|
if (importPath.startsWith(".")) {
|
|
9918
|
-
const resolved =
|
|
10017
|
+
const resolved = ts7.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts7.sys).resolvedModule?.resolvedFileName;
|
|
9919
10018
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
9920
10019
|
const property = propertyMap.get(moduleName);
|
|
9921
10020
|
const isScalar = importPath.includes("_");
|
|
@@ -9930,7 +10029,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
9930
10029
|
}
|
|
9931
10030
|
}
|
|
9932
10031
|
}
|
|
9933
|
-
|
|
10032
|
+
ts7.forEachChild(node, visit);
|
|
9934
10033
|
}
|
|
9935
10034
|
visit(source);
|
|
9936
10035
|
}
|
|
@@ -10271,8 +10370,6 @@ class ApplicationRunner extends runner("application") {
|
|
|
10271
10370
|
const targets = await resolveMobileTargets(app, target);
|
|
10272
10371
|
if (operation === "release")
|
|
10273
10372
|
await this.#buildMobileCsr(app, env);
|
|
10274
|
-
else
|
|
10275
|
-
await this.start(app);
|
|
10276
10373
|
await this.#runMobileTargets(targets, async (mobileTarget2) => {
|
|
10277
10374
|
const capacitorApp2 = new CapacitorApp(app, mobileTarget2.config);
|
|
10278
10375
|
await capacitorApp2.runIos({ operation, env, regenerate });
|
|
@@ -10304,8 +10401,6 @@ class ApplicationRunner extends runner("application") {
|
|
|
10304
10401
|
const targets = await resolveMobileTargets(app, target);
|
|
10305
10402
|
if (operation === "release")
|
|
10306
10403
|
await this.#buildMobileCsr(app, env);
|
|
10307
|
-
else
|
|
10308
|
-
await this.start(app);
|
|
10309
10404
|
await this.#runMobileTargets(targets, async (mobileTarget2) => {
|
|
10310
10405
|
const capacitorApp2 = new CapacitorApp(app, mobileTarget2.config);
|
|
10311
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",
|