@h-ai/cli 0.1.0-alpha.10 → 0.1.0-alpha.12

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/dist/index.js CHANGED
@@ -2,18 +2,19 @@
2
2
  import { generateConfigFile } from './chunk-LANIDJC7.js';
3
3
  import './chunk-YV7WPUI6.js';
4
4
  import './chunk-2H7UOFLK.js';
5
+ import { readFileSync, existsSync } from 'fs';
6
+ import path2, { resolve } from 'path';
5
7
  import process3 from 'process';
8
+ import { fileURLToPath } from 'url';
6
9
  import { core } from '@h-ai/core';
7
10
  import { cac } from 'cac';
8
11
  import chalk from 'chalk';
9
- import path2, { resolve } from 'path';
12
+ import { createRequire } from 'module';
10
13
  import fse from 'fs-extra';
11
14
  import ora from 'ora';
12
15
  import prompts from 'prompts';
13
16
  import Handlebars from 'handlebars';
14
- import { execSync } from 'child_process';
15
- import { fileURLToPath } from 'url';
16
- import { existsSync, readFileSync } from 'fs';
17
+ import { execSync, execFileSync } from 'child_process';
17
18
  import { parse } from 'yaml';
18
19
 
19
20
  var CAMEL_CASE_SEPARATOR_REGEX = /[-_\s]+(.)?/g;
@@ -79,6 +80,9 @@ function registerHelpers() {
79
80
  });
80
81
  }
81
82
  registerHelpers();
83
+ Handlebars.registerHelper("if_eq", function(a, b, options) {
84
+ return a === b ? options.fn(this) : options.inverse(this);
85
+ });
82
86
  var FEATURE_ROUTE_DIRS = {
83
87
  iam: ["routes-shared"],
84
88
  storage: ["routes"],
@@ -255,6 +259,8 @@ async function renderHbsInDir(dir, destRoot, context) {
255
259
  }
256
260
 
257
261
  // src/commands/create.ts
262
+ var RE_HTTPS_URL = /^https:\/\/.+/;
263
+ var RE_GIT_SSH_URL = /^git@.+:.+/;
258
264
  var APP_TYPES = {
259
265
  "admin": {
260
266
  name: "\u7BA1\u7406\u540E\u53F0",
@@ -497,6 +503,14 @@ async function createProject(options) {
497
503
  if (resolvedOptions.git) {
498
504
  spinner.start("\u521D\u59CB\u5316 Git \u4ED3\u5E93...");
499
505
  execSync("git init", { cwd: projectPath, stdio: "ignore" });
506
+ if (resolvedOptions.gitRemote) {
507
+ const gitRemote = resolvedOptions.gitRemote;
508
+ if (!RE_HTTPS_URL.test(gitRemote) && !RE_GIT_SSH_URL.test(gitRemote)) {
509
+ spinner.fail();
510
+ throw new Error(`Invalid gitRemote URL: ${gitRemote}`);
511
+ }
512
+ execFileSync("git", ["remote", "add", "origin", gitRemote], { cwd: projectPath, stdio: "ignore" });
513
+ }
500
514
  spinner.succeed();
501
515
  }
502
516
  if (resolvedOptions.install) {
@@ -639,6 +653,23 @@ async function resolveOptions(options) {
639
653
  }, { onCancel });
640
654
  git = initGit;
641
655
  }
656
+ let gitRemote = options.gitRemote;
657
+ if (git && gitRemote === void 0) {
658
+ const { remote } = await prompts({
659
+ type: "text",
660
+ name: "remote",
661
+ message: "Git \u4ED3\u5E93\u5730\u5740 (\u53EF\u9009\uFF0C\u56DE\u8F66\u8DF3\u8FC7):",
662
+ initial: "",
663
+ validate: (value) => {
664
+ if (!value.trim())
665
+ return true;
666
+ if (RE_HTTPS_URL.test(value) || RE_GIT_SSH_URL.test(value))
667
+ return true;
668
+ return "\u8BF7\u8F93\u5165\u5408\u6CD5\u7684 Git \u4ED3\u5E93\u5730\u5740 (https://... \u6216 git@...:...)";
669
+ }
670
+ }, { onCancel });
671
+ gitRemote = remote?.trim() || "";
672
+ }
642
673
  return {
643
674
  name: projectName,
644
675
  appType: selectedAppType,
@@ -649,17 +680,25 @@ async function resolveOptions(options) {
649
680
  install: install ?? true,
650
681
  packageManager: packageManager || "pnpm",
651
682
  git: git ?? true,
683
+ gitRemote: gitRemote ?? "",
652
684
  verbose: options.verbose ?? false,
653
685
  cwd: options.cwd ?? "."
654
686
  };
655
687
  }
656
688
  function resolveFeatureDependencies(features) {
657
689
  const result = new Set(features);
658
- for (const featureId of features) {
659
- const feature = FEATURES[featureId];
660
- if (feature?.dependencies) {
661
- for (const dep of feature.dependencies) {
662
- result.add(dep);
690
+ let changed = true;
691
+ while (changed) {
692
+ changed = false;
693
+ for (const featureId of result) {
694
+ const feature = FEATURES[featureId];
695
+ if (feature?.dependencies) {
696
+ for (const dep of feature.dependencies) {
697
+ if (!result.has(dep)) {
698
+ result.add(dep);
699
+ changed = true;
700
+ }
701
+ }
663
702
  }
664
703
  }
665
704
  }
@@ -999,9 +1038,12 @@ async function addModule(options) {
999
1038
  const pkg = await fse.readJson(pkgPath);
1000
1039
  if (!pkg.dependencies)
1001
1040
  pkg.dependencies = {};
1041
+ const require2 = createRequire(import.meta.url);
1042
+ const cliPkg = require2("../../package.json");
1043
+ const depVersion = `^${cliPkg.version}`;
1002
1044
  for (const pkgName of allPackages) {
1003
1045
  if (!pkg.dependencies[pkgName]) {
1004
- pkg.dependencies[pkgName] = "workspace:*";
1046
+ pkg.dependencies[pkgName] = depVersion;
1005
1047
  }
1006
1048
  }
1007
1049
  await fse.writeJson(pkgPath, pkg, { spaces: 2 });
@@ -1551,11 +1593,21 @@ async function initProject(options) {
1551
1593
  }
1552
1594
 
1553
1595
  // src/index.ts
1554
- var VERSION = "0.0.1";
1596
+ function readCliVersion() {
1597
+ try {
1598
+ const here = path2.dirname(fileURLToPath(import.meta.url));
1599
+ const pkgPath = path2.resolve(here, "../package.json");
1600
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
1601
+ return pkg.version ?? "0.0.0";
1602
+ } catch {
1603
+ return "0.0.0";
1604
+ }
1605
+ }
1606
+ var VERSION = readCliVersion();
1555
1607
  var cli = cac("hai");
1556
1608
  cli.option("-v, --verbose", "\u663E\u793A\u8BE6\u7EC6\u8F93\u51FA");
1557
1609
  cli.option("-C, --cwd <path>", "\u5DE5\u4F5C\u76EE\u5F55");
1558
- cli.command("create [name]", "\u521B\u5EFA\u65B0\u7684 hai \u9879\u76EE").option("--type <type>", "\u5E94\u7528\u7C7B\u578B (admin, website, h5, api)").option("-t, --template <template>", "\u9879\u76EE\u6A21\u677F (minimal, default, full, custom)").option("-f, --features <features>", "\u529F\u80FD\u5217\u8868 (\u9017\u53F7\u5206\u9694: iam,db,cache,ai,storage,crypto)").option("--examples", "\u6DFB\u52A0\u793A\u4F8B\u4EE3\u7801").option("--no-examples", "\u4E0D\u6DFB\u52A0\u793A\u4F8B\u4EE3\u7801").option("--no-install", "\u4E0D\u5B89\u88C5\u4F9D\u8D56").option("-p, --package-manager <pm>", "\u5305\u7BA1\u7406\u5668 (pnpm, npm, yarn)").option("--no-git", "\u4E0D\u521D\u59CB\u5316 Git").action(async (name, options) => {
1610
+ cli.command("create [name]", "\u521B\u5EFA\u65B0\u7684 hai \u9879\u76EE").option("--type <type>", "\u5E94\u7528\u7C7B\u578B (admin, website, h5, api)").option("-t, --template <template>", "\u9879\u76EE\u6A21\u677F (minimal, default, full, custom)").option("-f, --features <features>", "\u529F\u80FD\u5217\u8868 (\u9017\u53F7\u5206\u9694: iam,db,cache,ai,storage,crypto)").option("--examples", "\u6DFB\u52A0\u793A\u4F8B\u4EE3\u7801").option("--no-examples", "\u4E0D\u6DFB\u52A0\u793A\u4F8B\u4EE3\u7801").option("--no-install", "\u4E0D\u5B89\u88C5\u4F9D\u8D56").option("-p, --package-manager <pm>", "\u5305\u7BA1\u7406\u5668 (pnpm, npm, yarn)").option("--no-git", "\u4E0D\u521D\u59CB\u5316 Git").option("--git-remote <url>", "Git \u8FDC\u7A0B\u4ED3\u5E93\u5730\u5740").action(async (name, options) => {
1559
1611
  try {
1560
1612
  const features = typeof options.features === "string" ? options.features.split(",").map((f) => f.trim()) : void 0;
1561
1613
  await createProject({
@@ -1567,6 +1619,7 @@ cli.command("create [name]", "\u521B\u5EFA\u65B0\u7684 hai \u9879\u76EE").option
1567
1619
  install: options.install,
1568
1620
  packageManager: options.packageManager,
1569
1621
  git: options.git,
1622
+ gitRemote: options.gitRemote,
1570
1623
  verbose: options.verbose,
1571
1624
  cwd: options.cwd
1572
1625
  });