@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.
@@ -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.AKAN_PUBLIC_OPERATION_MODE === "local" ? "http://localhost" : "https://cloud.akanjs.com";
24
- var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}/api`;
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
- return ` ${JSON.stringify(key)}: async () => page${index},`;
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 ts5 from "typescript";
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 = ts5.createSourceFile(filePath, source, ts5.ScriptTarget.Latest, true, ts5.ScriptKind.TSX);
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 (!ts5.isVariableStatement(statement))
7019
+ if (!ts6.isVariableStatement(statement))
6952
7020
  continue;
6953
- const modifiers = ts5.canHaveModifiers(statement) ? ts5.getModifiers(statement) : undefined;
6954
- const isExported = modifiers?.some((modifier) => modifier.kind === ts5.SyntaxKind.ExportKeyword) ?? false;
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 (!ts5.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
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 (ts5.isStringLiteralLike(node))
7037
+ if (ts6.isStringLiteralLike(node))
6970
7038
  return node.text;
6971
- if (ts5.isNumericLiteral(node))
7039
+ if (ts6.isNumericLiteral(node))
6972
7040
  return Number(node.text);
6973
- if (node.kind === ts5.SyntaxKind.TrueKeyword)
7041
+ if (node.kind === ts6.SyntaxKind.TrueKeyword)
6974
7042
  return true;
6975
- if (node.kind === ts5.SyntaxKind.FalseKeyword)
7043
+ if (node.kind === ts6.SyntaxKind.FalseKeyword)
6976
7044
  return false;
6977
- if (ts5.isArrayLiteralExpression(node))
7045
+ if (ts6.isArrayLiteralExpression(node))
6978
7046
  return node.elements.map((element) => this.#literalToValue(element));
6979
- if (ts5.isObjectLiteralExpression(node)) {
7047
+ if (ts6.isObjectLiteralExpression(node)) {
6980
7048
  const obj = {};
6981
7049
  for (const prop of node.properties) {
6982
- if (!ts5.isPropertyAssignment(prop))
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 (ts5.isAsExpression(node) || ts5.isSatisfiesExpression(node) || ts5.isParenthesizedExpression(node)) {
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 (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name))
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 fs3 from "fs";
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 = fs3.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
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 fs4 from "fs";
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 (!fs4.existsSync(root) || !fs4.statSync(root).isDirectory())
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
- if (command !== "build")
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 fs5 from "fs";
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 (fs5.existsSync(resolved))
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: \`mobile/\${target.name}/www\`,
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 ts6 from "typescript";
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 = ts6.readConfigFile(tsConfigPath, (path37) => {
9809
- return ts6.sys.readFile(path37);
9907
+ const configFile = ts7.readConfigFile(tsConfigPath, (path37) => {
9908
+ return ts7.sys.readFile(path37);
9810
9909
  });
9811
- return ts6.parseJsonConfigFileContent(configFile.config, ts6.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
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 = ts6.resolveModuleName(importPath, filePath, parsedConfig.options, ts6.sys).resolvedModule?.resolvedFileName;
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 = ts6.createProgram(Array.from(filePaths), options);
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 (ts6.isPropertyAccessExpression(node)) {
9982
+ if (ts7.isPropertyAccessExpression(node)) {
9884
9983
  const left = node.expression;
9885
9984
  const right = node.name;
9886
- const { line } = ts6.getLineAndCharacterOfPosition(source, node.getStart());
9887
- if (ts6.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},`))) {
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(`${ts6.sys.getCurrentDirectory()}/`, "");
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 (ts6.isImportDeclaration(node) && ts6.isStringLiteral(node.moduleSpecifier)) {
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 = ts6.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts6.sys).resolvedModule?.resolvedFileName;
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
- ts6.forEachChild(node, visit);
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.AKAN_PUBLIC_OPERATION_MODE === "local" ? "http://localhost" : "https://cloud.akanjs.com";
22
- var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}/api`;
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
- return ` ${JSON.stringify(key)}: async () => page${index},`;
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 ts5 from "typescript";
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 = ts5.createSourceFile(filePath, source, ts5.ScriptTarget.Latest, true, ts5.ScriptKind.TSX);
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 (!ts5.isVariableStatement(statement))
7017
+ if (!ts6.isVariableStatement(statement))
6950
7018
  continue;
6951
- const modifiers = ts5.canHaveModifiers(statement) ? ts5.getModifiers(statement) : undefined;
6952
- const isExported = modifiers?.some((modifier) => modifier.kind === ts5.SyntaxKind.ExportKeyword) ?? false;
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 (!ts5.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
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 (ts5.isStringLiteralLike(node))
7035
+ if (ts6.isStringLiteralLike(node))
6968
7036
  return node.text;
6969
- if (ts5.isNumericLiteral(node))
7037
+ if (ts6.isNumericLiteral(node))
6970
7038
  return Number(node.text);
6971
- if (node.kind === ts5.SyntaxKind.TrueKeyword)
7039
+ if (node.kind === ts6.SyntaxKind.TrueKeyword)
6972
7040
  return true;
6973
- if (node.kind === ts5.SyntaxKind.FalseKeyword)
7041
+ if (node.kind === ts6.SyntaxKind.FalseKeyword)
6974
7042
  return false;
6975
- if (ts5.isArrayLiteralExpression(node))
7043
+ if (ts6.isArrayLiteralExpression(node))
6976
7044
  return node.elements.map((element) => this.#literalToValue(element));
6977
- if (ts5.isObjectLiteralExpression(node)) {
7045
+ if (ts6.isObjectLiteralExpression(node)) {
6978
7046
  const obj = {};
6979
7047
  for (const prop of node.properties) {
6980
- if (!ts5.isPropertyAssignment(prop))
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 (ts5.isAsExpression(node) || ts5.isSatisfiesExpression(node) || ts5.isParenthesizedExpression(node)) {
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 (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name))
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 fs3 from "fs";
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 = fs3.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
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 fs4 from "fs";
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 (!fs4.existsSync(root) || !fs4.statSync(root).isDirectory())
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
- if (command !== "build")
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 fs5 from "fs";
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 (fs5.existsSync(resolved))
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: \`mobile/\${target.name}/www\`,
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 ts6 from "typescript";
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 = ts6.readConfigFile(tsConfigPath, (path37) => {
9807
- return ts6.sys.readFile(path37);
9905
+ const configFile = ts7.readConfigFile(tsConfigPath, (path37) => {
9906
+ return ts7.sys.readFile(path37);
9808
9907
  });
9809
- return ts6.parseJsonConfigFileContent(configFile.config, ts6.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
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 = ts6.resolveModuleName(importPath, filePath, parsedConfig.options, ts6.sys).resolvedModule?.resolvedFileName;
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 = ts6.createProgram(Array.from(filePaths), options);
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 (ts6.isPropertyAccessExpression(node)) {
9980
+ if (ts7.isPropertyAccessExpression(node)) {
9882
9981
  const left = node.expression;
9883
9982
  const right = node.name;
9884
- const { line } = ts6.getLineAndCharacterOfPosition(source, node.getStart());
9885
- if (ts6.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},`))) {
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(`${ts6.sys.getCurrentDirectory()}/`, "");
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 (ts6.isImportDeclaration(node) && ts6.isStringLiteral(node.moduleSpecifier)) {
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 = ts6.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts6.sys).resolvedModule?.resolvedFileName;
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
- ts6.forEachChild(node, visit);
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.1.2-rc.0",
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.1.2-rc.0",
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",