@h-ai/cli 0.1.0-alpha.20 → 0.1.0-alpha.21
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/README.md +10 -7
- package/dist/{chunk-GSMXGUYF.js → chunk-5IGMJVV5.js} +56 -38
- package/dist/chunk-5IGMJVV5.js.map +1 -0
- package/dist/{chunk-3BBXDQ4Y.js → chunk-CFCXOKGV.js} +24 -2
- package/dist/chunk-CFCXOKGV.js.map +1 -0
- package/dist/cli-config-templates-5J5VKWWD.js +5 -0
- package/dist/{cli-config-templates-IGGO7P45.js.map → cli-config-templates-5J5VKWWD.js.map} +1 -1
- package/dist/cli-skill-templates-JMSV2SVW.js +5 -0
- package/dist/{cli-skill-templates-IMYZPQRG.js.map → cli-skill-templates-JMSV2SVW.js.map} +1 -1
- package/dist/index.js +567 -75
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/templates/README.md +40 -29
- package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +16 -0
- package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +38 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-contract.ts.hbs +27 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +33 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/index.ts.hbs +3 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +12 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +18 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tsconfig.json.hbs +12 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +11 -0
- package/templates/apps/api/apps/{{projectName}}-contract/vitest.config.ts.hbs +9 -0
- package/templates/apps/api/apps/{{projectName}}-service/README.md.hbs +17 -0
- package/templates/apps/api/apps/{{projectName}}-service/config/_core.yml.hbs +19 -0
- package/templates/apps/api/apps/{{projectName}}-service/config/_serv.yml.hbs +26 -0
- package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +55 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +98 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/index.ts.hbs +21 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +184 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/app-procedures.ts.hbs +49 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/index.ts.hbs +18 -0
- package/templates/apps/api/apps/{{projectName}}-service/tests/service.test.ts.hbs +168 -0
- package/templates/apps/api/apps/{{projectName}}-service/tsconfig.json.hbs +16 -0
- package/templates/apps/api/apps/{{projectName}}-service/tsup.config.ts.hbs +11 -0
- package/templates/apps/api/apps/{{projectName}}-service/vitest.config.ts.hbs +9 -0
- package/templates/apps/api/e2e/api-service.spec.ts.hbs +18 -0
- package/templates/apps/api/eslint.config.js +32 -0
- package/templates/apps/api/package.json.hbs +29 -0
- package/templates/apps/api/playwright.config.ts.hbs +58 -0
- package/templates/apps/api/pnpm-workspace.yaml.hbs +14 -0
- package/templates/apps/api/tsconfig.base.json +15 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/.env.example.hbs +10 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +24 -7
- package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/en-US.json.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/zh-CN.json.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +51 -29
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +186 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.css.hbs +2 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.d.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/main.ts.hbs +14 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +1 -5
- package/templates/apps/fullstack/apps/{{projectName}}-app/tsconfig.json.hbs +10 -4
- package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +4 -3
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/.env.example.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +20 -6
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/eslint.config.js.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/index.html.hbs +15 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +33 -30
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +152 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.d.ts.hbs +1 -2
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/main.ts.hbs +13 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/Cargo.toml.hbs +22 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/build.rs.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/capabilities/default.json.hbs +12 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128@2x.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/32x32.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.icns +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.ico +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/lib.rs.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/main.rs.hbs +8 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +41 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +2 -8
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/tsconfig.json.hbs +9 -4
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +44 -21
- package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +15 -6
- package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +15 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +25 -27
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/App.svelte.hbs +153 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.d.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +14 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +1 -5
- package/templates/apps/fullstack/apps/{{projectName}}-web/tsconfig.json.hbs +10 -4
- package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +3 -2
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +2 -1
- package/templates/apps/fullstack/eslint.config.js +0 -1
- package/templates/apps/fullstack/package.json.hbs +18 -17
- package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +3 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/{server-app.test.ts.hbs → app-server.test.ts.hbs} +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +9 -8
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/index.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +5 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ThemeSwitcher.svelte.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tsconfig.json.hbs +1 -1
- package/templates/apps/fullstack/playwright.config.ts.hbs +41 -4
- package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +15 -0
- package/templates/apps/mobile-app/.env.hbs +3 -0
- package/templates/apps/{android-app → mobile-app}/capacitor.config.ts.hbs +2 -2
- package/templates/apps/mobile-app/index.html.hbs +13 -0
- package/templates/apps/mobile-app/messages/en-US.json +36 -0
- package/templates/apps/mobile-app/messages/zh-CN.json +36 -0
- package/templates/apps/mobile-app/src/App.svelte.hbs +162 -0
- package/templates/apps/mobile-app/src/lib/api.ts.hbs +54 -0
- package/templates/apps/{android-app → mobile-app}/src/lib/capacitor.ts +5 -6
- package/templates/apps/mobile-app/src/main.ts.hbs +11 -0
- package/templates/base/.gitignore.hbs +16 -0
- package/templates/base/{eslint.config.js → eslint.config.js.hbs} +4 -1
- package/templates/base/package.json.hbs +52 -33
- package/templates/base/playwright.config.ts +30 -3
- package/templates/base/pnpm-workspace.yaml.hbs +14 -0
- package/templates/base/src/app.d.ts.hbs +3 -0
- package/templates/base/src/app.html.hbs +3 -0
- package/templates/base/svelte.config.js.hbs +43 -3
- package/templates/base/tests/scaffold.test.ts.hbs +7 -0
- package/templates/base/tsconfig.json.hbs +50 -0
- package/templates/base/vite.config.ts.hbs +10 -0
- package/templates/skills/AGENTS.md +57 -24
- package/templates/skills/CLAUDE.md +18 -7
- package/templates/skills/bridges/admin/AGENTS.md +66 -0
- package/templates/skills/bridges/admin/CLAUDE.md +19 -0
- package/templates/skills/bridges/admin/copilot-instructions.md +46 -0
- package/templates/skills/bridges/api/AGENTS.md +65 -0
- package/templates/skills/bridges/api/CLAUDE.md +19 -0
- package/templates/skills/bridges/api/copilot-instructions.md +46 -0
- package/templates/skills/bridges/fullstack/AGENTS.md +84 -0
- package/templates/skills/bridges/fullstack/CLAUDE.md +19 -0
- package/templates/skills/bridges/fullstack/copilot-instructions.md +54 -0
- package/templates/skills/bridges/h5/AGENTS.md +65 -0
- package/templates/skills/bridges/h5/CLAUDE.md +19 -0
- package/templates/skills/bridges/h5/copilot-instructions.md +44 -0
- package/templates/skills/bridges/mobile-app/AGENTS.md +77 -0
- package/templates/skills/bridges/mobile-app/CLAUDE.md +19 -0
- package/templates/skills/bridges/mobile-app/copilot-instructions.md +45 -0
- package/templates/skills/bridges/website/AGENTS.md +65 -0
- package/templates/skills/bridges/website/CLAUDE.md +19 -0
- package/templates/skills/bridges/website/copilot-instructions.md +44 -0
- package/templates/skills/copilot-instructions.md +27 -64
- package/templates/skills/hai-app-create/SKILL.md +1 -0
- package/templates/skills/hai-app-review/SKILL.md +1 -1
- package/templates/skills/hai-app-tests/SKILL.md +28 -3
- package/templates/skills/hai-capacitor/SKILL.md +14 -22
- package/templates/skills/opencode.json +1 -6
- package/dist/chunk-3BBXDQ4Y.js.map +0 -1
- package/dist/chunk-GSMXGUYF.js.map +0 -1
- package/dist/cli-config-templates-IGGO7P45.js +0 -5
- package/dist/cli-skill-templates-IMYZPQRG.js +0 -5
- package/templates/apps/android-app/.env.hbs +0 -3
- package/templates/apps/android-app/messages/en-US.json +0 -24
- package/templates/apps/android-app/messages/zh-CN.json +0 -24
- package/templates/apps/android-app/src/lib/api.ts.hbs +0 -32
- package/templates/apps/android-app/src/routes/+layout.svelte.hbs +0 -43
- package/templates/apps/android-app/src/routes/+layout.ts +0 -7
- package/templates/apps/android-app/src/routes/+page.svelte.hbs +0 -38
- package/templates/apps/api/src/routes/+layout.svelte +0 -14
- package/templates/apps/api/src/routes/+page.svelte +0 -11
- package/templates/apps/api/src/routes/api/v1/health/+server.ts +0 -14
- package/templates/apps/api/src/routes/api/v1/items/+server.ts +0 -37
- package/templates/apps/api/src/routes/api/v1/items/[id]/+server.ts +0 -30
- package/templates/apps/api/tests/health.test.ts.hbs +0 -26
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.html.hbs +0 -14
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/routes/+layout.svelte.hbs +0 -18
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/routes/+page.svelte.hbs +0 -162
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.html.hbs +0 -14
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/routes/+layout.svelte.hbs +0 -18
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/routes/+page.svelte.hbs +0 -162
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.html.hbs +0 -14
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/routes/+layout.svelte.hbs +0 -18
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/routes/+page.svelte.hbs +0 -162
- package/templates/apps/fullstack/pnpm-workspace.yaml +0 -7
- package/templates/base/tsconfig.json +0 -20
- /package/templates/apps/fullstack/packages/{{projectName}}-serv/src/{server-app.ts.hbs → app-server.ts.hbs} +0 -0
- /package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/{theme.svelte.ts.hbs → theme-store.svelte.ts.hbs} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { generateConfigFile } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
import { generateConfigFile } from './chunk-CFCXOKGV.js';
|
|
3
|
+
import './chunk-5IGMJVV5.js';
|
|
4
4
|
import './chunk-2H7UOFLK.js';
|
|
5
5
|
import process3 from 'process';
|
|
6
6
|
import { core } from '@h-ai/core';
|
|
@@ -12,6 +12,7 @@ import fse from 'fs-extra';
|
|
|
12
12
|
import Handlebars from 'handlebars';
|
|
13
13
|
import ora from 'ora';
|
|
14
14
|
import prompts from 'prompts';
|
|
15
|
+
import { Buffer } from 'buffer';
|
|
15
16
|
import { execSync, execFileSync } from 'child_process';
|
|
16
17
|
import { existsSync, readFileSync } from 'fs';
|
|
17
18
|
import { parse } from 'yaml';
|
|
@@ -98,7 +99,6 @@ registerHelpers();
|
|
|
98
99
|
Handlebars.registerHelper("if_eq", function(a, b, options) {
|
|
99
100
|
return a === b ? options.fn(this) : options.inverse(this);
|
|
100
101
|
});
|
|
101
|
-
var HAI_VERSION = `^${getCliVersion()}`;
|
|
102
102
|
var TEMPLATE_SKIP_IF_EMPTY_MARKER = "@skipIfEmpty";
|
|
103
103
|
var NORMALIZED_RENDER_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".js", ".svelte", ".json", ".css"]);
|
|
104
104
|
var CAPACITOR_SKIPPED_SERVER_FILES = /* @__PURE__ */ new Set([
|
|
@@ -107,15 +107,22 @@ var CAPACITOR_SKIPPED_SERVER_FILES = /* @__PURE__ */ new Set([
|
|
|
107
107
|
]);
|
|
108
108
|
var VERSIONS = {
|
|
109
109
|
antfuEslintConfig: "^9.0.0",
|
|
110
|
-
|
|
111
|
-
apiClient: HAI_VERSION,
|
|
112
|
-
core: HAI_VERSION,
|
|
113
|
-
serv: HAI_VERSION,
|
|
114
|
-
ui: HAI_VERSION,
|
|
110
|
+
capacitorSecureStorage: "^8.0.0",
|
|
115
111
|
// UI / Icon
|
|
116
112
|
bitsUi: "^2.18.1",
|
|
117
113
|
iconifyJsonTabler: "^1.2.35",
|
|
118
114
|
iconifyTailwind: "^1.2.3",
|
|
115
|
+
// Capacitor
|
|
116
|
+
capacitorAndroid: "^8.3.4",
|
|
117
|
+
capacitorApp: "^8.0.1",
|
|
118
|
+
capacitorCamera: "^8.0.1",
|
|
119
|
+
capacitorCli: "^8.3.4",
|
|
120
|
+
capacitorCore: "^8.3.4",
|
|
121
|
+
capacitorDevice: "^8.0.1",
|
|
122
|
+
capacitorIos: "^8.3.4",
|
|
123
|
+
capacitorPreferences: "^8.0.1",
|
|
124
|
+
capacitorPushNotifications: "^8.0.1",
|
|
125
|
+
capacitorStatusBar: "^8.0.1",
|
|
119
126
|
// Tailwind / DaisyUI
|
|
120
127
|
daisyui: "^5.5.20",
|
|
121
128
|
tailwindcss: "^4.3.0",
|
|
@@ -123,13 +130,10 @@ var VERSIONS = {
|
|
|
123
130
|
// i18n
|
|
124
131
|
inlangParaglide: "^2.18.1",
|
|
125
132
|
inlangMessageFormat: "^4.4.0",
|
|
126
|
-
// Svelte /
|
|
133
|
+
// Svelte / Vite
|
|
127
134
|
svelte: "^5.55.9",
|
|
128
|
-
svelteKit: "^2.61.1",
|
|
129
135
|
svelteCheck: "^4.4.8",
|
|
130
136
|
sveltePlugin: "^7.1.2",
|
|
131
|
-
adapterAuto: "^7.0.1",
|
|
132
|
-
adapterStatic: "^3.0.10",
|
|
133
137
|
// Build / Test
|
|
134
138
|
vite: "^8.0.14",
|
|
135
139
|
vitest: "^4.1.7",
|
|
@@ -146,12 +150,14 @@ var VERSIONS = {
|
|
|
146
150
|
// E2E
|
|
147
151
|
playwright: "^1.60.0",
|
|
148
152
|
// Validation
|
|
149
|
-
zod: "^4.4.3"
|
|
153
|
+
zod: "^4.4.3",
|
|
154
|
+
// Tauri
|
|
155
|
+
tauriCli: "^2.10.1"
|
|
150
156
|
};
|
|
151
157
|
var FRONTEND_PORTS_DEFAULT = {
|
|
152
158
|
web: 4173,
|
|
153
|
-
app:
|
|
154
|
-
desktop:
|
|
159
|
+
app: 5175,
|
|
160
|
+
desktop: 5176
|
|
155
161
|
};
|
|
156
162
|
var FRONTEND_LABELS = {
|
|
157
163
|
web: "Web",
|
|
@@ -163,6 +169,277 @@ var IMPLEMENTED_FRONTENDS = ["web", "app", "desktop"];
|
|
|
163
169
|
var DEFAULT_FULLSTACK_FRONTENDS = ["web", "app", "desktop"];
|
|
164
170
|
var DEFAULT_THEMES = ["light", "dark"];
|
|
165
171
|
var DEFAULT_THEME_NAME = "light";
|
|
172
|
+
var HAI_PACKAGE_VERSION = `^${getCliVersion()}`;
|
|
173
|
+
var HAI_PACKAGE_SPECIFIER_CATALOG = "catalog:";
|
|
174
|
+
var HAI_CATALOG_PACKAGE_NAMES = [
|
|
175
|
+
"@h-ai/ai",
|
|
176
|
+
"@h-ai/api-client",
|
|
177
|
+
"@h-ai/api-contract",
|
|
178
|
+
"@h-ai/audit",
|
|
179
|
+
"@h-ai/cache",
|
|
180
|
+
"@h-ai/capacitor",
|
|
181
|
+
"@h-ai/core",
|
|
182
|
+
"@h-ai/crypto",
|
|
183
|
+
"@h-ai/datapipe",
|
|
184
|
+
"@h-ai/deploy",
|
|
185
|
+
"@h-ai/iam",
|
|
186
|
+
"@h-ai/kit",
|
|
187
|
+
"@h-ai/payment",
|
|
188
|
+
"@h-ai/reach",
|
|
189
|
+
"@h-ai/reldb",
|
|
190
|
+
"@h-ai/scheduler",
|
|
191
|
+
"@h-ai/serv",
|
|
192
|
+
"@h-ai/storage",
|
|
193
|
+
"@h-ai/ui",
|
|
194
|
+
"@h-ai/vecdb"
|
|
195
|
+
];
|
|
196
|
+
var HAI_CATALOG_PACKAGES = Object.fromEntries(
|
|
197
|
+
HAI_CATALOG_PACKAGE_NAMES.map((packageName) => [packageName, HAI_PACKAGE_VERSION])
|
|
198
|
+
);
|
|
199
|
+
var FULLSTACK_EXTERNAL_CATALOG_PACKAGES = {
|
|
200
|
+
"@antfu/eslint-config": VERSIONS.antfuEslintConfig,
|
|
201
|
+
"@aparajita/capacitor-secure-storage": VERSIONS.capacitorSecureStorage,
|
|
202
|
+
"@capacitor/android": VERSIONS.capacitorAndroid,
|
|
203
|
+
"@capacitor/app": VERSIONS.capacitorApp,
|
|
204
|
+
"@capacitor/camera": VERSIONS.capacitorCamera,
|
|
205
|
+
"@capacitor/cli": VERSIONS.capacitorCli,
|
|
206
|
+
"@capacitor/core": VERSIONS.capacitorCore,
|
|
207
|
+
"@capacitor/device": VERSIONS.capacitorDevice,
|
|
208
|
+
"@capacitor/ios": VERSIONS.capacitorIos,
|
|
209
|
+
"@capacitor/preferences": VERSIONS.capacitorPreferences,
|
|
210
|
+
"@capacitor/push-notifications": VERSIONS.capacitorPushNotifications,
|
|
211
|
+
"@capacitor/status-bar": VERSIONS.capacitorStatusBar,
|
|
212
|
+
"@iconify-json/tabler": VERSIONS.iconifyJsonTabler,
|
|
213
|
+
"@iconify/tailwind4": VERSIONS.iconifyTailwind,
|
|
214
|
+
"@inlang/paraglide-js": VERSIONS.inlangParaglide,
|
|
215
|
+
"@inlang/plugin-message-format": VERSIONS.inlangMessageFormat,
|
|
216
|
+
"@playwright/test": VERSIONS.playwright,
|
|
217
|
+
"@sveltejs/vite-plugin-svelte": VERSIONS.sveltePlugin,
|
|
218
|
+
"@tailwindcss/vite": VERSIONS.tailwindcssVite,
|
|
219
|
+
"@tauri-apps/cli": VERSIONS.tauriCli,
|
|
220
|
+
"@types/node": VERSIONS.nodeTypes,
|
|
221
|
+
"bits-ui": VERSIONS.bitsUi,
|
|
222
|
+
"daisyui": VERSIONS.daisyui,
|
|
223
|
+
"eslint": VERSIONS.eslint,
|
|
224
|
+
"eslint-plugin-format": VERSIONS.eslintPluginFormat,
|
|
225
|
+
"eslint-plugin-svelte": VERSIONS.eslintPluginSvelte,
|
|
226
|
+
"rimraf": VERSIONS.rimraf,
|
|
227
|
+
"svelte": VERSIONS.svelte,
|
|
228
|
+
"svelte-check": VERSIONS.svelteCheck,
|
|
229
|
+
"svelte-eslint-parser": VERSIONS.svelteEslintParser,
|
|
230
|
+
"tailwindcss": VERSIONS.tailwindcss,
|
|
231
|
+
"tsup": VERSIONS.tsup,
|
|
232
|
+
"typescript": VERSIONS.typescript,
|
|
233
|
+
"vite": VERSIONS.vite,
|
|
234
|
+
"vitest": VERSIONS.vitest,
|
|
235
|
+
"zod": VERSIONS.zod
|
|
236
|
+
};
|
|
237
|
+
var FULLSTACK_CATALOG_PACKAGES = {
|
|
238
|
+
...HAI_CATALOG_PACKAGES,
|
|
239
|
+
...FULLSTACK_EXTERNAL_CATALOG_PACKAGES
|
|
240
|
+
};
|
|
241
|
+
var FULLSTACK_ROOT_CATALOG_PACKAGE_NAMES = [
|
|
242
|
+
"@antfu/eslint-config",
|
|
243
|
+
"@playwright/test",
|
|
244
|
+
"@sveltejs/vite-plugin-svelte",
|
|
245
|
+
"@types/node",
|
|
246
|
+
"eslint",
|
|
247
|
+
"eslint-plugin-format",
|
|
248
|
+
"eslint-plugin-svelte",
|
|
249
|
+
"rimraf",
|
|
250
|
+
"svelte",
|
|
251
|
+
"svelte-check",
|
|
252
|
+
"svelte-eslint-parser",
|
|
253
|
+
"tsup",
|
|
254
|
+
"typescript",
|
|
255
|
+
"vite",
|
|
256
|
+
"vitest"
|
|
257
|
+
];
|
|
258
|
+
var FULLSTACK_CONTRACT_CATALOG_PACKAGE_NAMES = [
|
|
259
|
+
"@h-ai/api-contract",
|
|
260
|
+
"@h-ai/core",
|
|
261
|
+
"zod"
|
|
262
|
+
];
|
|
263
|
+
var FULLSTACK_SERV_CATALOG_PACKAGE_NAMES = [
|
|
264
|
+
"@h-ai/core",
|
|
265
|
+
"@h-ai/serv"
|
|
266
|
+
];
|
|
267
|
+
var FULLSTACK_SHARED_CATALOG_PACKAGE_NAMES = [
|
|
268
|
+
"@h-ai/api-client",
|
|
269
|
+
"@h-ai/ui",
|
|
270
|
+
"@inlang/paraglide-js",
|
|
271
|
+
"@inlang/plugin-message-format",
|
|
272
|
+
"svelte",
|
|
273
|
+
"svelte-check",
|
|
274
|
+
"typescript",
|
|
275
|
+
"vite",
|
|
276
|
+
"vitest"
|
|
277
|
+
];
|
|
278
|
+
var FULLSTACK_WEB_CATALOG_PACKAGE_NAMES = [
|
|
279
|
+
"@antfu/eslint-config",
|
|
280
|
+
"@h-ai/ui",
|
|
281
|
+
"@iconify-json/tabler",
|
|
282
|
+
"@iconify/tailwind4",
|
|
283
|
+
"@inlang/paraglide-js",
|
|
284
|
+
"@inlang/plugin-message-format",
|
|
285
|
+
"@sveltejs/vite-plugin-svelte",
|
|
286
|
+
"@tailwindcss/vite",
|
|
287
|
+
"bits-ui",
|
|
288
|
+
"daisyui",
|
|
289
|
+
"eslint",
|
|
290
|
+
"eslint-plugin-format",
|
|
291
|
+
"eslint-plugin-svelte",
|
|
292
|
+
"svelte",
|
|
293
|
+
"svelte-check",
|
|
294
|
+
"svelte-eslint-parser",
|
|
295
|
+
"tailwindcss",
|
|
296
|
+
"typescript",
|
|
297
|
+
"vite",
|
|
298
|
+
"vitest"
|
|
299
|
+
];
|
|
300
|
+
var FULLSTACK_APP_CATALOG_PACKAGE_NAMES = [
|
|
301
|
+
...FULLSTACK_WEB_CATALOG_PACKAGE_NAMES,
|
|
302
|
+
"@aparajita/capacitor-secure-storage",
|
|
303
|
+
"@capacitor/android",
|
|
304
|
+
"@capacitor/app",
|
|
305
|
+
"@capacitor/camera",
|
|
306
|
+
"@capacitor/cli",
|
|
307
|
+
"@capacitor/core",
|
|
308
|
+
"@capacitor/device",
|
|
309
|
+
"@capacitor/ios",
|
|
310
|
+
"@capacitor/preferences",
|
|
311
|
+
"@capacitor/push-notifications",
|
|
312
|
+
"@capacitor/status-bar",
|
|
313
|
+
"@h-ai/capacitor"
|
|
314
|
+
];
|
|
315
|
+
var FULLSTACK_DESKTOP_CATALOG_PACKAGE_NAMES = [
|
|
316
|
+
...FULLSTACK_WEB_CATALOG_PACKAGE_NAMES,
|
|
317
|
+
"@tauri-apps/cli"
|
|
318
|
+
];
|
|
319
|
+
var API_WORKSPACE_EXTERNAL_CATALOG_PACKAGE_NAMES = [
|
|
320
|
+
"@antfu/eslint-config",
|
|
321
|
+
"@playwright/test",
|
|
322
|
+
"@types/node",
|
|
323
|
+
"eslint",
|
|
324
|
+
"eslint-plugin-format",
|
|
325
|
+
"rimraf",
|
|
326
|
+
"tsup",
|
|
327
|
+
"typescript",
|
|
328
|
+
"vitest",
|
|
329
|
+
"zod"
|
|
330
|
+
];
|
|
331
|
+
function pickCatalogPackages(packageNames, availableCatalogPackages) {
|
|
332
|
+
return Object.fromEntries(
|
|
333
|
+
[...new Set(packageNames)].sort((left, right) => left.localeCompare(right)).map((packageName) => {
|
|
334
|
+
const version = availableCatalogPackages[packageName];
|
|
335
|
+
if (!version) {
|
|
336
|
+
throw new Error(`Missing catalog version for package "${packageName}"`);
|
|
337
|
+
}
|
|
338
|
+
return [packageName, version];
|
|
339
|
+
})
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
function buildFullstackPackageSpecifiers(useCatalogProtocol) {
|
|
343
|
+
return Object.fromEntries(
|
|
344
|
+
Object.entries(VERSIONS).map(([key, version]) => [key, useCatalogProtocol ? HAI_PACKAGE_SPECIFIER_CATALOG : version])
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
function buildApiWorkspaceCatalogPackages(featureMap) {
|
|
348
|
+
const packageNames = [
|
|
349
|
+
...API_WORKSPACE_EXTERNAL_CATALOG_PACKAGE_NAMES,
|
|
350
|
+
"@h-ai/api-client",
|
|
351
|
+
"@h-ai/api-contract",
|
|
352
|
+
"@h-ai/core",
|
|
353
|
+
"@h-ai/serv"
|
|
354
|
+
];
|
|
355
|
+
if (featureMap.db)
|
|
356
|
+
packageNames.push("@h-ai/reldb");
|
|
357
|
+
if (featureMap.cache)
|
|
358
|
+
packageNames.push("@h-ai/cache");
|
|
359
|
+
if (featureMap.iam)
|
|
360
|
+
packageNames.push("@h-ai/iam");
|
|
361
|
+
if (featureMap.crypto)
|
|
362
|
+
packageNames.push("@h-ai/crypto");
|
|
363
|
+
if (featureMap.storage)
|
|
364
|
+
packageNames.push("@h-ai/storage");
|
|
365
|
+
if (featureMap.ai)
|
|
366
|
+
packageNames.push("@h-ai/ai");
|
|
367
|
+
if (featureMap.audit)
|
|
368
|
+
packageNames.push("@h-ai/audit");
|
|
369
|
+
if (featureMap.reach)
|
|
370
|
+
packageNames.push("@h-ai/reach");
|
|
371
|
+
if (featureMap.payment)
|
|
372
|
+
packageNames.push("@h-ai/payment");
|
|
373
|
+
if (featureMap.vecdb)
|
|
374
|
+
packageNames.push("@h-ai/vecdb");
|
|
375
|
+
if (featureMap.datapipe)
|
|
376
|
+
packageNames.push("@h-ai/datapipe");
|
|
377
|
+
if (featureMap.scheduler)
|
|
378
|
+
packageNames.push("@h-ai/scheduler");
|
|
379
|
+
if (featureMap.deploy)
|
|
380
|
+
packageNames.push("@h-ai/deploy");
|
|
381
|
+
return pickCatalogPackages(packageNames, FULLSTACK_CATALOG_PACKAGES);
|
|
382
|
+
}
|
|
383
|
+
function buildAppHaiCatalogPackages(options) {
|
|
384
|
+
const packageNames = [];
|
|
385
|
+
if (options.isSvelteOnlyApp) {
|
|
386
|
+
packageNames.push("@h-ai/api-client", "@h-ai/capacitor", "@h-ai/ui");
|
|
387
|
+
return pickCatalogPackages(packageNames, HAI_CATALOG_PACKAGES);
|
|
388
|
+
}
|
|
389
|
+
packageNames.push("@h-ai/core", "@h-ai/kit");
|
|
390
|
+
if (options.hasUi)
|
|
391
|
+
packageNames.push("@h-ai/ui");
|
|
392
|
+
if (options.featureMap.db)
|
|
393
|
+
packageNames.push("@h-ai/reldb");
|
|
394
|
+
if (options.featureMap.cache)
|
|
395
|
+
packageNames.push("@h-ai/cache");
|
|
396
|
+
if (options.featureMap.iam)
|
|
397
|
+
packageNames.push("@h-ai/iam");
|
|
398
|
+
if (options.featureMap.crypto)
|
|
399
|
+
packageNames.push("@h-ai/crypto");
|
|
400
|
+
if (options.featureMap.storage)
|
|
401
|
+
packageNames.push("@h-ai/storage");
|
|
402
|
+
if (options.featureMap.ai)
|
|
403
|
+
packageNames.push("@h-ai/ai");
|
|
404
|
+
if (options.featureMap.audit)
|
|
405
|
+
packageNames.push("@h-ai/audit");
|
|
406
|
+
if (options.featureMap.reach)
|
|
407
|
+
packageNames.push("@h-ai/reach");
|
|
408
|
+
if (options.featureMap.payment)
|
|
409
|
+
packageNames.push("@h-ai/payment");
|
|
410
|
+
if (options.featureMap.vecdb)
|
|
411
|
+
packageNames.push("@h-ai/vecdb");
|
|
412
|
+
if (options.featureMap.datapipe)
|
|
413
|
+
packageNames.push("@h-ai/datapipe");
|
|
414
|
+
if (options.featureMap.scheduler)
|
|
415
|
+
packageNames.push("@h-ai/scheduler");
|
|
416
|
+
if (options.featureMap.deploy)
|
|
417
|
+
packageNames.push("@h-ai/deploy");
|
|
418
|
+
if (options.featureMap["api-client"])
|
|
419
|
+
packageNames.push("@h-ai/api-client");
|
|
420
|
+
if (options.featureMap.capacitor)
|
|
421
|
+
packageNames.push("@h-ai/capacitor");
|
|
422
|
+
if (options.isCapacitorApp && !options.featureMap["api-client"])
|
|
423
|
+
packageNames.push("@h-ai/api-client");
|
|
424
|
+
if (options.isCapacitorApp && !options.featureMap.capacitor)
|
|
425
|
+
packageNames.push("@h-ai/capacitor");
|
|
426
|
+
return pickCatalogPackages(packageNames, HAI_CATALOG_PACKAGES);
|
|
427
|
+
}
|
|
428
|
+
function buildFullstackCatalogPackages(frontends) {
|
|
429
|
+
const packageNames = [
|
|
430
|
+
...FULLSTACK_ROOT_CATALOG_PACKAGE_NAMES,
|
|
431
|
+
...FULLSTACK_CONTRACT_CATALOG_PACKAGE_NAMES,
|
|
432
|
+
...FULLSTACK_SERV_CATALOG_PACKAGE_NAMES,
|
|
433
|
+
...FULLSTACK_SHARED_CATALOG_PACKAGE_NAMES
|
|
434
|
+
];
|
|
435
|
+
if (frontends.includes("web"))
|
|
436
|
+
packageNames.push(...FULLSTACK_WEB_CATALOG_PACKAGE_NAMES);
|
|
437
|
+
if (frontends.includes("app"))
|
|
438
|
+
packageNames.push(...FULLSTACK_APP_CATALOG_PACKAGE_NAMES);
|
|
439
|
+
if (frontends.includes("desktop"))
|
|
440
|
+
packageNames.push(...FULLSTACK_DESKTOP_CATALOG_PACKAGE_NAMES);
|
|
441
|
+
return pickCatalogPackages(packageNames, FULLSTACK_CATALOG_PACKAGES);
|
|
442
|
+
}
|
|
166
443
|
var FEATURE_ROUTE_DIRS = {
|
|
167
444
|
iam: ["routes-shared"],
|
|
168
445
|
storage: ["routes"],
|
|
@@ -179,6 +456,7 @@ var FEATURE_APP_ROUTE_DIRS = {
|
|
|
179
456
|
};
|
|
180
457
|
var FEATURE_ID_REGEX = /^[a-z0-9-]+$/;
|
|
181
458
|
var HBS_SUFFIX_REGEX = /\.hbs$/;
|
|
459
|
+
var FULLSTACK_FRONTEND_TEMPLATE_PATH_REGEX = /^apps\/\{\{projectName\}\}-(web|app|desktop|miniapp)\//;
|
|
182
460
|
var NON_IDENTIFIER_CHAR_REGEX = /[^a-z0-9]+/i;
|
|
183
461
|
var IDENTIFIER_START_REGEX = /^[a-z_$]/i;
|
|
184
462
|
function getTemplatesRoot() {
|
|
@@ -229,6 +507,28 @@ async function findHbsFiles(dir) {
|
|
|
229
507
|
await walk(dir);
|
|
230
508
|
return results;
|
|
231
509
|
}
|
|
510
|
+
async function findRenderedStaticPathFiles(dir) {
|
|
511
|
+
if (!await fse.pathExists(dir)) {
|
|
512
|
+
return [];
|
|
513
|
+
}
|
|
514
|
+
const results = [];
|
|
515
|
+
async function walk(current) {
|
|
516
|
+
const entries = await fse.readdir(current, { withFileTypes: true });
|
|
517
|
+
for (const entry of entries) {
|
|
518
|
+
const fullPath = path2.join(current, entry.name);
|
|
519
|
+
if (entry.isDirectory()) {
|
|
520
|
+
await walk(fullPath);
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
const relPath = path2.relative(dir, fullPath);
|
|
524
|
+
if (!entry.name.endsWith(".hbs") && (relPath.includes("{{") || relPath.includes("}}"))) {
|
|
525
|
+
results.push(relPath);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
await walk(dir);
|
|
530
|
+
return results;
|
|
531
|
+
}
|
|
232
532
|
function buildTemplateContext(options) {
|
|
233
533
|
const featureMap = {};
|
|
234
534
|
for (const f of options.features) {
|
|
@@ -244,24 +544,62 @@ function buildTemplateContext(options) {
|
|
|
244
544
|
}
|
|
245
545
|
const isApi = options.appType === "api";
|
|
246
546
|
const isFullstack = options.appType === "fullstack";
|
|
247
|
-
const isCapacitorApp = options.appType === "
|
|
547
|
+
const isCapacitorApp = options.appType === "mobile-app";
|
|
548
|
+
const isSvelteOnlyApp = isCapacitorApp;
|
|
549
|
+
const useCatalogProtocol = options.packageManager === "pnpm";
|
|
550
|
+
const hasUi = !isApi && !isFullstack;
|
|
551
|
+
const selectedFrontends = options.frontends ?? DEFAULT_FULLSTACK_FRONTENDS;
|
|
552
|
+
let haiCatalogPackages;
|
|
553
|
+
if (isFullstack) {
|
|
554
|
+
haiCatalogPackages = buildFullstackCatalogPackages(selectedFrontends);
|
|
555
|
+
} else if (isApi) {
|
|
556
|
+
haiCatalogPackages = buildApiWorkspaceCatalogPackages(featureMap);
|
|
557
|
+
} else {
|
|
558
|
+
haiCatalogPackages = buildAppHaiCatalogPackages({
|
|
559
|
+
featureMap,
|
|
560
|
+
hasUi,
|
|
561
|
+
isCapacitorApp,
|
|
562
|
+
isSvelteOnlyApp
|
|
563
|
+
});
|
|
564
|
+
}
|
|
248
565
|
return {
|
|
249
566
|
projectName: options.name,
|
|
567
|
+
useCatalogProtocol,
|
|
568
|
+
haiPackageSpecifier: useCatalogProtocol ? HAI_PACKAGE_SPECIFIER_CATALOG : HAI_PACKAGE_VERSION,
|
|
569
|
+
haiPackageVersion: HAI_PACKAGE_VERSION,
|
|
570
|
+
haiCatalogPackages,
|
|
250
571
|
appType: options.appType,
|
|
251
572
|
features: featureMap,
|
|
252
|
-
hasUi
|
|
573
|
+
hasUi,
|
|
253
574
|
hasI18n: !isApi && !isFullstack,
|
|
254
575
|
isCapacitorApp,
|
|
576
|
+
isApiWorkspace: isApi,
|
|
577
|
+
isSvelteOnlyApp,
|
|
255
578
|
defaultLocale: options.moduleConfigs?.core?.defaultLocale ?? "zh-CN",
|
|
256
579
|
packageManager: options.packageManager,
|
|
580
|
+
api: isApi ? buildApiWorkspaceTemplateContext(options.name, useCatalogProtocol) : void 0,
|
|
257
581
|
fullstack: isFullstack ? buildFullstackTemplateContext(
|
|
258
582
|
options.name,
|
|
259
|
-
|
|
260
|
-
options.moduleConfigs
|
|
583
|
+
selectedFrontends,
|
|
584
|
+
options.moduleConfigs,
|
|
585
|
+
useCatalogProtocol
|
|
261
586
|
) : void 0
|
|
262
587
|
};
|
|
263
588
|
}
|
|
264
|
-
function
|
|
589
|
+
function buildApiWorkspaceTemplateContext(projectName, useCatalogProtocol = false) {
|
|
590
|
+
const identifier = toIdentifier(projectName);
|
|
591
|
+
const pascalName = toPascalIdentifier(identifier);
|
|
592
|
+
return {
|
|
593
|
+
versions: VERSIONS,
|
|
594
|
+
packageSpecifiers: buildFullstackPackageSpecifiers(useCatalogProtocol),
|
|
595
|
+
contractPackageName: `${projectName}-contract`,
|
|
596
|
+
contractExportName: `${identifier}Contract`,
|
|
597
|
+
servicePackageName: `${projectName}-service`,
|
|
598
|
+
serviceAppFactoryName: `create${pascalName}App`,
|
|
599
|
+
serviceProceduresFactoryName: `create${pascalName}Procedures`
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
function buildFullstackTemplateContext(projectName, frontendsInput, moduleConfigs, useCatalogProtocol = false) {
|
|
265
603
|
const selectedFrontends = [...new Set(frontendsInput.length > 0 ? frontendsInput : DEFAULT_FULLSTACK_FRONTENDS)];
|
|
266
604
|
const portsConfig = moduleConfigs?.fullstack?.ports ?? {};
|
|
267
605
|
const portFor = (target) => portsConfig[target] ?? FRONTEND_PORTS_DEFAULT[target];
|
|
@@ -273,9 +611,11 @@ function buildFullstackTemplateContext(projectName, frontendsInput, moduleConfig
|
|
|
273
611
|
}));
|
|
274
612
|
return {
|
|
275
613
|
versions: VERSIONS,
|
|
614
|
+
packageSpecifiers: buildFullstackPackageSpecifiers(useCatalogProtocol),
|
|
276
615
|
contractPackageName: `${projectName}-contract`,
|
|
277
616
|
contractExportName: `${toIdentifier(projectName)}Contract`,
|
|
278
617
|
servPackageName: `${projectName}-serv`,
|
|
618
|
+
nativeAppIdSegment: toIdentifier(projectName).toLowerCase(),
|
|
279
619
|
sharedPackageName: `${projectName}-shared`,
|
|
280
620
|
selectedFrontends,
|
|
281
621
|
selectedFrontendsJson: `[${selectedFrontends.map((f) => `'${f}'`).join(", ")}]`,
|
|
@@ -330,9 +670,14 @@ function toIdentifier(value) {
|
|
|
330
670
|
return "app";
|
|
331
671
|
return IDENTIFIER_START_REGEX.test(camel) ? camel : `app${camel}`;
|
|
332
672
|
}
|
|
673
|
+
function toPascalIdentifier(value) {
|
|
674
|
+
if (!value)
|
|
675
|
+
return "App";
|
|
676
|
+
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
677
|
+
}
|
|
333
678
|
async function generateFromTemplates(projectPath, context) {
|
|
334
679
|
const root = getTemplatesRoot();
|
|
335
|
-
const includeBaseTemplate = context.appType !== "fullstack";
|
|
680
|
+
const includeBaseTemplate = context.appType !== "fullstack" && !context.isApiWorkspace;
|
|
336
681
|
if (includeBaseTemplate) {
|
|
337
682
|
await copyStaticDir(path2.join(root, "base"), projectPath);
|
|
338
683
|
}
|
|
@@ -341,32 +686,37 @@ async function generateFromTemplates(projectPath, context) {
|
|
|
341
686
|
const appExcludes = context.hasI18n ? [] : ["messages"];
|
|
342
687
|
await copyStaticDir(appDir, projectPath, appExcludes);
|
|
343
688
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
if (!FEATURE_ID_REGEX.test(featureId)) {
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
const featureDir = path2.join(root, "features", featureId);
|
|
352
|
-
if (!await fse.pathExists(featureDir)) {
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
const sharedDirs = FEATURE_ROUTE_DIRS[featureId] || [];
|
|
356
|
-
for (const dirName of sharedDirs) {
|
|
357
|
-
if (context.isCapacitorApp && dirName === "routes-shared") {
|
|
689
|
+
if (!context.isApiWorkspace) {
|
|
690
|
+
for (const featureId of Object.keys(context.features)) {
|
|
691
|
+
if (context.isSvelteOnlyApp) {
|
|
358
692
|
continue;
|
|
359
693
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
await copyStaticDir(routesSrc, path2.join(projectPath, "src", "routes"));
|
|
694
|
+
if (!context.features[featureId]) {
|
|
695
|
+
continue;
|
|
363
696
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const
|
|
368
|
-
if (await fse.pathExists(
|
|
369
|
-
|
|
697
|
+
if (!FEATURE_ID_REGEX.test(featureId)) {
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
const featureDir = path2.join(root, "features", featureId);
|
|
701
|
+
if (!await fse.pathExists(featureDir)) {
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
const sharedDirs = FEATURE_ROUTE_DIRS[featureId] || [];
|
|
705
|
+
for (const dirName of sharedDirs) {
|
|
706
|
+
if (context.isCapacitorApp && dirName === "routes-shared") {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
const routesSrc = path2.join(featureDir, dirName);
|
|
710
|
+
if (await fse.pathExists(routesSrc)) {
|
|
711
|
+
await copyStaticDir(routesSrc, path2.join(projectPath, "src", "routes"));
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
const appSpecificTypes = FEATURE_APP_ROUTE_DIRS[featureId] || [];
|
|
715
|
+
if (appSpecificTypes.includes(context.appType)) {
|
|
716
|
+
const appRouteSrc = path2.join(featureDir, `routes-${context.appType}`);
|
|
717
|
+
if (await fse.pathExists(appRouteSrc)) {
|
|
718
|
+
await copyStaticDir(appRouteSrc, path2.join(projectPath, "src", "routes"));
|
|
719
|
+
}
|
|
370
720
|
}
|
|
371
721
|
}
|
|
372
722
|
}
|
|
@@ -382,15 +732,22 @@ async function generateFromTemplates(projectPath, context) {
|
|
|
382
732
|
}
|
|
383
733
|
}
|
|
384
734
|
async function renderDynamicFiles(templatesRoot, projectPath, context) {
|
|
385
|
-
const rootDirs = context.appType === "fullstack" ? [path2.join(templatesRoot, "apps", context.appType)] : [
|
|
735
|
+
const rootDirs = context.appType === "fullstack" || context.isApiWorkspace ? [path2.join(templatesRoot, "apps", context.appType)] : [
|
|
386
736
|
path2.join(templatesRoot, "base"),
|
|
387
737
|
path2.join(templatesRoot, "apps", context.appType)
|
|
388
738
|
];
|
|
389
739
|
for (const dir of rootDirs) {
|
|
390
740
|
await renderHbsInDir(dir, projectPath, context);
|
|
741
|
+
await copyRenderedStaticPathFiles(dir, projectPath, context);
|
|
742
|
+
}
|
|
743
|
+
if (context.isApiWorkspace) {
|
|
744
|
+
return;
|
|
391
745
|
}
|
|
392
746
|
const routesDest = path2.join(projectPath, "src", "routes");
|
|
393
747
|
for (const featureId of Object.keys(context.features)) {
|
|
748
|
+
if (context.isSvelteOnlyApp) {
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
394
751
|
if (!context.features[featureId]) {
|
|
395
752
|
continue;
|
|
396
753
|
}
|
|
@@ -439,6 +796,34 @@ async function renderHbsInDir(dir, destRoot, context) {
|
|
|
439
796
|
await fse.writeFile(destPath, normalizedRendered, "utf-8");
|
|
440
797
|
}
|
|
441
798
|
}
|
|
799
|
+
async function copyRenderedStaticPathFiles(dir, destRoot, context) {
|
|
800
|
+
const staticFiles = await findRenderedStaticPathFiles(dir);
|
|
801
|
+
for (const relPath of staticFiles) {
|
|
802
|
+
if (!shouldCopyRenderedStaticPathFile(relPath, context)) {
|
|
803
|
+
continue;
|
|
804
|
+
}
|
|
805
|
+
const outRelPath = renderOutputPath(relPath, context);
|
|
806
|
+
if (!isSafeRelativePath(outRelPath)) {
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
const srcPath = path2.join(dir, relPath);
|
|
810
|
+
const destPath = path2.join(destRoot, outRelPath);
|
|
811
|
+
await fse.ensureDir(path2.dirname(destPath));
|
|
812
|
+
await fse.copyFile(srcPath, destPath);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
function shouldCopyRenderedStaticPathFile(relPath, context) {
|
|
816
|
+
if (context.appType !== "fullstack" || !context.fullstack) {
|
|
817
|
+
return true;
|
|
818
|
+
}
|
|
819
|
+
const normalizedPath = relPath.split(path2.sep).join("/");
|
|
820
|
+
const frontendMatch = FULLSTACK_FRONTEND_TEMPLATE_PATH_REGEX.exec(normalizedPath);
|
|
821
|
+
if (!frontendMatch) {
|
|
822
|
+
return true;
|
|
823
|
+
}
|
|
824
|
+
const target = frontendMatch[1];
|
|
825
|
+
return Boolean(context.fullstack.frontends[target]);
|
|
826
|
+
}
|
|
442
827
|
function normalizeRenderedContent(content, outRelPath) {
|
|
443
828
|
const normalizedLineEndings = content.replace(/\r\n/g, "\n");
|
|
444
829
|
const ext = path2.extname(outRelPath);
|
|
@@ -482,13 +867,13 @@ var APP_TYPES = {
|
|
|
482
867
|
},
|
|
483
868
|
"api": {
|
|
484
869
|
name: "API \u670D\u52A1",
|
|
485
|
-
description: "
|
|
870
|
+
description: "typed API workspace\uFF0C\u542B contract + service \u53CC\u5DE5\u7A0B\u3001\u65E0 UI",
|
|
486
871
|
defaultFeatures: ["db", "cache"]
|
|
487
872
|
},
|
|
488
|
-
"
|
|
489
|
-
name: "
|
|
490
|
-
description: "
|
|
491
|
-
defaultFeatures: ["
|
|
873
|
+
"mobile-app": {
|
|
874
|
+
name: "\u79FB\u52A8\u5E94\u7528",
|
|
875
|
+
description: "\u79FB\u52A8\u7AEF\u5E94\u7528\uFF08Capacitor + Svelte 5 + Vite\uFF09\uFF0C\u53EF\u6253\u5305\u4E3A Android/iOS",
|
|
876
|
+
defaultFeatures: ["api-client", "capacitor"]
|
|
492
877
|
},
|
|
493
878
|
"fullstack": {
|
|
494
879
|
name: "\u524D\u540E\u7AEF\u5206\u79BB\u5DE5\u7A0B",
|
|
@@ -498,9 +883,9 @@ var APP_TYPES = {
|
|
|
498
883
|
};
|
|
499
884
|
var FRONTEND_TARGETS = {
|
|
500
885
|
web: { name: "Web", description: "\u6D4F\u89C8\u5668 Web \u5E94\u7528", implemented: true },
|
|
501
|
-
app: { name: "App", description: "\u79FB\u52A8\u7AEF
|
|
886
|
+
app: { name: "App", description: "\u79FB\u52A8\u7AEF Capacitor App / H5 \u524D\u7AEF", implemented: true },
|
|
502
887
|
miniapp: { name: "\u5C0F\u7A0B\u5E8F", description: "\u9884\u7559\u76EE\u6807\uFF0C\u5F53\u524D\u53EA\u751F\u6210\u8BF4\u660E\u5360\u4F4D", implemented: false },
|
|
503
|
-
desktop: { name: "\u684C\u9762\u7AEF", description: "\u684C\u9762\u7AEF\u524D\u7AEF\u5DE5\u7A0B
|
|
888
|
+
desktop: { name: "\u684C\u9762\u7AEF", description: "Tauri \u684C\u9762\u7AEF\u524D\u7AEF\u5DE5\u7A0B", implemented: true }
|
|
504
889
|
};
|
|
505
890
|
var DEFAULT_FULLSTACK_FRONTENDS2 = ["web", "app", "desktop"];
|
|
506
891
|
var FEATURES = {
|
|
@@ -691,29 +1076,36 @@ async function createProject(options) {
|
|
|
691
1076
|
});
|
|
692
1077
|
await generateFromTemplates(projectPath, context);
|
|
693
1078
|
if (resolvedOptions.appType !== "fullstack") {
|
|
694
|
-
const { generateConfigFile: generateConfigFile2 } = await import('./cli-config-templates-
|
|
1079
|
+
const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-5J5VKWWD.js');
|
|
695
1080
|
const configs = resolvedOptions.moduleConfigs;
|
|
1081
|
+
const isApiWorkspace = resolvedOptions.appType === "api";
|
|
1082
|
+
const configDir = isApiWorkspace ? path2.join(projectPath, "apps", `${resolvedOptions.name}-service`, "config") : path2.join(projectPath, "config");
|
|
1083
|
+
const envExamplePath = isApiWorkspace ? path2.join(projectPath, "apps", `${resolvedOptions.name}-service`, ".env.example") : path2.join(projectPath, ".env.example");
|
|
696
1084
|
for (const featureId of resolvedOptions.features) {
|
|
697
1085
|
const configKey = getFeatureConfigKey(featureId);
|
|
698
1086
|
if (configKey) {
|
|
699
1087
|
const content = generateConfigFile2(configKey, configs);
|
|
700
|
-
await writeFile(path2.join(
|
|
1088
|
+
await writeFile(path2.join(configDir, `_${configKey}.yml`), content);
|
|
701
1089
|
}
|
|
702
1090
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
1091
|
+
if (!isApiWorkspace) {
|
|
1092
|
+
await writeFile(
|
|
1093
|
+
path2.join(configDir, "_core.yml"),
|
|
1094
|
+
generateConfigFile2("core", configs)
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
const envExample = isApiWorkspace ? `${generateEnvExample(resolvedOptions.features, configs)}
|
|
1098
|
+
# =============================================================================
|
|
1099
|
+
# Service Runtime
|
|
1100
|
+
# =============================================================================
|
|
1101
|
+
PORT=3000
|
|
1102
|
+
` : generateEnvExample(resolvedOptions.features, configs);
|
|
1103
|
+
await writeFile(envExamplePath, envExample);
|
|
712
1104
|
}
|
|
713
|
-
const { generateSkillFiles } = await import('./cli-skill-templates-
|
|
1105
|
+
const { generateSkillFiles } = await import('./cli-skill-templates-JMSV2SVW.js');
|
|
714
1106
|
await generateSkillFiles(projectPath, resolvedOptions.features, resolvedOptions.appType);
|
|
715
1107
|
const appTypeLabel = APP_TYPES[resolvedOptions.appType].name;
|
|
716
|
-
const readmeContent = resolvedOptions.appType === "fullstack" ? generateFullstackReadme(resolvedOptions.name, resolvedOptions.packageManager, resolvedOptions.frontends) : generateReadme(resolvedOptions.name, appTypeLabel, resolvedOptions.packageManager);
|
|
1108
|
+
const readmeContent = resolvedOptions.appType === "fullstack" ? generateFullstackReadme(resolvedOptions.name, resolvedOptions.packageManager, resolvedOptions.frontends) : resolvedOptions.appType === "api" ? generateApiWorkspaceReadme(resolvedOptions.name, resolvedOptions.packageManager) : generateReadme(resolvedOptions.name, appTypeLabel, resolvedOptions.packageManager);
|
|
717
1109
|
await writeFile(
|
|
718
1110
|
path2.join(projectPath, "README.md"),
|
|
719
1111
|
readmeContent
|
|
@@ -734,8 +1126,7 @@ async function createProject(options) {
|
|
|
734
1126
|
}
|
|
735
1127
|
if (resolvedOptions.install) {
|
|
736
1128
|
spinner.start(`\u5B89\u88C5\u4F9D\u8D56 (${resolvedOptions.packageManager})...`);
|
|
737
|
-
|
|
738
|
-
execSync(installCmd, { cwd: projectPath, stdio: "ignore" });
|
|
1129
|
+
installDependencies(projectPath, resolvedOptions.packageManager);
|
|
739
1130
|
spinner.succeed();
|
|
740
1131
|
}
|
|
741
1132
|
printCompletionMessage(resolvedOptions);
|
|
@@ -855,7 +1246,7 @@ async function resolveOptions(options) {
|
|
|
855
1246
|
addExamples = examples;
|
|
856
1247
|
}
|
|
857
1248
|
const detected = await detectPackageManager(options.cwd ?? ".");
|
|
858
|
-
let packageManager = selectedAppType === "fullstack" ? "pnpm" : options.packageManager;
|
|
1249
|
+
let packageManager = selectedAppType === "fullstack" || selectedAppType === "api" ? "pnpm" : options.packageManager;
|
|
859
1250
|
if (!packageManager && useDefaults) {
|
|
860
1251
|
packageManager = detected;
|
|
861
1252
|
}
|
|
@@ -1172,6 +1563,50 @@ function getInstallCommand(pm) {
|
|
|
1172
1563
|
function getRunCommand(pm, script) {
|
|
1173
1564
|
return pm === "npm" ? `npm run ${script}` : `${pm} ${script}`;
|
|
1174
1565
|
}
|
|
1566
|
+
function installDependencies(projectPath, pm) {
|
|
1567
|
+
const installCmd = getInstallCommand(pm);
|
|
1568
|
+
try {
|
|
1569
|
+
execSync(installCmd, {
|
|
1570
|
+
cwd: projectPath,
|
|
1571
|
+
stdio: "pipe",
|
|
1572
|
+
encoding: "utf-8",
|
|
1573
|
+
maxBuffer: 10 * 1024 * 1024
|
|
1574
|
+
});
|
|
1575
|
+
} catch (error) {
|
|
1576
|
+
const details = formatCommandFailure(installCmd, error);
|
|
1577
|
+
throw new Error(`\u5B89\u88C5\u4F9D\u8D56\u5931\u8D25\uFF08${pm}\uFF09\u3002
|
|
1578
|
+
${details}`);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
function formatCommandFailure(command, error) {
|
|
1582
|
+
if (!error || typeof error !== "object") {
|
|
1583
|
+
return `\u547D\u4EE4: ${command}`;
|
|
1584
|
+
}
|
|
1585
|
+
const failure = error;
|
|
1586
|
+
const stdout = normalizeChildOutput(failure.stdout);
|
|
1587
|
+
const stderr = normalizeChildOutput(failure.stderr);
|
|
1588
|
+
const status = typeof failure.status === "number" ? `\u9000\u51FA\u7801: ${failure.status}` : "";
|
|
1589
|
+
const signal = typeof failure.signal === "string" ? `\u4FE1\u53F7: ${failure.signal}` : "";
|
|
1590
|
+
const output = [
|
|
1591
|
+
`\u547D\u4EE4: ${command}`,
|
|
1592
|
+
status,
|
|
1593
|
+
signal,
|
|
1594
|
+
stderr ? `stderr:
|
|
1595
|
+
${stderr}` : "",
|
|
1596
|
+
stdout ? `stdout:
|
|
1597
|
+
${stdout}` : ""
|
|
1598
|
+
].filter(Boolean);
|
|
1599
|
+
return output.join("\n\n");
|
|
1600
|
+
}
|
|
1601
|
+
function normalizeChildOutput(output) {
|
|
1602
|
+
if (typeof output === "string") {
|
|
1603
|
+
return output.trim();
|
|
1604
|
+
}
|
|
1605
|
+
if (Buffer.isBuffer(output)) {
|
|
1606
|
+
return output.toString("utf-8").trim();
|
|
1607
|
+
}
|
|
1608
|
+
return "";
|
|
1609
|
+
}
|
|
1175
1610
|
function generateReadme(name, appTypeLabel, pm) {
|
|
1176
1611
|
const install = getInstallCommand(pm);
|
|
1177
1612
|
return `# ${name}
|
|
@@ -1196,10 +1631,50 @@ ${getRunCommand(pm, "preview")}
|
|
|
1196
1631
|
## \u6587\u6863
|
|
1197
1632
|
|
|
1198
1633
|
- [hai Agent Framework](https://github.com/hai-series/hai-framework)
|
|
1199
|
-
- [SvelteKit](https://kit.svelte.dev/)
|
|
1200
1634
|
- [Svelte 5](https://svelte.dev/)
|
|
1201
1635
|
`;
|
|
1202
1636
|
}
|
|
1637
|
+
function generateApiWorkspaceReadme(name, pm) {
|
|
1638
|
+
return `# ${name}
|
|
1639
|
+
|
|
1640
|
+
\u57FA\u4E8E hai Agent Framework \u6784\u5EFA\u7684 typed API workspace\u3002
|
|
1641
|
+
|
|
1642
|
+
## \u5DE5\u7A0B\u7ED3\u6784
|
|
1643
|
+
|
|
1644
|
+
- \`apps/${name}-contract\`\uFF1A\u5171\u4EAB API contract\u3001Zod schema \u4E0E\u7C7B\u578B
|
|
1645
|
+
- \`apps/${name}-service\`\uFF1A\u540E\u7AEF API service\uFF0C\u57FA\u4E8E \`@h-ai/serv\` \u66B4\u9732 HTTP \u5E94\u7528
|
|
1646
|
+
|
|
1647
|
+
## \u5F00\u53D1
|
|
1648
|
+
|
|
1649
|
+
\`\`\`bash
|
|
1650
|
+
${pm} install
|
|
1651
|
+
${pm} dev
|
|
1652
|
+
\`\`\`
|
|
1653
|
+
|
|
1654
|
+
## \u8D28\u91CF\u95E8\u7981
|
|
1655
|
+
|
|
1656
|
+
\`\`\`bash
|
|
1657
|
+
${pm} typecheck
|
|
1658
|
+
${pm} lint
|
|
1659
|
+
${pm} build
|
|
1660
|
+
${pm} test
|
|
1661
|
+
${pm} test:e2e
|
|
1662
|
+
\`\`\`
|
|
1663
|
+
|
|
1664
|
+
## \u6269\u5C55\u5EFA\u8BAE
|
|
1665
|
+
|
|
1666
|
+
- \u5728 \`${name}-contract\` \u4E2D\u7EF4\u62A4\u5E94\u7528\u7EA7 contract\uFF0C\u524D\u540E\u7AEF\u5171\u7528\u540C\u4E00\u4EFD\u7C7B\u578B\u4E0E\u8DEF\u5F84\u5B9A\u4E49\u3002
|
|
1667
|
+
- \u5728 \`${name}-service\` \u4E2D\u6269\u5C55 procedures\u3001\u6A21\u5757\u521D\u59CB\u5316\u4E0E\u914D\u7F6E\u3002
|
|
1668
|
+
- \u9700\u8981 IAM / storage / ai \u65F6\uFF0C\u4F18\u5148\u590D\u7528 \`@h-ai/api-contract\` \u4E0E \`@h-ai/serv/features/*\`\u3002
|
|
1669
|
+
|
|
1670
|
+
## \u6587\u6863
|
|
1671
|
+
|
|
1672
|
+
- [hai Agent Framework](https://github.com/hai-series/hai-framework)
|
|
1673
|
+
- [@h-ai/serv](./.agents/skills/hai-serv/SKILL.md)
|
|
1674
|
+
- [@h-ai/api-contract](./.agents/skills/hai-api-contract/SKILL.md)
|
|
1675
|
+
- [@h-ai/api-client](./.agents/skills/hai-api-client/SKILL.md)
|
|
1676
|
+
`;
|
|
1677
|
+
}
|
|
1203
1678
|
function generateFullstackReadme(name, pm, frontends) {
|
|
1204
1679
|
const enabledFrontends = frontends.map((target) => FRONTEND_TARGETS[target].name).join(" / ");
|
|
1205
1680
|
return `# ${name}
|
|
@@ -1218,13 +1693,28 @@ function generateFullstackReadme(name, pm, frontends) {
|
|
|
1218
1693
|
|
|
1219
1694
|
\u5DF2\u542F\u7528\u524D\u7AEF\uFF1A${enabledFrontends || "Web / App / Desktop"}
|
|
1220
1695
|
|
|
1221
|
-
## \u5F00\u53D1
|
|
1696
|
+
## \u5F00\u53D1\u3001\u7F16\u8BD1\u4E0E\u6253\u5305
|
|
1222
1697
|
|
|
1223
1698
|
\`\`\`bash
|
|
1224
1699
|
${pm} install
|
|
1225
1700
|
${pm} dev
|
|
1701
|
+
|
|
1702
|
+
# \u4E00\u952E\u7F16\u8BD1\uFF1A\u7C7B\u578B\u68C0\u67E5 + \u5168\u5DE5\u4F5C\u533A\u6784\u5EFA
|
|
1703
|
+
${pm} compile
|
|
1704
|
+
|
|
1705
|
+
# \u4E00\u952E\u6253\u5305\uFF1AWeb build\u3001App Capacitor sync\u3001Desktop Tauri build\uFF08\u6309\u542F\u7528\u524D\u7AEF\u6267\u884C\uFF09
|
|
1706
|
+
${pm} package
|
|
1707
|
+
|
|
1708
|
+
# \u90E8\u7F72\u5165\u53E3\uFF1A\u9ED8\u8BA4\u6267\u884C package\uFF0C\u53EF\u66FF\u6362\u4E3A\u56E2\u961F\u81EA\u5DF1\u7684 CI/CD \u53D1\u5E03\u811A\u672C
|
|
1709
|
+
${pm} deploy
|
|
1226
1710
|
\`\`\`
|
|
1227
1711
|
|
|
1712
|
+
\u524D\u7AEF\u5355\u72EC\u4EA4\u4ED8\u547D\u4EE4\uFF1A
|
|
1713
|
+
|
|
1714
|
+
- Web\uFF1A\`${pm} --filter ${name}-web build\` / \`${pm} --filter ${name}-web package\`
|
|
1715
|
+
- App\uFF1A\`${pm} --filter ${name}-app package\`\uFF0CAndroid/iOS \u53EF\u7528 \`cap:build:android:debug\` / \`cap:build:android:release\` / \`cap:build:ios\`
|
|
1716
|
+
- Desktop\uFF1A\`${pm} --filter ${name}-desktop tauri:dev\` / \`${pm} --filter ${name}-desktop package\`
|
|
1717
|
+
|
|
1228
1718
|
## i18n \u4E0E shared \u534F\u540C
|
|
1229
1719
|
|
|
1230
1720
|
- shared\uFF1A\`packages/${name}-shared/project.inlang\` + \`messages/\`\uFF0C\u53EA\u653E\u8DE8\u7AEF\u5171\u4EAB\u7EC4\u4EF6\u6587\u6848\u3002
|
|
@@ -1251,7 +1741,6 @@ ${pm} test:e2e
|
|
|
1251
1741
|
## \u6587\u6863
|
|
1252
1742
|
|
|
1253
1743
|
- [hai Agent Framework](https://github.com/hai-series/hai-framework)
|
|
1254
|
-
- [SvelteKit](https://kit.svelte.dev/)
|
|
1255
1744
|
- [@h-ai/serv](./.agents/skills/hai-serv/SKILL.md)
|
|
1256
1745
|
- [@h-ai/ui](./.agents/skills/hai-ui/SKILL.md)
|
|
1257
1746
|
`;
|
|
@@ -1275,7 +1764,8 @@ function printCompletionMessage(options) {
|
|
|
1275
1764
|
if (!options.install) {
|
|
1276
1765
|
core.logger.info(chalk.cyan(` ${getInstallCommand(options.packageManager)}`));
|
|
1277
1766
|
}
|
|
1278
|
-
if (options.appType === "fullstack") {
|
|
1767
|
+
if (options.appType === "fullstack" || options.appType === "api") {
|
|
1768
|
+
core.logger.info(chalk.cyan(` ${getRunCommand(options.packageManager, "dev")}`));
|
|
1279
1769
|
core.logger.info(chalk.cyan(` ${getRunCommand(options.packageManager, "typecheck")}`));
|
|
1280
1770
|
core.logger.info(chalk.cyan(` ${getRunCommand(options.packageManager, "test")}`));
|
|
1281
1771
|
core.logger.info(chalk.cyan(` ${getRunCommand(options.packageManager, "test:e2e")}`));
|
|
@@ -1364,7 +1854,7 @@ async function addModule(options) {
|
|
|
1364
1854
|
core.logger.info(`\u53EF\u7528\u6A21\u5757: ${Object.keys(MODULE_MAP).join(", ")}`);
|
|
1365
1855
|
return;
|
|
1366
1856
|
}
|
|
1367
|
-
const { generateProjectAiSupport, resolveSkillNamesForPackages } = await import('./cli-skill-templates-
|
|
1857
|
+
const { generateProjectAiSupport, resolveSkillNamesForPackages } = await import('./cli-skill-templates-JMSV2SVW.js');
|
|
1368
1858
|
if (moduleDef.packages.every((p) => project.haiPackages.includes(p))) {
|
|
1369
1859
|
const generatedFiles2 = await generateProjectAiSupport(
|
|
1370
1860
|
cwd,
|
|
@@ -1400,7 +1890,8 @@ async function addModule(options) {
|
|
|
1400
1890
|
const pkg = await fse.readJson(pkgPath);
|
|
1401
1891
|
if (!pkg.dependencies)
|
|
1402
1892
|
pkg.dependencies = {};
|
|
1403
|
-
const
|
|
1893
|
+
const existingHaiSpecifier = Object.entries(pkg.dependencies).find(([pkgName]) => pkgName.startsWith("@h-ai/"))?.[1];
|
|
1894
|
+
const depVersion = existingHaiSpecifier === "catalog:" ? "catalog:" : `^${getCliVersion()}`;
|
|
1404
1895
|
for (const pkgName of allPackages) {
|
|
1405
1896
|
if (!pkg.dependencies[pkgName]) {
|
|
1406
1897
|
pkg.dependencies[pkgName] = depVersion;
|
|
@@ -1846,6 +2337,7 @@ export const down: MigrationFn = async (db) => {
|
|
|
1846
2337
|
}
|
|
1847
2338
|
var MODULE_CONFIG_MAP = {
|
|
1848
2339
|
"@h-ai/core": { configKey: "core", label: "Core" },
|
|
2340
|
+
"@h-ai/serv": { configKey: "serv", label: "Service" },
|
|
1849
2341
|
"@h-ai/reldb": { configKey: "db", label: "Database" },
|
|
1850
2342
|
"@h-ai/cache": { configKey: "cache", label: "Cache" },
|
|
1851
2343
|
"@h-ai/iam": { configKey: "iam", label: "IAM" },
|
|
@@ -1965,7 +2457,7 @@ var VERSION = getCliVersion();
|
|
|
1965
2457
|
var cli = cac("hai");
|
|
1966
2458
|
cli.option("-v, --verbose", "\u663E\u793A\u8BE6\u7EC6\u8F93\u51FA");
|
|
1967
2459
|
cli.option("-C, --cwd <path>", "\u5DE5\u4F5C\u76EE\u5F55");
|
|
1968
|
-
cli.command("create [name]", "\u521B\u5EFA\u65B0\u7684 hai \u9879\u76EE").option("--type <type>", "\u5E94\u7528\u7C7B\u578B (admin, website, h5, api,
|
|
2460
|
+
cli.command("create [name]", "\u521B\u5EFA\u65B0\u7684 hai \u9879\u76EE").option("--type <type>", "\u5E94\u7528\u7C7B\u578B (admin, website, h5, api, mobile-app, fullstack)").option("--frontends <targets>", "\u524D\u540E\u7AEF\u5206\u79BB\u5DE5\u7A0B\u524D\u7AEF\u76EE\u6807 (\u9017\u53F7\u5206\u9694: web,app,miniapp,desktop)").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").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E\uFF0C\u8DF3\u8FC7\u4EA4\u4E92").action(async (name, options) => {
|
|
1969
2461
|
try {
|
|
1970
2462
|
const features = typeof options.features === "string" ? options.features.split(",").map((f) => f.trim()) : void 0;
|
|
1971
2463
|
const frontends = typeof options.frontends === "string" ? options.frontends.split(",").map((f) => f.trim()).filter(Boolean) : void 0;
|