@akanjs/cli 0.9.13 → 0.9.15

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,8 +774,93 @@ 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(
783
+ ([arch, script]) => `RUN if [ "$TARGETARCH" = "${arch}" ]; then ${script} fi`
784
+ ).join("\n");
785
+ });
786
+ };
787
+ var getDockerImageScript = (image, defaultImage) => {
788
+ if (typeof image === "string")
789
+ return `FROM ${image}`;
790
+ else
791
+ return archs.map((arch) => `FROM ${image[arch] ?? defaultImage} AS ${arch}`).join("\n");
792
+ };
793
+ var makeDockerfile = (type, config, props) => {
794
+ const { name, repoName, serveDomain, env } = props;
795
+ if (config.content)
796
+ return { content: config.content, image: {}, preRuns: [], postRuns: [], command: [] };
797
+ const preRunScripts = getDockerRunScripts(config.preRuns ?? []);
798
+ const postRunScripts = getDockerRunScripts(config.postRuns ?? []);
799
+ if (type === "backend") {
800
+ const imageScript = config.image ? getDockerImageScript(config.image, "node:22-slim") : "FROM node:22-slim";
801
+ const command = config.command ?? ["node", "main.js"];
802
+ const content = `${imageScript}
803
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
804
+ RUN apt-get update && apt-get upgrade -y
805
+ 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/*
806
+ ARG TARGETARCH
807
+ 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
808
+ ${preRunScripts.join("\n")}
809
+ RUN mkdir -p /workspace
810
+ WORKDIR /workspace
811
+ COPY ./package.json ./package.json
812
+ RUN npx pnpm i --prod
813
+ COPY . .
814
+ ENV PORT=8080
815
+ ENV NODE_OPTIONS=--max_old_space_size=8192
816
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
817
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
818
+ ENV NEXT_PUBLIC_APP_NAME=${name}
819
+ ENV NEXT_PUBLIC_ENV=${env}
820
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
821
+ ${postRunScripts.join("\n")}
822
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
823
+ return {
824
+ content,
825
+ image: imageScript,
826
+ preRuns: config.preRuns ?? [],
827
+ postRuns: config.postRuns ?? [],
828
+ command
829
+ };
830
+ } else {
831
+ const imageScript = config.image ? getDockerImageScript(config.image, "node:22-alpine") : "FROM node:22-alpine";
832
+ const command = config.command ?? ["npm", "start"];
833
+ const content = `${imageScript}
834
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
835
+ ARG TARGETARCH
836
+ RUN apk --no-cache add git
837
+ ${preRunScripts.join("\n")}
838
+ RUN mkdir -p /workspace
839
+ WORKDIR /workspace
840
+ COPY ./package.json ./package.json
841
+ RUN npx pnpm i --prod
842
+ COPY . .
843
+ ENV PORT 4200
844
+ ENV NODE_OPTIONS=--max_old_space_size=8192
845
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
846
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
847
+ ENV NEXT_PUBLIC_APP_NAME=${name}
848
+ ENV NEXT_PUBLIC_ENV=${env}
849
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
850
+ ${postRunScripts.join("\n")}
851
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
852
+ return {
853
+ content,
854
+ image: imageScript,
855
+ preRuns: config.preRuns ?? [],
856
+ postRuns: config.postRuns ?? [],
857
+ command
858
+ };
859
+ }
860
+ };
809
861
 
810
862
  // pkgs/@akanjs/config/src/types.ts
863
+ var archs = ["amd64", "arm64"];
811
864
  var getDefaultFileScan = () => ({
812
865
  constants: {
813
866
  databases: [],
@@ -2191,17 +2244,28 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2191
2244
  }
2192
2245
  async syncAssets(libDeps) {
2193
2246
  const projectPublicLibPath = `${this.cwdPath}/public/libs`;
2194
- if (import_fs4.default.existsSync(projectPublicLibPath))
2195
- await import_promises.default.rm(projectPublicLibPath, { recursive: true });
2247
+ const projectAssetsLibPath = `${this.cwdPath}/assets/libs`;
2248
+ await Promise.all([
2249
+ import_fs4.default.existsSync(projectPublicLibPath) && import_promises.default.rm(projectPublicLibPath, { recursive: true }),
2250
+ import_fs4.default.existsSync(projectAssetsLibPath) && import_promises.default.rm(projectAssetsLibPath, { recursive: true })
2251
+ ]);
2196
2252
  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}`, {
2253
+ await Promise.all([
2254
+ ...targetDeps.map((dep) => import_promises.default.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })),
2255
+ ...targetDeps.map((dep) => import_promises.default.mkdir(`${projectAssetsLibPath}/${dep}`, { recursive: true }))
2256
+ ]);
2257
+ await Promise.all([
2258
+ ...targetDeps.map(
2259
+ (dep) => import_fs4.default.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`) && import_promises.default.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2260
+ recursive: true
2261
+ })
2262
+ ),
2263
+ ...targetDeps.map(
2264
+ (dep) => import_fs4.default.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/assets`) && import_promises.default.cp(`${this.workspace.workspaceRoot}/libs/${dep}/assets`, `${projectAssetsLibPath}/${dep}`, {
2201
2265
  recursive: true
2202
2266
  })
2203
2267
  )
2204
- );
2268
+ ]);
2205
2269
  }
2206
2270
  };
2207
2271
  var LibExecutor = class _LibExecutor extends SysExecutor {
@@ -2566,7 +2630,7 @@ var extractDependencies = (filepaths, pacakgeJson, defaultDependencies = []) =>
2566
2630
  ...pacakgeJson.dependencies ?? {},
2567
2631
  ...pacakgeJson.devDependencies ?? {}
2568
2632
  };
2569
- const requireRegex = /require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
2633
+ const requireRegex = /(?:require\s*\(|import\s*(?:[\w\s{},*]*\s+from\s*)?|import\s*\()\s*['"`]([^'"`]+)['"`]/g;
2570
2634
  for (const { text } of filepaths.filter(({ path: path9 }) => path9.endsWith(".js"))) {
2571
2635
  let requireMatch;
2572
2636
  while ((requireMatch = requireRegex.exec(text)) !== null) {
@@ -3929,6 +3993,8 @@ var ApplicationRunner = class {
3929
3993
  app.writeFile("next.config.ts", defaultNextConfigFile);
3930
3994
  } else if (target === "csr")
3931
3995
  await app.workspace.exec("rm -rf node_modules/.vite");
3996
+ else if (target === "backend")
3997
+ await app.cp("assets", import_path4.default.join(app.dist.cwdPath, "backend", "assets"));
3932
3998
  return { env: this.#getEnv(app, { AKAN_COMMAND_TYPE: type }) };
3933
3999
  }
3934
4000
  async buildBackend(app) {
@@ -3957,7 +4023,7 @@ var ApplicationRunner = class {
3957
4023
  dependencies
3958
4024
  };
3959
4025
  app.dist.writeJson("backend/package.json", appPackageJson);
3960
- app.dist.writeFile(import_path4.default.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
4026
+ app.dist.writeFile(import_path4.default.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.docker.content);
3961
4027
  }
3962
4028
  async startBackend(app, { open: open2 = false, onStart } = {}) {
3963
4029
  const { env } = await this.#prepareCommand(app, "start", "backend");
@@ -3976,7 +4042,7 @@ var ApplicationRunner = class {
3976
4042
  onStart?.();
3977
4043
  if (open2)
3978
4044
  setTimeout(() => (0, import_open.default)("http://localhost:8080/backend/graphql"), 3e3);
3979
- await app.dist.spawn("node", ["--watch", "backend/main.js"], { env, stdio: "inherit" });
4045
+ await app.dist.spawn("node", ["--watch", "main.js"], { env, stdio: "inherit", cwd: `${app.dist.cwdPath}/backend` });
3980
4046
  }
3981
4047
  async buildFrontend(app, { spawnOptions } = {}) {
3982
4048
  const { env } = await this.#prepareCommand(app, "build", "frontend");
@@ -3991,7 +4057,6 @@ var ApplicationRunner = class {
3991
4057
  format: "esm",
3992
4058
  write: false,
3993
4059
  logLevel: "warning"
3994
- // footer: { js: "module.exports = module.exports.default;" },
3995
4060
  });
3996
4061
  const rootPackageJson = app.workspace.readJson("package.json");
3997
4062
  const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
@@ -4009,7 +4074,7 @@ var ApplicationRunner = class {
4009
4074
  app.cp(".next", import_path4.default.join(app.dist.cwdPath, "frontend", ".next")),
4010
4075
  app.cp("public", import_path4.default.join(app.dist.cwdPath, "frontend", "public"))
4011
4076
  ]);
4012
- app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
4077
+ app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.docker.content);
4013
4078
  }
4014
4079
  async startFrontend(app, { open: open2 = false, turbo = true, onStart } = {}) {
4015
4080
  const { env } = await this.#prepareCommand(app, "start", "frontend");
@@ -4992,6 +5057,15 @@ ${import_chalk6.default.green("\u27A4")} Authentication Required`));
4992
5057
  Logger.info("All libraries are published to npm");
4993
5058
  }
4994
5059
  async update(workspace) {
5060
+ if (!workspace.exists("package.json"))
5061
+ await workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]);
5062
+ else
5063
+ await Promise.all([
5064
+ workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5065
+ this.#updateAkanPkgs(workspace)
5066
+ ]);
5067
+ }
5068
+ async #updateAkanPkgs(workspace) {
4995
5069
  const latestPublishedVersionOfBase = await (0, import_latest_version.default)("@akanjs/base");
4996
5070
  const rootPackageJson = workspace.readJson("package.json");
4997
5071
  if (!rootPackageJson.dependencies)
@@ -5005,10 +5079,7 @@ ${import_chalk6.default.green("\u27A4")} Authentication Required`));
5005
5079
  Object.assign(rootPackageJson.devDependencies ?? {}, { [dependency]: latestPublishedVersionOfBase });
5006
5080
  });
5007
5081
  workspace.writeJson("package.json", rootPackageJson);
5008
- await Promise.all([
5009
- workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5010
- workspace.spawn("pnpm", ["install"])
5011
- ]);
5082
+ await workspace.spawn("pnpm", ["install"]);
5012
5083
  }
5013
5084
  };
5014
5085
 
@@ -5664,13 +5735,9 @@ var ModuleScript = class {
5664
5735
  // pkgs/@akanjs/cli/src/module/module.command.ts
5665
5736
  var ModuleCommand = class {
5666
5737
  moduleScript = new ModuleScript();
5667
- async createModule(sys3, moduleName, description, schemaDescription, ai) {
5738
+ async createModule(moduleName, sys3) {
5668
5739
  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
- }
5740
+ await this.moduleScript.createModuleTemplate(sys3, name);
5674
5741
  }
5675
5742
  removeModule(module2) {
5676
5743
  this.moduleScript.removeModule(module2);
@@ -5687,11 +5754,8 @@ var ModuleCommand = class {
5687
5754
  };
5688
5755
  __decorateClass([
5689
5756
  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" }))
5757
+ __decorateParam(0, Argument("moduleName", { desc: "name of module" })),
5758
+ __decorateParam(1, Sys())
5695
5759
  ], ModuleCommand.prototype, "createModule", 1);
5696
5760
  __decorateClass([
5697
5761
  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,8 +754,93 @@ 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(
763
+ ([arch, script]) => `RUN if [ "$TARGETARCH" = "${arch}" ]; then ${script} fi`
764
+ ).join("\n");
765
+ });
766
+ };
767
+ var getDockerImageScript = (image, defaultImage) => {
768
+ if (typeof image === "string")
769
+ return `FROM ${image}`;
770
+ else
771
+ return archs.map((arch) => `FROM ${image[arch] ?? defaultImage} AS ${arch}`).join("\n");
772
+ };
773
+ var makeDockerfile = (type, config, props) => {
774
+ const { name, repoName, serveDomain, env } = props;
775
+ if (config.content)
776
+ return { content: config.content, image: {}, preRuns: [], postRuns: [], command: [] };
777
+ const preRunScripts = getDockerRunScripts(config.preRuns ?? []);
778
+ const postRunScripts = getDockerRunScripts(config.postRuns ?? []);
779
+ if (type === "backend") {
780
+ const imageScript = config.image ? getDockerImageScript(config.image, "node:22-slim") : "FROM node:22-slim";
781
+ const command = config.command ?? ["node", "main.js"];
782
+ const content = `${imageScript}
783
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
784
+ RUN apt-get update && apt-get upgrade -y
785
+ 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/*
786
+ ARG TARGETARCH
787
+ 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
788
+ ${preRunScripts.join("\n")}
789
+ RUN mkdir -p /workspace
790
+ WORKDIR /workspace
791
+ COPY ./package.json ./package.json
792
+ RUN npx pnpm i --prod
793
+ COPY . .
794
+ ENV PORT=8080
795
+ ENV NODE_OPTIONS=--max_old_space_size=8192
796
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
797
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
798
+ ENV NEXT_PUBLIC_APP_NAME=${name}
799
+ ENV NEXT_PUBLIC_ENV=${env}
800
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
801
+ ${postRunScripts.join("\n")}
802
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
803
+ return {
804
+ content,
805
+ image: imageScript,
806
+ preRuns: config.preRuns ?? [],
807
+ postRuns: config.postRuns ?? [],
808
+ command
809
+ };
810
+ } else {
811
+ const imageScript = config.image ? getDockerImageScript(config.image, "node:22-alpine") : "FROM node:22-alpine";
812
+ const command = config.command ?? ["npm", "start"];
813
+ const content = `${imageScript}
814
+ RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
815
+ ARG TARGETARCH
816
+ RUN apk --no-cache add git
817
+ ${preRunScripts.join("\n")}
818
+ RUN mkdir -p /workspace
819
+ WORKDIR /workspace
820
+ COPY ./package.json ./package.json
821
+ RUN npx pnpm i --prod
822
+ COPY . .
823
+ ENV PORT 4200
824
+ ENV NODE_OPTIONS=--max_old_space_size=8192
825
+ ENV NEXT_PUBLIC_REPO_NAME=${repoName}
826
+ ENV NEXT_PUBLIC_SERVE_DOMAIN=${serveDomain}
827
+ ENV NEXT_PUBLIC_APP_NAME=${name}
828
+ ENV NEXT_PUBLIC_ENV=${env}
829
+ ENV NEXT_PUBLIC_OPERATION_MODE=cloud
830
+ ${postRunScripts.join("\n")}
831
+ CMD [${command.map((c) => `"${c}"`).join(",")}]`;
832
+ return {
833
+ content,
834
+ image: imageScript,
835
+ preRuns: config.preRuns ?? [],
836
+ postRuns: config.postRuns ?? [],
837
+ command
838
+ };
839
+ }
840
+ };
789
841
 
790
842
  // pkgs/@akanjs/config/src/types.ts
843
+ var archs = ["amd64", "arm64"];
791
844
  var getDefaultFileScan = () => ({
792
845
  constants: {
793
846
  databases: [],
@@ -2170,17 +2223,28 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2170
2223
  }
2171
2224
  async syncAssets(libDeps) {
2172
2225
  const projectPublicLibPath = `${this.cwdPath}/public/libs`;
2173
- if (fs8.existsSync(projectPublicLibPath))
2174
- await fsPromise.rm(projectPublicLibPath, { recursive: true });
2226
+ const projectAssetsLibPath = `${this.cwdPath}/assets/libs`;
2227
+ await Promise.all([
2228
+ fs8.existsSync(projectPublicLibPath) && fsPromise.rm(projectPublicLibPath, { recursive: true }),
2229
+ fs8.existsSync(projectAssetsLibPath) && fsPromise.rm(projectAssetsLibPath, { recursive: true })
2230
+ ]);
2175
2231
  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}`, {
2232
+ await Promise.all([
2233
+ ...targetDeps.map((dep) => fsPromise.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })),
2234
+ ...targetDeps.map((dep) => fsPromise.mkdir(`${projectAssetsLibPath}/${dep}`, { recursive: true }))
2235
+ ]);
2236
+ await Promise.all([
2237
+ ...targetDeps.map(
2238
+ (dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`) && fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2239
+ recursive: true
2240
+ })
2241
+ ),
2242
+ ...targetDeps.map(
2243
+ (dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/assets`) && fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/assets`, `${projectAssetsLibPath}/${dep}`, {
2180
2244
  recursive: true
2181
2245
  })
2182
2246
  )
2183
- );
2247
+ ]);
2184
2248
  }
2185
2249
  };
2186
2250
  var LibExecutor = class _LibExecutor extends SysExecutor {
@@ -2545,7 +2609,7 @@ var extractDependencies = (filepaths, pacakgeJson, defaultDependencies = []) =>
2545
2609
  ...pacakgeJson.dependencies ?? {},
2546
2610
  ...pacakgeJson.devDependencies ?? {}
2547
2611
  };
2548
- const requireRegex = /require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
2612
+ const requireRegex = /(?:require\s*\(|import\s*(?:[\w\s{},*]*\s+from\s*)?|import\s*\()\s*['"`]([^'"`]+)['"`]/g;
2549
2613
  for (const { text } of filepaths.filter(({ path: path9 }) => path9.endsWith(".js"))) {
2550
2614
  let requireMatch;
2551
2615
  while ((requireMatch = requireRegex.exec(text)) !== null) {
@@ -3911,6 +3975,8 @@ var ApplicationRunner = class {
3911
3975
  app.writeFile("next.config.ts", defaultNextConfigFile);
3912
3976
  } else if (target === "csr")
3913
3977
  await app.workspace.exec("rm -rf node_modules/.vite");
3978
+ else if (target === "backend")
3979
+ await app.cp("assets", path7.join(app.dist.cwdPath, "backend", "assets"));
3914
3980
  return { env: this.#getEnv(app, { AKAN_COMMAND_TYPE: type }) };
3915
3981
  }
3916
3982
  async buildBackend(app) {
@@ -3939,7 +4005,7 @@ var ApplicationRunner = class {
3939
4005
  dependencies
3940
4006
  };
3941
4007
  app.dist.writeJson("backend/package.json", appPackageJson);
3942
- app.dist.writeFile(path7.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
4008
+ app.dist.writeFile(path7.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.docker.content);
3943
4009
  }
3944
4010
  async startBackend(app, { open: open2 = false, onStart } = {}) {
3945
4011
  const { env } = await this.#prepareCommand(app, "start", "backend");
@@ -3958,7 +4024,7 @@ var ApplicationRunner = class {
3958
4024
  onStart?.();
3959
4025
  if (open2)
3960
4026
  setTimeout(() => openBrowser("http://localhost:8080/backend/graphql"), 3e3);
3961
- await app.dist.spawn("node", ["--watch", "backend/main.js"], { env, stdio: "inherit" });
4027
+ await app.dist.spawn("node", ["--watch", "main.js"], { env, stdio: "inherit", cwd: `${app.dist.cwdPath}/backend` });
3962
4028
  }
3963
4029
  async buildFrontend(app, { spawnOptions } = {}) {
3964
4030
  const { env } = await this.#prepareCommand(app, "build", "frontend");
@@ -3973,7 +4039,6 @@ var ApplicationRunner = class {
3973
4039
  format: "esm",
3974
4040
  write: false,
3975
4041
  logLevel: "warning"
3976
- // footer: { js: "module.exports = module.exports.default;" },
3977
4042
  });
3978
4043
  const rootPackageJson = app.workspace.readJson("package.json");
3979
4044
  const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
@@ -3991,7 +4056,7 @@ var ApplicationRunner = class {
3991
4056
  app.cp(".next", path7.join(app.dist.cwdPath, "frontend", ".next")),
3992
4057
  app.cp("public", path7.join(app.dist.cwdPath, "frontend", "public"))
3993
4058
  ]);
3994
- app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
4059
+ app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.docker.content);
3995
4060
  }
3996
4061
  async startFrontend(app, { open: open2 = false, turbo = true, onStart } = {}) {
3997
4062
  const { env } = await this.#prepareCommand(app, "start", "frontend");
@@ -4974,6 +5039,15 @@ ${chalk6.green("\u27A4")} Authentication Required`));
4974
5039
  Logger.info("All libraries are published to npm");
4975
5040
  }
4976
5041
  async update(workspace) {
5042
+ if (!workspace.exists("package.json"))
5043
+ await workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]);
5044
+ else
5045
+ await Promise.all([
5046
+ workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
5047
+ this.#updateAkanPkgs(workspace)
5048
+ ]);
5049
+ }
5050
+ async #updateAkanPkgs(workspace) {
4977
5051
  const latestPublishedVersionOfBase = await latestVersion("@akanjs/base");
4978
5052
  const rootPackageJson = workspace.readJson("package.json");
4979
5053
  if (!rootPackageJson.dependencies)
@@ -4987,10 +5061,7 @@ ${chalk6.green("\u27A4")} Authentication Required`));
4987
5061
  Object.assign(rootPackageJson.devDependencies ?? {}, { [dependency]: latestPublishedVersionOfBase });
4988
5062
  });
4989
5063
  workspace.writeJson("package.json", rootPackageJson);
4990
- await Promise.all([
4991
- workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
4992
- workspace.spawn("pnpm", ["install"])
4993
- ]);
5064
+ await workspace.spawn("pnpm", ["install"]);
4994
5065
  }
4995
5066
  };
4996
5067
 
@@ -5646,13 +5717,9 @@ var ModuleScript = class {
5646
5717
  // pkgs/@akanjs/cli/src/module/module.command.ts
5647
5718
  var ModuleCommand = class {
5648
5719
  moduleScript = new ModuleScript();
5649
- async createModule(sys3, moduleName, description, schemaDescription, ai) {
5720
+ async createModule(moduleName, sys3) {
5650
5721
  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
- }
5722
+ await this.moduleScript.createModuleTemplate(sys3, name);
5656
5723
  }
5657
5724
  removeModule(module) {
5658
5725
  this.moduleScript.removeModule(module);
@@ -5669,11 +5736,8 @@ var ModuleCommand = class {
5669
5736
  };
5670
5737
  __decorateClass([
5671
5738
  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" }))
5739
+ __decorateParam(0, Argument("moduleName", { desc: "name of module" })),
5740
+ __decorateParam(1, Sys())
5677
5741
  ], ModuleCommand.prototype, "createModule", 1);
5678
5742
  __decorateClass([
5679
5743
  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.15",
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>;