@akanjs/cli 0.9.58-canary.0 → 0.9.58-canary.2

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.
Files changed (25) hide show
  1. package/cjs/index.js +555 -133
  2. package/cjs/src/templates/app/lib/___appName__/__appName__.dictionary.js +6 -3
  3. package/cjs/src/templates/app/lib/___appName__/__appName__.service.js +1 -1
  4. package/cjs/src/templates/app/{middleware.js → proxy.js} +5 -5
  5. package/cjs/src/templates/lib/cnst.js +1 -1
  6. package/cjs/src/templates/libRoot/lib/___libName__/__libName__.dictionary.js +7 -3
  7. package/cjs/src/templates/libRoot/lib/___libName__/__libName__.service.js +1 -1
  8. package/cjs/src/templates/localDev/docker-compose.yaml.template +7 -1
  9. package/cjs/src/templates/module/__model__.service.js +1 -1
  10. package/cjs/src/templates/workspaceRoot/package.json.template +9 -9
  11. package/esm/index.js +549 -127
  12. package/esm/src/templates/app/lib/___appName__/__appName__.dictionary.js +6 -3
  13. package/esm/src/templates/app/lib/___appName__/__appName__.service.js +1 -1
  14. package/esm/src/templates/app/{middleware.js → proxy.js} +2 -2
  15. package/esm/src/templates/lib/cnst.js +1 -1
  16. package/esm/src/templates/libRoot/lib/___libName__/__libName__.dictionary.js +7 -3
  17. package/esm/src/templates/libRoot/lib/___libName__/__libName__.service.js +1 -1
  18. package/esm/src/templates/localDev/docker-compose.yaml.template +7 -1
  19. package/esm/src/templates/module/__model__.service.js +1 -1
  20. package/esm/src/templates/workspaceRoot/package.json.template +9 -9
  21. package/package.json +4 -4
  22. package/src/application/application.command.d.ts +3 -3
  23. package/src/application/application.runner.d.ts +14 -5
  24. package/src/application/application.script.d.ts +7 -6
  25. /package/src/templates/app/{middleware.d.ts → proxy.d.ts} +0 -0
package/esm/index.js CHANGED
@@ -316,6 +316,7 @@ var uploadRelease = async (appName, {
316
316
  environment,
317
317
  buildNum,
318
318
  platformVersion,
319
+ os,
319
320
  local
320
321
  }) => {
321
322
  const logger = new Logger("uploadRelease");
@@ -359,7 +360,7 @@ var uploadRelease = async (appName, {
359
360
  fetchingAppSpinner.succeed(`Fetching dev app information for ${appName}... done`);
360
361
  const pushingReleaseSpinner = spinning(`Pushing release to ${environment} environment...`);
361
362
  const release = (await axios.post(
362
- `${basePath2}/release/pushRelease/${devApp.id}/${environment}/${major}/${minor}/${sourceFile.id}/${buildFile.id}/${appBuildFile.id}`
363
+ `${basePath2}/release/pushRelease/${devApp.id}/${environment}/${major}/${minor}/${patch}/${sourceFile.id}/${buildFile.id}/${appBuildFile.id}${os ? `/${os}` : ""}`
363
364
  )).data;
364
365
  pushingReleaseSpinner.succeed(`Pushing release to ${environment} environment... done`);
365
366
  new Spinner(`Successfully pushed release to ${appName}-${environment} server. `, {
@@ -586,7 +587,7 @@ var withBase = (appName, config, libs, routes = []) => {
586
587
  ...commandType !== "start" || process.env.USE_PWA === "true" ? [withPWA] : []
587
588
  )({
588
589
  ...config,
589
- eslint: { ...config.eslint, ignoreDuringBuilds: true },
590
+ // eslint: { ...config.eslint, ignoreDuringBuilds: true },
590
591
  env: {
591
592
  ...config.env,
592
593
  basePaths: [...new Set(routes.map(({ basePath: basePath2 }) => basePath2))].join(",")
@@ -618,8 +619,6 @@ var withBase = (appName, config, libs, routes = []) => {
618
619
  },
619
620
  webpack: (config2) => {
620
621
  const watchOptions = config2.watchOptions;
621
- config2.resolve.alias.canvas = false;
622
- config2.resolve.alias.encoding = false;
623
622
  const ignored = watchOptions?.ignored ? typeof watchOptions.ignored === "string" ? [watchOptions.ignored] : Array.isArray(watchOptions.ignored) ? watchOptions.ignored.filter((ignore) => typeof ignore === "string") : [] : [];
624
623
  config2.watchOptions = {
625
624
  ...config2.watchOptions ?? {},
@@ -628,10 +627,11 @@ var withBase = (appName, config, libs, routes = []) => {
628
627
  return config2;
629
628
  },
630
629
  turbopack: {
630
+ ...config.turbopack ?? {},
631
631
  resolveAlias: {
632
632
  // canvas: false,
633
633
  // encoding: false,
634
- // ...(process.env.USE_AKANJS_PKGS === "true" ? { "@akanjs/config": "../../pkgs/@akanjs/config" } : {}),
634
+ ...process.env.USE_AKANJS_PKGS === "true" ? { "@akanjs/config": "../../pkgs/@akanjs/config" } : {},
635
635
  ...config.turbopack?.resolveAlias ?? {}
636
636
  }
637
637
  },
@@ -675,7 +675,7 @@ var withBase = (appName, config, libs, routes = []) => {
675
675
  };
676
676
  var defaultNextConfigFile = `import "tsconfig-paths/register.js";
677
677
 
678
- import { getNextConfig } from "@akanjs/config";
678
+ import { getNextConfig } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/@akanjs/config" : "@akanjs/config"}";
679
679
 
680
680
  import appInfo from "./akan.app.json";
681
681
  import config from "./akan.config";
@@ -687,7 +687,6 @@ export default getNextConfig(config, appInfo);
687
687
  var archs = ["amd64", "arm64"];
688
688
 
689
689
  // pkgs/@akanjs/config/src/akanConfig.ts
690
- var jiti = createJiti(import.meta.url);
691
690
  var makeAppConfig = (config, props) => {
692
691
  const { name, repoName } = props;
693
692
  return {
@@ -709,10 +708,12 @@ var makeAppConfig = (config, props) => {
709
708
  explicitDependencies: config.frontend?.explicitDependencies ?? []
710
709
  },
711
710
  mobile: {
711
+ ...config.mobile,
712
712
  appName: config.mobile?.appName ?? name,
713
- bundleId: config.mobile?.bundleId ?? `com.${repoName}.${name}`,
714
- version: config.mobile?.version,
715
- buildNum: config.mobile?.buildNum
713
+ appId: config.mobile?.appId ?? `com.${repoName}.app`,
714
+ version: config.mobile?.version ?? "0.0.1",
715
+ buildNum: config.mobile?.buildNum ?? 1,
716
+ plugins: config.mobile?.plugins
716
717
  }
717
718
  };
718
719
  };
@@ -720,6 +721,11 @@ var getAppConfig = async (appRoot, props) => {
720
721
  const akanConfigPath = path.join(appRoot, "akan.config.ts");
721
722
  if (!fs4.existsSync(akanConfigPath))
722
723
  throw new Error(`application akan.config.ts is not found ${appRoot}`);
724
+ const jiti = createJiti(import.meta.url, {
725
+ fsCache: false,
726
+ requireCache: false,
727
+ interopDefault: true
728
+ });
723
729
  const configImp = (await jiti.import(akanConfigPath)).default;
724
730
  const config = typeof configImp === "function" ? configImp(props) : configImp;
725
731
  return makeAppConfig(config, props);
@@ -740,6 +746,9 @@ var getLibConfig = async (libRoot, props) => {
740
746
  const akanConfigPath = path.join(libRoot, "akan.config.ts");
741
747
  if (!fs4.existsSync(akanConfigPath))
742
748
  throw new Error(`library akan.config.ts is not found ${libRoot}`);
749
+ const jiti = createJiti(import.meta.url, {
750
+ cache: false
751
+ });
743
752
  const configImp = (await jiti.import(akanConfigPath)).default;
744
753
  const config = typeof configImp === "function" ? configImp(props) : configImp;
745
754
  return makeLibConfig(config, props);
@@ -828,6 +837,26 @@ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
828
837
  };
829
838
  }
830
839
  };
840
+ var increaseBuildNum = async (appRoot, props) => {
841
+ const appConfig = await getAppConfig(appRoot, props);
842
+ const akanConfigPath = path.join(appRoot, "akan.config.ts");
843
+ const akanConfig = fs4.readFileSync(akanConfigPath, "utf8");
844
+ const akanConfigContent = akanConfig.replace(
845
+ `buildNum: ${appConfig.mobile.buildNum}`,
846
+ `buildNum: ${appConfig.mobile.buildNum + 1}`
847
+ );
848
+ fs4.writeFileSync(akanConfigPath, akanConfigContent);
849
+ };
850
+ var decreaseBuildNum = async (appRoot, props) => {
851
+ const appConfig = await getAppConfig(appRoot, props);
852
+ const akanConfigPath = path.join(appRoot, "akan.config.ts");
853
+ const akanConfig = fs4.readFileSync(akanConfigPath, "utf8");
854
+ const akanConfigContent = akanConfig.replace(
855
+ `buildNum: ${appConfig.mobile.buildNum}`,
856
+ `buildNum: ${appConfig.mobile.buildNum - 1}`
857
+ );
858
+ fs4.writeFileSync(akanConfigPath, akanConfigContent);
859
+ };
831
860
 
832
861
  // pkgs/@akanjs/devkit/src/executors.ts
833
862
  import chalk3 from "chalk";
@@ -1878,13 +1907,13 @@ var Executor = class _Executor {
1878
1907
  let stdout = "";
1879
1908
  let stderr = "";
1880
1909
  proc.stdout?.on("data", (data) => {
1881
- stdout += data;
1882
- this.logs.push(data);
1910
+ stdout += data.toString();
1911
+ this.logs.push(data.toString());
1883
1912
  this.#stdout(data);
1884
1913
  });
1885
1914
  proc.stderr?.on("data", (data) => {
1886
- stderr += data;
1887
- this.logs.push(data);
1915
+ stderr += data.toString();
1916
+ this.logs.push(data.toString());
1888
1917
  this.#stdout(data);
1889
1918
  });
1890
1919
  return new Promise((resolve, reject) => {
@@ -2050,6 +2079,10 @@ var Executor = class _Executor {
2050
2079
  this.logger.verbose(msg);
2051
2080
  return this;
2052
2081
  }
2082
+ debug(msg) {
2083
+ this.logger.debug(msg);
2084
+ return this;
2085
+ }
2053
2086
  spinning(msg, { prefix = `${this.emoji}${this.name}`, indent = 0, enableSpin = !_Executor.verbose } = {}) {
2054
2087
  return new Spinner(msg, { prefix, indent, enableSpin }).start();
2055
2088
  }
@@ -2600,10 +2633,8 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2600
2633
  await Promise.all([this.removeDir(projectPublicLibPath), this.removeDir(projectAssetsLibPath)]);
2601
2634
  const targetPublicDeps = libDeps.filter((dep) => this.exists(`${this.workspace.workspaceRoot}/libs/${dep}/public`));
2602
2635
  const targetAssetsDeps = libDeps.filter((dep) => this.exists(`${this.workspace.workspaceRoot}/libs/${dep}/assets`));
2603
- await Promise.all([
2604
- ...targetPublicDeps.map((dep) => this.mkdir(`${projectPublicLibPath}/${dep}`)),
2605
- ...targetAssetsDeps.map((dep) => this.mkdir(`${projectAssetsLibPath}/${dep}`))
2606
- ]);
2636
+ targetPublicDeps.forEach((dep) => this.mkdir(`${projectPublicLibPath}/${dep}`));
2637
+ targetAssetsDeps.forEach((dep) => this.mkdir(`${projectAssetsLibPath}/${dep}`));
2607
2638
  await Promise.all([
2608
2639
  ...targetPublicDeps.map(
2609
2640
  (dep) => this.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`)
@@ -2613,6 +2644,12 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2613
2644
  )
2614
2645
  ]);
2615
2646
  }
2647
+ async increaseBuildNum() {
2648
+ await increaseBuildNum(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "app", name: this.name });
2649
+ }
2650
+ async decreaseBuildNum() {
2651
+ await decreaseBuildNum(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "app", name: this.name });
2652
+ }
2616
2653
  };
2617
2654
  var LibExecutor = class _LibExecutor extends SysExecutor {
2618
2655
  workspaceRoot;
@@ -2723,7 +2760,95 @@ var getSelf = async (token) => {
2723
2760
 
2724
2761
  // pkgs/@akanjs/devkit/src/capacitorApp.ts
2725
2762
  import { MobileProject } from "@trapezedev/project";
2763
+ import fs11 from "fs";
2764
+
2765
+ // pkgs/@akanjs/devkit/src/fileEditor.ts
2726
2766
  import fs10 from "fs";
2767
+ var FileEditor = class {
2768
+ filePath;
2769
+ content;
2770
+ constructor(filePath) {
2771
+ this.filePath = filePath;
2772
+ this.content = this.#readFile();
2773
+ }
2774
+ #readFile() {
2775
+ try {
2776
+ return fs10.readFileSync(this.filePath, "utf-8");
2777
+ } catch (error) {
2778
+ throw new Error(`Failed to read file: ${this.filePath}`);
2779
+ }
2780
+ }
2781
+ find(pattern) {
2782
+ const lines = this.content.split("\n");
2783
+ const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
2784
+ for (let i = 0; i < lines.length; i++) {
2785
+ if (regex.test(lines[i])) {
2786
+ return i;
2787
+ }
2788
+ }
2789
+ return -1;
2790
+ }
2791
+ findAll(pattern) {
2792
+ const lines = this.content.split("\n");
2793
+ const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
2794
+ const matches = [];
2795
+ for (let i = 0; i < lines.length; i++) {
2796
+ if (regex.test(lines[i])) {
2797
+ matches.push(i);
2798
+ }
2799
+ }
2800
+ return matches;
2801
+ }
2802
+ insertAfter(pattern, data) {
2803
+ const lineIndex = this.find(pattern);
2804
+ if (lineIndex === -1) {
2805
+ throw new Error(`Pattern not found: ${pattern}`);
2806
+ }
2807
+ const lines = this.content.split("\n");
2808
+ lines.splice(lineIndex + 1, 0, data);
2809
+ this.content = lines.join("\n");
2810
+ return this;
2811
+ }
2812
+ insertBefore(pattern, data) {
2813
+ const lineIndex = this.find(pattern);
2814
+ if (lineIndex === -1) {
2815
+ throw new Error(`Pattern not found: ${pattern}`);
2816
+ }
2817
+ const lines = this.content.split("\n");
2818
+ lines.splice(lineIndex, 0, data);
2819
+ this.content = lines.join("\n");
2820
+ return this;
2821
+ }
2822
+ replace(pattern, replacement) {
2823
+ const regex = typeof pattern === "string" ? new RegExp(pattern, "g") : pattern;
2824
+ this.content = this.content.replace(regex, replacement);
2825
+ return this;
2826
+ }
2827
+ append(data) {
2828
+ this.content += "\n" + data;
2829
+ return this;
2830
+ }
2831
+ prepend(data) {
2832
+ this.content = data + "\n" + this.content;
2833
+ return this;
2834
+ }
2835
+ save() {
2836
+ try {
2837
+ fs10.writeFileSync(this.filePath, this.content, "utf-8");
2838
+ } catch (error) {
2839
+ throw new Error(`Failed to save file: ${this.filePath}`);
2840
+ }
2841
+ }
2842
+ getContent() {
2843
+ return this.content;
2844
+ }
2845
+ setContent(content) {
2846
+ this.content = content;
2847
+ return this;
2848
+ }
2849
+ };
2850
+
2851
+ // pkgs/@akanjs/devkit/src/capacitorApp.ts
2727
2852
  var CapacitorApp = class {
2728
2853
  constructor(app) {
2729
2854
  this.app = app;
@@ -2751,78 +2876,160 @@ var CapacitorApp = class {
2751
2876
  await this.project.commit();
2752
2877
  }
2753
2878
  async #prepareIos() {
2754
- const isAdded = fs10.existsSync(`${this.app.cwdPath}/ios/App/Podfile`);
2879
+ const isAdded = fs11.existsSync(`${this.app.cwdPath}/ios/App/Podfile`);
2755
2880
  if (!isAdded) {
2756
2881
  await this.app.spawn("npx", ["cap", "add", "ios"]);
2757
2882
  await this.app.spawn("npx", ["@capacitor/assets", "generate"]);
2758
2883
  } else
2759
2884
  this.app.verbose(`iOS already added, skip adding process`);
2885
+ this.app.verbose(`syncing iOS`);
2760
2886
  await this.app.spawn("npx", ["cap", "sync", "ios"]);
2887
+ this.app.verbose(`sync completed.`);
2761
2888
  }
2762
2889
  async buildIos() {
2763
2890
  await this.#prepareIos();
2764
- await this.app.spawn("npx", ["cap", "run", "ios"]);
2891
+ this.app.verbose(`build completed iOS.`);
2892
+ return;
2893
+ }
2894
+ async syncIos() {
2895
+ await this.app.spawn("npx", ["cap", "sync", "ios"]);
2765
2896
  }
2766
2897
  async openIos() {
2767
2898
  await this.app.spawn("npx", ["cap", "open", "ios"]);
2768
2899
  }
2769
- async runIos({ operation, bundleId, version = "0.0.1", buildNum = 1 }) {
2900
+ async runIos({ operation, appId, version = "0.0.1", buildNum = 1, host = "local" }) {
2901
+ const defaultAppId = `com.${this.app.name}.app`;
2770
2902
  await this.#prepareIos();
2771
- this.project.ios.setBundleId("App", "Debug", bundleId);
2772
- this.project.ios.setBundleId("App", "Release", bundleId);
2903
+ this.project.ios.setBundleId("App", "Debug", appId ?? defaultAppId);
2904
+ this.project.ios.setBundleId("App", "Release", appId ?? defaultAppId);
2773
2905
  await this.project.ios.setVersion("App", "Debug", version);
2774
2906
  await this.project.ios.setVersion("App", "Release", version);
2775
2907
  await this.project.ios.setBuild("App", "Debug", buildNum);
2776
2908
  await this.project.ios.setBuild("App", "Release", buildNum);
2777
2909
  await this.project.commit();
2778
- await this.app.spawn("npx", [
2779
- "cross-env",
2780
- `APP_OPERATION_MODE=${operation}`,
2910
+ await this.app.spawn(
2781
2911
  "npx",
2782
- "cap",
2783
- "run",
2784
- "ios",
2785
- "--live-reload",
2786
- "--port",
2787
- "4201"
2788
- ]);
2912
+ [
2913
+ "cross-env",
2914
+ `APP_OPERATION_MODE=${operation}`,
2915
+ `NEXT_PUBLIC_ENV=${host}`,
2916
+ "npx",
2917
+ "cap",
2918
+ "run",
2919
+ "ios",
2920
+ "--live-reload",
2921
+ operation === "release" ? "" : "--live-reload",
2922
+ operation === "release" ? "" : "--port",
2923
+ operation === "release" ? "" : "4201"
2924
+ ],
2925
+ {
2926
+ stdio: "inherit"
2927
+ }
2928
+ );
2789
2929
  }
2790
2930
  async #prepareAndroid() {
2791
- const isAdded = fs10.existsSync(`${this.app.cwdPath}/android/app/build.gradle`);
2931
+ const isAdded = fs11.existsSync(`${this.app.cwdPath}/android/app/build.gradle`);
2792
2932
  if (!isAdded) {
2793
2933
  await this.app.spawn("npx", ["cap", "add", "android"]);
2794
- await this.app.spawn("npx", ["@capacitor/assets", "generate"]);
2795
2934
  } else
2796
2935
  this.app.verbose(`Android already added, skip adding process`);
2936
+ await this.app.spawn("npx", ["@capacitor/assets", "generate"]);
2797
2937
  await this.app.spawn("npx", ["cap", "sync", "android"]);
2798
2938
  }
2799
- async buildAndroid() {
2939
+ #updateAndroidBuildTypes() {
2940
+ const appGradle = new FileEditor(`${this.app.cwdPath}/android/app/build.gradle`);
2941
+ const buildTypesBlock = `
2942
+ debug {
2943
+ applicationIdSuffix ".debug"
2944
+ versionNameSuffix "-DEBUG"
2945
+ debuggable true
2946
+ minifyEnabled false
2947
+ }
2948
+ `;
2949
+ const singinConfigBlock = `
2950
+ signingConfigs {
2951
+ debug {
2952
+ storeFile file('debug.keystore')
2953
+ storePassword 'android'
2954
+ keyAlias 'androiddebugkey'
2955
+ keyPassword 'android'
2956
+ }
2957
+ release {
2958
+ if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
2959
+ storeFile file(MYAPP_RELEASE_STORE_FILE)
2960
+ storePassword MYAPP_RELEASE_STORE_PASSWORD
2961
+ keyAlias MYAPP_RELEASE_KEY_ALIAS
2962
+ keyPassword MYAPP_RELEASE_KEY_PASSWORD
2963
+ }
2964
+ }
2965
+ }
2966
+ `;
2967
+ if (appGradle.find("signingConfigs {") === -1) {
2968
+ appGradle.insertBefore("buildTypes {", singinConfigBlock);
2969
+ }
2970
+ if (appGradle.find(`applicationIdSuffix ".debug"`) === -1) {
2971
+ appGradle.insertAfter("buildTypes {", buildTypesBlock);
2972
+ }
2973
+ appGradle.save();
2974
+ }
2975
+ async buildAndroid(assembleType) {
2800
2976
  await this.#prepareAndroid();
2801
- await this.app.spawn("npx", ["cap", "build", "android"]);
2977
+ this.#updateAndroidBuildTypes();
2978
+ const isWindows = process.platform === "win32";
2979
+ const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
2980
+ await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
2981
+ stdio: "inherit",
2982
+ cwd: `${this.app.cwdPath}/android`
2983
+ });
2802
2984
  }
2803
2985
  async openAndroid() {
2804
2986
  await this.app.spawn("npx", ["cap", "open", "android"]);
2805
2987
  }
2806
- async runAndroid({ operation, appName, bundleId, version = "0.0.1", buildNum = 1 }) {
2988
+ async syncAndroid() {
2989
+ await this.#prepareAndroid();
2990
+ this.app.log(`Sync Android Completed.`);
2991
+ }
2992
+ async runAndroid({ operation, appName, appId, version = "0.0.1", buildNum = 1, host = "local" }) {
2993
+ const defaultAppId = `com.${this.app.name}.app`;
2994
+ const defaultAppName = this.app.name;
2807
2995
  await this.project.android.setVersionName(version);
2996
+ await this.project.android.setPackageName(appId ?? defaultAppId);
2808
2997
  await this.project.android.setVersionCode(buildNum);
2809
- await this.project.android.setPackageName(bundleId);
2810
- await this.project.android.setAppName(appName);
2811
- await this.app.spawn("npx", [
2812
- "cross-env",
2813
- `APP_OPERATION_MODE=${operation}`,
2998
+ const versionName = await this.project.android.getVersionName();
2999
+ const versionCode = await this.project.android.getVersionCode();
3000
+ await this.project.android.setAppName(appName ?? defaultAppName);
3001
+ await this.project.commit();
3002
+ await this.#prepareAndroid();
3003
+ this.app.logger.info(`Running Android in ${operation} mode on ${host} host`);
3004
+ await this.app.spawn(
2814
3005
  "npx",
2815
- "cap",
2816
- "run",
2817
- "android",
2818
- "--live-reload",
2819
- "--port",
2820
- "--list",
2821
- "4201"
2822
- ]);
3006
+ [
3007
+ "cross-env",
3008
+ `NEXT_PUBLIC_ENV=${host}`,
3009
+ `APP_OPERATION_MODE=${operation}`,
3010
+ "npx",
3011
+ "cap",
3012
+ "run",
3013
+ "android",
3014
+ operation === "release" ? "" : "--live-reload",
3015
+ operation === "release" ? "" : "--port",
3016
+ operation === "release" ? "" : "4201"
3017
+ ],
3018
+ {
3019
+ stdio: "inherit"
3020
+ }
3021
+ );
3022
+ }
3023
+ //? 릴리즈시 buildNum +1 version 파라미터 받아서 업데이트
3024
+ async updateAndroidVersion(version, buildNum) {
3025
+ await this.project.android.setVersionName(version);
3026
+ await this.project.android.setVersionCode(buildNum);
3027
+ const versionName = await this.project.android.getVersionName();
3028
+ const versionCode = await this.project.android.getVersionCode();
3029
+ await this.project.commit();
2823
3030
  }
2824
3031
  async releaseIos() {
2825
- const isAdded = fs10.existsSync(`${this.app.cwdPath}/ios/App/Podfile`);
3032
+ const isAdded = fs11.existsSync(`${this.app.cwdPath}/ios/App/Podfile`);
2826
3033
  if (!isAdded) {
2827
3034
  await this.app.spawn("npx cap add ios");
2828
3035
  await this.app.spawn("npx @capacitor/assets generate");
@@ -2831,7 +3038,7 @@ var CapacitorApp = class {
2831
3038
  await this.app.spawn("cross-env", ["APP_OPERATION_MODE=release", "npx", "cap", "sync", "ios"]);
2832
3039
  }
2833
3040
  async releaseAndroid() {
2834
- const isAdded = fs10.existsSync(`${this.app.cwdPath}/android/app/build.gradle`);
3041
+ const isAdded = fs11.existsSync(`${this.app.cwdPath}/android/app/build.gradle`);
2835
3042
  if (!isAdded) {
2836
3043
  await this.app.spawn("npx cap add android");
2837
3044
  await this.app.spawn("npx @capacitor/assets generate");
@@ -3076,7 +3283,7 @@ var Target = {
3076
3283
  import { confirm, input, select as select2 } from "@inquirer/prompts";
3077
3284
  import chalk4 from "chalk";
3078
3285
  import { program } from "commander";
3079
- import fs11 from "fs";
3286
+ import fs12 from "fs";
3080
3287
  var camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
3081
3288
  var handleOption = (programCommand, argMeta) => {
3082
3289
  const {
@@ -3253,10 +3460,10 @@ var runCommands = async (...commands) => {
3253
3460
  process.exit(1);
3254
3461
  });
3255
3462
  const __dirname = getDirname(import.meta.url);
3256
- const hasPackageJson = fs11.existsSync(`${__dirname}/../package.json`);
3257
- process.env.AKAN_VERSION = hasPackageJson ? JSON.parse(fs11.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
3463
+ const hasPackageJson = fs12.existsSync(`${__dirname}/../package.json`);
3464
+ process.env.AKAN_VERSION = hasPackageJson ? JSON.parse(fs12.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
3258
3465
  program.version(process.env.AKAN_VERSION).description("Akan CLI");
3259
- const akanBasePackageJson = fs11.existsSync("./node_modules/@akanjs/base/package.json") ? JSON.parse(fs11.readFileSync("./node_modules/@akanjs/base/package.json", "utf8")) : null;
3466
+ const akanBasePackageJson = fs12.existsSync("./node_modules/@akanjs/base/package.json") ? JSON.parse(fs12.readFileSync("./node_modules/@akanjs/base/package.json", "utf8")) : null;
3260
3467
  if (akanBasePackageJson && akanBasePackageJson.version !== process.env.AKAN_VERSION) {
3261
3468
  Logger.rawLog(
3262
3469
  chalk4.yellow(
@@ -3350,7 +3557,7 @@ import {
3350
3557
  import { ChatDeepSeek } from "@langchain/deepseek";
3351
3558
  import { ChatOpenAI as ChatOpenAI2 } from "@langchain/openai";
3352
3559
  import chalk5 from "chalk";
3353
- import fs12 from "fs";
3560
+ import fs13 from "fs";
3354
3561
  var MAX_ASK_TRY = 300;
3355
3562
  var supportedLlmModels = ["deepseek-chat", "deepseek-reasoner"];
3356
3563
  var AiSession = class _AiSession {
@@ -3418,7 +3625,7 @@ var AiSession = class _AiSession {
3418
3625
  }
3419
3626
  static clearCache(workspaceRoot) {
3420
3627
  const cacheDir = `${workspaceRoot}/${this.#cacheDir}`;
3421
- fs12.rmSync(cacheDir, { recursive: true, force: true });
3628
+ fs13.rmSync(cacheDir, { recursive: true, force: true });
3422
3629
  }
3423
3630
  messageHistory = [];
3424
3631
  sessionKey;
@@ -3618,7 +3825,7 @@ ${fileCheck.lintResult.message}`
3618
3825
  // pkgs/@akanjs/devkit/src/builder.ts
3619
3826
  import * as esbuild from "esbuild";
3620
3827
  import { dtsPlugin } from "esbuild-plugin-d.ts";
3621
- import fs13 from "fs";
3828
+ import fs14 from "fs";
3622
3829
  var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
3623
3830
  var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "copy"]));
3624
3831
  var Builder = class {
@@ -3664,7 +3871,7 @@ var Builder = class {
3664
3871
  };
3665
3872
  }
3666
3873
  async build(options = {}) {
3667
- if (fs13.existsSync(this.#distExecutor.cwdPath))
3874
+ if (fs14.existsSync(this.#distExecutor.cwdPath))
3668
3875
  await this.#distExecutor.exec(`rm -rf ${this.#distExecutor.cwdPath}`);
3669
3876
  const plugins = [dtsPlugin({ tsconfig: `${this.#executor.cwdPath}/tsconfig.json` })];
3670
3877
  const [buildResult] = await Promise.all([
@@ -3761,6 +3968,9 @@ var useStdoutDimensions = () => {
3761
3968
  return dimensions;
3762
3969
  };
3763
3970
 
3971
+ // pkgs/@akanjs/cli/src/application/application.command.ts
3972
+ import { select as select6 } from "@inquirer/prompts";
3973
+
3764
3974
  // pkgs/@akanjs/cli/src/library/library.runner.ts
3765
3975
  import { compareVersions } from "compare-versions";
3766
3976
  import dotenv2 from "dotenv";
@@ -4214,9 +4424,8 @@ import { ChatOpenAI as ChatOpenAI3 } from "@langchain/openai";
4214
4424
  import react from "@vitejs/plugin-react";
4215
4425
  import dotenv3 from "dotenv";
4216
4426
  import * as esbuild2 from "esbuild";
4217
- import fs14 from "fs";
4427
+ import fs15 from "fs";
4218
4428
  import fsPromise3 from "fs/promises";
4219
- import yaml2 from "js-yaml";
4220
4429
  import openBrowser from "open";
4221
4430
  import ora3 from "ora";
4222
4431
  import path8 from "path";
@@ -4241,8 +4450,8 @@ var ApplicationRunner = class {
4241
4450
  async getConfig(app) {
4242
4451
  return await app.getConfig();
4243
4452
  }
4244
- async scanSync(app) {
4245
- const scanInfo = await app.scan();
4453
+ async scanSync(app, { refresh = false } = {}) {
4454
+ const scanInfo = await app.scan({ refresh });
4246
4455
  await app.syncAssets(scanInfo.getScanResult().akanConfig.libs);
4247
4456
  return scanInfo;
4248
4457
  }
@@ -4359,7 +4568,7 @@ var ApplicationRunner = class {
4359
4568
  async buildFrontend(app, { spawnOptions } = {}) {
4360
4569
  const { env } = await this.#prepareCommand(app, "build", "frontend");
4361
4570
  const akanConfig = await app.getConfig();
4362
- await app.spawn("npx", ["next", "build", "--no-lint"], { env, ...spawnOptions });
4571
+ await app.spawn("npx", ["next", "build"], { env, ...spawnOptions });
4363
4572
  const buildResult = await esbuild2.build({
4364
4573
  entryPoints: [`${app.cwdPath}/next.config.ts`],
4365
4574
  outfile: `${app.dist.cwdPath}/frontend/next.config.ts`,
@@ -4371,7 +4580,12 @@ var ApplicationRunner = class {
4371
4580
  logLevel: "warning"
4372
4581
  });
4373
4582
  const rootPackageJson = app.workspace.getPackageJson();
4374
- const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
4583
+ const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, [
4584
+ "next",
4585
+ "react",
4586
+ "react-dom",
4587
+ "typescript"
4588
+ ]);
4375
4589
  buildResult.outputFiles.map((file) => app.dist.writeFile(file.path, file.text));
4376
4590
  const appPackageJson = {
4377
4591
  name: `${app.name}/frontend`,
@@ -4379,7 +4593,8 @@ var ApplicationRunner = class {
4379
4593
  version: "1.0.0",
4380
4594
  engines: { node: ">=20" },
4381
4595
  dependencies,
4382
- scripts: { start: "next start" }
4596
+ scripts: { start: "next start" },
4597
+ browserslist: "> 1%"
4383
4598
  };
4384
4599
  app.dist.writeJson("frontend/package.json", appPackageJson);
4385
4600
  await Promise.all([
@@ -4403,7 +4618,7 @@ var ApplicationRunner = class {
4403
4618
  stdio: withInk ? ["ignore", "pipe", "pipe"] : "inherit"
4404
4619
  });
4405
4620
  }
4406
- async #getViteConfig(app, command, viteConfig = {}) {
4621
+ async #getViteConfig(app, command, viteConfig = {}, options = {}) {
4407
4622
  const { env } = await this.#prepareCommand(app, command, "csr");
4408
4623
  const { NODE_ENV, NODE_NO_WARNINGS, ...applyEnvs } = env;
4409
4624
  const tsconfig = app.workspace.getTsConfig();
@@ -4471,10 +4686,10 @@ var ApplicationRunner = class {
4471
4686
  AKAN_COMMAND_TYPE: "start",
4472
4687
  NEXT_PUBLIC_REPO_NAME: app.workspace.repoName,
4473
4688
  NEXT_PUBLIC_SERVE_DOMAIN: processEnv.NEXT_PUBLIC_SERVE_DOMAIN ?? "localhost",
4474
- NEXT_PUBLIC_ENV: processEnv.NEXT_PUBLIC_ENV ?? "debug",
4689
+ NEXT_PUBLIC_ENV: options.host ?? processEnv.NEXT_PUBLIC_ENV ?? "debug",
4475
4690
  NEXT_PUBLIC_OPERATION_MODE: processEnv.NEXT_PUBLIC_OPERATION_MODE ?? "local",
4476
4691
  NEXT_PUBLIC_LOG_LEVEL: processEnv.NEXT_PUBLIC_LOG_LEVEL ?? "log",
4477
- APP_OPERATION_MODE: processEnv.APP_OPERATION_MODE ?? "local",
4692
+ APP_OPERATION_MODE: options.operation ?? processEnv.APP_OPERATION_MODE ?? "local",
4478
4693
  AKAN_WORKSPACE_ROOT: app.workspace.workspaceRoot,
4479
4694
  AKAN_APP_ROOT: app.cwdPath,
4480
4695
  RENDER_ENV: "csr",
@@ -4488,8 +4703,8 @@ var ApplicationRunner = class {
4488
4703
  });
4489
4704
  return config;
4490
4705
  }
4491
- async buildCsr(app) {
4492
- const config = await this.#getViteConfig(app, "build");
4706
+ async buildCsr(app, { operation, host } = {}) {
4707
+ const config = await this.#getViteConfig(app, "build", {}, { operation, host });
4493
4708
  await vite.build(config);
4494
4709
  }
4495
4710
  async startCsr(app, { open: open2 = false, onStart, withInk = false } = {}) {
@@ -4532,10 +4747,15 @@ var ApplicationRunner = class {
4532
4747
  const capacitorApp = await new CapacitorApp(app).init();
4533
4748
  await capacitorApp.buildIos();
4534
4749
  }
4535
- async startIos(app, { open: open2 = false, operation = "local" } = {}) {
4750
+ async startIos(app, {
4751
+ open: open2 = false,
4752
+ operation = "local",
4753
+ host = "local"
4754
+ } = {}) {
4536
4755
  const akanConfig = await app.getConfig();
4756
+ await this.buildCsr(app, { operation, host });
4537
4757
  const capacitorApp = await new CapacitorApp(app).init();
4538
- await capacitorApp.runIos({ ...akanConfig.mobile, operation });
4758
+ await capacitorApp.runIos({ ...akanConfig.mobile, operation, host });
4539
4759
  if (open2)
4540
4760
  await capacitorApp.openIos();
4541
4761
  }
@@ -4545,18 +4765,34 @@ var ApplicationRunner = class {
4545
4765
  await capacitorApp.releaseIos();
4546
4766
  }
4547
4767
  async buildAndroid(app) {
4548
- const capacitorApp = await new CapacitorApp(app).init();
4549
- await capacitorApp.buildAndroid();
4768
+ const capacitorApp = new CapacitorApp(app);
4769
+ await capacitorApp.init();
4770
+ await capacitorApp.syncAndroid();
4550
4771
  }
4551
- async startAndroid(app, { open: open2 = false, operation = "local" } = {}) {
4772
+ async startAndroid(app, {
4773
+ open: open2 = false,
4774
+ operation = "local",
4775
+ host = "local"
4776
+ } = {}) {
4552
4777
  const akanConfig = await app.getConfig();
4778
+ await this.buildCsr(app, { operation, host });
4553
4779
  const capacitorApp = await new CapacitorApp(app).init();
4554
- await capacitorApp.runAndroid({ ...akanConfig.mobile, operation });
4780
+ await capacitorApp.runAndroid({ ...akanConfig.mobile, operation, host });
4781
+ }
4782
+ async releaseAndroid(app, assembleType) {
4783
+ const capacitorApp = new CapacitorApp(app);
4784
+ const akanConfig = await app.getConfig();
4785
+ await capacitorApp.init();
4786
+ await capacitorApp.updateAndroidVersion(akanConfig.mobile.version, akanConfig.mobile.buildNum);
4787
+ await capacitorApp.buildAndroid(assembleType);
4788
+ app.log(
4789
+ `Release Android ${app.name} ${assembleType} Completed. app-${assembleType === "apk" ? "release" : "release"}.${assembleType === "apk" ? "apk" : "aab"}`
4790
+ );
4791
+ app.log(`Path : ${app.cwdPath}/android/app/build/outputs/${assembleType === "apk" ? "apk" : "bundle"}/release`);
4555
4792
  }
4556
- async releaseAndroid(app) {
4793
+ async codepush(app, os) {
4557
4794
  const capacitorApp = new CapacitorApp(app);
4558
4795
  await capacitorApp.init();
4559
- await capacitorApp.releaseAndroid();
4560
4796
  }
4561
4797
  async #prepareMongo(app, environment) {
4562
4798
  if (environment === "local")
@@ -4612,17 +4848,17 @@ var ApplicationRunner = class {
4612
4848
  await capacitorApp.save();
4613
4849
  }
4614
4850
  async releaseSource(app, { rebuild, buildNum = 0, environment = "debug", local = true } = {}) {
4851
+ const akanConfig = await app.getConfig();
4615
4852
  const buildRoot = `${app.workspace.workspaceRoot}/releases/builds/${app.name}`;
4616
- const appVersionInfo = yaml2.load(app.readFile("config.yaml"));
4617
- const platformVersion = appVersionInfo.platforms.android.versionName;
4618
- if (fs14.existsSync(buildRoot))
4853
+ const platformVersion = akanConfig.mobile.version;
4854
+ if (fs15.existsSync(buildRoot))
4619
4855
  await fsPromise3.rm(buildRoot, { recursive: true, force: true });
4620
4856
  await fsPromise3.mkdir(buildRoot, { recursive: true });
4621
- if (rebuild || !fs14.existsSync(`${app.dist.cwdPath}/backend`))
4857
+ if (rebuild || !fs15.existsSync(`${app.dist.cwdPath}/backend`))
4622
4858
  await this.buildBackend(app);
4623
- if (rebuild || !fs14.existsSync(`${app.dist.cwdPath}/frontend`))
4859
+ if (rebuild || !fs15.existsSync(`${app.dist.cwdPath}/frontend`))
4624
4860
  await this.buildFrontend(app);
4625
- if (rebuild || !fs14.existsSync(`${app.dist.cwdPath}/csr`))
4861
+ if (rebuild || !fs15.existsSync(`${app.dist.cwdPath}/csr`))
4626
4862
  await this.buildCsr(app);
4627
4863
  const buildVersion = `${platformVersion}-${buildNum}`;
4628
4864
  const buildPath = `${buildRoot}/${buildVersion}`;
@@ -4637,7 +4873,7 @@ var ApplicationRunner = class {
4637
4873
  buildRoot,
4638
4874
  "./"
4639
4875
  ]);
4640
- if (fs14.existsSync(`${app.dist.cwdPath}/csr`)) {
4876
+ if (fs15.existsSync(`${app.dist.cwdPath}/csr`)) {
4641
4877
  await fsPromise3.cp(`${app.dist.cwdPath}/csr`, "./csr", { recursive: true });
4642
4878
  await app.workspace.spawn("zip", [
4643
4879
  "-r",
@@ -4647,7 +4883,7 @@ var ApplicationRunner = class {
4647
4883
  await fsPromise3.rm("./csr", { recursive: true, force: true });
4648
4884
  }
4649
4885
  const sourceRoot = `${app.workspace.workspaceRoot}/releases/sources/${app.name}`;
4650
- if (fs14.existsSync(sourceRoot)) {
4886
+ if (fs15.existsSync(sourceRoot)) {
4651
4887
  const MAX_RETRY = 3;
4652
4888
  for (let i = 0; i < MAX_RETRY; i++) {
4653
4889
  try {
@@ -4667,7 +4903,7 @@ var ApplicationRunner = class {
4667
4903
  await Promise.all(
4668
4904
  [".next", "ios", "android", "public/libs"].map(async (path10) => {
4669
4905
  const targetPath = `${sourceRoot}/apps/${app.name}/${path10}`;
4670
- if (fs14.existsSync(targetPath))
4906
+ if (fs15.existsSync(targetPath))
4671
4907
  await fsPromise3.rm(targetPath, { recursive: true, force: true });
4672
4908
  })
4673
4909
  );
@@ -4695,8 +4931,8 @@ var ApplicationRunner = class {
4695
4931
  []
4696
4932
  )
4697
4933
  ]);
4698
- fs14.writeFileSync(`${sourceRoot}/tsconfig.json`, JSON.stringify(tsconfig, null, 2));
4699
- fs14.writeFileSync(
4934
+ fs15.writeFileSync(`${sourceRoot}/tsconfig.json`, JSON.stringify(tsconfig, null, 2));
4935
+ fs15.writeFileSync(
4700
4936
  `${sourceRoot}/README.md`,
4701
4937
  `# ${app.name}
4702
4938
  \uBCF8 \uD504\uB85C\uC81D\uD2B8\uC758 \uC18C\uC2A4\uCF54\uB4DC \uBC0F \uAD00\uB828\uC790\uB8CC\uB294 \uBAA8\uB450 \uBE44\uBC00\uC815\uBCF4\uB85C \uAD00\uB9AC\uB429\uB2C8\uB2E4.
@@ -4737,16 +4973,142 @@ var ApplicationRunner = class {
4737
4973
  "./"
4738
4974
  ]);
4739
4975
  await uploadRelease(app.name, {
4740
- workspaceRoot: app.workspace.cwdPath,
4741
- environment,
4976
+ local,
4742
4977
  buildNum,
4978
+ environment,
4743
4979
  platformVersion,
4744
- local
4980
+ workspaceRoot: app.workspace.cwdPath
4745
4981
  });
4746
4982
  }
4747
4983
  async createApplicationTemplate(workspace, appName) {
4748
4984
  await workspace.applyTemplate({ basePath: `apps/${appName}`, template: "appRoot", dict: { appName } });
4749
4985
  }
4986
+ async compressProjectFiles(app, { rebuild, buildNum = 0, environment = "debug", local = true } = {}) {
4987
+ const akanConfig = await app.getConfig();
4988
+ const buildRoot = `${app.workspace.workspaceRoot}/releases/builds/${app.name}`;
4989
+ const platformVersion = akanConfig.mobile.version;
4990
+ if (fs15.existsSync(buildRoot))
4991
+ await fsPromise3.rm(buildRoot, { recursive: true, force: true });
4992
+ await fsPromise3.mkdir(buildRoot, { recursive: true });
4993
+ if (rebuild || !fs15.existsSync(`${app.dist.cwdPath}/backend`))
4994
+ await this.buildBackend(app);
4995
+ if (rebuild || !fs15.existsSync(`${app.dist.cwdPath}/frontend`))
4996
+ await this.buildFrontend(app);
4997
+ if (rebuild || !fs15.existsSync(`${app.dist.cwdPath}/csr`))
4998
+ await this.buildCsr(app);
4999
+ const buildVersion = `${platformVersion}-${buildNum}`;
5000
+ const buildPath = `${buildRoot}/${buildVersion}`;
5001
+ await fsPromise3.mkdir(buildPath, { recursive: true });
5002
+ await fsPromise3.cp(`${app.dist.cwdPath}/backend`, `${buildPath}/backend`, { recursive: true });
5003
+ await fsPromise3.cp(app.dist.cwdPath, buildRoot, { recursive: true });
5004
+ await fsPromise3.rm(`${buildRoot}/frontend/.next`, { recursive: true, force: true });
5005
+ await app.workspace.spawn("tar", [
5006
+ "-zcf",
5007
+ `${app.workspace.workspaceRoot}/releases/builds/${app.name}-release.tar.gz`,
5008
+ "-C",
5009
+ buildRoot,
5010
+ "./"
5011
+ ]);
5012
+ if (fs15.existsSync(`${app.dist.cwdPath}/csr`)) {
5013
+ await fsPromise3.cp(`${app.dist.cwdPath}/csr`, "./csr", { recursive: true });
5014
+ await app.workspace.spawn("zip", [
5015
+ "-r",
5016
+ `${app.workspace.workspaceRoot}/releases/builds/${app.name}-appBuild.zip`,
5017
+ "./csr"
5018
+ ]);
5019
+ await fsPromise3.rm("./csr", { recursive: true, force: true });
5020
+ }
5021
+ const sourceRoot = `${app.workspace.workspaceRoot}/releases/sources/${app.name}`;
5022
+ if (fs15.existsSync(sourceRoot)) {
5023
+ const MAX_RETRY = 3;
5024
+ for (let i = 0; i < MAX_RETRY; i++) {
5025
+ try {
5026
+ await fsPromise3.rm(sourceRoot, { recursive: true, force: true });
5027
+ } catch (e) {
5028
+ }
5029
+ }
5030
+ }
5031
+ await fsPromise3.mkdir(sourceRoot, { recursive: true });
5032
+ await fsPromise3.cp(app.dist.cwdPath, `${sourceRoot}/apps/${app.name}`, { recursive: true });
5033
+ const libDeps = ["social", "shared", "platform", "util"];
5034
+ await Promise.all(
5035
+ libDeps.map(
5036
+ (lib) => fsPromise3.cp(`${app.workspace.cwdPath}/libs/${lib}`, `${sourceRoot}/libs/${lib}`, { recursive: true })
5037
+ )
5038
+ );
5039
+ await Promise.all(
5040
+ [".next", "ios", "android", "public/libs"].map(async (path10) => {
5041
+ const targetPath = `${sourceRoot}/apps/${app.name}/${path10}`;
5042
+ if (fs15.existsSync(targetPath))
5043
+ await fsPromise3.rm(targetPath, { recursive: true, force: true });
5044
+ })
5045
+ );
5046
+ const syncPaths = [
5047
+ ".husky",
5048
+ // ".vscode",
5049
+ ".editorconfig",
5050
+ // ".eslintrc.json",
5051
+ ".gitignore",
5052
+ ".prettierignore",
5053
+ ".prettierrc.json",
5054
+ // "jest.config.ts",
5055
+ "package.json"
5056
+ ];
5057
+ await Promise.all(
5058
+ syncPaths.map(
5059
+ (path10) => fsPromise3.cp(`${app.workspace.cwdPath}/${path10}`, `${sourceRoot}/${path10}`, { recursive: true })
5060
+ )
5061
+ );
5062
+ const tsconfig = app.workspace.readJson("tsconfig.json");
5063
+ tsconfig.compilerOptions.paths = Object.fromEntries([
5064
+ [`@${app.name}/*`, [`apps/${app.name}/*`]],
5065
+ ...libDeps.reduce(
5066
+ (acc, lib) => [...acc, [`@${lib}`, [`libs/${lib}/index.ts`]], [`@${lib}/*`, [`libs/${lib}/*`]]],
5067
+ []
5068
+ )
5069
+ ]);
5070
+ fs15.writeFileSync(`${sourceRoot}/tsconfig.json`, JSON.stringify(tsconfig, null, 2));
5071
+ fs15.writeFileSync(
5072
+ `${sourceRoot}/README.md`,
5073
+ `# ${app.name}
5074
+ \uBCF8 \uD504\uB85C\uC81D\uD2B8\uC758 \uC18C\uC2A4\uCF54\uB4DC \uBC0F \uAD00\uB828\uC790\uB8CC\uB294 \uBAA8\uB450 \uBE44\uBC00\uC815\uBCF4\uB85C \uAD00\uB9AC\uB429\uB2C8\uB2E4.
5075
+
5076
+ ## Get Started
5077
+ Run the code below.
5078
+ \`\`\`
5079
+ npm i -g nx pnpm
5080
+ pnpm i -w
5081
+
5082
+ cat <<EOF >> .env
5083
+ # ENV For Server => debug | debug.local | develop | develop.local | main | main.local
5084
+ SERVER_ENV=debug.local
5085
+ # Run Mode For Server => federation | batch | all
5086
+ SERVER_MODE=federation
5087
+ # ENV For Client => debug | debug.local | develop | develop.local | main | main.local
5088
+ NEXT_PUBLIC_CLIENT_ENV=debug.local
5089
+ ANALYZE=false
5090
+ EOF
5091
+
5092
+ akn start-backend ${app.name}
5093
+ # or akn start-frontend ${app.name}, etc
5094
+ \`\`\`
5095
+
5096
+ ## Build
5097
+ Run the code below.
5098
+ \`\`\`
5099
+ akn build-backend ${app.name}
5100
+ # or akn build-frontend ${app.name}, etc
5101
+ \`\`\`
5102
+ `
5103
+ );
5104
+ await app.workspace.spawn("tar", [
5105
+ "-zcf",
5106
+ `${app.workspace.cwdPath}/releases/sources/${app.name}-source.tar.gz`,
5107
+ "-C",
5108
+ sourceRoot,
5109
+ "./"
5110
+ ]);
5111
+ }
4750
5112
  async generateApplicationTemplate(app) {
4751
5113
  const openAIApiKey = process.env.OPENAI_API_KEY;
4752
5114
  if (!openAIApiKey)
@@ -4936,8 +5298,9 @@ var ApplicationScript = class {
4936
5298
  async startIos(app, {
4937
5299
  open: open2 = false,
4938
5300
  operation = "local",
5301
+ host = "local",
4939
5302
  sync = true
4940
- } = {}) {
5303
+ }) {
4941
5304
  if (sync)
4942
5305
  await this.syncApplication(app);
4943
5306
  await this.#runner.startIos(app, { open: open2, operation });
@@ -4954,15 +5317,22 @@ var ApplicationScript = class {
4954
5317
  async startAndroid(app, {
4955
5318
  open: open2 = false,
4956
5319
  operation = "local",
5320
+ host = "local",
4957
5321
  sync = true
4958
5322
  } = {}) {
4959
5323
  if (sync)
4960
5324
  await this.syncApplication(app);
4961
- await this.#runner.startAndroid(app, { open: open2, operation });
5325
+ await this.#runner.startAndroid(app, { open: open2, operation, host });
4962
5326
  }
4963
- async releaseAndroid(app, { sync = true } = {}) {
4964
- await this.buildCsr(app, { sync });
4965
- await this.#runner.releaseAndroid(app);
5327
+ //* 안드로이드 릴리즈(apk or aab 추출) 메서드
5328
+ async releaseAndroid(app, assembleType) {
5329
+ try {
5330
+ await app.increaseBuildNum();
5331
+ await this.buildCsr(app, { sync: true });
5332
+ await this.#runner.releaseAndroid(app, assembleType);
5333
+ } catch (e) {
5334
+ await app.decreaseBuildNum();
5335
+ }
4966
5336
  }
4967
5337
  async dumpDatabase(app, environment) {
4968
5338
  await this.dbdown(app.workspace);
@@ -4988,6 +5358,9 @@ var ApplicationScript = class {
4988
5358
  async releaseSource(app, options) {
4989
5359
  await this.#runner.releaseSource(app, options);
4990
5360
  }
5361
+ async codepush(app, os) {
5362
+ await this.#runner.codepush(app, os);
5363
+ }
4991
5364
  async dbup(workspace) {
4992
5365
  const spinner = workspace.spinning("Starting local database...");
4993
5366
  await this.#runner.dbup(workspace);
@@ -5057,20 +5430,62 @@ var ApplicationCommand = class {
5057
5430
  await this.applicationScript.startCsr(app, { open: open2, sync });
5058
5431
  }
5059
5432
  async startIos(app, open2, release, sync) {
5060
- await this.applicationScript.startIos(app, { open: open2, operation: release ? "release" : "local", sync });
5433
+ const operation_ = await select6({
5434
+ message: "Select ios operation mode",
5435
+ choices: [
5436
+ { value: "local", name: "local", description: "Connect to the React web server." },
5437
+ { value: "release", name: "release", description: "Real production package environment." }
5438
+ ]
5439
+ });
5440
+ const host_ = await select6({
5441
+ message: "Select connect backend server.",
5442
+ choices: [
5443
+ { value: "local", name: "local", description: "connect to the localhost backend server." },
5444
+ { value: "debug", name: "debug", description: "connect to the debug cloud backend server." },
5445
+ { value: "develop", name: "develop", description: "connect to the develop cloud backend server." },
5446
+ { value: "main", name: "main", description: "connect to the main cloud backend server." }
5447
+ ]
5448
+ });
5449
+ await this.applicationScript.startIos(app, { open: open2, host: host_, operation: operation_, sync });
5061
5450
  }
5062
- async startAndroid(app, open2, release, sync) {
5063
- await this.applicationScript.startAndroid(app, { open: open2, operation: release ? "release" : "local", sync });
5451
+ async startAndroid(app, host, release, open2, sync) {
5452
+ const host_ = await select6({
5453
+ message: "Select connect backend server.",
5454
+ choices: [
5455
+ { value: "local", name: "local", description: "connect to the localhost backend server." },
5456
+ { value: "debug", name: "debug", description: "connect to the debug cloud backend server." },
5457
+ { value: "develop", name: "develop", description: "connect to the develop cloud backend server." },
5458
+ { value: "main", name: "main", description: "connect to the main cloud backend server." }
5459
+ ]
5460
+ });
5461
+ const operation_ = await select6({
5462
+ message: "Select android operation mode",
5463
+ choices: [
5464
+ { value: "local", name: "local", description: "Connect to the React web server." },
5465
+ { value: "release", name: "release", description: "Real production package environment." }
5466
+ ]
5467
+ });
5468
+ await this.applicationScript.startAndroid(app, { open: open2, operation: operation_, host: host_, sync });
5064
5469
  }
5065
5470
  async releaseIos(app) {
5066
5471
  await this.applicationScript.releaseIos(app);
5067
5472
  }
5068
- async releaseAndroid(app) {
5069
- await this.applicationScript.releaseAndroid(app);
5473
+ async releaseAndroid(app, assembleType) {
5474
+ await this.applicationScript.releaseAndroid(app, assembleType);
5070
5475
  }
5071
5476
  async releaseSource(app, rebuild, buildNum, environment, local) {
5072
5477
  await this.applicationScript.releaseSource(app, { rebuild, buildNum, environment, local });
5073
5478
  }
5479
+ async codepush(app) {
5480
+ const os = await select6({
5481
+ message: "Select os",
5482
+ choices: [
5483
+ { value: "ios", name: "ios", description: "ios" },
5484
+ { value: "android", name: "android", description: "android" }
5485
+ ]
5486
+ });
5487
+ await this.applicationScript.codepush(app, os);
5488
+ }
5074
5489
  async dumpDatabase(app, environment) {
5075
5490
  await this.applicationScript.dumpDatabase(app, environment);
5076
5491
  }
@@ -5089,9 +5504,6 @@ var ApplicationCommand = class {
5089
5504
  async configureApp(app) {
5090
5505
  await this.applicationScript.configureApp(app);
5091
5506
  }
5092
- async test(sys3) {
5093
- await this.applicationScript.testSys(sys3);
5094
- }
5095
5507
  };
5096
5508
  __decorateClass([
5097
5509
  Target.Public(),
@@ -5171,9 +5583,15 @@ __decorateClass([
5171
5583
  __decorateClass([
5172
5584
  Target.Public({ short: true }),
5173
5585
  __decorateParam(0, App()),
5174
- __decorateParam(1, Option("open", { type: "boolean", desc: "open android simulator", default: false })),
5586
+ __decorateParam(1, Option("host", {
5587
+ type: "string",
5588
+ enum: ["local", "debug", "develop", "main"],
5589
+ desc: "host sever",
5590
+ default: "local"
5591
+ })),
5175
5592
  __decorateParam(2, Option("release", { type: "boolean", desc: "release mode", default: false })),
5176
- __decorateParam(3, Option("sync", { type: "boolean", desc: "sync application", default: true }))
5593
+ __decorateParam(3, Option("open", { type: "boolean", desc: "open android simulator", default: false })),
5594
+ __decorateParam(4, Option("sync", { type: "boolean", desc: "sync application", default: true }))
5177
5595
  ], ApplicationCommand.prototype, "startAndroid", 1);
5178
5596
  __decorateClass([
5179
5597
  Target.Public(),
@@ -5181,7 +5599,8 @@ __decorateClass([
5181
5599
  ], ApplicationCommand.prototype, "releaseIos", 1);
5182
5600
  __decorateClass([
5183
5601
  Target.Public(),
5184
- __decorateParam(0, App())
5602
+ __decorateParam(0, App()),
5603
+ __decorateParam(1, Option("assembleType", { type: "string", enum: ["apk", "aab"], default: "apk" }))
5185
5604
  ], ApplicationCommand.prototype, "releaseAndroid", 1);
5186
5605
  __decorateClass([
5187
5606
  Target.Public(),
@@ -5191,6 +5610,10 @@ __decorateClass([
5191
5610
  __decorateParam(3, Option("environment", { desc: "environment", default: "debug" })),
5192
5611
  __decorateParam(4, Option("local", { type: "boolean", desc: "local", default: true }))
5193
5612
  ], ApplicationCommand.prototype, "releaseSource", 1);
5613
+ __decorateClass([
5614
+ Target.Public(),
5615
+ __decorateParam(0, App())
5616
+ ], ApplicationCommand.prototype, "codepush", 1);
5194
5617
  __decorateClass([
5195
5618
  Target.Public(),
5196
5619
  __decorateParam(0, App()),
@@ -5233,10 +5656,6 @@ __decorateClass([
5233
5656
  Target.Public(),
5234
5657
  __decorateParam(0, App())
5235
5658
  ], ApplicationCommand.prototype, "configureApp", 1);
5236
- __decorateClass([
5237
- Target.Public(),
5238
- __decorateParam(0, Sys())
5239
- ], ApplicationCommand.prototype, "test", 1);
5240
5659
  ApplicationCommand = __decorateClass([
5241
5660
  Commands()
5242
5661
  ], ApplicationCommand);
@@ -5388,18 +5807,20 @@ ${chalk6.green("\u27A4")} Authentication Required`));
5388
5807
  async deployAkan(workspace, akanPkgs) {
5389
5808
  const basePackageJson = workspace.readJson("pkgs/@akanjs/base/package.json");
5390
5809
  const [majorVersionOfBase, minorVersionOfBase, patchVersionOfBase, devPatchVersionOfBase] = basePackageJson.version.split(".");
5391
- const targetVersionPrefix = devPatchVersionOfBase ? `${majorVersionOfBase}.${minorVersionOfBase}.${patchVersionOfBase}` : `${majorVersionOfBase}.${minorVersionOfBase}`;
5392
- const getNextVersion = async (prefix) => {
5810
+ const isOfficialRelease = !devPatchVersionOfBase;
5811
+ const targetVersionPrefix = isOfficialRelease ? `${majorVersionOfBase}.${minorVersionOfBase}` : `${majorVersionOfBase}.${minorVersionOfBase}.${patchVersionOfBase}`;
5812
+ const tag = isOfficialRelease ? "latest" : patchVersionOfBase.split("-").at(1) ?? "dev";
5813
+ const getNextVersion = async (prefix, tag2) => {
5393
5814
  try {
5394
- const latestPublishedVersionOfBase = await latestVersion("@akanjs/base", { version: prefix });
5395
- const latestPatch = parseInt(latestPublishedVersionOfBase.split(".")[2]);
5815
+ const latestPublishedVersionOfBase = await latestVersion("@akanjs/base", { version: tag2 });
5816
+ const latestPatch = parseInt(latestPublishedVersionOfBase.split(".").at(-1) ?? "0");
5396
5817
  const nextVersion2 = `${prefix}.${latestPatch + 1}`;
5397
5818
  return { nextVersion: nextVersion2, latestPublishedVersion: latestPublishedVersionOfBase };
5398
5819
  } catch (e) {
5399
5820
  return { nextVersion: `${prefix}.0`, latestPublishedVersion: null };
5400
5821
  }
5401
5822
  };
5402
- const { nextVersion, latestPublishedVersion } = await getNextVersion(targetVersionPrefix);
5823
+ const { nextVersion, latestPublishedVersion } = await getNextVersion(targetVersionPrefix, tag);
5403
5824
  Logger.info(`Latest published version of @akanjs/base: ${latestPublishedVersion ?? "none"}`);
5404
5825
  Logger.info(`Next version of @akanjs/base: ${nextVersion}`);
5405
5826
  for (const library of akanPkgs) {
@@ -5420,7 +5841,7 @@ ${chalk6.green("\u27A4")} Authentication Required`));
5420
5841
  await Promise.all(
5421
5842
  akanPkgs.map(async (library) => {
5422
5843
  Logger.info(`Publishing ${library}@${nextVersion} to npm...`);
5423
- await workspace.exec(`npm publish`, { cwd: `dist/pkgs/${library}` });
5844
+ await workspace.exec(`npm publish --tag ${tag}`, { cwd: `dist/pkgs/${library}` });
5424
5845
  Logger.info(`${library}@${nextVersion} is published to npm`);
5425
5846
  })
5426
5847
  );
@@ -5602,7 +6023,7 @@ LibraryCommand = __decorateClass([
5602
6023
  ], LibraryCommand);
5603
6024
 
5604
6025
  // pkgs/@akanjs/cli/src/module/module.script.ts
5605
- import fs15 from "fs";
6026
+ import fs16 from "fs";
5606
6027
 
5607
6028
  // pkgs/@akanjs/cli/src/page/page.runner.ts
5608
6029
  var PageRunner = class {
@@ -6067,7 +6488,7 @@ var ModuleScript = class {
6067
6488
  );
6068
6489
  const Name = capitalize(mod.name);
6069
6490
  const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
6070
- const constant = fs15.readFileSync(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`, "utf-8");
6491
+ const constant = fs16.readFileSync(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`, "utf-8");
6071
6492
  const session = new AiSession("createTemplate", { workspace: mod.sys.workspace, cacheKey: mod.name });
6072
6493
  const promptRst = requestTemplate({
6073
6494
  sysName: mod.sys.name,
@@ -6088,7 +6509,7 @@ var ModuleScript = class {
6088
6509
  (f) => !f.filePath.includes(`${mod.name}.Unit.tsx`)
6089
6510
  );
6090
6511
  const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
6091
- const constant = fs15.readFileSync(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`, "utf-8");
6512
+ const constant = fs16.readFileSync(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`, "utf-8");
6092
6513
  const session = new AiSession("createUnit", { workspace: mod.sys.workspace, cacheKey: mod.name });
6093
6514
  const promptRst = requestUnit({
6094
6515
  sysName: mod.sys.name,
@@ -6109,7 +6530,7 @@ var ModuleScript = class {
6109
6530
  );
6110
6531
  const Name = capitalize(mod.name);
6111
6532
  const relatedCnsts = getRelatedCnsts(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`);
6112
- const constant = fs15.readFileSync(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`, "utf-8");
6533
+ const constant = fs16.readFileSync(`${mod.sys.cwdPath}/lib/${mod.name}/${mod.name}.constant.ts`, "utf-8");
6113
6534
  const session = new AiSession("createView", { workspace: mod.sys.workspace, cacheKey: mod.name });
6114
6535
  const promptRst = requestView({
6115
6536
  sysName: mod.sys.name,
@@ -6481,7 +6902,7 @@ WorkspaceCommand = __decorateClass([
6481
6902
  ], WorkspaceCommand);
6482
6903
 
6483
6904
  // pkgs/@akanjs/cli/src/guideline/guideline.prompt.ts
6484
- import fs16 from "fs";
6905
+ import fs17 from "fs";
6485
6906
  import fsPromise5 from "fs/promises";
6486
6907
  var GuidelinePrompt = class extends Prompter {
6487
6908
  constructor(workspace, name) {
@@ -6496,7 +6917,7 @@ var GuidelinePrompt = class extends Prompter {
6496
6917
  });
6497
6918
  const paths = [];
6498
6919
  for await (const path10 of matchingPaths) {
6499
- const fileContent = fs16.readFileSync(path10, "utf-8");
6920
+ const fileContent = fs17.readFileSync(path10, "utf-8");
6500
6921
  const textFilter = filterText ? new RegExp(filterText) : null;
6501
6922
  if (filterText && !textFilter?.test(fileContent))
6502
6923
  continue;
@@ -7021,5 +7442,6 @@ void runCommands(
7021
7442
  //! 2. csr폴더를 현 위치로 복사 후 압축 후 삭제
7022
7443
  //! execSync를 가져오기 싫으니 일단 2번 방법으로 해보자
7023
7444
  //! add path in tsconfig.json
7445
+ //! 추후 param에서 select할 수 있도록 수정 필요
7024
7446
  //! 파일을 {name}.View.tsx에 저장.
7025
7447
  //! 파일을 {name}.Unit.tsx에 저장.