@akanjs/cli 0.9.9 → 0.9.11

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/esm/index.js CHANGED
@@ -1,13 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
- }) : x)(function(x) {
7
- if (typeof require !== "undefined")
8
- return require.apply(this, arguments);
9
- throw Error('Dynamic require of "' + x + '" is not supported');
10
- });
11
4
  var __decorateClass = (decorators, target, key, kind) => {
12
5
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
13
6
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
@@ -19,6 +12,9 @@ var __decorateClass = (decorators, target, key, kind) => {
19
12
  };
20
13
  var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
21
14
 
15
+ // pkgs/@akanjs/cli/index.ts
16
+ import dotenv4 from "dotenv";
17
+
22
18
  // pkgs/@akanjs/devkit/src/createTunnel.ts
23
19
  import { createTunnel as create } from "tunnel-ssh";
24
20
  var getSshTunnelOptions = (app, environment) => {
@@ -55,15 +51,16 @@ var getCredentials = (app, environment) => {
55
51
  };
56
52
 
57
53
  // pkgs/@akanjs/common/isDayjs.ts
58
- import { isDayjs } from "dayjs";
54
+ import dayjs from "dayjs";
55
+ var isDayjs = dayjs.isDayjs;
59
56
 
60
57
  // pkgs/@akanjs/common/isQueryEqual.ts
61
- import dayjs from "dayjs";
58
+ import dayjs2 from "dayjs";
62
59
 
63
60
  // pkgs/@akanjs/common/isValidDate.ts
64
- import dayjs2 from "dayjs";
61
+ import dayjs3 from "dayjs";
65
62
  import customParseFormat from "dayjs/plugin/customParseFormat.js";
66
- dayjs2.extend(customParseFormat);
63
+ dayjs3.extend(customParseFormat);
67
64
 
68
65
  // pkgs/@akanjs/common/randomPicks.ts
69
66
  var randomPicks = (arr, count = 1, allowDuplicate = false) => {
@@ -89,7 +86,7 @@ var capitalize = (str) => {
89
86
  };
90
87
 
91
88
  // pkgs/@akanjs/common/Logger.ts
92
- import dayjs3 from "dayjs";
89
+ import dayjs4 from "dayjs";
93
90
  var logLevels = ["trace", "verbose", "debug", "log", "info", "warn", "error"];
94
91
  var clc = {
95
92
  bold: (text) => `\x1B[1m${text}\x1B[0m`,
@@ -120,7 +117,7 @@ var Logger = class _Logger {
120
117
  ]);
121
118
  static level = process.env.NEXT_PUBLIC_LOG_LEVEL ?? "log";
122
119
  static #levelIdx = logLevels.findIndex((l) => l === (process.env.NEXT_PUBLIC_LOG_LEVEL ?? "log"));
123
- static #startAt = dayjs3();
120
+ static #startAt = dayjs4();
124
121
  static setLevel(level) {
125
122
  this.level = level;
126
123
  this.#levelIdx = logLevels.findIndex((l) => l === level);
@@ -197,7 +194,7 @@ var Logger = class _Logger {
197
194
  static #printMessages(name, content, context2, logLevel, writeStreamType = logLevel === "error" ? "stderr" : "stdout") {
198
195
  if (this.#ignoreCtxSet.has(context2))
199
196
  return;
200
- const now = dayjs3();
197
+ const now = dayjs4();
201
198
  const processMsg = this.#colorize(
202
199
  `[${name ?? "App"}] ${global.process?.pid ?? "window"} -`,
203
200
  logLevel
@@ -383,8 +380,8 @@ import * as fs3 from "fs";
383
380
  import ora2 from "ora";
384
381
  import * as ts from "typescript";
385
382
  var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
386
- const configFile = ts.readConfigFile(tsConfigPath, (path9) => {
387
- return ts.sys.readFile(path9);
383
+ const configFile = ts.readConfigFile(tsConfigPath, (path10) => {
384
+ return ts.sys.readFile(path10);
388
385
  });
389
386
  return ts.parseJsonConfigFileContent(
390
387
  configFile.config,
@@ -552,7 +549,7 @@ import path2 from "path";
552
549
  // pkgs/@akanjs/config/src/nextConfig.ts
553
550
  import withAnalyze from "@next/bundle-analyzer";
554
551
  import pwa from "next-pwa";
555
- import runtimeCaching from "next-pwa/cache";
552
+ import runtimeCaching from "next-pwa/cache.js";
556
553
  import path from "path";
557
554
  var composePlugins = (...plugins) => {
558
555
  return function(baseConfig) {
@@ -571,16 +568,17 @@ var composePlugins = (...plugins) => {
571
568
  };
572
569
  };
573
570
  var commandType = process.env.AKAN_COMMAND_TYPE?.includes("start") ? "start" : process.env.AKAN_COMMAND_TYPE?.includes("build") ? "build" : "deploy";
574
- var withPWA = pwa({
575
- dest: "public",
576
- register: true,
577
- skipWaiting: true,
578
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
579
- runtimeCaching,
580
- disable: commandType === "start"
581
- });
582
571
  var devDomain = process.env.NEXT_PUBLIC_SERVE_DOMAIN ?? "akanjs.com";
583
572
  var withBase = (appName, config, libs, routes = []) => {
573
+ const __dirname = path.dirname(new URL(import.meta.url).pathname);
574
+ const withPWA = pwa({
575
+ dest: "public",
576
+ register: true,
577
+ skipWaiting: true,
578
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
579
+ runtimeCaching,
580
+ disable: commandType === "start"
581
+ });
584
582
  return composePlugins(
585
583
  withAnalyze({ enabled: process.env.ANALYZE === "true" }),
586
584
  ...commandType !== "start" || process.env.USE_PWA === "true" ? [withPWA] : []
@@ -693,7 +691,7 @@ var withBase = (appName, config, libs, routes = []) => {
693
691
  }
694
692
  });
695
693
  };
696
- var defaultNextConfigFile = `import "tsconfig-paths/register";
694
+ var defaultNextConfigFile = `import "tsconfig-paths/register.js";
697
695
 
698
696
  import { getNextConfig } from "@akanjs/config";
699
697
 
@@ -836,7 +834,7 @@ import { exec, fork, spawn } from "child_process";
836
834
  import dotenv from "dotenv";
837
835
  import fs8 from "fs";
838
836
  import fsPromise from "fs/promises";
839
- import path6 from "path";
837
+ import path7 from "path";
840
838
 
841
839
  // pkgs/@akanjs/devkit/src/dependencyScanner.ts
842
840
  import * as fs5 from "fs";
@@ -985,11 +983,15 @@ var TypeScriptDependencyScanner = class {
985
983
  }
986
984
  };
987
985
 
986
+ // pkgs/@akanjs/devkit/src/getDirname.ts
987
+ import path4 from "path";
988
+ var getDirname = (url) => path4.dirname(new URL(url).pathname);
989
+
988
990
  // pkgs/@akanjs/devkit/src/linter.ts
989
991
  import chalk from "chalk";
990
992
  import { ESLint } from "eslint";
991
993
  import * as fs6 from "fs";
992
- import * as path4 from "path";
994
+ import * as path5 from "path";
993
995
  var Linter = class {
994
996
  #logger = new Logger("Linter");
995
997
  #eslint;
@@ -999,10 +1001,10 @@ var Linter = class {
999
1001
  this.#eslint = new ESLint({ cwd: this.lintRoot, errorOnUnmatchedPattern: false });
1000
1002
  }
1001
1003
  #findEslintRootPath(dir) {
1002
- const configPath2 = path4.join(dir, "eslint.config.ts");
1004
+ const configPath2 = path5.join(dir, "eslint.config.ts");
1003
1005
  if (fs6.existsSync(configPath2))
1004
1006
  return dir;
1005
- const parentDir = path4.dirname(dir);
1007
+ const parentDir = path5.dirname(dir);
1006
1008
  return this.#findEslintRootPath(parentDir);
1007
1009
  }
1008
1010
  async lint(filePath, { fix = false, dryRun = false } = {}) {
@@ -1191,7 +1193,7 @@ ${errorText}, ${warningText} found`];
1191
1193
  // pkgs/@akanjs/devkit/src/typeChecker.ts
1192
1194
  import chalk2 from "chalk";
1193
1195
  import * as fs7 from "fs";
1194
- import * as path5 from "path";
1196
+ import * as path6 from "path";
1195
1197
  import * as ts3 from "typescript";
1196
1198
  var TypeChecker = class {
1197
1199
  configPath;
@@ -1206,7 +1208,7 @@ var TypeChecker = class {
1206
1208
  const parsedConfig = ts3.parseJsonConfigFileContent(
1207
1209
  this.configFile.config,
1208
1210
  ts3.sys,
1209
- path5.dirname(this.configPath),
1211
+ path6.dirname(this.configPath),
1210
1212
  void 0,
1211
1213
  this.configPath
1212
1214
  );
@@ -1378,6 +1380,7 @@ var Executor = class _Executor {
1378
1380
  }
1379
1381
  name;
1380
1382
  logger;
1383
+ logs;
1381
1384
  cwdPath;
1382
1385
  emoji = execEmoji.default;
1383
1386
  typeChecker = null;
@@ -1385,6 +1388,7 @@ var Executor = class _Executor {
1385
1388
  constructor(name, cwdPath) {
1386
1389
  this.name = name;
1387
1390
  this.logger = new Logger(name);
1391
+ this.logs = [];
1388
1392
  this.cwdPath = cwdPath;
1389
1393
  if (!fs8.existsSync(cwdPath))
1390
1394
  fs8.mkdirSync(cwdPath, { recursive: true });
@@ -1423,10 +1427,12 @@ var Executor = class _Executor {
1423
1427
  let stderr = "";
1424
1428
  proc.stdout?.on("data", (data) => {
1425
1429
  stdout += data;
1430
+ this.logs.push(data);
1426
1431
  this.#stdout(data);
1427
1432
  });
1428
1433
  proc.stderr?.on("data", (data) => {
1429
1434
  stderr += data;
1435
+ this.logs.push(data);
1430
1436
  this.#stdout(data);
1431
1437
  });
1432
1438
  return new Promise((resolve, reject) => {
@@ -1438,6 +1444,14 @@ var Executor = class _Executor {
1438
1444
  });
1439
1445
  });
1440
1446
  }
1447
+ spawnSync(command, args = [], options = {}) {
1448
+ const proc = spawn(command, args, {
1449
+ cwd: this.cwdPath,
1450
+ // stdio: "inherit",
1451
+ ...options
1452
+ });
1453
+ return proc;
1454
+ }
1441
1455
  fork(modulePath, args = [], options = {}) {
1442
1456
  const proc = fork(modulePath, args, {
1443
1457
  cwd: this.cwdPath,
@@ -1460,7 +1474,7 @@ var Executor = class _Executor {
1460
1474
  });
1461
1475
  }
1462
1476
  getPath(filePath) {
1463
- if (path6.isAbsolute(filePath))
1477
+ if (path7.isAbsolute(filePath))
1464
1478
  return filePath;
1465
1479
  const baseParts = this.cwdPath.split("/").filter(Boolean);
1466
1480
  const targetParts = filePath.split("/").filter(Boolean);
@@ -1513,7 +1527,7 @@ var Executor = class _Executor {
1513
1527
  }
1514
1528
  writeFile(filePath, content, { overwrite = true } = {}) {
1515
1529
  const writePath = this.getPath(filePath);
1516
- const dir = path6.dirname(writePath);
1530
+ const dir = path7.dirname(writePath);
1517
1531
  if (!fs8.existsSync(dir))
1518
1532
  fs8.mkdirSync(dir, { recursive: true });
1519
1533
  let contentStr = typeof content === "string" ? content : JSON.stringify(content, null, 2);
@@ -1537,7 +1551,7 @@ var Executor = class _Executor {
1537
1551
  return this;
1538
1552
  }
1539
1553
  getLocalFile(targetPath) {
1540
- const filePath = path6.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
1554
+ const filePath = path7.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
1541
1555
  const content = this.readFile(filePath);
1542
1556
  return { filePath, content };
1543
1557
  }
@@ -1584,15 +1598,15 @@ var Executor = class _Executor {
1584
1598
  overwrite = true
1585
1599
  }, dict = {}) {
1586
1600
  if (targetPath.endsWith(".js") || targetPath.endsWith(".jsx")) {
1587
- const getContent = __require(templatePath);
1601
+ const getContent = await import(templatePath);
1588
1602
  const result = getContent.default(scanResult ?? null, dict);
1589
1603
  if (result === null)
1590
1604
  return null;
1591
- const filename = typeof result === "object" ? result.filename : path6.basename(targetPath).replace(".js", ".ts");
1605
+ const filename = typeof result === "object" ? result.filename : path7.basename(targetPath).replace(".js", ".ts");
1592
1606
  const content = typeof result === "object" ? result.content : result;
1593
- const dirname3 = path6.dirname(targetPath);
1607
+ const dirname3 = path7.dirname(targetPath);
1594
1608
  const convertedTargetPath = Object.entries(dict).reduce(
1595
- (path9, [key, value]) => path9.replace(new RegExp(`__${key}__`, "g"), value),
1609
+ (path10, [key, value]) => path10.replace(new RegExp(`__${key}__`, "g"), value),
1596
1610
  `${dirname3}/${filename}`
1597
1611
  );
1598
1612
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
@@ -1600,7 +1614,7 @@ var Executor = class _Executor {
1600
1614
  } else if (targetPath.endsWith(".template")) {
1601
1615
  const content = await fsPromise.readFile(templatePath, "utf8");
1602
1616
  const convertedTargetPath = Object.entries(dict).reduce(
1603
- (path9, [key, value]) => path9.replace(new RegExp(`__${key}__`, "g"), value),
1617
+ (path10, [key, value]) => path10.replace(new RegExp(`__${key}__`, "g"), value),
1604
1618
  targetPath.slice(0, -9)
1605
1619
  );
1606
1620
  const convertedContent = Object.entries(dict).reduce(
@@ -1619,12 +1633,12 @@ var Executor = class _Executor {
1619
1633
  dict = {},
1620
1634
  overwrite = true
1621
1635
  }) {
1622
- const templatePath = `${__dirname}/src/templates${template ? `/${template}` : ""}`;
1636
+ const templatePath = `${getDirname(import.meta.url)}/src/templates${template ? `/${template}` : ""}`;
1623
1637
  const prefixTemplatePath = templatePath.endsWith(".tsx") ? templatePath : templatePath.replace(".ts", ".js");
1624
1638
  if (fs8.statSync(prefixTemplatePath).isFile()) {
1625
- const filename = path6.basename(prefixTemplatePath);
1639
+ const filename = path7.basename(prefixTemplatePath);
1626
1640
  const fileContent = await this.#applyTemplateFile(
1627
- { templatePath: prefixTemplatePath, targetPath: path6.join(basePath2, filename), scanResult, overwrite },
1641
+ { templatePath: prefixTemplatePath, targetPath: path7.join(basePath2, filename), scanResult, overwrite },
1628
1642
  dict
1629
1643
  );
1630
1644
  return fileContent ? [fileContent] : [];
@@ -1632,17 +1646,17 @@ var Executor = class _Executor {
1632
1646
  const subdirs = await this.readdir(templatePath);
1633
1647
  const fileContents = (await Promise.all(
1634
1648
  subdirs.map(async (subdir) => {
1635
- const subpath = path6.join(templatePath, subdir);
1649
+ const subpath = path7.join(templatePath, subdir);
1636
1650
  if (fs8.statSync(subpath).isFile()) {
1637
1651
  const fileContent = await this.#applyTemplateFile(
1638
- { templatePath: subpath, targetPath: path6.join(basePath2, subdir), scanResult, overwrite },
1652
+ { templatePath: subpath, targetPath: path7.join(basePath2, subdir), scanResult, overwrite },
1639
1653
  dict
1640
1654
  );
1641
1655
  return fileContent ? [fileContent] : [];
1642
1656
  } else
1643
1657
  return await this._applyTemplate({
1644
- basePath: path6.join(basePath2, subdir),
1645
- template: path6.join(template, subdir),
1658
+ basePath: path7.join(basePath2, subdir),
1659
+ template: path7.join(template, subdir),
1646
1660
  scanResult,
1647
1661
  dict,
1648
1662
  overwrite
@@ -1666,9 +1680,9 @@ var Executor = class _Executor {
1666
1680
  return this.typeChecker;
1667
1681
  }
1668
1682
  typeCheck(filePath) {
1669
- const path9 = this.getPath(filePath);
1683
+ const path10 = this.getPath(filePath);
1670
1684
  const typeChecker = this.getTypeChecker();
1671
- const { fileDiagnostics, fileErrors, fileWarnings } = typeChecker.check(path9);
1685
+ const { fileDiagnostics, fileErrors, fileWarnings } = typeChecker.check(path10);
1672
1686
  const message = typeChecker.formatDiagnostics(fileDiagnostics);
1673
1687
  return { fileDiagnostics, fileErrors, fileWarnings, message };
1674
1688
  }
@@ -1677,9 +1691,9 @@ var Executor = class _Executor {
1677
1691
  return this.linter;
1678
1692
  }
1679
1693
  async lint(filePath, { fix = false, dryRun = false } = {}) {
1680
- const path9 = this.getPath(filePath);
1694
+ const path10 = this.getPath(filePath);
1681
1695
  const linter = this.getLinter();
1682
- const { results, errors, warnings } = await linter.lint(path9, { fix, dryRun });
1696
+ const { results, errors, warnings } = await linter.lint(path10, { fix, dryRun });
1683
1697
  const message = linter.formatLintResults(results);
1684
1698
  return { results, message, errors, warnings };
1685
1699
  }
@@ -1694,7 +1708,7 @@ var WorkspaceExecutor = class _WorkspaceExecutor extends Executor {
1694
1708
  this.repoName = repoName;
1695
1709
  }
1696
1710
  static fromRoot() {
1697
- const repoName = path6.basename(process.cwd());
1711
+ const repoName = path7.basename(process.cwd());
1698
1712
  return new _WorkspaceExecutor({ workspaceRoot: process.cwd(), repoName });
1699
1713
  }
1700
1714
  getBaseDevEnv() {
@@ -1803,7 +1817,7 @@ var WorkspaceExecutor = class _WorkspaceExecutor extends Executor {
1803
1817
  dirs.map(async (dir) => {
1804
1818
  if (dir.includes("_") || AVOID_DIRS.includes(dir))
1805
1819
  return;
1806
- const dirPath = path6.join(dirname3, dir);
1820
+ const dirPath = path7.join(dirname3, dir);
1807
1821
  if (fs8.lstatSync(dirPath).isDirectory()) {
1808
1822
  results.push(`${prefix}${dir}`);
1809
1823
  if (maxDepth > 0)
@@ -1830,9 +1844,9 @@ var WorkspaceExecutor = class _WorkspaceExecutor extends Executor {
1830
1844
  dirs.map(async (dir) => {
1831
1845
  if (AVOID_DIRS.includes(dir))
1832
1846
  return;
1833
- const dirPath = path6.join(dirname3, dir);
1847
+ const dirPath = path7.join(dirname3, dir);
1834
1848
  if (fs8.lstatSync(dirPath).isDirectory()) {
1835
- const hasTargetFile = fs8.existsSync(path6.join(dirPath, targetFilename));
1849
+ const hasTargetFile = fs8.existsSync(path7.join(dirPath, targetFilename));
1836
1850
  if (hasTargetFile)
1837
1851
  results.push(`${prefix}${dir}`);
1838
1852
  if (maxDepth > 0)
@@ -1893,8 +1907,8 @@ var SysExecutor = class extends Executor {
1893
1907
  return this.type === "app" ? await getAppConfig(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "app", name: this.name, command }) : await getLibConfig(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "lib", name: this.name, command });
1894
1908
  }
1895
1909
  async getModules() {
1896
- const path9 = this.type === "app" ? `apps/${this.name}/lib` : `libs/${this.name}/lib`;
1897
- return await this.workspace.getDirInModule(path9, this.name);
1910
+ const path10 = this.type === "app" ? `apps/${this.name}/lib` : `libs/${this.name}/lib`;
1911
+ return await this.workspace.getDirInModule(path10, this.name);
1898
1912
  }
1899
1913
  async scan({
1900
1914
  tsconfig = this.getTsConfig(`${this.cwdPath}/tsconfig.json`),
@@ -1906,19 +1920,19 @@ var SysExecutor = class extends Executor {
1906
1920
  const scanner = new TypeScriptDependencyScanner(this.cwdPath);
1907
1921
  const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
1908
1922
  const pkgPathSet = new Set(
1909
- Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path9) => tsconfig.compilerOptions.paths?.[path9]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path9) => path9.replace("/*", ""))
1923
+ Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path10) => tsconfig.compilerOptions.paths?.[path10]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path10) => path10.replace("/*", ""))
1910
1924
  );
1911
1925
  const libPathSet = new Set(
1912
- Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path9) => tsconfig.compilerOptions.paths?.[path9]?.some((resolve) => resolve.startsWith("libs/"))).map((path9) => path9.replace("/*", ""))
1926
+ Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path10) => tsconfig.compilerOptions.paths?.[path10]?.some((resolve) => resolve.startsWith("libs/"))).map((path10) => path10.replace("/*", ""))
1913
1927
  );
1914
1928
  const [npmDepSet, pkgPathDepSet, libPathDepSet] = await scanner.getImportSets([npmSet, pkgPathSet, libPathSet]);
1915
- const pkgDeps = [...pkgPathDepSet].map((path9) => {
1916
- const pathSplitLength = path9.split("/").length;
1917
- return (tsconfig.compilerOptions.paths?.[path9]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
1929
+ const pkgDeps = [...pkgPathDepSet].map((path10) => {
1930
+ const pathSplitLength = path10.split("/").length;
1931
+ return (tsconfig.compilerOptions.paths?.[path10]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
1918
1932
  });
1919
- const libDeps = [...libPathDepSet].map((path9) => {
1920
- const pathSplitLength = path9.split("/").length;
1921
- return (tsconfig.compilerOptions.paths?.[path9]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
1933
+ const libDeps = [...libPathDepSet].map((path10) => {
1934
+ const pathSplitLength = path10.split("/").length;
1935
+ return (tsconfig.compilerOptions.paths?.[path10]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
1922
1936
  }).filter((libName) => libName !== this.name);
1923
1937
  if (!fs8.existsSync(`${this.cwdPath}/lib/__scalar`))
1924
1938
  fs8.mkdirSync(`${this.cwdPath}/lib/__scalar`, { recursive: true });
@@ -1930,7 +1944,7 @@ var SysExecutor = class extends Executor {
1930
1944
  const serviceDirs = dirnames.filter((name) => name.startsWith("_") && !name.startsWith("__"));
1931
1945
  await Promise.all(
1932
1946
  databaseDirs.map(async (name) => {
1933
- const filenames = await this.readdir(path6.join("lib", name));
1947
+ const filenames = await this.readdir(path7.join("lib", name));
1934
1948
  filenames.forEach((filename) => {
1935
1949
  if (filename.endsWith(".constant.ts"))
1936
1950
  files.constants.databases.push(name);
@@ -1952,7 +1966,7 @@ var SysExecutor = class extends Executor {
1952
1966
  await Promise.all(
1953
1967
  serviceDirs.map(async (dirname3) => {
1954
1968
  const name = dirname3.slice(1);
1955
- const filenames = await this.readdir(path6.join("lib", dirname3));
1969
+ const filenames = await this.readdir(path7.join("lib", dirname3));
1956
1970
  filenames.forEach((filename) => {
1957
1971
  if (filename.endsWith(".dictionary.ts"))
1958
1972
  files.dictionary.services.push(name);
@@ -1970,7 +1984,7 @@ var SysExecutor = class extends Executor {
1970
1984
  const scalarDirs = (await this.readdir("lib/__scalar")).filter((name) => !name.startsWith("_"));
1971
1985
  await Promise.all(
1972
1986
  scalarDirs.map(async (name) => {
1973
- const filenames = await this.readdir(path6.join("lib/__scalar", name));
1987
+ const filenames = await this.readdir(path7.join("lib/__scalar", name));
1974
1988
  filenames.forEach((filename) => {
1975
1989
  if (filename.endsWith(".constant.ts"))
1976
1990
  files.constants.scalars.push(name);
@@ -2045,7 +2059,7 @@ var SysExecutor = class extends Executor {
2045
2059
  return scanResult;
2046
2060
  }
2047
2061
  getLocalFile(targetPath) {
2048
- const filePath = path6.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
2062
+ const filePath = path7.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
2049
2063
  const content = this.workspace.readFile(filePath);
2050
2064
  return { filePath, content };
2051
2065
  }
@@ -2160,28 +2174,17 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
2160
2174
  }
2161
2175
  async syncAssets(libDeps) {
2162
2176
  const projectPublicLibPath = `${this.cwdPath}/public/libs`;
2163
- const projectAssetsLibPath = `${this.cwdPath}/assets/libs`;
2164
- await Promise.all([
2165
- fs8.existsSync(projectPublicLibPath) && fsPromise.rm(projectPublicLibPath, { recursive: true }),
2166
- fs8.existsSync(projectAssetsLibPath) && fsPromise.rm(projectAssetsLibPath, { recursive: true })
2167
- ]);
2177
+ if (fs8.existsSync(projectPublicLibPath))
2178
+ await fsPromise.rm(projectPublicLibPath, { recursive: true });
2168
2179
  const targetDeps = libDeps.filter((dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`));
2169
- await Promise.all([
2170
- ...targetDeps.map((dep) => fsPromise.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })),
2171
- ...targetDeps.map((dep) => fsPromise.mkdir(`${projectAssetsLibPath}/${dep}`, { recursive: true }))
2172
- ]);
2173
- await Promise.all([
2174
- ...targetDeps.map(
2175
- (dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`) && fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2176
- recursive: true
2177
- })
2178
- ),
2179
- ...targetDeps.map(
2180
- (dep) => fs8.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/assets`) && fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/assets`, `${projectAssetsLibPath}/${dep}`, {
2180
+ await Promise.all(targetDeps.map((dep) => fsPromise.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })));
2181
+ await Promise.all(
2182
+ targetDeps.map(
2183
+ (dep) => fsPromise.cp(`${this.workspace.workspaceRoot}/libs/${dep}/public`, `${projectPublicLibPath}/${dep}`, {
2181
2184
  recursive: true
2182
2185
  })
2183
2186
  )
2184
- ]);
2187
+ );
2185
2188
  }
2186
2189
  };
2187
2190
  var LibExecutor = class _LibExecutor extends SysExecutor {
@@ -2231,12 +2234,12 @@ var PkgExecutor = class _PkgExecutor extends Executor {
2231
2234
  const scanner = new TypeScriptDependencyScanner(this.cwdPath);
2232
2235
  const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
2233
2236
  const pkgPathSet = new Set(
2234
- Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path9) => tsconfig.compilerOptions.paths?.[path9]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path9) => path9.replace("/*", ""))
2237
+ Object.keys(tsconfig.compilerOptions.paths ?? {}).filter((path10) => tsconfig.compilerOptions.paths?.[path10]?.some((resolve) => resolve.startsWith("pkgs/"))).map((path10) => path10.replace("/*", ""))
2235
2238
  );
2236
2239
  const [npmDepSet, pkgPathDepSet] = await scanner.getImportSets([npmSet, pkgPathSet]);
2237
- const pkgDeps = [...pkgPathDepSet].map((path9) => {
2238
- const pathSplitLength = path9.split("/").length;
2239
- return (tsconfig.compilerOptions.paths?.[path9]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
2240
+ const pkgDeps = [...pkgPathDepSet].map((path10) => {
2241
+ const pathSplitLength = path10.split("/").length;
2242
+ return (tsconfig.compilerOptions.paths?.[path10]?.[0] ?? "*").split("/").slice(1, 1 + pathSplitLength).join("/");
2240
2243
  }).filter((pkg) => pkg !== this.name);
2241
2244
  const pkgScanResult = {
2242
2245
  name: this.name,
@@ -2547,7 +2550,7 @@ var extractDependencies = (filepaths, pacakgeJson, defaultDependencies = []) =>
2547
2550
  ...pacakgeJson.devDependencies ?? {}
2548
2551
  };
2549
2552
  const requireRegex = /require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
2550
- for (const { text } of filepaths.filter(({ path: path9 }) => path9.endsWith(".js"))) {
2553
+ for (const { text } of filepaths.filter(({ path: path10 }) => path10.endsWith(".js"))) {
2551
2554
  let requireMatch;
2552
2555
  while ((requireMatch = requireRegex.exec(text)) !== null) {
2553
2556
  const moduleName = requireMatch[1];
@@ -2827,6 +2830,7 @@ var runCommands = async (...commands) => {
2827
2830
  process.on("unhandledRejection", (error) => {
2828
2831
  process.exit(1);
2829
2832
  });
2833
+ const __dirname = getDirname(import.meta.url);
2830
2834
  const hasPackageJson = fs11.existsSync(`${__dirname}/../package.json`);
2831
2835
  const version = hasPackageJson ? JSON.parse(fs11.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
2832
2836
  program.version(version).description("Akan CLI");
@@ -3262,16 +3266,18 @@ import { input as input3, select as select4 } from "@inquirer/prompts";
3262
3266
  import fsPromise2 from "fs/promises";
3263
3267
  var Prompter = class {
3264
3268
  static async selectGuideline() {
3265
- const guideNames = (await fsPromise2.readdir(`${__dirname}/src/guidelines`)).filter((name) => !name.startsWith("_"));
3269
+ const guideNames = (await fsPromise2.readdir(`${getDirname(import.meta.url)}/src/guidelines`)).filter(
3270
+ (name) => !name.startsWith("_")
3271
+ );
3266
3272
  return await select4({ message: "Select a guideline", choices: guideNames.map((name) => ({ name, value: name })) });
3267
3273
  }
3268
3274
  static async getGuideJson(guideName) {
3269
- const filePath = `${__dirname}/src/guidelines/${guideName}/${guideName}.generate.json`;
3275
+ const filePath = `${getDirname(import.meta.url)}/src/guidelines/${guideName}/${guideName}.generate.json`;
3270
3276
  const guideJson = await fsPromise2.readFile(filePath, "utf-8");
3271
3277
  return JSON.parse(guideJson);
3272
3278
  }
3273
3279
  static async getInstruction(guideName) {
3274
- const filePath = `${__dirname}/src/guidelines/${guideName}/${guideName}.instruction.md`;
3280
+ const filePath = `${getDirname(import.meta.url)}/src/guidelines/${guideName}/${guideName}.instruction.md`;
3275
3281
  const content = await fsPromise2.readFile(filePath, "utf-8");
3276
3282
  return content;
3277
3283
  }
@@ -3295,7 +3301,7 @@ ${request}
3295
3301
  `;
3296
3302
  }
3297
3303
  async getDocumentation(guideName) {
3298
- const filePath = `${__dirname}/src/guidelines/${guideName}/${guideName}.instruction.md`;
3304
+ const filePath = `${getDirname(import.meta.url)}/src/guidelines/${guideName}/${guideName}.instruction.md`;
3299
3305
  const document = await fsPromise2.readFile(filePath, "utf-8");
3300
3306
  return `\`\`\`markdown
3301
3307
  ${document}
@@ -3304,6 +3310,24 @@ ${document}
3304
3310
  }
3305
3311
  };
3306
3312
 
3313
+ // pkgs/@akanjs/devkit/src/useStdoutDimensions.ts
3314
+ import { useStdout } from "ink";
3315
+ import { useEffect, useState } from "react";
3316
+ var useStdoutDimensions = () => {
3317
+ const { stdout } = useStdout();
3318
+ const [dimensions, setDimensions] = useState([stdout.columns, stdout.rows]);
3319
+ useEffect(() => {
3320
+ const handler = () => {
3321
+ setDimensions([stdout.columns, stdout.rows]);
3322
+ };
3323
+ stdout.on("resize", handler);
3324
+ return () => {
3325
+ stdout.off("resize", handler);
3326
+ };
3327
+ }, [stdout]);
3328
+ return dimensions;
3329
+ };
3330
+
3307
3331
  // pkgs/@akanjs/cli/src/library/library.runner.ts
3308
3332
  import { compareVersions } from "compare-versions";
3309
3333
  import dotenv2 from "dotenv";
@@ -3452,11 +3476,343 @@ import fsPromise3 from "fs/promises";
3452
3476
  import yaml2 from "js-yaml";
3453
3477
  import openBrowser from "open";
3454
3478
  import ora3 from "ora";
3455
- import path7 from "path";
3479
+ import path8 from "path";
3456
3480
  import * as vite from "vite";
3457
3481
  import commonjs from "vite-plugin-commonjs";
3458
3482
  import { nodePolyfills } from "vite-plugin-node-polyfills";
3459
3483
  import tsconfigPaths from "vite-tsconfig-paths";
3484
+
3485
+ // pkgs/@akanjs/cli/src/application/appilcation.interface.tsx
3486
+ import { Box as Box3, render, Text as Text3 } from "ink";
3487
+ import React3, { useEffect as useEffect4, useState as useState4 } from "react";
3488
+
3489
+ // pkgs/@akanjs/cli/ui/ScrollList.tsx
3490
+ import { Box, Newline, Text, useInput } from "ink";
3491
+ import React, { useEffect as useEffect2, useState as useState2 } from "react";
3492
+ var ScrollList = ({ list, ...props }) => {
3493
+ const [renderLogs, setRenderLogs] = useState2(list);
3494
+ const [width, height] = useStdoutDimensions();
3495
+ const [scrollPos, setScrollPos] = useState2(0);
3496
+ const [isRunning, setIsRunning] = useState2(false);
3497
+ const [boxHeight, setBoxHeight] = useState2(height - 3);
3498
+ useInput((input6, key) => {
3499
+ if (key.escape) {
3500
+ setIsRunning(false);
3501
+ setScrollPos(0);
3502
+ }
3503
+ if (input6 === " " && isRunning) {
3504
+ setIsRunning(false);
3505
+ setScrollPos(0);
3506
+ }
3507
+ if (key.downArrow && scrollPos > 0) {
3508
+ if (key.shift) {
3509
+ setScrollPos(scrollPos - 10);
3510
+ } else {
3511
+ setScrollPos(scrollPos - 1);
3512
+ }
3513
+ }
3514
+ if (key.upArrow && scrollPos < list.length - boxHeight) {
3515
+ if (key.shift) {
3516
+ setScrollPos(scrollPos + 10);
3517
+ } else {
3518
+ setScrollPos(scrollPos + 1);
3519
+ }
3520
+ }
3521
+ });
3522
+ useEffect2(() => {
3523
+ if (isRunning) {
3524
+ setScrollPos(scrollPos + 1);
3525
+ return;
3526
+ }
3527
+ if (list.length > boxHeight) {
3528
+ setRenderLogs(list.slice(list.length - boxHeight, list.length));
3529
+ } else {
3530
+ setRenderLogs(list);
3531
+ }
3532
+ }, [list, isRunning]);
3533
+ useEffect2(() => {
3534
+ setBoxHeight(Math.floor(height * 0.9));
3535
+ }, [height]);
3536
+ useEffect2(() => {
3537
+ if (scrollPos > 0) {
3538
+ setRenderLogs(list.slice(list.length - boxHeight - scrollPos, list.length - scrollPos));
3539
+ setIsRunning(true);
3540
+ } else {
3541
+ setRenderLogs(list.slice(list.length - boxHeight, list.length));
3542
+ setIsRunning(false);
3543
+ }
3544
+ }, [scrollPos]);
3545
+ return /* @__PURE__ */ React.createElement(Box, { ...props, width, height: "100%", flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { borderStyle: "round", width, height: height - 3 }, /* @__PURE__ */ React.createElement(Newline, null), /* @__PURE__ */ React.createElement(Text, null, isRunning ? /* @__PURE__ */ React.createElement(React.Fragment, null, renderLogs.slice(0, renderLogs.length - 1).map((log, index) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { key: index }, log), /* @__PURE__ */ React.createElement(Newline, null))), /* @__PURE__ */ React.createElement(Text, { backgroundColor: "green" }, "scrolling... + ", scrollPos)) : /* @__PURE__ */ React.createElement(React.Fragment, null, renderLogs.map((log, index) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { key: index }, log), /* @__PURE__ */ React.createElement(Newline, null)))))), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "You can use the following shortcuts:", /* @__PURE__ */ React.createElement(Newline, null), "* ", /* @__PURE__ */ React.createElement(Text, { backgroundColor: "green" }, "up"), " and ", /* @__PURE__ */ React.createElement(Text, { backgroundColor: "green" }, "down"), " to scroll.", " ", /* @__PURE__ */ React.createElement(Text, { backgroundColor: "green" }, "shift"), " to scroll faster.", /* @__PURE__ */ React.createElement(Newline, null), "* ", /* @__PURE__ */ React.createElement(Text, { backgroundColor: "green" }, "escape"), " to stop scrolling.")));
3546
+ };
3547
+
3548
+ // pkgs/@akanjs/cli/ui/MultiScrollList.tsx
3549
+ import { Box as Box2, Newline as Newline2, Text as Text2, useInput as useInput2 } from "ink";
3550
+ import React2, { useEffect as useEffect3, useState as useState3 } from "react";
3551
+ var MultiScrollList = ({ logList }) => {
3552
+ const [width, height] = useStdoutDimensions();
3553
+ const [renderMultiLogs, setRenderMultiLogs] = useState3(
3554
+ Array.from({ length: logList.length }, () => [])
3555
+ );
3556
+ const [lengthMap, setLengthMap] = useState3(/* @__PURE__ */ new Map());
3557
+ const [scrollPos, setScrollPos] = useState3(0);
3558
+ const [tabIndex, setTabIndex] = useState3(null);
3559
+ const [isRunning, setIsRunning] = useState3(false);
3560
+ const [boxHeight, setBoxHeight] = useState3(height - 7);
3561
+ useInput2((input6, key) => {
3562
+ if (key.tab) {
3563
+ if (tabIndex === null) {
3564
+ setTabIndex(0);
3565
+ } else {
3566
+ setTabIndex((prev) => (prev + 1) % logList.length);
3567
+ setIsRunning(false);
3568
+ }
3569
+ }
3570
+ if (key.escape) {
3571
+ setScrollPos(0);
3572
+ if (tabIndex !== null)
3573
+ setTabIndex(null);
3574
+ setIsRunning(false);
3575
+ }
3576
+ if (input6 === " ") {
3577
+ setScrollPos(0);
3578
+ setIsRunning(false);
3579
+ }
3580
+ if (key.downArrow && scrollPos > 0) {
3581
+ if (key.shift) {
3582
+ const newScrollPos = scrollPos - 10;
3583
+ if (newScrollPos < 0) {
3584
+ setScrollPos(0);
3585
+ } else {
3586
+ setScrollPos(newScrollPos);
3587
+ }
3588
+ } else {
3589
+ const newScrollPos = scrollPos - 1;
3590
+ setScrollPos(newScrollPos);
3591
+ }
3592
+ }
3593
+ if (key.upArrow && tabIndex !== null && scrollPos < logList[tabIndex].logs.length - boxHeight) {
3594
+ if (key.shift) {
3595
+ const newScrollPos = scrollPos + 10;
3596
+ if (newScrollPos > logList[tabIndex].logs.length - boxHeight) {
3597
+ setScrollPos(logList[tabIndex].logs.length - boxHeight);
3598
+ } else {
3599
+ setScrollPos(newScrollPos);
3600
+ }
3601
+ } else {
3602
+ setScrollPos(scrollPos + 1);
3603
+ }
3604
+ if (!isRunning)
3605
+ setIsRunning(true);
3606
+ }
3607
+ });
3608
+ useEffect3(() => {
3609
+ const getLogsToRender = (logs, index) => {
3610
+ if (scrollPos > 0 && tabIndex === index) {
3611
+ return logs.slice(logs.length - boxHeight - scrollPos, logs.length - scrollPos);
3612
+ } else if (logs.length > boxHeight) {
3613
+ return logs.slice(logs.length - boxHeight, logs.length);
3614
+ } else {
3615
+ return logs;
3616
+ }
3617
+ };
3618
+ if (isRunning) {
3619
+ if (tabIndex !== null && lengthMap.has(tabIndex)) {
3620
+ const tabLength = lengthMap.get(tabIndex);
3621
+ if (tabLength && tabLength < logList[tabIndex].logs.length) {
3622
+ setScrollPos(scrollPos + 1);
3623
+ lengthMap.set(tabIndex, logList[tabIndex].logs.length);
3624
+ }
3625
+ }
3626
+ setRenderMultiLogs((prev) => {
3627
+ const newState = [...prev];
3628
+ logList.forEach((logData, index) => {
3629
+ newState[index] = getLogsToRender(logData.logs, index);
3630
+ });
3631
+ return newState;
3632
+ });
3633
+ } else {
3634
+ setRenderMultiLogs((prev) => {
3635
+ const newState = [...prev];
3636
+ logList.forEach((logData, index) => {
3637
+ lengthMap.set(index, logData.logs.length);
3638
+ newState[index] = getLogsToRender(logData.logs, index);
3639
+ });
3640
+ return newState;
3641
+ });
3642
+ }
3643
+ }, [logList, isRunning, scrollPos, tabIndex, boxHeight]);
3644
+ useEffect3(() => {
3645
+ setBoxHeight(height - 7);
3646
+ }, [height]);
3647
+ useEffect3(() => {
3648
+ setLengthMap(new Map(logList.map((log, index) => [index, log.logs.length])));
3649
+ }, []);
3650
+ return /* @__PURE__ */ React2.createElement(Box2, { width, height, flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Box2, { width, height: "100%" }, renderMultiLogs.map((logData, index) => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Box2, { width, height: "100%", flexDirection: "column", key: index }, /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: logList[index].color }, logList[index].title)), /* @__PURE__ */ React2.createElement(
3651
+ Box2,
3652
+ {
3653
+ flexWrap: "wrap",
3654
+ height,
3655
+ borderStyle: index === tabIndex ? "double" : "round",
3656
+ borderDimColor: index !== tabIndex,
3657
+ borderColor: index === tabIndex && isRunning ? "green" : logList[index].color
3658
+ },
3659
+ /* @__PURE__ */ React2.createElement(Text2, null, isRunning && tabIndex === index ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, logData.slice(0, logData.length - 1).map((log, index2) => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text2, { key: index2 }, log), /* @__PURE__ */ React2.createElement(Newline2, null))), /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "scrolling... +", scrollPos)) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, logData.map((data, index2) => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text2, { key: index2 }, data), /* @__PURE__ */ React2.createElement(Newline2, null)))))
3660
+ ))))), /* @__PURE__ */ React2.createElement(Box2, { width, height: "auto" }, /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, /* @__PURE__ */ React2.createElement(Text2, null, "You can use the following shortcuts:"), /* @__PURE__ */ React2.createElement(Newline2, null), "* ", /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "tab"), " to switch tab.", /* @__PURE__ */ React2.createElement(Newline2, null), "* ", /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "space"), " to scroll.", /* @__PURE__ */ React2.createElement(Newline2, null), "* ", /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "up"), " and ", /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "down"), " to scroll.", " ", /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "shift"), " to scroll faster.", /* @__PURE__ */ React2.createElement(Newline2, null), "* ", /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "green" }, "escape"), " to stop scrolling.")));
3661
+ };
3662
+
3663
+ // pkgs/@akanjs/cli/src/application/appilcation.interface.tsx
3664
+ var Backend = ({ app, env }) => {
3665
+ const [logs, setLogs] = useState4([]);
3666
+ const [width, height] = useStdoutDimensions();
3667
+ useEffect4(() => {
3668
+ const proc = app.dist.spawnSync("node", ["--watch", "backend/main.js"], {
3669
+ env,
3670
+ stdio: "pipe"
3671
+ });
3672
+ proc.stdout?.on("data", (data) => {
3673
+ const newOutput = data.toString().split("\n");
3674
+ setLogs((prevLogs) => [...prevLogs, ...newOutput]);
3675
+ });
3676
+ proc.stderr?.on("data", (data) => {
3677
+ const newOutput = data.toString().split("\n");
3678
+ setLogs((prevLogs) => [...prevLogs, ...newOutput]);
3679
+ });
3680
+ return () => {
3681
+ proc.kill();
3682
+ };
3683
+ }, []);
3684
+ return /* @__PURE__ */ React3.createElement(Box3, { width, height }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Akan.JS Backend"));
3685
+ };
3686
+ var Frontend = ({ app, env }) => {
3687
+ const [logs, setLogs] = useState4([]);
3688
+ const [width, height] = useStdoutDimensions();
3689
+ useEffect4(() => {
3690
+ const proc = app.spawnSync("npx", ["next", "dev", "-p", "4200"], {
3691
+ env,
3692
+ stdio: ["ignore", "pipe", "pipe"],
3693
+ detached: true
3694
+ });
3695
+ proc.stdout?.on("data", (data) => {
3696
+ const newOutput = data.toString().split("\n");
3697
+ setLogs((prevLogs) => [...prevLogs, ...newOutput]);
3698
+ });
3699
+ proc.stderr?.on("data", (data) => {
3700
+ const newOutput = data.toString().split("\n");
3701
+ setLogs((prevLogs) => [...prevLogs, ...newOutput]);
3702
+ });
3703
+ return () => {
3704
+ proc.kill();
3705
+ };
3706
+ }, []);
3707
+ return /* @__PURE__ */ React3.createElement(Box3, { width, height, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Akan.JS Frontend"), logs.map((log) => /* @__PURE__ */ React3.createElement(Text3, { key: log }, log)));
3708
+ };
3709
+ var Csr = ({
3710
+ app,
3711
+ onLoad
3712
+ }) => {
3713
+ const [logs, setLogs] = useState4([]);
3714
+ const [width, height] = useStdoutDimensions();
3715
+ useEffect4(() => {
3716
+ void onLoad({
3717
+ onLog: (log) => {
3718
+ setLogs((prevLogs) => [...prevLogs, log]);
3719
+ }
3720
+ });
3721
+ }, []);
3722
+ return /* @__PURE__ */ React3.createElement(Box3, { width, height, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Akan.JS CSR"), /* @__PURE__ */ React3.createElement(ScrollList, { list: logs }));
3723
+ };
3724
+ var Start = ({
3725
+ app,
3726
+ backendEnv,
3727
+ frontendEnv,
3728
+ onLoadCsr
3729
+ }) => {
3730
+ const [width, height] = useStdoutDimensions();
3731
+ const [csrLogs, setCsrLogs] = useState4([]);
3732
+ const [backendLogs, setBackendLogs] = useState4([]);
3733
+ const [frontendLogs, setFrontendLogs] = useState4([]);
3734
+ useEffect4(() => {
3735
+ const backend = app.dist.spawnSync("node", ["--watch", "backend/main.js"], {
3736
+ stdio: ["ignore", "pipe", "pipe"],
3737
+ // stdin은 무시
3738
+ env: backendEnv,
3739
+ detached: true
3740
+ });
3741
+ const frontend = app.spawnSync("npx", ["next", "dev", "-p", "4200"], {
3742
+ stdio: ["ignore", "pipe", "pipe"],
3743
+ // stdin은 무시
3744
+ env: frontendEnv,
3745
+ detached: true
3746
+ });
3747
+ backend.stdout?.on("data", (data) => {
3748
+ const newOutput = data.toString().split("\n");
3749
+ setBackendLogs((currentLogs) => [
3750
+ ...currentLogs,
3751
+ ...newOutput.map((line) => ({ type: "stdout", content: line }))
3752
+ ]);
3753
+ });
3754
+ backend.stderr?.on("data", (data) => {
3755
+ const newOutput = data.toString().split("\n");
3756
+ setBackendLogs((currentLogs) => [
3757
+ ...currentLogs,
3758
+ ...newOutput.map((line) => ({ type: "stderr", content: line }))
3759
+ ]);
3760
+ });
3761
+ frontend.stdout?.on("data", (data) => {
3762
+ const newOutput = data.toString().split("\n");
3763
+ setFrontendLogs((currentLogs) => [
3764
+ ...currentLogs,
3765
+ ...newOutput.map((line) => ({ type: "stdout", content: line }))
3766
+ ]);
3767
+ });
3768
+ frontend.stderr?.on("data", (data) => {
3769
+ const newOutput = data.toString().split("\n");
3770
+ setFrontendLogs((currentLogs) => [
3771
+ ...currentLogs,
3772
+ ...newOutput.map((line) => ({ type: "stderr", content: line }))
3773
+ ]);
3774
+ });
3775
+ void onLoadCsr({
3776
+ onLog: (log) => {
3777
+ setCsrLogs((prevLogs) => [...prevLogs, { type: "stdout", content: log }]);
3778
+ }
3779
+ });
3780
+ return () => {
3781
+ backend.kill();
3782
+ frontend.kill();
3783
+ };
3784
+ }, []);
3785
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(Box3, { borderColor: "#ff493b", height, width, flexDirection: "row" }, /* @__PURE__ */ React3.createElement(
3786
+ MultiScrollList,
3787
+ {
3788
+ logList: [
3789
+ {
3790
+ title: `${app.name} frontend`,
3791
+ logs: frontendLogs.map((log) => log.content),
3792
+ color: "#ff493b"
3793
+ },
3794
+ {
3795
+ title: `${app.name} backend`,
3796
+ logs: backendLogs.map((log) => log.content),
3797
+ color: "#e535ab"
3798
+ },
3799
+ {
3800
+ title: `${app.name} react`,
3801
+ logs: csrLogs.map((log) => log.content),
3802
+ color: "#7cc5d9"
3803
+ }
3804
+ ]
3805
+ }
3806
+ )));
3807
+ };
3808
+ var Interface = {
3809
+ Csr: (app, onLoad) => render(/* @__PURE__ */ React3.createElement(Csr, { app, onLoad })),
3810
+ Backend: (app, env) => render(/* @__PURE__ */ React3.createElement(Backend, { app, env })),
3811
+ Frontend: (app, env) => render(/* @__PURE__ */ React3.createElement(Frontend, { app, env })),
3812
+ Start: (app, backendEnv, frontendEnv, onLoadCsr) => render(/* @__PURE__ */ React3.createElement(Start, { app, backendEnv, frontendEnv, onLoadCsr }))
3813
+ };
3814
+
3815
+ // pkgs/@akanjs/cli/src/application/application.runner.ts
3460
3816
  var ApplicationRunner = class {
3461
3817
  async createApplication(appName, workspace) {
3462
3818
  await workspace.applyTemplate({
@@ -3484,6 +3840,34 @@ var ApplicationRunner = class {
3484
3840
  await app.syncAssets(scanResult.akanConfig.libs);
3485
3841
  return scanResult;
3486
3842
  }
3843
+ async start(app) {
3844
+ const { env: frontendEnv } = await this.#prepareCommand(app, "start", "frontend");
3845
+ const { env: backendEnv } = await this.#prepareCommand(app, "start", "backend");
3846
+ Interface.Start(app, backendEnv, frontendEnv, async ({ onLog }) => {
3847
+ const config = await this.#getViteConfig(app, "start", {
3848
+ customLogger: {
3849
+ info: (msg) => {
3850
+ onLog(msg);
3851
+ },
3852
+ warn: (msg) => {
3853
+ },
3854
+ warnOnce: (msg) => {
3855
+ },
3856
+ error: (msg) => {
3857
+ onLog(msg);
3858
+ },
3859
+ clearScreen: (type) => {
3860
+ },
3861
+ hasErrorLogged: (error) => {
3862
+ return false;
3863
+ },
3864
+ hasWarned: false
3865
+ }
3866
+ });
3867
+ const server = await vite.createServer(config);
3868
+ await server.listen(4201);
3869
+ });
3870
+ }
3487
3871
  async getScriptFilename(app) {
3488
3872
  if (!app.exists("scripts")) {
3489
3873
  app.mkdir("scripts");
@@ -3531,8 +3915,6 @@ var ApplicationRunner = class {
3531
3915
  app.writeFile("next.config.ts", defaultNextConfigFile);
3532
3916
  } else if (target === "csr")
3533
3917
  await app.workspace.exec("rm -rf node_modules/.vite");
3534
- else if (target === "backend")
3535
- await app.cp("assets", path7.join(app.dist.cwdPath, "backend", "assets"));
3536
3918
  return { env: this.#getEnv(app, { AKAN_COMMAND_TYPE: type }) };
3537
3919
  }
3538
3920
  async buildBackend(app) {
@@ -3561,7 +3943,7 @@ var ApplicationRunner = class {
3561
3943
  dependencies
3562
3944
  };
3563
3945
  app.dist.writeJson("backend/package.json", appPackageJson);
3564
- app.dist.writeFile(path7.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
3946
+ app.dist.writeFile(path8.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
3565
3947
  }
3566
3948
  async startBackend(app, { open: open2 = false, onStart } = {}) {
3567
3949
  const { env } = await this.#prepareCommand(app, "start", "backend");
@@ -3572,7 +3954,7 @@ var ApplicationRunner = class {
3572
3954
  packages: "external",
3573
3955
  platform: "node",
3574
3956
  format: "cjs",
3575
- outdir: path7.join(app.dist.cwdPath, "backend"),
3957
+ outdir: path8.join(app.dist.cwdPath, "backend"),
3576
3958
  logLevel: "warning"
3577
3959
  });
3578
3960
  await ctx.watch();
@@ -3592,10 +3974,10 @@ var ApplicationRunner = class {
3592
3974
  bundle: true,
3593
3975
  packages: "external",
3594
3976
  platform: "node",
3595
- format: "cjs",
3977
+ format: "esm",
3596
3978
  write: false,
3597
- logLevel: "warning",
3598
- footer: { js: "module.exports = module.exports.default;" }
3979
+ logLevel: "warning"
3980
+ // footer: { js: "module.exports = module.exports.default;" },
3599
3981
  });
3600
3982
  const rootPackageJson = app.workspace.readJson("package.json");
3601
3983
  const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
@@ -3610,8 +3992,8 @@ var ApplicationRunner = class {
3610
3992
  };
3611
3993
  app.dist.writeJson("frontend/package.json", appPackageJson);
3612
3994
  await Promise.all([
3613
- app.cp(".next", path7.join(app.dist.cwdPath, "frontend", ".next")),
3614
- app.cp("public", path7.join(app.dist.cwdPath, "frontend", "public"))
3995
+ app.cp(".next", path8.join(app.dist.cwdPath, "frontend", ".next")),
3996
+ app.cp("public", path8.join(app.dist.cwdPath, "frontend", "public"))
3615
3997
  ]);
3616
3998
  app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
3617
3999
  }
@@ -3622,7 +4004,7 @@ var ApplicationRunner = class {
3622
4004
  onStart?.();
3623
4005
  await app.spawn("npx", ["next", "dev", "-p", "4200", ...turbo ? ["--turbo"] : []], { env, stdio: "inherit" });
3624
4006
  }
3625
- async #getViteConfig(app, command) {
4007
+ async #getViteConfig(app, command, viteConfig = {}) {
3626
4008
  const { env } = await this.#prepareCommand(app, command, "csr");
3627
4009
  const tsconfig = app.workspace.getTsConfig();
3628
4010
  const akanConfig = await app.getConfig();
@@ -3630,6 +4012,7 @@ var ApplicationRunner = class {
3630
4012
  const processEnv = env;
3631
4013
  const akanjsPrefix = process.env.USE_AKANJS_PKGS === "true" ? `${app.workspace.workspaceRoot}/pkgs/` : "";
3632
4014
  const config = vite.defineConfig({
4015
+ ...viteConfig,
3633
4016
  root: `${app.cwdPath}/app`,
3634
4017
  base: "/",
3635
4018
  build: {
@@ -3647,6 +4030,8 @@ var ApplicationRunner = class {
3647
4030
  react(),
3648
4031
  tsconfigPaths(),
3649
4032
  commonjs(),
4033
+ //? A postCSS 어쩌구 에러 제거하는 방법인데 적용시 tailwind가 망가져버림.
4034
+ // tailwindcss(),
3650
4035
  nodePolyfills({
3651
4036
  exclude: ["fs"],
3652
4037
  include: ["crypto", "process", "stream", "util"],
@@ -3705,12 +4090,36 @@ var ApplicationRunner = class {
3705
4090
  const config = await this.#getViteConfig(app, "build");
3706
4091
  await vite.build(config);
3707
4092
  }
3708
- async startCsr(app, { open: open2 = false, onStart } = {}) {
3709
- const config = await this.#getViteConfig(app, "start");
3710
- const server = await vite.createServer(config);
3711
- await server.listen(4201);
4093
+ startCsr(app, { open: open2 = false, onStart } = {}) {
4094
+ Interface.Csr(app, async ({ onLog }) => {
4095
+ const config = await this.#getViteConfig(app, "start", {
4096
+ customLogger: {
4097
+ info: (msg) => {
4098
+ onLog(msg);
4099
+ },
4100
+ warn: (msg) => {
4101
+ onLog(msg);
4102
+ },
4103
+ warnOnce: (msg) => {
4104
+ onLog(msg);
4105
+ },
4106
+ error: (msg) => {
4107
+ onLog(msg);
4108
+ },
4109
+ clearScreen: (type) => {
4110
+ onLog(type);
4111
+ },
4112
+ hasErrorLogged: (error) => {
4113
+ return false;
4114
+ },
4115
+ hasWarned: false
4116
+ }
4117
+ });
4118
+ const env = this.#prepareCommand(app, "start", "csr");
4119
+ const server = await vite.createServer(config);
4120
+ await server.listen(4201);
4121
+ });
3712
4122
  onStart?.();
3713
- app.log(`CSR server is running on http://localhost:4201`);
3714
4123
  if (open2)
3715
4124
  setTimeout(() => openBrowser("http://localhost:4201"), 3e3);
3716
4125
  }
@@ -3846,8 +4255,8 @@ var ApplicationRunner = class {
3846
4255
  )
3847
4256
  );
3848
4257
  await Promise.all(
3849
- [".next", "ios", "android", "public/libs"].map(async (path9) => {
3850
- const targetPath = `${sourceRoot}/apps/${app.name}/${path9}`;
4258
+ [".next", "ios", "android", "public/libs"].map(async (path10) => {
4259
+ const targetPath = `${sourceRoot}/apps/${app.name}/${path10}`;
3851
4260
  if (fs14.existsSync(targetPath))
3852
4261
  await fsPromise3.rm(targetPath, { recursive: true, force: true });
3853
4262
  })
@@ -3865,7 +4274,7 @@ var ApplicationRunner = class {
3865
4274
  ];
3866
4275
  await Promise.all(
3867
4276
  syncPaths.map(
3868
- (path9) => fsPromise3.cp(`${app.workspace.cwdPath}/${path9}`, `${sourceRoot}/${path9}`, { recursive: true })
4277
+ (path10) => fsPromise3.cp(`${app.workspace.cwdPath}/${path10}`, `${sourceRoot}/${path10}`, { recursive: true })
3869
4278
  )
3870
4279
  );
3871
4280
  const tsconfig = app.workspace.readJson("tsconfig.json");
@@ -4006,11 +4415,7 @@ var ApplicationScript = class {
4006
4415
  await this.syncApplication(app);
4007
4416
  if (app.workspace.getBaseDevEnv().env === "local")
4008
4417
  await this.dbup(app.workspace);
4009
- await Promise.all([
4010
- this.startBackend(app, { open: open2, sync: false }),
4011
- this.startFrontend(app, { open: open2, sync: false }),
4012
- this.startCsr(app, { open: open2, sync: false })
4013
- ]);
4418
+ await this.#runner.start(app);
4014
4419
  }
4015
4420
  async buildBackend(app, { sync = true } = {}) {
4016
4421
  if (sync)
@@ -4070,11 +4475,9 @@ var ApplicationScript = class {
4070
4475
  async startCsr(app, { open: open2 = false, sync = true } = {}) {
4071
4476
  if (sync)
4072
4477
  await this.syncApplication(app);
4073
- const spinner = app.spinning("Preparing CSR...");
4074
- await this.#runner.startCsr(app, {
4478
+ this.#runner.startCsr(app, {
4075
4479
  open: open2,
4076
4480
  onStart: () => {
4077
- spinner.succeed(`CSR prepared, ready to start`);
4078
4481
  }
4079
4482
  });
4080
4483
  }
@@ -4242,6 +4645,10 @@ var ApplicationCommand = class {
4242
4645
  async test(sys3) {
4243
4646
  await this.applicationScript.testSys(sys3);
4244
4647
  }
4648
+ // @Target.Public()
4649
+ // ink(@Workspace() workspace: Workspace) {
4650
+ // run();
4651
+ // }
4245
4652
  };
4246
4653
  __decorateClass([
4247
4654
  Target.Public(),
@@ -4571,15 +4978,6 @@ ${chalk6.green("\u27A4")} Authentication Required`));
4571
4978
  Logger.info("All libraries are published to npm");
4572
4979
  }
4573
4980
  async update(workspace) {
4574
- if (!workspace.exists("package.json"))
4575
- await workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]);
4576
- else
4577
- await Promise.all([
4578
- workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
4579
- this.#updateAkanPkgs(workspace)
4580
- ]);
4581
- }
4582
- async #updateAkanPkgs(workspace) {
4583
4981
  const latestPublishedVersionOfBase = await latestVersion("@akanjs/base");
4584
4982
  const rootPackageJson = workspace.readJson("package.json");
4585
4983
  if (!rootPackageJson.dependencies)
@@ -4593,7 +4991,10 @@ ${chalk6.green("\u27A4")} Authentication Required`));
4593
4991
  Object.assign(rootPackageJson.devDependencies ?? {}, { [dependency]: latestPublishedVersionOfBase });
4594
4992
  });
4595
4993
  workspace.writeJson("package.json", rootPackageJson);
4596
- await workspace.spawn("pnpm", ["install"]);
4994
+ await Promise.all([
4995
+ workspace.spawn("npm", ["update", "-g", "@akanjs/cli", "--latest"]),
4996
+ workspace.spawn("pnpm", ["install"])
4997
+ ]);
4597
4998
  }
4598
4999
  };
4599
5000
 
@@ -5249,9 +5650,13 @@ var ModuleScript = class {
5249
5650
  // pkgs/@akanjs/cli/src/module/module.command.ts
5250
5651
  var ModuleCommand = class {
5251
5652
  moduleScript = new ModuleScript();
5252
- async createModule(moduleName, sys3) {
5653
+ async createModule(sys3, moduleName, description, schemaDescription, ai) {
5253
5654
  const name = lowerlize(moduleName.replace(/ /g, ""));
5254
- await this.moduleScript.createModuleTemplate(sys3, name);
5655
+ if (ai) {
5656
+ await this.moduleScript.createModule(sys3, name, description, schemaDescription);
5657
+ } else {
5658
+ await this.moduleScript.createModuleTemplate(sys3, name);
5659
+ }
5255
5660
  }
5256
5661
  removeModule(module) {
5257
5662
  this.moduleScript.removeModule(module);
@@ -5268,8 +5673,11 @@ var ModuleCommand = class {
5268
5673
  };
5269
5674
  __decorateClass([
5270
5675
  Target.Public(),
5271
- __decorateParam(0, Argument("moduleName", { desc: "name of module" })),
5272
- __decorateParam(1, Sys())
5676
+ __decorateParam(0, Sys()),
5677
+ __decorateParam(1, Argument("moduleName", { desc: "name of module" })),
5678
+ __decorateParam(2, Option("description", { desc: "description of module" })),
5679
+ __decorateParam(3, Option("schemaDescription", { desc: "schema description of module" })),
5680
+ __decorateParam(4, Option("ai", { type: "boolean", default: false, desc: "use ai to create module" }))
5273
5681
  ], ModuleCommand.prototype, "createModule", 1);
5274
5682
  __decorateClass([
5275
5683
  Target.Public(),
@@ -5366,12 +5774,12 @@ PageCommand = __decorateClass([
5366
5774
 
5367
5775
  // pkgs/@akanjs/cli/src/workspace/workspace.runner.ts
5368
5776
  import latestVersion2 from "latest-version";
5369
- import path8 from "path";
5777
+ import path9 from "path";
5370
5778
  import { v5 as uuid } from "uuid";
5371
5779
  var WorkspaceRunner = class {
5372
5780
  async createWorkspace(repoName, appName, dirname3 = ".") {
5373
5781
  const cwdPath = process.cwd();
5374
- const workspaceRoot = path8.join(cwdPath, dirname3, repoName);
5782
+ const workspaceRoot = path9.join(cwdPath, dirname3, repoName);
5375
5783
  const workspace = new WorkspaceExecutor({ workspaceRoot, repoName });
5376
5784
  const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname3}/${repoName}...`);
5377
5785
  await workspace.applyTemplate({
@@ -5569,15 +5977,15 @@ var GuidelinePrompt = class extends Prompter {
5569
5977
  async #getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
5570
5978
  const matchingPaths = fsPromise5.glob(matchPattern, {
5571
5979
  cwd: this.workspace.workspaceRoot,
5572
- exclude: (path9) => avoidDirs.some((dir) => path9.includes(dir))
5980
+ exclude: (path10) => avoidDirs.some((dir) => path10.includes(dir))
5573
5981
  });
5574
5982
  const paths = [];
5575
- for await (const path9 of matchingPaths) {
5576
- const fileContent = fs16.readFileSync(path9, "utf-8");
5983
+ for await (const path10 of matchingPaths) {
5984
+ const fileContent = fs16.readFileSync(path10, "utf-8");
5577
5985
  const textFilter = filterText ? new RegExp(filterText) : null;
5578
5986
  if (filterText && !textFilter?.test(fileContent))
5579
5987
  continue;
5580
- paths.push(path9);
5988
+ paths.push(path10);
5581
5989
  }
5582
5990
  return paths;
5583
5991
  }
@@ -5590,7 +5998,7 @@ var GuidelinePrompt = class extends Prompter {
5590
5998
  const scanResult = targetFilePaths.map((filePath) => ({ ...scan, ...this.workspace.getLocalFile(filePath) }));
5591
5999
  scanFiles.push(...scanResult);
5592
6000
  }
5593
- const resultPath = `${__dirname}/src/guidelines/${this.name}/${guideJson.update.filePath}`;
6001
+ const resultPath = `${getDirname(import.meta.url)}/src/guidelines/${this.name}/${guideJson.update.filePath}`;
5594
6002
  const writePath = `${this.workspace.workspaceRoot}/pkgs/@akanjs/cli/src/guidelines/${this.name}/${guideJson.update.filePath}`;
5595
6003
  const isResultExists = this.workspace.exists(writePath);
5596
6004
  const existingResult = isResultExists ? this.workspace.readFile(resultPath) : null;
@@ -5632,7 +6040,7 @@ ${guideJson.update.rules.map((rule) => `- ${rule}`).join("\n")}
5632
6040
  }
5633
6041
  async requestUpdateInstruction(updateRequest) {
5634
6042
  const guideJson = await Prompter.getGuideJson(this.name);
5635
- const resultPath = `${__dirname}/src/guidelines/${this.name}/${guideJson.update.filePath}`;
6043
+ const resultPath = `${getDirname(import.meta.url)}/src/guidelines/${this.name}/${guideJson.update.filePath}`;
5636
6044
  const writePath = `${this.workspace.workspaceRoot}/pkgs/@akanjs/cli/src/guidelines/${this.name}/${guideJson.update.filePath}`;
5637
6045
  const isResultExists = this.workspace.exists(writePath);
5638
6046
  if (!isResultExists)
@@ -6079,7 +6487,7 @@ ScalarCommand = __decorateClass([
6079
6487
  ], ScalarCommand);
6080
6488
 
6081
6489
  // pkgs/@akanjs/cli/index.ts
6082
- __require("dotenv").config({ path: `${process.cwd()}/.env` });
6490
+ dotenv4.config({ path: `${process.cwd()}/.env` });
6083
6491
  void runCommands(
6084
6492
  WorkspaceCommand,
6085
6493
  ApplicationCommand,