@akanjs/cli 0.9.13 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/index.js CHANGED
@@ -724,43 +724,11 @@ var makeAppConfig = (config, props) => {
724
724
  rootLib: config.rootLib,
725
725
  libs: config.libs ?? [],
726
726
  backend: {
727
- dockerfile: config.backend?.dockerfile ?? `FROM node:22-slim
728
- RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
729
- RUN apt-get update && apt-get upgrade -y && apt-get install -y git redis build-essential python3 ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils udev ffmpeg && rm -rf /var/lib/apt/lists/*
730
- ARG TARGETARCH
731
- RUN if [ "$TARGETARCH" = "amd64" ]; then wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-debian92-x86_64-100.3.1.deb && apt-get install -y ./mongodb-database-tools-*.deb && rm -f mongodb-database-tools-*.deb; fi
732
- RUN mkdir -p /workspace
733
- WORKDIR /workspace
734
- COPY ./package.json ./package.json
735
- RUN npx pnpm i --prod
736
- COPY . .
737
- ENV PORT 8080
738
- ENV NODE_OPTIONS=--max_old_space_size=8192
739
- ENV NEXT_PUBLIC_REPO_NAME=${repoName}
740
- ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
741
- ENV NEXT_PUBLIC_APP_NAME=${name}
742
- ENV NEXT_PUBLIC_ENV=${env}
743
- ENV NEXT_PUBLIC_OPERATION_MODE=cloud
744
- CMD ["node", "main.js"]`,
727
+ docker: makeDockerfile("backend", config.backend?.docker ?? {}, props),
745
728
  explicitDependencies: config.backend?.explicitDependencies ?? []
746
729
  },
747
730
  frontend: {
748
- dockerfile: config.frontend?.dockerfile ?? `FROM node:22-alpine
749
- RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
750
- RUN apk --no-cache add git
751
- RUN mkdir -p /workspace
752
- WORKDIR /workspace
753
- COPY ./package.json ./package.json
754
- RUN npx pnpm i --prod
755
- COPY . .
756
- ENV PORT 4200
757
- ENV NODE_OPTIONS=--max_old_space_size=8192
758
- ENV NEXT_PUBLIC_REPO_NAME=${repoName}
759
- ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
760
- ENV NEXT_PUBLIC_APP_NAME=${name}
761
- ENV NEXT_PUBLIC_ENV=${env}
762
- ENV NEXT_PUBLIC_OPERATION_MODE=cloud
763
- CMD ["npm", "start"]`,
731
+ docker: makeDockerfile("frontend", config.frontend?.docker ?? {}, props),
764
732
  nextConfig: withBase(
765
733
  name,
766
734
  config.frontend?.nextConfig ? typeof config.frontend.nextConfig === "function" ? config.frontend.nextConfig() : config.frontend.nextConfig : {},
@@ -806,6 +774,88 @@ var getLibConfig = async (libRoot, props) => {
806
774
  const config = typeof configImp === "function" ? configImp(props) : configImp;
807
775
  return makeLibConfig(config, props);
808
776
  };
777
+ var getDockerRunScripts = (runs) => {
778
+ return runs.map((run) => {
779
+ if (typeof run === "string")
780
+ return `RUN ${run}`;
781
+ else
782
+ return Object.entries(run).map(([arch, script]) => `RUN if [ "$TARGETARCH" = "${arch}" ]; then ${script}; fi`).join("\n");
783
+ });
784
+ };
785
+ var getDockerImageScript = (image) => {
786
+ if (typeof image === "string")
787
+ return `FROM ${image}`;
788
+ else
789
+ return Object.entries(image).map(([arch, image2]) => `FROM ${image2} AS ${arch}`).join("\n");
790
+ };
791
+ var makeDockerfile = (type, config, props) => {
792
+ const { name, repoName, serveDomain, env } = props;
793
+ if (config.content)
794
+ return { content: config.content, image: {}, preRuns: [], postRuns: [], command: [] };
795
+ const preRunScripts = getDockerRunScripts(config.preRuns ?? []);
796
+ const postRunScripts = getDockerRunScripts(config.postRuns ?? []);
797
+ if (type === "backend") {
798
+ const imageScript = config.image ? getDockerImageScript(config.image) : "FROM node:22-slim";
799
+ const command = config.command ?? ["node", "main.js"];
800
+ const content = `${imageScript}
801
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
802
+ RUN apt-get update && apt-get upgrade -y
803
+ RUN apt-get install -y git redis build-essential python3 ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils udev ffmpeg && rm -rf /var/lib/apt/lists/*
804
+ ARG TARGETARCH
805
+ RUN if [ "$TARGETARCH" = "amd64" ]; then wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-debian92-x86_64-100.3.1.deb && apt-get install -y ./mongodb-database-tools-*.deb && rm -f mongodb-database-tools-*.deb; fi
806
+ ${preRunScripts.join("\n")}
807
+ RUN mkdir -p /workspace
808
+ WORKDIR /workspace
809
+ COPY ./package.json ./package.json
810
+ RUN npx pnpm i --prod
811
+ COPY . .
812
+ ENV PORT 8080
813
+ ENV NODE_OPTIONS=--max_old_space_size=8192
814
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
815
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
816
+ ENV NEXT_PUBLIC_APP_NAME=${name}
817
+ ENV NEXT_PUBLIC_ENV=${env}
818
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
819
+ ${postRunScripts.join("\n")}
820
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
821
+ return {
822
+ content,
823
+ image: imageScript,
824
+ preRuns: config.preRuns ?? [],
825
+ postRuns: config.postRuns ?? [],
826
+ command
827
+ };
828
+ } else {
829
+ const imageScript = config.image ? getDockerImageScript(config.image) : "FROM node:22-alpine";
830
+ const command = config.command ?? ["npm", "start"];
831
+ const content = `${imageScript}
832
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
833
+ ARG TARGETARCH
834
+ RUN apk --no-cache add git
835
+ ${preRunScripts.join("\n")}
836
+ RUN mkdir -p /workspace
837
+ WORKDIR /workspace
838
+ COPY ./package.json ./package.json
839
+ RUN npx pnpm i --prod
840
+ COPY . .
841
+ ENV PORT 4200
842
+ ENV NODE_OPTIONS=--max_old_space_size=8192
843
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
844
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
845
+ ENV NEXT_PUBLIC_APP_NAME=${name}
846
+ ENV NEXT_PUBLIC_ENV=${env}
847
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
848
+ ${postRunScripts.join("\n")}
849
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
850
+ return {
851
+ content,
852
+ image: imageScript,
853
+ preRuns: config.preRuns ?? [],
854
+ postRuns: config.postRuns ?? [],
855
+ command
856
+ };
857
+ }
858
+ };
809
859
 
810
860
  // pkgs/@akanjs/config/src/types.ts
811
861
  var getDefaultFileScan = () => ({
@@ -2191,17 +2241,28 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2191
2241
  }
2192
2242
  async syncAssets(libDeps) {
2193
2243
  const projectPublicLibPath = `${this.cwdPath}/public/libs`;
2194
- if (import_fs4.default.existsSync(projectPublicLibPath))
2195
- await import_promises.default.rm(projectPublicLibPath, { recursive: true });
2244
+ const projectAssetsLibPath = `${this.cwdPath}/assets/libs`;
2245
+ await Promise.all([
2246
+ import_fs4.default.existsSync(projectPublicLibPath) && import_promises.default.rm(projectPublicLibPath, { recursive: true }),
2247
+ import_fs4.default.existsSync(projectAssetsLibPath) && import_promises.default.rm(projectAssetsLibPath, { recursive: true })
2248
+ ]);
2196
2249
  const targetDeps = libDeps.filter((dep) => import_fs4.default.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`));
2197
- await Promise.all(targetDeps.map((dep) => import_promises.default.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })));
2198
- await Promise.all(
2199
- targetDeps.map(
2200
- (dep) => import_promises.default.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2250
+ await Promise.all([
2251
+ ...targetDeps.map((dep) => import_promises.default.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })),
2252
+ ...targetDeps.map((dep) => import_promises.default.mkdir(`${projectAssetsLibPath}/${dep}`, { recursive: true }))
2253
+ ]);
2254
+ await Promise.all([
2255
+ ...targetDeps.map(
2256
+ (dep) => import_fs4.default.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`) && import_promises.default.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2257
+ recursive: true
2258
+ })
2259
+ ),
2260
+ ...targetDeps.map(
2261
+ (dep) => import_fs4.default.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/assets`) && import_promises.default.cp(`${this.workspace.workspaceRoot}/libs/${dep}/assets`, `${projectAssetsLibPath}/${dep}`, {
2201
2262
  recursive: true
2202
2263
  })
2203
2264
  )
2204
- );
2265
+ ]);
2205
2266
  }
2206
2267
  };
2207
2268
  var LibExecutor = class _LibExecutor extends SysExecutor {
@@ -2566,7 +2627,7 @@ var extractDependencies = (filepaths, pacakgeJson, defaultDependencies = []) =>
2566
2627
  ...pacakgeJson.dependencies ?? {},
2567
2628
  ...pacakgeJson.devDependencies ?? {}
2568
2629
  };
2569
- const requireRegex = /require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
2630
+ const requireRegex = /(?:require\s*\(|import\s*(?:[\w\s{},*]*\s+from\s*)?|import\s*\()\s*['"`]([^'"`]+)['"`]/g;
2570
2631
  for (const { text } of filepaths.filter(({ path: path9 }) => path9.endsWith(".js"))) {
2571
2632
  let requireMatch;
2572
2633
  while ((requireMatch = requireRegex.exec(text)) !== null) {
@@ -3929,6 +3990,8 @@ var ApplicationRunner = class {
3929
3990
  app.writeFile("next.config.ts", defaultNextConfigFile);
3930
3991
  } else if (target === "csr")
3931
3992
  await app.workspace.exec("rm -rf node_modules/.vite");
3993
+ else if (target === "backend")
3994
+ await app.cp("assets", import_path4.default.join(app.dist.cwdPath, "backend", "assets"));
3932
3995
  return { env: this.#getEnv(app, { AKAN_COMMAND_TYPE: type }) };
3933
3996
  }
3934
3997
  async buildBackend(app) {
@@ -3957,7 +4020,7 @@ var ApplicationRunner = class {
3957
4020
  dependencies
3958
4021
  };
3959
4022
  app.dist.writeJson("backend/package.json", appPackageJson);
3960
- app.dist.writeFile(import_path4.default.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
4023
+ app.dist.writeFile(import_path4.default.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.docker.content);
3961
4024
  }
3962
4025
  async startBackend(app, { open: open2 = false, onStart } = {}) {
3963
4026
  const { env } = await this.#prepareCommand(app, "start", "backend");
@@ -3976,7 +4039,7 @@ var ApplicationRunner = class {
3976
4039
  onStart?.();
3977
4040
  if (open2)
3978
4041
  setTimeout(() => (0, import_open.default)("http://localhost:8080/backend/graphql"), 3e3);
3979
- await app.dist.spawn("node", ["--watch", "backend/main.js"], { env, stdio: "inherit" });
4042
+ await app.dist.spawn("node", ["--watch", "main.js"], { env, stdio: "inherit", cwd: `${app.dist.cwdPath}/backend` });
3980
4043
  }
3981
4044
  async buildFrontend(app, { spawnOptions } = {}) {
3982
4045
  const { env } = await this.#prepareCommand(app, "build", "frontend");
@@ -3991,7 +4054,6 @@ var ApplicationRunner = class {
3991
4054
  format: "esm",
3992
4055
  write: false,
3993
4056
  logLevel: "warning"
3994
- // footer: { js: "module.exports = module.exports.default;" },
3995
4057
  });
3996
4058
  const rootPackageJson = app.workspace.readJson("package.json");
3997
4059
  const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
@@ -4009,7 +4071,7 @@ var ApplicationRunner = class {
4009
4071
  app.cp(".next", import_path4.default.join(app.dist.cwdPath, "frontend", ".next")),
4010
4072
  app.cp("public", import_path4.default.join(app.dist.cwdPath, "frontend", "public"))
4011
4073
  ]);
4012
- app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
4074
+ app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.docker.content);
4013
4075
  }
4014
4076
  async startFrontend(app, { open: open2 = false, turbo = true, onStart } = {}) {
4015
4077
  const { env } = await this.#prepareCommand(app, "start", "frontend");
@@ -4992,6 +5054,15 @@ ${import_chalk6.default.green("\u27A4")} Authentication Required`));
4992
5054
  Logger.info("All libraries are published to npm");
4993
5055
  }
4994
5056
  async update(workspace) {
5057
+ if (!workspace.exists("package.json"))
5058
+ await workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]);
5059
+ else
5060
+ await Promise.all([
5061
+ workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5062
+ this.#updateAkanPkgs(workspace)
5063
+ ]);
5064
+ }
5065
+ async #updateAkanPkgs(workspace) {
4995
5066
  const latestPublishedVersionOfBase = await (0, import_latest_version.default)("@akanjs/base");
4996
5067
  const rootPackageJson = workspace.readJson("package.json");
4997
5068
  if (!rootPackageJson.dependencies)
@@ -5005,10 +5076,7 @@ ${import_chalk6.default.green("\u27A4")} Authentication Required`));
5005
5076
  Object.assign(rootPackageJson.devDependencies ?? {}, { [dependency]: latestPublishedVersionOfBase });
5006
5077
  });
5007
5078
  workspace.writeJson("package.json", rootPackageJson);
5008
- await Promise.all([
5009
- workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5010
- workspace.spawn("pnpm", ["install"])
5011
- ]);
5079
+ await workspace.spawn("pnpm", ["install"]);
5012
5080
  }
5013
5081
  };
5014
5082
 
@@ -5664,13 +5732,9 @@ var ModuleScript = class {
5664
5732
  // pkgs/@akanjs/cli/src/module/module.command.ts
5665
5733
  var ModuleCommand = class {
5666
5734
  moduleScript = new ModuleScript();
5667
- async createModule(sys3, moduleName, description, schemaDescription, ai) {
5735
+ async createModule(moduleName, sys3) {
5668
5736
  const name = lowerlize(moduleName.replace(/ /g, ""));
5669
- if (ai) {
5670
- await this.moduleScript.createModule(sys3, name, description, schemaDescription);
5671
- } else {
5672
- await this.moduleScript.createModuleTemplate(sys3, name);
5673
- }
5737
+ await this.moduleScript.createModuleTemplate(sys3, name);
5674
5738
  }
5675
5739
  removeModule(module2) {
5676
5740
  this.moduleScript.removeModule(module2);
@@ -5687,11 +5751,8 @@ var ModuleCommand = class {
5687
5751
  };
5688
5752
  __decorateClass([
5689
5753
  Target.Public(),
5690
- __decorateParam(0, Sys()),
5691
- __decorateParam(1, Argument("moduleName", { desc: "name of module" })),
5692
- __decorateParam(2, Option("description", { desc: "description of module" })),
5693
- __decorateParam(3, Option("schemaDescription", { desc: "schema description of module" })),
5694
- __decorateParam(4, Option("ai", { type: "boolean", default: false, desc: "use ai to create module" }))
5754
+ __decorateParam(0, Argument("moduleName", { desc: "name of module" })),
5755
+ __decorateParam(1, Sys())
5695
5756
  ], ModuleCommand.prototype, "createModule", 1);
5696
5757
  __decorateClass([
5697
5758
  Target.Public(),
@@ -28,18 +28,17 @@ function getContent(scanResult, dict) {
28
28
  content: `
29
29
  "use client";
30
30
  import { cnst, st, usePage } from "@${dict.sysName}/client";
31
- import { Field } from "@shared/ui";
32
- import { Layout } from "@akanjs/ui";
31
+ import { Layout, Field } from "@akanjs/ui";
33
32
 
34
33
  interface ${dict.Model}EditProps {
35
- ${dict.model}Id?: string | null;
34
+ className?: string;
36
35
  }
37
36
 
38
- export const General = ({ ${dict.model}Id = undefined }: ${dict.Model}EditProps) => {
37
+ export const General = ({ className }: ${dict.Model}EditProps) => {
39
38
  const ${dict.model}Form = st.use.${dict.model}Form();
40
39
  const { l } = usePage();
41
40
  return (
42
- <Layout.Template>
41
+ <Layout.Template className={className}>
43
42
  <Field.Text
44
43
  label={l.field("${dict.model}", "id")}
45
44
  desc={l.desc("${dict.model}", "id")}
@@ -43,10 +43,7 @@ export class ${dict.Model}Object extends via(${dict.Model}Input) {
43
43
  }
44
44
 
45
45
  @Model.Light("Light${dict.Model}")
46
- export class Light${dict.Model} extends via(${dict.Model}Object, [
47
- "field",
48
- "status",
49
- ] as const) {}
46
+ export class Light${dict.Model} extends via(${dict.Model}Object, ["status"] as const) {}
50
47
 
51
48
  @Model.Full("${dict.Model}")
52
49
  export class ${dict.Model} extends via(${dict.Model}Object, Light${dict.Model}) {}
@@ -69,9 +66,7 @@ export class ${dict.Model}Filter extends sortOf(${dict.Model}, {}) {
69
66
  inStatus(
70
67
  @Filter.Arg("status", () => String) status: ${dict.Model}Status,
71
68
  ) {
72
- return {
73
- status,
74
- };
69
+ return { status };
75
70
  }
76
71
  }
77
72
  `;
@@ -67,6 +67,7 @@ local.properties
67
67
  **/public/worker-*.js.map
68
68
  **/public/fallback-*.js
69
69
  **/public/libs
70
+ **/assets/libs
70
71
 
71
72
  **/vendor/bundle/
72
73
  **/ios/App/App/public
package/esm/index.js CHANGED
@@ -704,43 +704,11 @@ var makeAppConfig = (config, props) => {
704
704
  rootLib: config.rootLib,
705
705
  libs: config.libs ?? [],
706
706
  backend: {
707
- dockerfile: config.backend?.dockerfile ?? `FROM node:22-slim
708
- RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
709
- RUN apt-get update && apt-get upgrade -y && apt-get install -y git redis build-essential python3 ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils udev ffmpeg && rm -rf /var/lib/apt/lists/*
710
- ARG TARGETARCH
711
- RUN if [ "$TARGETARCH" = "amd64" ]; then wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-debian92-x86_64-100.3.1.deb && apt-get install -y ./mongodb-database-tools-*.deb && rm -f mongodb-database-tools-*.deb; fi
712
- RUN mkdir -p /workspace
713
- WORKDIR /workspace
714
- COPY ./package.json ./package.json
715
- RUN npx pnpm i --prod
716
- COPY . .
717
- ENV PORT 8080
718
- ENV NODE_OPTIONS=--max_old_space_size=8192
719
- ENV NEXT_PUBLIC_REPO_NAME=${repoName}
720
- ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
721
- ENV NEXT_PUBLIC_APP_NAME=${name}
722
- ENV NEXT_PUBLIC_ENV=${env}
723
- ENV NEXT_PUBLIC_OPERATION_MODE=cloud
724
- CMD ["node", "main.js"]`,
707
+ docker: makeDockerfile("backend", config.backend?.docker ?? {}, props),
725
708
  explicitDependencies: config.backend?.explicitDependencies ?? []
726
709
  },
727
710
  frontend: {
728
- dockerfile: config.frontend?.dockerfile ?? `FROM node:22-alpine
729
- RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
730
- RUN apk --no-cache add git
731
- RUN mkdir -p /workspace
732
- WORKDIR /workspace
733
- COPY ./package.json ./package.json
734
- RUN npx pnpm i --prod
735
- COPY . .
736
- ENV PORT 4200
737
- ENV NODE_OPTIONS=--max_old_space_size=8192
738
- ENV NEXT_PUBLIC_REPO_NAME=${repoName}
739
- ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
740
- ENV NEXT_PUBLIC_APP_NAME=${name}
741
- ENV NEXT_PUBLIC_ENV=${env}
742
- ENV NEXT_PUBLIC_OPERATION_MODE=cloud
743
- CMD ["npm", "start"]`,
711
+ docker: makeDockerfile("frontend", config.frontend?.docker ?? {}, props),
744
712
  nextConfig: withBase(
745
713
  name,
746
714
  config.frontend?.nextConfig ? typeof config.frontend.nextConfig === "function" ? config.frontend.nextConfig() : config.frontend.nextConfig : {},
@@ -786,6 +754,88 @@ var getLibConfig = async (libRoot, props) => {
786
754
  const config = typeof configImp === "function" ? configImp(props) : configImp;
787
755
  return makeLibConfig(config, props);
788
756
  };
757
+ var getDockerRunScripts = (runs) => {
758
+ return runs.map((run) => {
759
+ if (typeof run === "string")
760
+ return `RUN ${run}`;
761
+ else
762
+ return Object.entries(run).map(([arch, script]) => `RUN if [ "$TARGETARCH" = "${arch}" ]; then ${script}; fi`).join("\n");
763
+ });
764
+ };
765
+ var getDockerImageScript = (image) => {
766
+ if (typeof image === "string")
767
+ return `FROM ${image}`;
768
+ else
769
+ return Object.entries(image).map(([arch, image2]) => `FROM ${image2} AS ${arch}`).join("\n");
770
+ };
771
+ var makeDockerfile = (type, config, props) => {
772
+ const { name, repoName, serveDomain, env } = props;
773
+ if (config.content)
774
+ return { content: config.content, image: {}, preRuns: [], postRuns: [], command: [] };
775
+ const preRunScripts = getDockerRunScripts(config.preRuns ?? []);
776
+ const postRunScripts = getDockerRunScripts(config.postRuns ?? []);
777
+ if (type === "backend") {
778
+ const imageScript = config.image ? getDockerImageScript(config.image) : "FROM node:22-slim";
779
+ const command = config.command ?? ["node", "main.js"];
780
+ const content = `${imageScript}
781
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
782
+ RUN apt-get update && apt-get upgrade -y
783
+ RUN apt-get install -y git redis build-essential python3 ca-certificates fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils udev ffmpeg && rm -rf /var/lib/apt/lists/*
784
+ ARG TARGETARCH
785
+ RUN if [ "$TARGETARCH" = "amd64" ]; then wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-debian92-x86_64-100.3.1.deb && apt-get install -y ./mongodb-database-tools-*.deb && rm -f mongodb-database-tools-*.deb; fi
786
+ ${preRunScripts.join("\n")}
787
+ RUN mkdir -p /workspace
788
+ WORKDIR /workspace
789
+ COPY ./package.json ./package.json
790
+ RUN npx pnpm i --prod
791
+ COPY . .
792
+ ENV PORT 8080
793
+ ENV NODE_OPTIONS=--max_old_space_size=8192
794
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
795
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
796
+ ENV NEXT_PUBLIC_APP_NAME=${name}
797
+ ENV NEXT_PUBLIC_ENV=${env}
798
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
799
+ ${postRunScripts.join("\n")}
800
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
801
+ return {
802
+ content,
803
+ image: imageScript,
804
+ preRuns: config.preRuns ?? [],
805
+ postRuns: config.postRuns ?? [],
806
+ command
807
+ };
808
+ } else {
809
+ const imageScript = config.image ? getDockerImageScript(config.image) : "FROM node:22-alpine";
810
+ const command = config.command ?? ["npm", "start"];
811
+ const content = `${imageScript}
812
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
813
+ ARG TARGETARCH
814
+ RUN apk --no-cache add git
815
+ ${preRunScripts.join("\n")}
816
+ RUN mkdir -p /workspace
817
+ WORKDIR /workspace
818
+ COPY ./package.json ./package.json
819
+ RUN npx pnpm i --prod
820
+ COPY . .
821
+ ENV PORT 4200
822
+ ENV NODE_OPTIONS=--max_old_space_size=8192
823
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
824
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
825
+ ENV NEXT_PUBLIC_APP_NAME=${name}
826
+ ENV NEXT_PUBLIC_ENV=${env}
827
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
828
+ ${postRunScripts.join("\n")}
829
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
830
+ return {
831
+ content,
832
+ image: imageScript,
833
+ preRuns: config.preRuns ?? [],
834
+ postRuns: config.postRuns ?? [],
835
+ command
836
+ };
837
+ }
838
+ };
789
839
 
790
840
  // pkgs/@akanjs/config/src/types.ts
791
841
  var getDefaultFileScan = () => ({
@@ -2170,17 +2220,28 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2170
2220
  }
2171
2221
  async syncAssets(libDeps) {
2172
2222
  const projectPublicLibPath = `${this.cwdPath}/public/libs`;
2173
- if (fs8.existsSync(projectPublicLibPath))
2174
- await fsPromise.rm(projectPublicLibPath, { recursive: true });
2223
+ const projectAssetsLibPath = `${this.cwdPath}/assets/libs`;
2224
+ await Promise.all([
2225
+ fs8.existsSync(projectPublicLibPath) && fsPromise.rm(projectPublicLibPath, { recursive: true }),
2226
+ fs8.existsSync(projectAssetsLibPath) && fsPromise.rm(projectAssetsLibPath, { recursive: true })
2227
+ ]);
2175
2228
  const targetDeps = libDeps.filter((dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`));
2176
- await Promise.all(targetDeps.map((dep) => fsPromise.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })));
2177
- await Promise.all(
2178
- targetDeps.map(
2179
- (dep) => fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2229
+ await Promise.all([
2230
+ ...targetDeps.map((dep) => fsPromise.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })),
2231
+ ...targetDeps.map((dep) => fsPromise.mkdir(`${projectAssetsLibPath}/${dep}`, { recursive: true }))
2232
+ ]);
2233
+ await Promise.all([
2234
+ ...targetDeps.map(
2235
+ (dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`) && fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2236
+ recursive: true
2237
+ })
2238
+ ),
2239
+ ...targetDeps.map(
2240
+ (dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/assets`) && fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/assets`, `${projectAssetsLibPath}/${dep}`, {
2180
2241
  recursive: true
2181
2242
  })
2182
2243
  )
2183
- );
2244
+ ]);
2184
2245
  }
2185
2246
  };
2186
2247
  var LibExecutor = class _LibExecutor extends SysExecutor {
@@ -2545,7 +2606,7 @@ var extractDependencies = (filepaths, pacakgeJson, defaultDependencies = []) =>
2545
2606
  ...pacakgeJson.dependencies ?? {},
2546
2607
  ...pacakgeJson.devDependencies ?? {}
2547
2608
  };
2548
- const requireRegex = /require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
2609
+ const requireRegex = /(?:require\s*\(|import\s*(?:[\w\s{},*]*\s+from\s*)?|import\s*\()\s*['"`]([^'"`]+)['"`]/g;
2549
2610
  for (const { text } of filepaths.filter(({ path: path9 }) => path9.endsWith(".js"))) {
2550
2611
  let requireMatch;
2551
2612
  while ((requireMatch = requireRegex.exec(text)) !== null) {
@@ -3911,6 +3972,8 @@ var ApplicationRunner = class {
3911
3972
  app.writeFile("next.config.ts", defaultNextConfigFile);
3912
3973
  } else if (target === "csr")
3913
3974
  await app.workspace.exec("rm -rf node_modules/.vite");
3975
+ else if (target === "backend")
3976
+ await app.cp("assets", path7.join(app.dist.cwdPath, "backend", "assets"));
3914
3977
  return { env: this.#getEnv(app, { AKAN_COMMAND_TYPE: type }) };
3915
3978
  }
3916
3979
  async buildBackend(app) {
@@ -3939,7 +4002,7 @@ var ApplicationRunner = class {
3939
4002
  dependencies
3940
4003
  };
3941
4004
  app.dist.writeJson("backend/package.json", appPackageJson);
3942
- app.dist.writeFile(path7.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
4005
+ app.dist.writeFile(path7.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.docker.content);
3943
4006
  }
3944
4007
  async startBackend(app, { open: open2 = false, onStart } = {}) {
3945
4008
  const { env } = await this.#prepareCommand(app, "start", "backend");
@@ -3958,7 +4021,7 @@ var ApplicationRunner = class {
3958
4021
  onStart?.();
3959
4022
  if (open2)
3960
4023
  setTimeout(() => openBrowser("http://localhost:8080/backend/graphql"), 3e3);
3961
- await app.dist.spawn("node", ["--watch", "backend/main.js"], { env, stdio: "inherit" });
4024
+ await app.dist.spawn("node", ["--watch", "main.js"], { env, stdio: "inherit", cwd: `${app.dist.cwdPath}/backend` });
3962
4025
  }
3963
4026
  async buildFrontend(app, { spawnOptions } = {}) {
3964
4027
  const { env } = await this.#prepareCommand(app, "build", "frontend");
@@ -3973,7 +4036,6 @@ var ApplicationRunner = class {
3973
4036
  format: "esm",
3974
4037
  write: false,
3975
4038
  logLevel: "warning"
3976
- // footer: { js: "module.exports = module.exports.default;" },
3977
4039
  });
3978
4040
  const rootPackageJson = app.workspace.readJson("package.json");
3979
4041
  const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
@@ -3991,7 +4053,7 @@ var ApplicationRunner = class {
3991
4053
  app.cp(".next", path7.join(app.dist.cwdPath, "frontend", ".next")),
3992
4054
  app.cp("public", path7.join(app.dist.cwdPath, "frontend", "public"))
3993
4055
  ]);
3994
- app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
4056
+ app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.docker.content);
3995
4057
  }
3996
4058
  async startFrontend(app, { open: open2 = false, turbo = true, onStart } = {}) {
3997
4059
  const { env } = await this.#prepareCommand(app, "start", "frontend");
@@ -4974,6 +5036,15 @@ ${chalk6.green("\u27A4")} Authentication Required`));
4974
5036
  Logger.info("All libraries are published to npm");
4975
5037
  }
4976
5038
  async update(workspace) {
5039
+ if (!workspace.exists("package.json"))
5040
+ await workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]);
5041
+ else
5042
+ await Promise.all([
5043
+ workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5044
+ this.#updateAkanPkgs(workspace)
5045
+ ]);
5046
+ }
5047
+ async #updateAkanPkgs(workspace) {
4977
5048
  const latestPublishedVersionOfBase = await latestVersion("@akanjs/base");
4978
5049
  const rootPackageJson = workspace.readJson("package.json");
4979
5050
  if (!rootPackageJson.dependencies)
@@ -4987,10 +5058,7 @@ ${chalk6.green("\u27A4")} Authentication Required`));
4987
5058
  Object.assign(rootPackageJson.devDependencies ?? {}, { [dependency]: latestPublishedVersionOfBase });
4988
5059
  });
4989
5060
  workspace.writeJson("package.json", rootPackageJson);
4990
- await Promise.all([
4991
- workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
4992
- workspace.spawn("pnpm", ["install"])
4993
- ]);
5061
+ await workspace.spawn("pnpm", ["install"]);
4994
5062
  }
4995
5063
  };
4996
5064
 
@@ -5646,13 +5714,9 @@ var ModuleScript = class {
5646
5714
  // pkgs/@akanjs/cli/src/module/module.command.ts
5647
5715
  var ModuleCommand = class {
5648
5716
  moduleScript = new ModuleScript();
5649
- async createModule(sys3, moduleName, description, schemaDescription, ai) {
5717
+ async createModule(moduleName, sys3) {
5650
5718
  const name = lowerlize(moduleName.replace(/ /g, ""));
5651
- if (ai) {
5652
- await this.moduleScript.createModule(sys3, name, description, schemaDescription);
5653
- } else {
5654
- await this.moduleScript.createModuleTemplate(sys3, name);
5655
- }
5719
+ await this.moduleScript.createModuleTemplate(sys3, name);
5656
5720
  }
5657
5721
  removeModule(module) {
5658
5722
  this.moduleScript.removeModule(module);
@@ -5669,11 +5733,8 @@ var ModuleCommand = class {
5669
5733
  };
5670
5734
  __decorateClass([
5671
5735
  Target.Public(),
5672
- __decorateParam(0, Sys()),
5673
- __decorateParam(1, Argument("moduleName", { desc: "name of module" })),
5674
- __decorateParam(2, Option("description", { desc: "description of module" })),
5675
- __decorateParam(3, Option("schemaDescription", { desc: "schema description of module" })),
5676
- __decorateParam(4, Option("ai", { type: "boolean", default: false, desc: "use ai to create module" }))
5736
+ __decorateParam(0, Argument("moduleName", { desc: "name of module" })),
5737
+ __decorateParam(1, Sys())
5677
5738
  ], ModuleCommand.prototype, "createModule", 1);
5678
5739
  __decorateClass([
5679
5740
  Target.Public(),
@@ -5,18 +5,17 @@ function getContent(scanResult, dict) {
5
5
  content: `
6
6
  "use client";
7
7
  import { cnst, st, usePage } from "@${dict.sysName}/client";
8
- import { Field } from "@shared/ui";
9
- import { Layout } from "@akanjs/ui";
8
+ import { Layout, Field } from "@akanjs/ui";
10
9
 
11
10
  interface ${dict.Model}EditProps {
12
- ${dict.model}Id?: string | null;
11
+ className?: string;
13
12
  }
14
13
 
15
- export const General = ({ ${dict.model}Id = undefined }: ${dict.Model}EditProps) => {
14
+ export const General = ({ className }: ${dict.Model}EditProps) => {
16
15
  const ${dict.model}Form = st.use.${dict.model}Form();
17
16
  const { l } = usePage();
18
17
  return (
19
- <Layout.Template>
18
+ <Layout.Template className={className}>
20
19
  <Field.Text
21
20
  label={l.field("${dict.model}", "id")}
22
21
  desc={l.desc("${dict.model}", "id")}
@@ -20,10 +20,7 @@ export class ${dict.Model}Object extends via(${dict.Model}Input) {
20
20
  }
21
21
 
22
22
  @Model.Light("Light${dict.Model}")
23
- export class Light${dict.Model} extends via(${dict.Model}Object, [
24
- "field",
25
- "status",
26
- ] as const) {}
23
+ export class Light${dict.Model} extends via(${dict.Model}Object, ["status"] as const) {}
27
24
 
28
25
  @Model.Full("${dict.Model}")
29
26
  export class ${dict.Model} extends via(${dict.Model}Object, Light${dict.Model}) {}
@@ -46,9 +43,7 @@ export class ${dict.Model}Filter extends sortOf(${dict.Model}, {}) {
46
43
  inStatus(
47
44
  @Filter.Arg("status", () => String) status: ${dict.Model}Status,
48
45
  ) {
49
- return {
50
- status,
51
- };
46
+ return { status };
52
47
  }
53
48
  }
54
49
  `;
@@ -67,6 +67,7 @@ local.properties
67
67
  **/public/worker-*.js.map
68
68
  **/public/fallback-*.js
69
69
  **/public/libs
70
+ **/assets/libs
70
71
 
71
72
  **/vendor/bundle/
72
73
  **/ios/App/App/public
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "sourceType": "module",
4
4
  "name": "@akanjs/cli",
5
- "version": "0.9.13",
5
+ "version": "0.9.14",
6
6
  "bin": {
7
7
  "akan": "esm/index.js"
8
8
  },
@@ -40,13 +40,16 @@
40
40
  "js-yaml": "^4.1.0",
41
41
  "latest-version": "^9.0.0",
42
42
  "lodash": "^4.17.21",
43
+ "next": "15.3.2",
43
44
  "next-pwa": "5.6.0",
44
45
  "open": "^10.1.1",
45
46
  "ora": "^3.4.0",
46
47
  "pluralize": "^8.0.0",
47
48
  "qrcode": "^1.5.4",
48
49
  "react": "18.3.1",
50
+ "react-icons": "^5.4.0",
49
51
  "reflect-metadata": "^0.2.2",
52
+ "tsconfig-paths": "^4.2.0",
50
53
  "tunnel-ssh": "^5.2.0",
51
54
  "typescript": "5.8.3",
52
55
  "uuid": "^11.0.3",
@@ -1,5 +1,6 @@
1
1
  import { type Workspace } from "@akanjs/devkit";
2
2
  export declare class CloudRunner {
3
+ #private;
3
4
  login(): Promise<boolean>;
4
5
  logout(): void;
5
6
  setLlm(): Promise<void>;
@@ -2,7 +2,7 @@ import { Module, Sys } from "@akanjs/devkit";
2
2
  import { ModuleScript } from "./module.script";
3
3
  export declare class ModuleCommand {
4
4
  moduleScript: ModuleScript;
5
- createModule(sys: Sys, moduleName: string, description: string, schemaDescription: string, ai: boolean): Promise<void>;
5
+ createModule(moduleName: string, sys: Sys): Promise<void>;
6
6
  removeModule(module: Module): void;
7
7
  createView(module: Module): Promise<void>;
8
8
  createUnit(module: Module): Promise<void>;