@h-ai/cli 0.1.0-alpha.53 → 0.1.0-alpha.54
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 +14 -0
- package/dist/{chunk-U4PA632G.js → chunk-FVDXJYMO.js} +34 -67
- package/dist/chunk-FVDXJYMO.js.map +1 -0
- package/dist/cli-config-templates-WGN2I23J.js +5 -0
- package/dist/{cli-config-templates-GSXKLGU5.js.map → cli-config-templates-WGN2I23J.js.map} +1 -1
- package/dist/index.js +174 -105
- package/dist/index.js.map +1 -1
- package/dist/{src-QNEJJ3BV.js → src-6ZBWDBUB.js} +127 -87
- package/dist/{src-QNEJJ3BV.js.map → src-6ZBWDBUB.js.map} +1 -1
- package/package.json +13 -4
- package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +1 -0
- package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +1 -0
- package/templates/apps/api/package.json.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +1 -0
- package/templates/apps/fullstack/package.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +1 -0
- package/templates/base/eslint.config.js.hbs +1 -0
- package/templates/base/package.json.hbs +3 -1
- package/templates/skills/hai-ai/reference.md +5 -1
- package/templates/skills/hai-app-review/SKILL.md +6 -0
- package/templates/skills/hai-build/SKILL.md +8 -0
- package/templates/skills/hai-cache/SKILL.md +2 -0
- package/templates/skills/hai-capacitor/SKILL.md +2 -0
- package/templates/skills/hai-ci/SKILL.md +12 -0
- package/templates/skills/hai-core/SKILL.md +2 -0
- package/templates/skills/hai-crypto/SKILL.md +2 -0
- package/templates/skills/hai-deploy/SKILL.md +12 -0
- package/templates/skills/hai-iam/SKILL.md +6 -0
- package/templates/skills/hai-scheduler/SKILL.md +12 -0
- package/templates/skills/hai-ui/SKILL.md +4 -0
- package/dist/chunk-U4PA632G.js.map +0 -1
- package/dist/cli-config-templates-GSXKLGU5.js +0 -5
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { generateConfigFile } from './chunk-
|
|
2
|
+
import { generateConfigFile } from './chunk-FVDXJYMO.js';
|
|
3
3
|
import './chunk-WUYLYCW2.js';
|
|
4
4
|
import './chunk-2H7UOFLK.js';
|
|
5
5
|
import process3 from 'process';
|
|
@@ -1076,7 +1076,7 @@ async function createProject(options) {
|
|
|
1076
1076
|
});
|
|
1077
1077
|
await generateFromTemplates(projectPath, context);
|
|
1078
1078
|
if (resolvedOptions.appType !== "fullstack") {
|
|
1079
|
-
const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-
|
|
1079
|
+
const { generateConfigFile: generateConfigFile2, generateEnvExample } = await import('./cli-config-templates-WGN2I23J.js');
|
|
1080
1080
|
const configs = resolvedOptions.moduleConfigs;
|
|
1081
1081
|
const isApiWorkspace = resolvedOptions.appType === "api";
|
|
1082
1082
|
const configDir = isApiWorkspace ? path2.join(projectPath, "apps", `${resolvedOptions.name}-service`, "config") : path2.join(projectPath, "config");
|
|
@@ -2118,6 +2118,69 @@ async function addModule(options) {
|
|
|
2118
2118
|
throw error;
|
|
2119
2119
|
}
|
|
2120
2120
|
}
|
|
2121
|
+
|
|
2122
|
+
// messages/en-US.json
|
|
2123
|
+
var en_US_default = {
|
|
2124
|
+
cli_invalidGenerateName: "Use a name starting with a letter, with only letters, digits, hyphens or underscores",
|
|
2125
|
+
cli_generateOutsideWorkspace: "Generated files must remain inside the workspace, including symbolic link targets",
|
|
2126
|
+
cli_generateExists: "File already exists: {path}. Use --force to overwrite it",
|
|
2127
|
+
cli_deploy_module_missing: "Deploy module not found. Install @h-ai/deploy first:",
|
|
2128
|
+
cli_deploy_load_credentials: "Loading credentials...",
|
|
2129
|
+
cli_deploy_credentials_failed: "Failed to load credentials: {message}",
|
|
2130
|
+
cli_deploy_credentials_loaded: "Loaded {count} credentials",
|
|
2131
|
+
cli_deploy_load_config: "Loading deploy config...",
|
|
2132
|
+
cli_deploy_config_missing: "Deploy config not found: {path}",
|
|
2133
|
+
cli_deploy_config_hint: "Run: hai add deploy to generate config template",
|
|
2134
|
+
cli_deploy_config_loaded: "Deploy config loaded",
|
|
2135
|
+
cli_deploy_scanning: "Scanning application...",
|
|
2136
|
+
cli_deploy_scan_failed: "Scan failed: {message}",
|
|
2137
|
+
cli_deploy_scanned: "Scanned: {name} (SvelteKit: {sveltekit}, Services: {services})",
|
|
2138
|
+
cli_deploy_none: "none",
|
|
2139
|
+
cli_deploy_initializing: "Initializing deploy module...",
|
|
2140
|
+
cli_deploy_init_failed: "Init failed: {message}",
|
|
2141
|
+
cli_deploy_initialized: "Deploy module initialized",
|
|
2142
|
+
cli_deploy_deploying: "Deploying application...",
|
|
2143
|
+
cli_deploy_failed: "Deploy failed: {message}",
|
|
2144
|
+
cli_deploy_success: "Deployment successful!",
|
|
2145
|
+
cli_deploy_url: " URL: {url}",
|
|
2146
|
+
cli_deploy_id: " ID: {id}",
|
|
2147
|
+
cli_deploy_env: " Env: {names}",
|
|
2148
|
+
cli_deploy_command_failed: "Deploy command failed"
|
|
2149
|
+
};
|
|
2150
|
+
|
|
2151
|
+
// messages/zh-CN.json
|
|
2152
|
+
var zh_CN_default = {
|
|
2153
|
+
cli_invalidGenerateName: "\u540D\u79F0\u5FC5\u987B\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u4E14\u4EC5\u5305\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u77ED\u6A2A\u7EBF\u6216\u4E0B\u5212\u7EBF",
|
|
2154
|
+
cli_generateOutsideWorkspace: "\u751F\u6210\u6587\u4EF6\u5FC5\u987B\u4F4D\u4E8E\u5DE5\u4F5C\u76EE\u5F55\u5185\uFF0C\u7B26\u53F7\u94FE\u63A5\u76EE\u6807\u4E5F\u4E0D\u5F97\u8D8A\u754C",
|
|
2155
|
+
cli_generateExists: "\u6587\u4EF6\u5DF2\u5B58\u5728\uFF1A{path}\u3002\u4F7F\u7528 --force \u624D\u53EF\u8986\u76D6",
|
|
2156
|
+
cli_deploy_module_missing: "\u672A\u627E\u5230\u90E8\u7F72\u6A21\u5757\uFF0C\u8BF7\u5148\u5B89\u88C5 @h-ai/deploy\uFF1A",
|
|
2157
|
+
cli_deploy_load_credentials: "\u6B63\u5728\u52A0\u8F7D\u51ED\u8BC1\u2026",
|
|
2158
|
+
cli_deploy_credentials_failed: "\u52A0\u8F7D\u51ED\u8BC1\u5931\u8D25\uFF1A{message}",
|
|
2159
|
+
cli_deploy_credentials_loaded: "\u5DF2\u52A0\u8F7D {count} \u9879\u51ED\u8BC1",
|
|
2160
|
+
cli_deploy_load_config: "\u6B63\u5728\u52A0\u8F7D\u90E8\u7F72\u914D\u7F6E\u2026",
|
|
2161
|
+
cli_deploy_config_missing: "\u672A\u627E\u5230\u90E8\u7F72\u914D\u7F6E\uFF1A{path}",
|
|
2162
|
+
cli_deploy_config_hint: "\u8FD0\u884C hai add deploy \u751F\u6210\u90E8\u7F72\u914D\u7F6E\u6A21\u677F",
|
|
2163
|
+
cli_deploy_config_loaded: "\u90E8\u7F72\u914D\u7F6E\u5DF2\u52A0\u8F7D",
|
|
2164
|
+
cli_deploy_scanning: "\u6B63\u5728\u626B\u63CF\u5E94\u7528\u2026",
|
|
2165
|
+
cli_deploy_scan_failed: "\u626B\u63CF\u5931\u8D25\uFF1A{message}",
|
|
2166
|
+
cli_deploy_scanned: "\u5DF2\u626B\u63CF\uFF1A{name}\uFF08SvelteKit\uFF1A{sveltekit}\uFF0C\u670D\u52A1\uFF1A{services}\uFF09",
|
|
2167
|
+
cli_deploy_none: "\u65E0",
|
|
2168
|
+
cli_deploy_initializing: "\u6B63\u5728\u521D\u59CB\u5316\u90E8\u7F72\u6A21\u5757\u2026",
|
|
2169
|
+
cli_deploy_init_failed: "\u521D\u59CB\u5316\u5931\u8D25\uFF1A{message}",
|
|
2170
|
+
cli_deploy_initialized: "\u90E8\u7F72\u6A21\u5757\u5DF2\u521D\u59CB\u5316",
|
|
2171
|
+
cli_deploy_deploying: "\u6B63\u5728\u90E8\u7F72\u5E94\u7528\u2026",
|
|
2172
|
+
cli_deploy_failed: "\u90E8\u7F72\u5931\u8D25\uFF1A{message}",
|
|
2173
|
+
cli_deploy_success: "\u90E8\u7F72\u6210\u529F\uFF01",
|
|
2174
|
+
cli_deploy_url: " \u5730\u5740\uFF1A{url}",
|
|
2175
|
+
cli_deploy_id: " \u6807\u8BC6\uFF1A{id}",
|
|
2176
|
+
cli_deploy_env: " \u73AF\u5883\u53D8\u91CF\uFF1A{names}",
|
|
2177
|
+
cli_deploy_command_failed: "\u90E8\u7F72\u547D\u4EE4\u5931\u8D25"
|
|
2178
|
+
};
|
|
2179
|
+
|
|
2180
|
+
// src/cli-i18n.ts
|
|
2181
|
+
var cliM = core.i18n.createMessageGetter({ "en-US": en_US_default, "zh-CN": zh_CN_default });
|
|
2182
|
+
|
|
2183
|
+
// src/commands/cli-deploy.ts
|
|
2121
2184
|
async function deployCommand(options) {
|
|
2122
2185
|
const spinner = ora();
|
|
2123
2186
|
const cwd = options.cwd ?? process3.cwd();
|
|
@@ -2126,67 +2189,68 @@ async function deployCommand(options) {
|
|
|
2126
2189
|
try {
|
|
2127
2190
|
let deployModule;
|
|
2128
2191
|
try {
|
|
2129
|
-
deployModule = await import('./src-
|
|
2192
|
+
deployModule = await import('./src-6ZBWDBUB.js');
|
|
2130
2193
|
} catch {
|
|
2131
|
-
core.logger.error(chalk.red("
|
|
2194
|
+
core.logger.error(chalk.red(cliM("cli_deploy_module_missing")));
|
|
2132
2195
|
core.logger.info(chalk.cyan(" pnpm add @h-ai/deploy"));
|
|
2133
|
-
|
|
2196
|
+
throw new Error(cliM("cli_deploy_module_missing"));
|
|
2134
2197
|
}
|
|
2135
2198
|
const { deploy } = deployModule;
|
|
2136
|
-
spinner.start("
|
|
2199
|
+
spinner.start(cliM("cli_deploy_load_credentials"));
|
|
2137
2200
|
const credResult = deploy.credentials.load();
|
|
2138
2201
|
if (!credResult.success) {
|
|
2139
|
-
|
|
2140
|
-
return;
|
|
2202
|
+
throw new Error(cliM("cli_deploy_credentials_failed", { params: { message: credResult.error.message } }));
|
|
2141
2203
|
}
|
|
2142
|
-
spinner.succeed(
|
|
2143
|
-
spinner.start("
|
|
2204
|
+
spinner.succeed(cliM("cli_deploy_credentials_loaded", { params: { count: credResult.data.length } }));
|
|
2205
|
+
spinner.start(cliM("cli_deploy_load_config"));
|
|
2144
2206
|
const configPath = resolve(appDir, "config", "_deploy.yml");
|
|
2145
2207
|
if (!existsSync(configPath)) {
|
|
2146
|
-
spinner.fail(chalk.red(
|
|
2147
|
-
core.logger.info(chalk.cyan("
|
|
2148
|
-
|
|
2208
|
+
spinner.fail(chalk.red(cliM("cli_deploy_config_missing", { params: { path: configPath } })));
|
|
2209
|
+
core.logger.info(chalk.cyan(cliM("cli_deploy_config_hint")));
|
|
2210
|
+
throw new Error(cliM("cli_deploy_config_missing", { params: { path: configPath } }));
|
|
2149
2211
|
}
|
|
2150
2212
|
const configContent = readFileSync(configPath, "utf-8");
|
|
2151
2213
|
const rawConfig = interpolateEnvFallback(configContent);
|
|
2152
2214
|
const deployConfig = parse(rawConfig);
|
|
2153
|
-
spinner.succeed("
|
|
2154
|
-
spinner.start("
|
|
2215
|
+
spinner.succeed(cliM("cli_deploy_config_loaded"));
|
|
2216
|
+
spinner.start(cliM("cli_deploy_scanning"));
|
|
2155
2217
|
const scanResult = await deploy.scan(appDir);
|
|
2156
2218
|
if (!scanResult.success) {
|
|
2157
|
-
|
|
2158
|
-
return;
|
|
2219
|
+
throw new Error(cliM("cli_deploy_scan_failed", { params: { message: scanResult.error.message } }));
|
|
2159
2220
|
}
|
|
2160
2221
|
const scan = scanResult.data;
|
|
2161
|
-
spinner.succeed(
|
|
2162
|
-
spinner.start("
|
|
2222
|
+
spinner.succeed(cliM("cli_deploy_scanned", { params: { name: scan.appName, sveltekit: String(scan.isSvelteKit), services: scan.requiredServices.join(", ") || cliM("cli_deploy_none") } }));
|
|
2223
|
+
spinner.start(cliM("cli_deploy_initializing"));
|
|
2163
2224
|
const initResult = await deploy.init(deployConfig);
|
|
2164
2225
|
if (!initResult.success) {
|
|
2165
|
-
|
|
2166
|
-
return;
|
|
2226
|
+
throw new Error(cliM("cli_deploy_init_failed", { params: { message: initResult.error.message } }));
|
|
2167
2227
|
}
|
|
2168
2228
|
closeDeploy = () => deploy.close();
|
|
2169
|
-
spinner.succeed("
|
|
2170
|
-
spinner.start("
|
|
2229
|
+
spinner.succeed(cliM("cli_deploy_initialized"));
|
|
2230
|
+
spinner.start(cliM("cli_deploy_deploying"));
|
|
2171
2231
|
const deployResult = await deploy.deployApp(appDir, {
|
|
2172
2232
|
projectName: options.projectName,
|
|
2173
2233
|
skipProvision: options.skipProvision,
|
|
2174
2234
|
skipBuild: options.skipBuild
|
|
2175
2235
|
});
|
|
2176
2236
|
if (!deployResult.success) {
|
|
2177
|
-
|
|
2178
|
-
|
|
2237
|
+
if (deployResult.error.ext?.recovery) {
|
|
2238
|
+
core.logger.warn(deployResult.error.suggestion ?? cliM("cli_deploy_command_failed"), {
|
|
2239
|
+
recovery: deployResult.error.ext.recovery
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
throw new Error(cliM("cli_deploy_failed", { params: { message: deployResult.error.message } }));
|
|
2179
2243
|
}
|
|
2180
|
-
spinner.succeed(chalk.green("
|
|
2244
|
+
spinner.succeed(chalk.green(cliM("cli_deploy_success")));
|
|
2181
2245
|
core.logger.info("");
|
|
2182
|
-
core.logger.info(chalk.cyan(
|
|
2183
|
-
core.logger.info(chalk.gray(
|
|
2246
|
+
core.logger.info(chalk.cyan(cliM("cli_deploy_url", { params: { url: deployResult.data.url } })));
|
|
2247
|
+
core.logger.info(chalk.gray(cliM("cli_deploy_id", { params: { id: deployResult.data.deploymentId } })));
|
|
2184
2248
|
if (deployResult.data.envVarsSet.length > 0) {
|
|
2185
|
-
core.logger.info(chalk.gray(
|
|
2249
|
+
core.logger.info(chalk.gray(cliM("cli_deploy_env", { params: { names: deployResult.data.envVarsSet.join(", ") } })));
|
|
2186
2250
|
}
|
|
2187
2251
|
core.logger.info("");
|
|
2188
2252
|
} catch (error) {
|
|
2189
|
-
spinner.fail(chalk.red("
|
|
2253
|
+
spinner.fail(chalk.red(cliM("cli_deploy_command_failed")));
|
|
2190
2254
|
core.logger.error(error instanceof Error ? error.message : String(error));
|
|
2191
2255
|
throw error;
|
|
2192
2256
|
} finally {
|
|
@@ -2195,6 +2259,7 @@ async function deployCommand(options) {
|
|
|
2195
2259
|
await closeDeploy();
|
|
2196
2260
|
} catch (error) {
|
|
2197
2261
|
core.logger.error("Failed to close deploy module", { error });
|
|
2262
|
+
process3.exitCode = 1;
|
|
2198
2263
|
}
|
|
2199
2264
|
}
|
|
2200
2265
|
}
|
|
@@ -2244,24 +2309,41 @@ async function generate(options) {
|
|
|
2244
2309
|
if (!generator) {
|
|
2245
2310
|
throw new Error(`\u672A\u77E5\u7684\u751F\u6210\u5668\u7C7B\u578B: ${resolvedOptions.type}`);
|
|
2246
2311
|
}
|
|
2312
|
+
if (!/^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/i.test(resolvedOptions.name))
|
|
2313
|
+
throw new Error(cliM("cli_invalidGenerateName"));
|
|
2247
2314
|
const outputDir = path2.resolve(cwd, resolvedOptions.output || generator.defaultPath);
|
|
2248
2315
|
const resolvedCwd = path2.resolve(cwd);
|
|
2249
2316
|
if (!outputDir.startsWith(resolvedCwd + path2.sep) && outputDir !== resolvedCwd) {
|
|
2250
|
-
|
|
2251
|
-
return;
|
|
2317
|
+
throw new Error(cliM("cli_generateOutsideWorkspace"));
|
|
2252
2318
|
}
|
|
2253
2319
|
const context = createTemplateContext(resolvedOptions.name, {
|
|
2254
2320
|
projectName: project?.name
|
|
2255
2321
|
});
|
|
2256
2322
|
spinner.start(`\u751F\u6210 ${generator.description}...`);
|
|
2257
|
-
const files = await generator.generate(
|
|
2323
|
+
const files = await generator.generate(context, outputDir);
|
|
2324
|
+
const realCwd = await fse.realpath(resolvedCwd);
|
|
2325
|
+
for (const file of files) {
|
|
2326
|
+
if (!resolvedOptions.force && await fse.pathExists(file.path))
|
|
2327
|
+
throw new Error(cliM("cli_generateExists", { params: { path: file.path } }));
|
|
2328
|
+
let ancestor = file.path;
|
|
2329
|
+
while (!await fse.pathExists(ancestor))
|
|
2330
|
+
ancestor = path2.dirname(ancestor);
|
|
2331
|
+
const realAncestor = await fse.realpath(ancestor);
|
|
2332
|
+
const relative = path2.relative(realCwd, realAncestor);
|
|
2333
|
+
if (relative === ".." || relative.startsWith(`..${path2.sep}`) || path2.isAbsolute(relative))
|
|
2334
|
+
throw new Error(cliM("cli_generateOutsideWorkspace"));
|
|
2335
|
+
}
|
|
2336
|
+
for (const file of files) {
|
|
2337
|
+
await fse.ensureDir(path2.dirname(file.path));
|
|
2338
|
+
await fse.writeFile(file.path, file.content, { encoding: "utf-8", flag: resolvedOptions.force ? "w" : "wx" });
|
|
2339
|
+
}
|
|
2258
2340
|
spinner.succeed();
|
|
2259
2341
|
core.logger.info("", {});
|
|
2260
2342
|
core.logger.info(chalk.green("\u2714 \u751F\u6210\u5B8C\u6210\uFF01"));
|
|
2261
2343
|
core.logger.info("", {});
|
|
2262
2344
|
core.logger.info("\u521B\u5EFA\u7684\u6587\u4EF6:");
|
|
2263
2345
|
files.forEach((file) => {
|
|
2264
|
-
core.logger.info(chalk.cyan(` ${path2.relative(cwd, file)}`));
|
|
2346
|
+
core.logger.info(chalk.cyan(` ${path2.relative(cwd, file.path)}`));
|
|
2265
2347
|
});
|
|
2266
2348
|
core.logger.info("", {});
|
|
2267
2349
|
} catch (error) {
|
|
@@ -2305,76 +2387,72 @@ async function resolveGenerateOptions(options) {
|
|
|
2305
2387
|
cwd: options.cwd ?? "."
|
|
2306
2388
|
};
|
|
2307
2389
|
}
|
|
2308
|
-
async function generatePage(
|
|
2390
|
+
async function generatePage(context, outputDir) {
|
|
2309
2391
|
const files = [];
|
|
2310
2392
|
const pageDir = path2.join(outputDir, context.kebabCase);
|
|
2311
|
-
const pageContent =
|
|
2312
|
-
/**
|
|
2313
|
-
* ${context.pascalCase} \u9875\u9762
|
|
2314
|
-
*/
|
|
2315
|
-
</script>
|
|
2316
|
-
|
|
2393
|
+
const pageContent = `<!-- ${context.pascalCase} \u9875\u9762 -->
|
|
2317
2394
|
<svelte:head>
|
|
2318
2395
|
<title>${context.pascalCase}</title>
|
|
2319
2396
|
</svelte:head>
|
|
2320
2397
|
|
|
2321
|
-
<div class=
|
|
2322
|
-
<h1 class=
|
|
2323
|
-
|
|
2398
|
+
<div class='container mx-auto p-4'>
|
|
2399
|
+
<h1 class='text-2xl font-bold mb-4'>${context.pascalCase}</h1>
|
|
2400
|
+
|
|
2324
2401
|
<!-- \u9875\u9762\u5185\u5BB9 -->
|
|
2325
2402
|
</div>
|
|
2326
2403
|
`;
|
|
2327
2404
|
const pagePath = path2.join(pageDir, "+page.svelte");
|
|
2328
|
-
|
|
2329
|
-
files.push(pagePath);
|
|
2405
|
+
files.push({ path: pagePath, content: pageContent });
|
|
2330
2406
|
const serverContent = `/**
|
|
2331
2407
|
* ${context.pascalCase} \u9875\u9762\u670D\u52A1\u7AEF
|
|
2332
2408
|
*/
|
|
2333
|
-
import type {
|
|
2409
|
+
import type { Actions, PageServerLoad } from './$types'
|
|
2334
2410
|
|
|
2335
|
-
export const load: PageServerLoad = async (
|
|
2411
|
+
export const load: PageServerLoad = async () => {
|
|
2336
2412
|
return {
|
|
2337
2413
|
// \u9875\u9762\u6570\u636E
|
|
2338
2414
|
}
|
|
2339
2415
|
}
|
|
2340
2416
|
|
|
2341
2417
|
export const actions: Actions = {
|
|
2342
|
-
default: async (
|
|
2418
|
+
default: async () => {
|
|
2343
2419
|
// \u8868\u5355\u5904\u7406
|
|
2344
2420
|
},
|
|
2345
2421
|
}
|
|
2346
2422
|
`;
|
|
2347
2423
|
const serverPath = path2.join(pageDir, "+page.server.ts");
|
|
2348
|
-
|
|
2349
|
-
files.push(serverPath);
|
|
2424
|
+
files.push({ path: serverPath, content: serverContent });
|
|
2350
2425
|
return files;
|
|
2351
2426
|
}
|
|
2352
|
-
async function generateComponent(
|
|
2427
|
+
async function generateComponent(context, outputDir) {
|
|
2353
2428
|
const files = [];
|
|
2354
|
-
const componentContent = `<script lang=
|
|
2429
|
+
const componentContent = `<script lang='ts'>
|
|
2430
|
+
import type { Snippet } from 'svelte'
|
|
2431
|
+
|
|
2355
2432
|
/**
|
|
2356
2433
|
* ${context.pascalCase} \u7EC4\u4EF6
|
|
2357
2434
|
*/
|
|
2358
|
-
|
|
2435
|
+
|
|
2359
2436
|
interface Props {
|
|
2360
2437
|
/** \u81EA\u5B9A\u4E49 class */
|
|
2361
2438
|
class?: string
|
|
2439
|
+
/** \u5B50\u5185\u5BB9\uFF08Svelte 5 snippet\uFF09 */
|
|
2440
|
+
children?: Snippet
|
|
2362
2441
|
}
|
|
2363
|
-
|
|
2364
|
-
|
|
2442
|
+
|
|
2443
|
+
const { class: className = '', children }: Props = $props()
|
|
2365
2444
|
</script>
|
|
2366
2445
|
|
|
2367
2446
|
<div class={className}>
|
|
2368
2447
|
<!-- \u7EC4\u4EF6\u5185\u5BB9 -->
|
|
2369
|
-
|
|
2448
|
+
{@render children?.()}
|
|
2370
2449
|
</div>
|
|
2371
2450
|
`;
|
|
2372
2451
|
const componentPath = path2.join(outputDir, `${context.pascalCase}.svelte`);
|
|
2373
|
-
|
|
2374
|
-
files.push(componentPath);
|
|
2452
|
+
files.push({ path: componentPath, content: componentContent });
|
|
2375
2453
|
return files;
|
|
2376
2454
|
}
|
|
2377
|
-
async function generateApi(
|
|
2455
|
+
async function generateApi(context, outputDir) {
|
|
2378
2456
|
const files = [];
|
|
2379
2457
|
const apiDir = path2.join(outputDir, context.kebabCase);
|
|
2380
2458
|
const serverContent = `/**
|
|
@@ -2382,44 +2460,35 @@ async function generateApi(_name, context, outputDir) {
|
|
|
2382
2460
|
*/
|
|
2383
2461
|
import type { RequestHandler } from './$types'
|
|
2384
2462
|
import { kit } from '@h-ai/kit'
|
|
2463
|
+
import { z } from 'zod'
|
|
2464
|
+
|
|
2465
|
+
/** \u793A\u4F8B\u8F93\u5165\uFF1B\u6DFB\u52A0\u4E1A\u52A1\u903B\u8F91\u524D\u6269\u5C55\u5B57\u6BB5\u548C\u7EA6\u675F\u3002 */
|
|
2466
|
+
const InputSchema = z.object({
|
|
2467
|
+
/** \u4E1A\u52A1\u540D\u79F0\uFF08\u975E\u7A7A\uFF09 */
|
|
2468
|
+
name: z.string().min(1),
|
|
2469
|
+
})
|
|
2385
2470
|
|
|
2386
2471
|
/**
|
|
2387
2472
|
* GET ${context.kebabCase}
|
|
2388
2473
|
*/
|
|
2389
|
-
export const GET: RequestHandler = async ({ locals }) => {
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
return kit.response.ok({ message: 'Hello from ${context.kebabCase}' }, requestId)
|
|
2394
|
-
}
|
|
2395
|
-
catch (error) {
|
|
2396
|
-
return kit.response.internalError()
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2474
|
+
export const GET: RequestHandler = kit.handler(async ({ locals }) => {
|
|
2475
|
+
return kit.response.ok({ items: [] }, locals.requestId)
|
|
2476
|
+
})
|
|
2399
2477
|
|
|
2400
2478
|
/**
|
|
2401
2479
|
* POST ${context.kebabCase}
|
|
2402
2480
|
*/
|
|
2403
|
-
export const POST: RequestHandler = async ({ request, locals }) => {
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
// \u5904\u7406\u8BF7\u6C42
|
|
2409
|
-
|
|
2410
|
-
return kit.response.ok({ success: true }, requestId)
|
|
2411
|
-
}
|
|
2412
|
-
catch (error) {
|
|
2413
|
-
return kit.response.internalError()
|
|
2414
|
-
}
|
|
2415
|
-
}
|
|
2481
|
+
export const POST: RequestHandler = kit.handler(async ({ request, locals }) => {
|
|
2482
|
+
const body = await kit.validate.body(request, InputSchema)
|
|
2483
|
+
// \u6821\u9A8C\u901A\u8FC7\u540E\u518D\u6267\u884C\u4E1A\u52A1\u64CD\u4F5C\uFF1B\u793A\u4F8B\u4EC5\u56DE\u4F20\u6570\u636E\uFF0C\u4E0D\u6267\u884C\u5199\u5165\u3002
|
|
2484
|
+
return kit.response.ok(body, locals.requestId)
|
|
2485
|
+
})
|
|
2416
2486
|
`;
|
|
2417
2487
|
const serverPath = path2.join(apiDir, "+server.ts");
|
|
2418
|
-
|
|
2419
|
-
files.push(serverPath);
|
|
2488
|
+
files.push({ path: serverPath, content: serverContent });
|
|
2420
2489
|
return files;
|
|
2421
2490
|
}
|
|
2422
|
-
async function generateModel(
|
|
2491
|
+
async function generateModel(context, outputDir) {
|
|
2423
2492
|
const files = [];
|
|
2424
2493
|
const modelContent = `/**
|
|
2425
2494
|
* ${context.pascalCase} \u6A21\u578B
|
|
@@ -2430,9 +2499,13 @@ import { z } from 'zod'
|
|
|
2430
2499
|
* ${context.pascalCase} Schema
|
|
2431
2500
|
*/
|
|
2432
2501
|
export const ${context.camelCase}Schema = z.object({
|
|
2502
|
+
/** \u8BB0\u5F55\u552F\u4E00\u6807\u8BC6 */
|
|
2433
2503
|
id: z.string(),
|
|
2504
|
+
/** \u663E\u793A\u540D\u79F0 */
|
|
2434
2505
|
name: z.string().min(1),
|
|
2506
|
+
/** \u521B\u5EFA\u65F6\u95F4 */
|
|
2435
2507
|
createdAt: z.date(),
|
|
2508
|
+
/** \u6700\u540E\u4FEE\u6539\u65F6\u95F4 */
|
|
2436
2509
|
updatedAt: z.date(),
|
|
2437
2510
|
})
|
|
2438
2511
|
|
|
@@ -2458,39 +2531,35 @@ export type Create${context.pascalCase} = z.infer<typeof create${context.pascalC
|
|
|
2458
2531
|
export type Update${context.pascalCase} = z.infer<typeof update${context.pascalCase}Schema>
|
|
2459
2532
|
`;
|
|
2460
2533
|
const modelPath = path2.join(outputDir, `${context.kebabCase}.ts`);
|
|
2461
|
-
|
|
2462
|
-
files.push(modelPath);
|
|
2534
|
+
files.push({ path: modelPath, content: modelContent });
|
|
2463
2535
|
return files;
|
|
2464
2536
|
}
|
|
2465
|
-
async function generateMigration(
|
|
2537
|
+
async function generateMigration(context, outputDir) {
|
|
2466
2538
|
const files = [];
|
|
2467
2539
|
const timestamp = Date.now();
|
|
2468
2540
|
const migrationContent = `/**
|
|
2469
2541
|
* \u8FC1\u79FB: ${context.pascalCase}
|
|
2470
2542
|
* \u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
2471
2543
|
*/
|
|
2472
|
-
import
|
|
2544
|
+
import { reldb } from '@h-ai/reldb'
|
|
2473
2545
|
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
)
|
|
2483
|
-
\`)
|
|
2546
|
+
/** \u5347\u7EA7\uFF1A\u8C03\u7528\u524D\u521D\u59CB\u5316 reldb\uFF0C\u8C03\u7528\u65B9\u5FC5\u987B\u68C0\u67E5\u8FD4\u56DE\u7684 HaiResult\u3002 */
|
|
2547
|
+
export function up() {
|
|
2548
|
+
return reldb.ddl.createTable('hai_app_${context.snakeCase}', {
|
|
2549
|
+
id: { type: 'TEXT', primaryKey: true },
|
|
2550
|
+
name: { type: 'TEXT', notNull: true },
|
|
2551
|
+
created_at: { type: 'TIMESTAMP', notNull: true },
|
|
2552
|
+
updated_at: { type: 'TIMESTAMP', notNull: true },
|
|
2553
|
+
})
|
|
2484
2554
|
}
|
|
2485
2555
|
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2556
|
+
/** \u56DE\u6EDA\u4F1A\u5220\u9664\u6574\u5F20\u8868\uFF1B\u7531\u5E94\u7528\u786E\u8BA4\u6570\u636E\u53EF\u5220\u9664\u540E\u663E\u5F0F\u8C03\u7528\u3002 */
|
|
2557
|
+
export function down() {
|
|
2558
|
+
return reldb.ddl.dropTable('hai_app_${context.snakeCase}')
|
|
2489
2559
|
}
|
|
2490
2560
|
`;
|
|
2491
2561
|
const migrationPath = path2.join(outputDir, `${timestamp}_${context.snakeCase}.ts`);
|
|
2492
|
-
|
|
2493
|
-
files.push(migrationPath);
|
|
2562
|
+
files.push({ path: migrationPath, content: migrationContent });
|
|
2494
2563
|
return files;
|
|
2495
2564
|
}
|
|
2496
2565
|
var MODULE_CONFIG_MAP = {
|