@agile-team/jh4j-cloud-cli 0.3.0 → 0.5.0
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/CHANGELOG.md +19 -0
- package/README.md +309 -87
- package/dist/index.js +113 -74
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../package.json","../src/constants.ts","../src/catalog.ts","../src/utils/fs.ts","../src/core/template-source.ts","../src/utils/process.ts","../src/core/template-cache.ts","../src/core/user-config.ts","../src/commands/create.ts","../src/core/project-generator.ts","../src/core/template-manifest.ts","../src/commands/doctor.ts","../src/commands/info.ts","../src/commands/list.ts","../src/commands/template.ts","../src/commands/config.ts","../src/commands/cache.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { COMMAND_NAME, CLI_VERSION } from \"./constants.js\";\nimport { findTemplate, loadCatalog } from \"./catalog.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./core/template-source.js\";\nimport { loadUserConfig } from \"./core/user-config.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { infoCommand } from \"./commands/info.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { validateTemplateCommand } from \"./commands/template.js\";\nimport {\n configGetCommand,\n configListCommand,\n configResetCommand,\n configSetCommand,\n configUnsetCommand\n} from \"./commands/config.js\";\nimport { cacheClearCommand, cacheListCommand } from \"./commands/cache.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n program\n .name(COMMAND_NAME)\n .description(\"JH4J Cloud 企业内部标准化项目脚手架\")\n .version(CLI_VERSION);\n\n program\n .command(\"create [name]\")\n .description(\"根据标准模板创建项目\")\n .option(\"-c, --category <category>\", \"项目类型:frontend、backend 或 mobile\")\n .option(\"-t, --template <id>\", \"模板 ID\")\n .option(\"--features <ids>\", \"启用的模板能力,多个 ID 使用逗号分隔\")\n .option(\"--no-standards\", \"不启用模板提供的 Git/代码标准化能力\")\n .option(\"--source <path-or-url>\", \"覆盖模板源(本地目录或 Git URL)\")\n .option(\"--ref <branch-or-tag>\", \"Git 分支或标签\", \"main\")\n .option(\"--module <name>\", \"平台模块标识\")\n .option(\"--title <title>\", \"系统标题\")\n .option(\"--port <port>\", \"开发端口\")\n .option(\"--npm-registry <url>\", \"npm registry(需包含企业定制包)\")\n .option(\"--jhlc-registry <url>\", \"@jhlc 私有 registry\")\n .option(\"--local-backend <url>\", \"本地后端地址\")\n .option(\"--local-public <url>\", \"本地 public 地址\")\n .option(\"--config <json-file>\", \"从 JSON 文件读取创建参数\")\n .option(\"-y, --yes\", \"接受模板默认值,非交互创建\")\n .option(\"--dry-run\", \"只预览,不写入文件\")\n .option(\"--skip-install\", \"跳过依赖安装\")\n .option(\"--skip-git\", \"跳过 Git 初始化\")\n .option(\"--force\", \"覆盖已存在的同名目录\")\n .option(\"--no-cache\", \"不使用已有远程模板缓存\")\n .action(createCommand);\n\n program\n .command(\"list\")\n .description(\"列出可用模板\")\n .option(\"--json\", \"输出 JSON\")\n .action(listCommand);\n program\n .command(\"doctor\")\n .description(\"检查本机环境和模板可用性\")\n .option(\"--json\", \"输出 JSON\")\n .action(doctorCommand);\n program\n .command(\"info [path]\")\n .description(\"显示已生成项目的模板与版本信息\")\n .option(\"--json\", \"输出 JSON\")\n .action(infoCommand);\n\n const template = program.command(\"template\").description(\"模板维护命令\");\n template\n .command(\"validate [path]\")\n .description(\"校验模板 manifest 与模板契约\")\n .action(async (templatePath?: string) => {\n if (templatePath) return validateTemplateCommand(templatePath);\n const config = await loadUserConfig();\n const selected = findTemplate(await loadCatalog(config));\n const acquired = await acquireTemplateFromSources(\n resolveTemplateSources(selected, undefined, config.templateSource),\n config.templateRef ?? selected.defaultRef,\n { cacheTtlMinutes: config.cacheTtlMinutes }\n );\n try {\n return await validateTemplateCommand(acquired.root);\n } finally {\n await acquired.cleanup();\n }\n });\n\n const config = program.command(\"config\").description(\"管理用户默认配置\");\n config\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(configListCommand);\n config.command(\"get <key>\").action(configGetCommand);\n config.command(\"set <key> <value>\").action(configSetCommand);\n config.command(\"unset <key>\").action(configUnsetCommand);\n config.command(\"reset\").action(configResetCommand);\n\n const cache = program.command(\"cache\").description(\"管理远程模板缓存\");\n cache\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(cacheListCommand);\n cache.command(\"clear\").action(cacheClearCommand);\n\n return program;\n}\n\nexport async function runCli(argv = process.argv): Promise<void> {\n await createProgram().parseAsync(argv);\n}\n","{\n \"name\": \"@agile-team/jh4j-cloud-cli\",\n \"version\": \"0.3.0\",\n \"description\": \"JH4J Cloud 企业内部标准化项目脚手架\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/ChenyCHENYU/jh4j-cloud-cli.git\"\n },\n \"homepage\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli/issues\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \"^22.12.0 || ^24.0.0\",\n \"pnpm\": \">=11.8.0\"\n },\n \"packageManager\": \"pnpm@11.8.0\",\n \"bin\": {\n \"jh4j\": \"bin/jh4j.js\"\n },\n \"files\": [\n \"bin\",\n \"dist\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"catalog.schema.json\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"start\": \"node bin/jh4j.js\",\n \"check\": \"pnpm typecheck && pnpm test && pnpm build\",\n \"prepack\": \"pnpm check\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.7.0\",\n \"commander\": \"^15.0.0\",\n \"semver\": \"^7.8.5\",\n \"tar\": \"^7.5.19\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.13.3\",\n \"@types/semver\": \"7.7.1\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\",\n \"vitest\": \"4.1.10\"\n }\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\n\nexport const CLI_NAME = \"@agile-team/jh4j-cloud-cli\";\nexport const CLI_VERSION = packageJson.version;\nexport const COMMAND_NAME = \"jh4j\";\nexport const SUPPORTED_NODE_MAJORS = new Set([22, 24]);\nexport const TEMPLATE_SOURCE_ENV = \"JH4J_UI_TEMPLATE_SOURCE\";\nexport const JH4J_HOME_ENV = \"JH4J_HOME\";\nexport const CATALOG_FILE_ENV = \"JH4J_CATALOG_FILE\";\nexport const USER_CONFIG_SCHEMA_VERSION = 1;\n","import { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { CATALOG_FILE_ENV, TEMPLATE_SOURCE_ENV } from \"./constants.js\";\nimport { readJson } from \"./utils/fs.js\";\nimport type { CatalogFile, CatalogTemplate, UserConfig } from \"./types.js\";\n\nconst siblingTemplatePath = fileURLToPath(\n new URL(\"../../jh4j-ui-template/\", import.meta.url)\n);\nconst remoteTemplateSources = [\n \"https://github.com/ChenyCHENYU/jh4j-ui-template.git\",\n \"https://gitee.com/ycyplus163/jh4j-ui-template.git\"\n];\n\nexport const BUILTIN_TEMPLATES: CatalogTemplate[] = [\n {\n id: \"web.jh4j-mf-remote\",\n name: \"JH4J PC 微前端业务模板\",\n description: \"Vue 3 + Vite + Module Federation 标准业务子系统\",\n category: \"frontend\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingTemplatePath)\n ? siblingTemplatePath\n : remoteTemplateSources[0],\n sources: remoteTemplateSources,\n defaultRef: \"main\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"module-federation\", \"pc\"]\n }\n];\n\nfunction validateCatalogTemplate(template: CatalogTemplate): void {\n if (!template.id || !template.name || !template.category) {\n throw new Error(\"Catalog 模板缺少 id、name 或 category\");\n }\n if (!new Set([\"frontend\", \"backend\", \"mobile\"]).has(template.category)) {\n throw new Error(`Catalog 模板 ${template.id} 的 category 无效`);\n }\n if (!new Set([\"stable\", \"beta\"]).has(template.status)) {\n throw new Error(`Catalog 模板 ${template.id} 的 status 无效`);\n }\n if (!template.defaultRef) {\n throw new Error(`Catalog 模板 ${template.id} 缺少 defaultRef`);\n }\n if (!template.defaultSource && !template.sourceEnvironment) {\n throw new Error(`Catalog 模板 ${template.id} 没有可解析的模板源`);\n }\n if (template.sources?.some((source) => !source.trim())) {\n throw new Error(`Catalog 模板 ${template.id} 包含空的备用源`);\n }\n}\n\nfunction resolveCatalogSource(source: string, catalogDirectory: string): string {\n const isRemote =\n /^(?:https?|ssh|file):\\/\\//.test(source) || source.startsWith(\"git@\");\n return isRemote || path.isAbsolute(source)\n ? source\n : path.resolve(catalogDirectory, source);\n}\n\nexport async function loadCatalog(config?: UserConfig): Promise<CatalogTemplate[]> {\n const configuredFile = process.env[CATALOG_FILE_ENV] || config?.catalogFile;\n if (!configuredFile) return [...BUILTIN_TEMPLATES];\n\n const catalogPath = path.resolve(configuredFile);\n if (!existsSync(catalogPath)) {\n throw new Error(`Catalog 文件不存在: ${catalogPath}`);\n }\n const external = await readJson<CatalogFile>(catalogPath);\n if (external.schemaVersion !== 1 || !Array.isArray(external.templates)) {\n throw new Error(`Catalog 文件格式无效: ${catalogPath}`);\n }\n const catalogDirectory = path.dirname(catalogPath);\n external.templates = external.templates.map((template) => {\n return {\n ...template,\n defaultSource: resolveCatalogSource(\n template.defaultSource,\n catalogDirectory\n ),\n sources: template.sources?.map((source) =>\n resolveCatalogSource(source, catalogDirectory)\n )\n };\n });\n external.templates.forEach(validateCatalogTemplate);\n\n const merged = new Map(BUILTIN_TEMPLATES.map((item) => [item.id, item]));\n external.templates.forEach((item) => merged.set(item.id, item));\n return [...merged.values()];\n}\n\nexport function findTemplate(\n catalog: CatalogTemplate[],\n id?: string\n): CatalogTemplate {\n const selected = id ?? catalog[0]?.id;\n const template = catalog.find((item) => item.id === selected);\n if (!template) {\n throw new Error(\n `模板不存在: ${selected}。可用模板: ${catalog.map((item) => item.id).join(\", \")}`\n );\n }\n return template;\n}\n","import { cp, mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst EXCLUDED_TEMPLATE_PATHS = new Set([\n \".git\",\n \".jhlc\",\n \"dist\",\n \"node_modules\"\n]);\n\nexport async function readJson<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, \"utf8\")) as T;\n}\n\nexport async function writeJson(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function isDirectory(directory: string): Promise<boolean> {\n try {\n return (await stat(directory)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function isDirectoryEmpty(directory: string): Promise<boolean> {\n if (!existsSync(directory)) return true;\n const { readdir } = await import(\"node:fs/promises\");\n return (await readdir(directory)).length === 0;\n}\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n targetRoot: string\n): Promise<void> {\n await mkdir(targetRoot, { recursive: true });\n await cp(sourceRoot, targetRoot, {\n recursive: true,\n force: true,\n filter(source) {\n const relative = path.relative(sourceRoot, source);\n if (!relative) return true;\n const [topLevel] = relative.split(path.sep);\n return !EXCLUDED_TEMPLATE_PATHS.has(topLevel);\n }\n });\n}\n\nexport async function removePath(target: string): Promise<void> {\n await rm(target, { recursive: true, force: true, maxRetries: 3 });\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { x as extractTar } from \"tar\";\nimport type { CatalogTemplate } from \"../types.js\";\nimport { isDirectory } from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n createTemplateCacheStaging,\n isTemplateCacheFresh,\n readTemplateCacheEntry\n} from \"./template-cache.js\";\n\nconst MAX_ARCHIVE_BYTES = 200 * 1024 * 1024;\n\nexport interface AcquiredTemplate {\n root: string;\n source: string;\n cleanup(): Promise<void>;\n}\n\nexport function resolveTemplateSource(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string {\n return resolveTemplateSources(template, override, configuredSource)[0];\n}\n\nexport function resolveTemplateSources(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string[] {\n const exclusiveSource =\n override ||\n (template.sourceEnvironment\n ? process.env[template.sourceEnvironment]\n : undefined) ||\n configuredSource;\n if (exclusiveSource) return [exclusiveSource];\n return [...new Set([template.defaultSource, ...(template.sources ?? [])])];\n}\n\nfunction isGitSource(source: string): boolean {\n return (\n source.startsWith(\"git@\") ||\n source.startsWith(\"ssh://\") ||\n source.startsWith(\"file://\") ||\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.endsWith(\".git\")\n );\n}\n\nfunction isArchiveSource(source: string): boolean {\n const pathname = source.split(/[?#]/, 1)[0].toLowerCase();\n return pathname.endsWith(\".tgz\") || pathname.endsWith(\".tar.gz\") || pathname.endsWith(\".tar\");\n}\n\nasync function getFreshCache(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate | null> {\n const cacheEntry = await readTemplateCacheEntry(source, ref);\n if (\n !options.noCache &&\n cacheEntry &&\n isTemplateCacheFresh(cacheEntry, options.cacheTtlMinutes ?? 60)\n ) {\n return {\n root: cacheEntry.root,\n source: `${source}#${ref} (cache)`,\n async cleanup() {}\n };\n }\n return null;\n}\n\nasync function normalizeExtractedTemplate(\n stagingRoot: string,\n templateRoot: string\n): Promise<void> {\n if (existsSync(path.join(templateRoot, \"template.manifest.json\"))) return;\n const children = await readdir(templateRoot, { withFileTypes: true });\n const candidates = children.filter(\n (entry) =>\n entry.isDirectory() &&\n existsSync(path.join(templateRoot, entry.name, \"template.manifest.json\"))\n );\n if (candidates.length !== 1) {\n throw new Error(\"压缩包根目录或唯一一级目录中未找到 template.manifest.json\");\n }\n const normalizedRoot = path.join(stagingRoot, \".normalized-template\");\n await rename(path.join(templateRoot, candidates[0].name), normalizedRoot);\n await rm(templateRoot, { recursive: true, force: true });\n await rename(normalizedRoot, templateRoot);\n}\n\nasync function acquireArchiveTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate> {\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n const archiveFile = path.join(cacheStaging.stagingRoot, \"template.tgz\");\n try {\n if (source.startsWith(\"http://\") || source.startsWith(\"https://\")) {\n const response = await fetch(source, { signal: AbortSignal.timeout(60_000) });\n if (!response.ok) {\n throw new Error(`模板压缩包下载失败: HTTP ${response.status}`);\n }\n const declaredLength = Number(response.headers.get(\"content-length\") || 0);\n if (declaredLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n const archiveBuffer = Buffer.from(await response.arrayBuffer());\n if (archiveBuffer.byteLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n await writeFile(archiveFile, archiveBuffer);\n } else {\n const { copyFile } = await import(\"node:fs/promises\");\n await copyFile(path.resolve(source), archiveFile);\n }\n await mkdir(cacheStaging.templateRoot, { recursive: true });\n await extractTar({ file: archiveFile, cwd: cacheStaging.templateRoot });\n await normalizeExtractedTemplate(\n cacheStaging.stagingRoot,\n cacheStaging.templateRoot\n );\n await rm(archiveFile, { force: true });\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source} (archive)`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n const localPath = path.resolve(source);\n if (existsSync(localPath)) {\n if (await isDirectory(localPath)) {\n return {\n root: localPath,\n source: localPath,\n async cleanup() {}\n };\n }\n if (isArchiveSource(localPath)) {\n return acquireArchiveTemplate(localPath, ref, options);\n }\n throw new Error(`模板源不是目录或支持的 tar 压缩包: ${localPath}`);\n }\n\n if (isArchiveSource(source)) {\n return acquireArchiveTemplate(source, ref, options);\n }\n\n if (!isGitSource(source)) {\n throw new Error(`模板源不存在: ${source}`);\n }\n\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n try {\n await runCommand(\n \"git\",\n [\n \"-c\",\n \"http.lowSpeedLimit=1024\",\n \"-c\",\n \"http.lowSpeedTime=15\",\n \"clone\",\n \"--depth\",\n \"1\",\n \"--branch\",\n ref,\n source,\n cacheStaging.templateRoot\n ],\n { stdio: \"pipe\", env: { GIT_TERMINAL_PROMPT: \"0\" } }\n );\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source}#${ref}`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplateFromSources(\n sources: string[],\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n if (!sources.length) throw new Error(\"没有可用的模板源\");\n const failures: string[] = [];\n for (const source of [...new Set(sources)]) {\n try {\n return await acquireTemplate(source, ref, options);\n } catch (error) {\n failures.push(`${source}: ${(error as Error).message}`);\n }\n }\n throw new Error(`所有模板源均不可用:\\n- ${failures.join(\"\\n- \")}`);\n}\n","import { spawn } from \"node:child_process\";\n\nexport interface RunCommandOptions {\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport function platformCommand(command: string): string {\n if (process.platform !== \"win32\") return command;\n return command === \"pnpm\" || command === \"npm\" || command === \"npx\"\n ? `${command}.cmd`\n : command;\n}\n\nexport async function runCommand(\n command: string,\n args: string[],\n options: RunCommandOptions = {}\n): Promise<string> {\n const stdio = options.stdio ?? \"inherit\";\n return new Promise((resolve, reject) => {\n const executable = platformCommand(command);\n const isWindowsCommand =\n process.platform === \"win32\" && executable.endsWith(\".cmd\");\n const spawnExecutable = isWindowsCommand\n ? process.env.ComSpec || \"cmd.exe\"\n : executable;\n const spawnArgs = isWindowsCommand\n ? [\"/d\", \"/s\", \"/c\", executable, ...args]\n : args;\n const child = spawn(spawnExecutable, spawnArgs, {\n cwd: options.cwd,\n stdio,\n env: { ...process.env, ...options.env },\n windowsHide: true\n });\n\n let output = \"\";\n if (stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolve(output.trim());\n return;\n }\n reject(\n new Error(\n `${command} ${args.join(\" \")} 执行失败(exit ${code ?? \"unknown\"})${output ? `\\n${output.trim()}` : \"\"}`\n )\n );\n });\n });\n}\n\nexport async function inspectCommand(\n command: string,\n args: string[] = [\"--version\"]\n): Promise<{ ok: boolean; output: string }> {\n try {\n return { ok: true, output: await runCommand(command, args, { stdio: \"pipe\" }) };\n } catch (error) {\n return { ok: false, output: (error as Error).message };\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getJh4jHome } from \"./user-config.js\";\nimport { readJson, removePath, writeJson } from \"../utils/fs.js\";\nimport type { TemplateCacheMetadata } from \"../types.js\";\n\nconst CACHE_SCHEMA_VERSION = 1;\n\nexport interface TemplateCacheEntry {\n key: string;\n root: string;\n metadata: TemplateCacheMetadata;\n sizeBytes: number;\n}\n\nexport function getTemplateCacheRoot(): string {\n return path.join(getJh4jHome(), \"cache\", \"templates\");\n}\n\nexport function getTemplateCacheKey(source: string, ref: string): string {\n return createHash(\"sha256\").update(`${source}\\0${ref}`).digest(\"hex\").slice(0, 20);\n}\n\nfunction getEntryPaths(key: string) {\n const entryRoot = path.join(getTemplateCacheRoot(), key);\n return {\n entryRoot,\n templateRoot: path.join(entryRoot, \"template\"),\n metadataPath: path.join(entryRoot, \"metadata.json\")\n };\n}\n\nexport async function readTemplateCacheEntry(\n source: string,\n ref: string\n): Promise<TemplateCacheEntry | null> {\n const key = getTemplateCacheKey(source, ref);\n const paths = getEntryPaths(key);\n if (!existsSync(paths.templateRoot) || !existsSync(paths.metadataPath)) return null;\n try {\n const metadata = await readJson<TemplateCacheMetadata>(paths.metadataPath);\n if (\n metadata.schemaVersion !== CACHE_SCHEMA_VERSION ||\n metadata.source !== source ||\n metadata.ref !== ref\n ) {\n return null;\n }\n return {\n key,\n root: paths.templateRoot,\n metadata,\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n };\n } catch {\n return null;\n }\n}\n\nexport function isTemplateCacheFresh(\n entry: TemplateCacheEntry,\n ttlMinutes: number\n): boolean {\n if (ttlMinutes <= 0) return false;\n const cachedAt = Date.parse(entry.metadata.cachedAt);\n return Number.isFinite(cachedAt) && Date.now() - cachedAt < ttlMinutes * 60_000;\n}\n\nexport async function createTemplateCacheStaging(\n source: string,\n ref: string\n): Promise<{\n key: string;\n entryRoot: string;\n stagingRoot: string;\n templateRoot: string;\n commit(): Promise<void>;\n cleanup(): Promise<void>;\n}> {\n const key = getTemplateCacheKey(source, ref);\n const cacheRoot = getTemplateCacheRoot();\n await mkdir(cacheRoot, { recursive: true });\n const stagingRoot = path.join(\n cacheRoot,\n `.${key}.tmp-${process.pid}-${Date.now()}`\n );\n const templateRoot = path.join(stagingRoot, \"template\");\n const entryRoot = path.join(cacheRoot, key);\n await mkdir(stagingRoot, { recursive: true });\n\n return {\n key,\n entryRoot,\n stagingRoot,\n templateRoot,\n async commit() {\n await writeJson(path.join(stagingRoot, \"metadata.json\"), {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source,\n ref,\n cachedAt: new Date().toISOString()\n } satisfies TemplateCacheMetadata);\n await removePath(entryRoot);\n await rename(stagingRoot, entryRoot);\n },\n cleanup: () => removePath(stagingRoot)\n };\n}\n\nasync function calculateDirectorySize(directory: string): Promise<number> {\n let total = 0;\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(directory, entry.name);\n if (entry.isDirectory()) total += await calculateDirectorySize(absolute);\n else if (entry.isFile()) total += (await stat(absolute)).size;\n }\n return total;\n}\n\nexport async function listTemplateCache(): Promise<TemplateCacheEntry[]> {\n const cacheRoot = getTemplateCacheRoot();\n if (!existsSync(cacheRoot)) return [];\n const entries: TemplateCacheEntry[] = [];\n for (const directory of await readdir(cacheRoot, { withFileTypes: true })) {\n if (!directory.isDirectory() || directory.name.startsWith(\".\")) continue;\n const paths = getEntryPaths(directory.name);\n if (!existsSync(paths.metadataPath) || !existsSync(paths.templateRoot)) continue;\n try {\n entries.push({\n key: directory.name,\n root: paths.templateRoot,\n metadata: await readJson<TemplateCacheMetadata>(paths.metadataPath),\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n });\n } catch {\n // 损坏条目由 clear 或下一次拉取覆盖。\n }\n }\n return entries.sort((a, b) =>\n b.metadata.cachedAt.localeCompare(a.metadata.cachedAt)\n );\n}\n\nexport async function clearTemplateCache(): Promise<void> {\n await removePath(getTemplateCacheRoot());\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { JH4J_HOME_ENV, USER_CONFIG_SCHEMA_VERSION } from \"../constants.js\";\nimport { readJson, writeJson } from \"../utils/fs.js\";\nimport type { UserConfig } from \"../types.js\";\n\nexport const DEFAULT_USER_CONFIG: UserConfig = {\n schemaVersion: USER_CONFIG_SCHEMA_VERSION,\n autoInstall: true,\n autoGit: true,\n cacheTtlMinutes: 60\n};\n\nexport function getJh4jHome(): string {\n return path.resolve(process.env[JH4J_HOME_ENV] || path.join(os.homedir(), \".jh4j\"));\n}\n\nexport function getUserConfigPath(): string {\n return path.join(getJh4jHome(), \"config.json\");\n}\n\nexport async function loadUserConfig(): Promise<UserConfig> {\n const configPath = getUserConfigPath();\n if (!existsSync(configPath)) return { ...DEFAULT_USER_CONFIG };\n\n const stored = await readJson<Partial<UserConfig>>(configPath);\n if (\n stored.schemaVersion !== undefined &&\n stored.schemaVersion !== USER_CONFIG_SCHEMA_VERSION\n ) {\n throw new Error(\n `不支持的用户配置版本: ${stored.schemaVersion},当前要求 ${USER_CONFIG_SCHEMA_VERSION}`\n );\n }\n return { ...DEFAULT_USER_CONFIG, ...stored };\n}\n\nexport async function saveUserConfig(config: UserConfig): Promise<void> {\n await writeJson(getUserConfigPath(), {\n ...config,\n schemaVersion: USER_CONFIG_SCHEMA_VERSION\n });\n}\n\nconst CONFIG_KEYS = new Set<keyof UserConfig>([\n \"catalogFile\",\n \"templateSource\",\n \"templateRef\",\n \"npmRegistry\",\n \"jhlcRegistry\",\n \"autoInstall\",\n \"autoGit\",\n \"cacheTtlMinutes\"\n]);\n\nexport function parseUserConfigValue(\n key: string,\n rawValue: string\n): [keyof UserConfig, UserConfig[keyof UserConfig]] {\n if (!CONFIG_KEYS.has(key as keyof UserConfig)) {\n throw new Error(`不支持的配置项: ${key}`);\n }\n const typedKey = key as keyof UserConfig;\n if (typedKey === \"autoInstall\" || typedKey === \"autoGit\") {\n const normalized = rawValue.toLowerCase();\n if (!new Set([\"true\", \"false\"]).has(normalized)) {\n throw new Error(`${key} 只能是 true 或 false`);\n }\n return [typedKey, normalized === \"true\"];\n }\n if (typedKey === \"cacheTtlMinutes\") {\n const value = Number(rawValue);\n if (!Number.isInteger(value) || value < 0 || value > 10080) {\n throw new Error(\"cacheTtlMinutes 必须是 0 到 10080 之间的整数\");\n }\n return [typedKey, value];\n }\n return [typedKey, rawValue.trim()];\n}\n","import * as prompts from \"@clack/prompts\";\nimport { findTemplate, loadCatalog } from \"../catalog.js\";\nimport { generateProject } from \"../core/project-generator.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n TemplateCategory\n} from \"../types.js\";\n\nconst CATEGORY_OPTIONS: Array<{\n value: TemplateCategory;\n label: string;\n hint: string;\n}> = [\n { value: \"frontend\", label: \"前端\", hint: \"PC、Web 与微前端应用\" },\n { value: \"backend\", label: \"后端\", hint: \"Java 服务与云原生应用\" },\n { value: \"mobile\", label: \"移动端\", hint: \"App、H5 与跨端应用\" }\n];\n\nfunction isCategory(value: string): value is TemplateCategory {\n return CATEGORY_OPTIONS.some((item) => item.value === value);\n}\n\nexport function templatesByCategory(\n templates: CatalogTemplate[],\n category: TemplateCategory\n): CatalogTemplate[] {\n return templates.filter((template) => template.category === category);\n}\n\nasync function selectCategory(\n templates: CatalogTemplate[],\n requestedCategory: string | undefined,\n nonInteractive: boolean\n): Promise<TemplateCategory> {\n if (requestedCategory) {\n if (!isCategory(requestedCategory)) {\n throw new Error(\n `项目类型无效: ${requestedCategory}。可用值: frontend、backend、mobile`\n );\n }\n if (!templatesByCategory(templates, requestedCategory).length) {\n throw new Error(`项目类型 ${requestedCategory} 暂无可用模板`);\n }\n return requestedCategory;\n }\n\n const firstAvailable = CATEGORY_OPTIONS.find(\n (item) => templatesByCategory(templates, item.value).length > 0\n );\n if (!firstAvailable) throw new Error(\"Catalog 中没有可用模板\");\n if (nonInteractive) return firstAvailable.value;\n\n const selected = await prompts.select({\n message: \"选择项目类型\",\n options: CATEGORY_OPTIONS.map((item) => {\n const count = templatesByCategory(templates, item.value).length;\n return {\n value: item.value,\n label: item.label,\n hint: count ? `${item.hint} · ${count} 个模板` : `${item.hint} · 暂未提供`,\n disabled: count === 0\n };\n })\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return selected as TemplateCategory;\n}\n\nasync function selectTemplate(\n templates: CatalogTemplate[],\n options: CreateOptions\n): Promise<CatalogTemplate> {\n if (options.template) {\n const selected = findTemplate(templates, options.template);\n if (options.category && selected.category !== options.category) {\n throw new Error(\n `模板 ${selected.id} 属于 ${selected.category},与 --category ${options.category} 不一致`\n );\n }\n return selected;\n }\n\n const category = await selectCategory(\n templates,\n options.category,\n Boolean(options.yes)\n );\n const candidates = templatesByCategory(templates, category);\n if (options.yes) return findTemplate(candidates);\n\n const selected = await prompts.select({\n message: \"选择项目模板\",\n options: candidates.map((template) => ({\n value: template.id,\n label: template.name,\n hint: `${template.status} · ${template.description}`\n }))\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return findTemplate(candidates, String(selected));\n}\n\nexport async function createCommand(\n requestedName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n prompts.intro(\"JH4J Cloud 项目创建\");\n const userConfig = await loadUserConfig();\n const catalog = await loadCatalog(userConfig);\n\n let projectName = requestedName;\n if (!projectName) {\n if (options.yes) throw new Error(\"非交互模式必须指定项目名称\");\n const answer = await prompts.text({\n message: \"项目名称\",\n placeholder: \"jh4j-ui-app\"\n });\n if (prompts.isCancel(answer)) throw new Error(\"用户取消创建\");\n projectName = String(answer);\n }\n\n const template = await selectTemplate(catalog, options);\n const result = await generateProject(\n template,\n projectName,\n options,\n process.cwd(),\n userConfig\n );\n if (options.dryRun) {\n prompts.outro(\"Dry Run 完成,未写入任何项目文件\");\n return;\n }\n\n prompts.note(\n [\n `目录: ${result.targetRoot}`,\n `模板: ${result.templateId}@${result.templateVersion}`,\n `来源: ${result.source}`,\n `能力: ${result.features.length ? result.features.join(\", \") : \"无可选能力\"}`,\n `依赖: ${result.installed ? \"已安装\" : \"未安装\"}`,\n `Git: ${result.gitInitialized ? \"main 已初始化\" : \"未初始化\"}`,\n \"\",\n `cd ${projectName}`,\n ...(!result.installed ? [\"pnpm install\"] : []),\n \"pnpm dev\"\n ].join(\"\\n\"),\n \"创建成功\"\n );\n prompts.outro(\"Happy coding!\");\n}\n","import { existsSync } from \"node:fs\";\nimport { rename, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as prompts from \"@clack/prompts\";\nimport { satisfies } from \"semver\";\nimport { CLI_NAME, CLI_VERSION } from \"../constants.js\";\nimport {\n copyTemplateTree,\n isDirectoryEmpty,\n readJson,\n removePath,\n writeJson\n} from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./template-source.js\";\nimport { loadTemplateManifest } from \"./template-manifest.js\";\nimport { DEFAULT_USER_CONFIG } from \"./user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n ProjectInput,\n TemplateManifest,\n UserConfig\n} from \"../types.js\";\n\nconst ENV_NAMES = [\"dev\", \"sit\", \"uat\", \"pre\", \"prd\"] as const;\ntype PartialProjectInput = Partial<Omit<ProjectInput, \"environments\">> & {\n environments?: Partial<ProjectInput[\"environments\"]>;\n};\n\nfunction cancelled(value: unknown): value is symbol {\n return prompts.isCancel(value);\n}\n\nfunction ensureProjectName(value: string): string {\n const name = value.trim();\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {\n throw new Error(\"项目名称只能包含小写字母、数字、点、下划线和连字符\");\n }\n return name;\n}\n\nfunction inferModuleName(projectName: string): string {\n const inferred = projectName\n .replace(/^(?:jh4j|wl)-ui-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return /^[a-z][a-z0-9-]*$/.test(inferred) ? inferred : \"app\";\n}\n\nfunction ensureModuleName(value: string): string {\n const name = value.trim();\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n throw new Error(\"模块标识必须以小写字母开头,只能包含小写字母、数字和连字符\");\n }\n return name;\n}\n\nfunction ensurePort(value: string | number): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1024 || port > 65535) {\n throw new Error(\"开发端口必须是 1024 到 65535 之间的整数\");\n }\n return port;\n}\n\nfunction ensureHttpUrl(value: string, label: string): string {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error();\n return value.replace(/\\/+$/, \"\");\n } catch {\n throw new Error(`${label} 必须是 http/https URL`);\n }\n}\n\nasync function askText(message: string, initialValue: string): Promise<string> {\n const answer = await prompts.text({ message, initialValue });\n if (cancelled(answer)) throw new Error(\"用户取消创建\");\n return String(answer).trim() || initialValue;\n}\n\nasync function loadCreateConfig(\n configFile: string | undefined,\n cwd: string\n): Promise<PartialProjectInput> {\n if (!configFile) return {};\n const resolved = path.resolve(cwd, configFile);\n if (!existsSync(resolved)) throw new Error(`创建配置文件不存在: ${resolved}`);\n return readJson<PartialProjectInput>(resolved);\n}\n\nfunction parseFeatureIds(value: string): string[] {\n return [...new Set(value.split(\",\").map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function collectTemplateFeatures(\n manifest: TemplateManifest,\n fileConfig: PartialProjectInput,\n options: CreateOptions\n): Promise<string[]> {\n const available = manifest.features ?? [];\n if (!available.length) return [];\n\n const knownIds = new Set(available.map((feature) => feature.id));\n let selected = options.features\n ? parseFeatureIds(options.features)\n : Array.isArray(fileConfig.features)\n ? fileConfig.features\n : available\n .filter((feature) => feature.defaultEnabled || feature.required)\n .map((feature) => feature.id);\n\n const unknown = selected.filter((id) => !knownIds.has(id));\n if (unknown.length) {\n throw new Error(\n `模板不支持以下能力: ${unknown.join(\", \")}。可用能力: ${[...knownIds].join(\", \")}`\n );\n }\n\n if (options.standards === false) {\n selected = selected.filter((id) => {\n const feature = available.find((item) => item.id === id);\n return feature?.package !== \"@robot-admin/git-standards\";\n });\n }\n\n if (!options.yes) {\n const selectable = available.filter(\n (feature) =>\n options.standards !== false ||\n feature.package !== \"@robot-admin/git-standards\"\n );\n if (selectable.length) {\n const answer = await prompts.multiselect({\n message: \"选择项目标准化能力\",\n options: selectable.map((feature) => ({\n value: feature.id,\n label: feature.name,\n hint: `${feature.description}${feature.package ? ` · ${feature.package}` : \"\"}`\n })),\n initialValues: selected,\n required: false\n });\n if (cancelled(answer)) throw new Error(\"用户取消创建\");\n selected = answer.map(String);\n }\n }\n\n for (const feature of available) {\n if (feature.required && !selected.includes(feature.id)) {\n selected.push(feature.id);\n }\n }\n return selected;\n}\n\nasync function collectProjectInput(\n projectName: string,\n sourceConfig: ProjectInput,\n fileConfig: PartialProjectInput,\n options: CreateOptions,\n userConfig: UserConfig,\n features: string[]\n): Promise<ProjectInput> {\n let moduleName = options.module ?? fileConfig.moduleName ?? inferModuleName(projectName);\n let title = options.title ?? fileConfig.title ?? sourceConfig.title;\n let port: string | number =\n options.port ?? fileConfig.devServerPort ?? sourceConfig.devServerPort;\n let npmRegistry =\n options.npmRegistry ??\n fileConfig.npmRegistry ??\n userConfig.npmRegistry ??\n sourceConfig.npmRegistry;\n let jhlcRegistry =\n options.jhlcRegistry ??\n fileConfig.jhlcRegistry ??\n userConfig.jhlcRegistry ??\n sourceConfig.jhlcRegistry;\n let localBackendUrl =\n options.localBackend ?? fileConfig.localBackendUrl ?? sourceConfig.localBackendUrl;\n let localPublicUrl =\n options.localPublic ?? fileConfig.localPublicUrl ?? sourceConfig.localPublicUrl;\n const environments = structuredClone(sourceConfig.environments);\n for (const [env, value] of Object.entries(fileConfig.environments ?? {})) {\n if (value && environments[env]) {\n environments[env] = { ...environments[env], ...value };\n }\n }\n\n if (!options.yes) {\n moduleName = await askText(\"模块标识\", moduleName);\n title = await askText(\"系统标题\", title);\n port = await askText(\"开发端口\", String(port));\n npmRegistry = await askText(\"npm registry\", npmRegistry);\n jhlcRegistry = await askText(\"@jhlc 私有 registry\", jhlcRegistry);\n localBackendUrl = await askText(\"本地后端地址\", localBackendUrl);\n localPublicUrl = await askText(\"本地 public 地址\", localPublicUrl);\n\n const configureEnvironments = await prompts.confirm({\n message: \"是否逐项确认五套环境地址\",\n initialValue: false\n });\n if (cancelled(configureEnvironments)) throw new Error(\"用户取消创建\");\n if (configureEnvironments) {\n for (const env of ENV_NAMES) {\n environments[env].webUrl = await askText(\n `${env.toUpperCase()} 平台地址`,\n environments[env].webUrl\n );\n environments[env].apiPrefix = await askText(\n `${env.toUpperCase()} API 前缀`,\n environments[env].apiPrefix\n );\n }\n }\n }\n\n if (!title.trim()) throw new Error(\"系统标题不能为空\");\n for (const env of ENV_NAMES) {\n if (!environments[env]) throw new Error(`缺少 ${env.toUpperCase()} 环境配置`);\n environments[env] = {\n webUrl: ensureHttpUrl(environments[env].webUrl, `${env.toUpperCase()} 平台地址`),\n apiPrefix: environments[env].apiPrefix.replace(/^\\/+|\\/+$/g, \"\")\n };\n if (!environments[env].apiPrefix) {\n throw new Error(`${env.toUpperCase()} API 前缀不能为空`);\n }\n }\n\n return {\n projectName,\n moduleName: ensureModuleName(moduleName),\n title: title.trim(),\n devServerPort: ensurePort(port),\n npmRegistry: ensureHttpUrl(npmRegistry, \"npm registry\"),\n jhlcRegistry: ensureHttpUrl(jhlcRegistry, \"@jhlc 私有 registry\"),\n localBackendUrl: ensureHttpUrl(localBackendUrl, \"本地后端地址\"),\n localPublicUrl: ensureHttpUrl(localPublicUrl, \"本地 public 地址\"),\n environments,\n features\n };\n}\n\nfunction assertSafeTarget(cwd: string, target: string): void {\n if (path.dirname(target) !== cwd || target === cwd) {\n throw new Error(\"仅允许在当前目录创建一级项目目录\");\n }\n}\n\nasync function promoteStaging(\n stagingRoot: string,\n targetRoot: string,\n force: boolean\n): Promise<void> {\n const targetExists = existsSync(targetRoot);\n if (!targetExists) {\n await rename(stagingRoot, targetRoot);\n return;\n }\n\n if (!(await isDirectoryEmpty(targetRoot)) && !force) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const backupRoot = `${targetRoot}.jh4j-backup-${Date.now()}`;\n await rename(targetRoot, backupRoot);\n try {\n await rename(stagingRoot, targetRoot);\n } catch (error) {\n await rename(backupRoot, targetRoot);\n throw error;\n }\n try {\n await removePath(backupRoot);\n } catch {\n prompts.log.warn(`旧目录备份未能自动清理: ${backupRoot}`);\n }\n}\n\nexport interface GenerateProjectResult {\n targetRoot: string;\n templateId: string;\n templateVersion: string;\n source: string;\n features: string[];\n installed: boolean;\n gitInitialized: boolean;\n}\n\nexport async function generateProject(\n catalogTemplate: CatalogTemplate,\n requestedProjectName: string,\n options: CreateOptions,\n cwd = process.cwd(),\n configuredUserConfig: UserConfig = DEFAULT_USER_CONFIG\n): Promise<GenerateProjectResult> {\n const userConfig = { ...DEFAULT_USER_CONFIG, ...configuredUserConfig };\n const projectName = ensureProjectName(requestedProjectName);\n const resolvedCwd = path.resolve(cwd);\n const targetRoot = path.resolve(resolvedCwd, projectName);\n assertSafeTarget(resolvedCwd, targetRoot);\n if (\n existsSync(targetRoot) &&\n !(await isDirectoryEmpty(targetRoot)) &&\n !options.force\n ) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const ref = options.ref ?? userConfig.templateRef ?? catalogTemplate.defaultRef;\n const sourceValues = resolveTemplateSources(\n catalogTemplate,\n options.source,\n userConfig.templateSource\n );\n const acquired = await acquireTemplateFromSources(sourceValues, ref, {\n noCache: options.cache === false,\n cacheTtlMinutes: userConfig.cacheTtlMinutes\n });\n const stagingRoot = path.join(\n resolvedCwd,\n `.${projectName}.jh4j-tmp-${process.pid}-${Date.now()}`\n );\n let promoted = false;\n\n try {\n const manifest = await loadTemplateManifest(acquired.root);\n if (manifest.id !== catalogTemplate.id) {\n throw new Error(\n `模板 ID 不匹配:Catalog=${catalogTemplate.id},Manifest=${manifest.id}`\n );\n }\n if (!satisfies(process.versions.node, manifest.runtime.node)) {\n throw new Error(\n `当前 Node ${process.versions.node} 不满足模板要求 ${manifest.runtime.node}`\n );\n }\n\n const sourceProjectConfig = await readJson<\n Omit<ProjectInput, \"npmRegistry\" | \"jhlcRegistry\">\n >(path.join(acquired.root, \"project.config.json\"));\n const fileConfig = await loadCreateConfig(options.config, resolvedCwd);\n const features = await collectTemplateFeatures(manifest, fileConfig, options);\n const input = await collectProjectInput(\n projectName,\n {\n ...sourceProjectConfig,\n npmRegistry: manifest.defaults.npmRegistry,\n jhlcRegistry: manifest.defaults.jhlcRegistry\n },\n fileConfig,\n options,\n userConfig,\n features\n );\n\n const shouldInstall = !options.skipInstall && userConfig.autoInstall;\n const shouldInitializeGit = !options.skipGit && userConfig.autoGit;\n\n if (options.dryRun) {\n prompts.note(\n [\n `模板: ${manifest.id}@${manifest.version}`,\n `来源: ${acquired.source}`,\n `目标: ${targetRoot}`,\n `模块: ${input.moduleName}`,\n `端口: ${input.devServerPort}`,\n `能力: ${input.features.length ? input.features.join(\", \") : \"无可选能力\"}`,\n `安装依赖: ${shouldInstall ? \"是\" : \"否\"}`,\n `初始化 Git: ${shouldInitializeGit ? \"是\" : \"否\"}`\n ].join(\"\\n\"),\n \"Dry Run\"\n );\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: false,\n gitInitialized: false\n };\n }\n\n await copyTemplateTree(acquired.root, stagingRoot);\n const inputFile = path.join(stagingRoot, \".jh4j-cli-input.json\");\n await writeJson(inputFile, input);\n try {\n await runCommand(\n process.execPath,\n [\n path.join(stagingRoot, \"scripts\", \"setup-project.mjs\"),\n \"--yes\",\n \"--config\",\n inputFile,\n \"--created-by\",\n `${CLI_NAME}@${CLI_VERSION}`\n ],\n { cwd: stagingRoot, stdio: \"pipe\" }\n );\n } finally {\n await rm(inputFile, { force: true });\n }\n\n if (!existsSync(path.join(stagingRoot, manifest.generatedMetadata))) {\n throw new Error(`模板初始化未生成元数据: ${manifest.generatedMetadata}`);\n }\n await promoteStaging(stagingRoot, targetRoot, Boolean(options.force));\n promoted = true;\n\n let gitInitialized = false;\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"init\", \"-b\", \"main\"], {\n cwd: targetRoot,\n stdio: \"pipe\"\n });\n gitInitialized = true;\n }\n\n if (shouldInstall) {\n try {\n await runCommand(\"pnpm\", [\"install\"], { cwd: targetRoot });\n } catch (error) {\n throw new Error(\n `项目已生成,但依赖安装失败;目录已保留在 ${targetRoot}\\n${(error as Error).message}`\n );\n }\n }\n\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"add\", \"-A\"], { cwd: targetRoot, stdio: \"pipe\" });\n try {\n await runCommand(\n \"git\",\n [\"commit\", \"-m\", `feat(init): 基于 ${manifest.id}@${manifest.version} 初始化`],\n {\n cwd: targetRoot,\n stdio: \"pipe\",\n env: { HUSKY: \"0\" }\n }\n );\n } catch (error) {\n prompts.log.warn(`Git 已初始化,但初始提交未完成:${(error as Error).message}`);\n }\n }\n\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: shouldInstall,\n gitInitialized\n };\n } finally {\n if (!promoted && existsSync(stagingRoot)) await removePath(stagingRoot);\n await acquired.cleanup();\n }\n}\n","import path from \"node:path\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { TemplateManifest } from \"../types.js\";\n\nexport async function loadTemplateManifest(\n templateRoot: string\n): Promise<TemplateManifest> {\n const manifest = await readJson<TemplateManifest>(\n path.join(templateRoot, \"template.manifest.json\")\n );\n const errors: string[] = [];\n\n if (manifest.schemaVersion !== 1) errors.push(\"schemaVersion 必须为 1\");\n if (!manifest.id) errors.push(\"缺少模板 id\");\n if (!manifest.name) errors.push(\"缺少模板名称\");\n if (!/^\\d+\\.\\d+\\.\\d+([+-].+)?$/.test(manifest.version ?? \"\")) {\n errors.push(\"模板 version 不是有效的语义化版本\");\n }\n if (!manifest.runtime?.node || !manifest.runtime?.packageManager) {\n errors.push(\"缺少模板运行时约束\");\n }\n if (!manifest.entry?.nonInteractive) {\n errors.push(\"缺少非交互初始化入口\");\n }\n const featureIds = new Set<string>();\n for (const feature of manifest.features ?? []) {\n if (!/^[a-z][a-z0-9-]*$/.test(feature.id)) {\n errors.push(`模板能力 id 无效: ${feature.id}`);\n }\n if (featureIds.has(feature.id)) {\n errors.push(`模板能力 id 重复: ${feature.id}`);\n }\n featureIds.add(feature.id);\n if (!feature.name || !feature.description) {\n errors.push(`模板能力 ${feature.id} 缺少名称或说明`);\n }\n }\n\n if (errors.length) {\n throw new Error(`模板 manifest 无效:\\n- ${errors.join(\"\\n- \")}`);\n }\n return manifest;\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { coerce, gte, satisfies } from \"semver\";\nimport { loadCatalog } from \"../catalog.js\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { resolveTemplateSources } from \"../core/template-source.js\";\nimport { getJh4jHome, loadUserConfig } from \"../core/user-config.js\";\nimport { inspectCommand } from \"../utils/process.js\";\nimport type { CatalogTemplate, UserConfig } from \"../types.js\";\n\nexport interface CheckResult {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nasync function checkHomeWritable(): Promise<CheckResult> {\n const home = getJh4jHome();\n const probe = path.join(home, `.write-probe-${process.pid}`);\n try {\n await mkdir(home, { recursive: true });\n await writeFile(probe, \"ok\", \"utf8\");\n await rm(probe, { force: true });\n return { name: \"JH4J_HOME\", ok: true, detail: home };\n } catch (error) {\n return { name: \"JH4J_HOME\", ok: false, detail: (error as Error).message };\n }\n}\n\nexport async function collectDoctorChecks(\n suppliedConfig?: UserConfig,\n suppliedCatalog?: CatalogTemplate[]\n): Promise<CheckResult[]> {\n const config = suppliedConfig ?? (await loadUserConfig());\n const catalog = suppliedCatalog ?? (await loadCatalog(config));\n const [git, pnpm, home] = await Promise.all([\n inspectCommand(\"git\"),\n inspectCommand(\"pnpm\"),\n checkHomeWritable()\n ]);\n const pnpmVersion = coerce(pnpm.output)?.version;\n const checks: CheckResult[] = [\n {\n name: \"Node.js\",\n ok: satisfies(process.versions.node, \"^22.12.0 || ^24.0.0\"),\n detail: `${process.versions.node}(要求 Node 22.12+ 或 24.x)`\n },\n { name: \"Git\", ok: git.ok, detail: git.output },\n {\n name: \"pnpm\",\n ok: pnpm.ok && Boolean(pnpmVersion && gte(pnpmVersion, \"11.8.0\")),\n detail: pnpm.output\n },\n home\n ];\n\n for (const template of catalog) {\n const sources = resolveTemplateSources(\n template,\n undefined,\n config.templateSource\n );\n const source = sources[0];\n if (!existsSync(source)) {\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.startsWith(\"git@\"),\n detail: `远程候选源(创建时依次验证): ${sources.join(\" → \")}`\n });\n continue;\n }\n try {\n const manifest = await loadTemplateManifest(source);\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n manifest.id === template.id &&\n satisfies(process.versions.node, manifest.runtime.node),\n detail: `${manifest.id}@${manifest.version} (${source})`\n });\n } catch (error) {\n checks.push({\n name: `模板 ${template.id}`,\n ok: false,\n detail: (error as Error).message\n });\n }\n }\n return checks;\n}\n\nexport async function doctorCommand(options: { json?: boolean } = {}): Promise<void> {\n const checks = await collectDoctorChecks();\n const failed = checks.filter((check) => !check.ok);\n if (options.json) {\n console.log(JSON.stringify({ ok: failed.length === 0, checks }, null, 2));\n } else {\n for (const check of checks) {\n console.log(`${check.ok ? \"✓\" : \"✗\"} ${check.name}: ${check.detail}`);\n }\n console.log(`\\n结果: ${checks.length - failed.length} 通过, ${failed.length} 失败`);\n }\n if (failed.length) process.exitCode = 1;\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { ProjectMetadata } from \"../types.js\";\n\nexport async function infoCommand(\n projectPath = process.cwd(),\n options: { json?: boolean } = {}\n): Promise<void> {\n const root = path.resolve(projectPath);\n const metadataPath = path.join(root, \".jhlc\", \"project.json\");\n if (!existsSync(metadataPath)) {\n throw new Error(`当前目录不是 JH4J CLI 创建的项目: ${metadataPath}`);\n }\n const metadata = await readJson<ProjectMetadata>(metadataPath);\n if (options.json) {\n console.log(JSON.stringify({ projectRoot: root, ...metadata }, null, 2));\n return;\n }\n console.log(`项目目录: ${root}`);\n console.log(`模板: ${metadata.template.id}@${metadata.template.version}`);\n console.log(`平台版本: ${metadata.platformVersion ?? \"未声明\"}`);\n console.log(`创建时间: ${metadata.createdAt}`);\n console.log(`创建工具: ${metadata.createdBy}`);\n console.log(\"项目参数:\");\n console.log(JSON.stringify(metadata.parameters, null, 2));\n}\n","import { loadCatalog } from \"../catalog.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\n\nexport async function listCommand(options: { json?: boolean } = {}): Promise<void> {\n const templates = await loadCatalog(await loadUserConfig());\n if (options.json) {\n console.log(JSON.stringify(templates, null, 2));\n return;\n }\n console.table(\n templates.map((template) => ({\n ID: template.id,\n 名称: template.name,\n 类型: template.category,\n 状态: template.status,\n 默认分支: template.defaultRef,\n 标签: template.tags?.join(\", \") ?? \"\"\n }))\n );\n}\n","import path from \"node:path\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { runCommand } from \"../utils/process.js\";\n\nexport async function validateTemplateCommand(templatePath: string): Promise<void> {\n const root = path.resolve(templatePath);\n const manifest = await loadTemplateManifest(root);\n await runCommand(process.execPath, [path.join(root, \"scripts\", \"validate-template.mjs\")], {\n cwd: root\n });\n console.log(`模板可用: ${manifest.id}@${manifest.version}`);\n}\n","import {\n DEFAULT_USER_CONFIG,\n getUserConfigPath,\n loadUserConfig,\n parseUserConfigValue,\n saveUserConfig\n} from \"../core/user-config.js\";\n\nexport async function configListCommand(options: { json?: boolean } = {}): Promise<void> {\n const config = await loadUserConfig();\n if (options.json) console.log(JSON.stringify(config, null, 2));\n else console.table(Object.entries(config).map(([key, value]) => ({ key, value })));\n console.log(`配置文件: ${getUserConfigPath()}`);\n}\n\nexport async function configGetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in config)) throw new Error(`配置项不存在: ${key}`);\n console.log(String((config as unknown as Record<string, unknown>)[key]));\n}\n\nexport async function configSetCommand(key: string, value: string): Promise<void> {\n const config = await loadUserConfig();\n const [typedKey, typedValue] = parseUserConfigValue(key, value);\n (config as unknown as Record<string, unknown>)[typedKey] = typedValue;\n await saveUserConfig(config);\n console.log(`已设置 ${typedKey}=${String(typedValue)}`);\n}\n\nexport async function configUnsetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in DEFAULT_USER_CONFIG) && !(key in config)) {\n throw new Error(`配置项不存在: ${key}`);\n }\n const defaults = DEFAULT_USER_CONFIG as unknown as Record<string, unknown>;\n const mutable = config as unknown as Record<string, unknown>;\n if (key in defaults) mutable[key] = defaults[key];\n else delete mutable[key];\n await saveUserConfig(config);\n console.log(`已重置配置项: ${key}`);\n}\n\nexport async function configResetCommand(): Promise<void> {\n await saveUserConfig({ ...DEFAULT_USER_CONFIG });\n console.log(`用户配置已恢复默认值: ${getUserConfigPath()}`);\n}\n","import {\n clearTemplateCache,\n getTemplateCacheRoot,\n listTemplateCache\n} from \"../core/template-cache.js\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n}\n\nexport async function cacheListCommand(options: { json?: boolean } = {}): Promise<void> {\n const entries = await listTemplateCache();\n if (options.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n if (!entries.length) {\n console.log(`模板缓存为空: ${getTemplateCacheRoot()}`);\n return;\n }\n console.table(\n entries.map((entry) => ({\n Key: entry.key,\n 来源: entry.metadata.source,\n Ref: entry.metadata.ref,\n 缓存时间: entry.metadata.cachedAt,\n 大小: formatBytes(entry.sizeBytes)\n }))\n );\n}\n\nexport async function cacheClearCommand(): Promise<void> {\n await clearTemplateCache();\n console.log(`模板缓存已清理: ${getTemplateCacheRoot()}`);\n}\n","import { runCli } from \"./cli.js\";\n\nrunCli().catch((error) => {\n console.error(`\\n错误: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["path","existsSync","readdir","existsSync","path","path","existsSync","mkdir","readdir","rename","rm","writeFile","existsSync","mkdir","stat","path","path","existsSync","path","existsSync","path","existsSync","mkdir","stat","existsSync","path","readdir","rename","rm","writeFile","mkdir","prompts","existsSync","rename","rm","path","path","path","path","existsSync","rename","rm","selected","existsSync","mkdir","writeFile","rm","path","satisfies","path","mkdir","writeFile","rm","satisfies","existsSync","path","existsSync","path","existsSync","path","path","config"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../package.json","../src/constants.ts","../src/catalog.ts","../src/utils/fs.ts","../src/core/template-source.ts","../src/utils/process.ts","../src/core/template-cache.ts","../src/core/user-config.ts","../src/commands/create.ts","../src/core/project-generator.ts","../src/core/template-manifest.ts","../src/commands/doctor.ts","../src/commands/info.ts","../src/commands/list.ts","../src/commands/template.ts","../src/commands/config.ts","../src/commands/cache.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { COMMAND_NAME, CLI_VERSION } from \"./constants.js\";\nimport { findTemplate, loadCatalog } from \"./catalog.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./core/template-source.js\";\nimport { loadUserConfig } from \"./core/user-config.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { infoCommand } from \"./commands/info.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { validateTemplateCommand } from \"./commands/template.js\";\nimport {\n configGetCommand,\n configListCommand,\n configResetCommand,\n configSetCommand,\n configUnsetCommand\n} from \"./commands/config.js\";\nimport { cacheClearCommand, cacheListCommand } from \"./commands/cache.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n program\n .name(COMMAND_NAME)\n .description(\"JH4J Cloud 企业内部标准化项目脚手架\")\n .version(CLI_VERSION);\n\n program\n .command(\"create [name]\")\n .description(\"根据标准模板创建项目\")\n .option(\"-c, --category <category>\", \"项目类型:frontend、backend 或 mobile\")\n .option(\"-t, --template <id>\", \"模板 ID\")\n .option(\"--features <ids>\", \"启用的模板能力,多个 ID 使用逗号分隔\")\n .option(\"--no-standards\", \"不启用模板提供的 Git/代码标准化能力\")\n .option(\"--source <path-or-url>\", \"覆盖模板源(本地目录或 Git URL)\")\n .option(\"--ref <branch-or-tag>\", \"Git 分支或标签;默认使用模板 Catalog 配置\")\n .option(\"--module <name>\", \"平台模块标识\")\n .option(\"--title <title>\", \"系统标题\")\n .option(\"--port <port>\", \"开发端口\")\n .option(\"--npm-registry <url>\", \"npm registry(需包含企业定制包)\")\n .option(\"--jhlc-registry <url>\", \"@jhlc 私有 registry\")\n .option(\"--local-backend <url>\", \"本地后端地址\")\n .option(\"--local-public <url>\", \"本地 public 地址\")\n .option(\"--config <json-file>\", \"从 JSON 文件读取创建参数\")\n .option(\"-y, --yes\", \"接受模板默认值,非交互创建\")\n .option(\"--dry-run\", \"只预览,不写入文件\")\n .option(\"--install\", \"创建完成后安装依赖(默认不安装)\")\n .option(\"--skip-install\", \"不安装依赖(兼容旧命令)\")\n .option(\"--skip-git\", \"跳过 Git 初始化\")\n .option(\"--force\", \"覆盖已存在的同名目录\")\n .option(\"--no-cache\", \"不使用已有远程模板缓存\")\n .action(createCommand);\n\n program\n .command(\"list\")\n .description(\"列出可用模板\")\n .option(\"--json\", \"输出 JSON\")\n .action(listCommand);\n program\n .command(\"doctor\")\n .description(\"检查本机环境和模板可用性\")\n .option(\"--json\", \"输出 JSON\")\n .action(doctorCommand);\n program\n .command(\"info [path]\")\n .description(\"显示已生成项目的模板与版本信息\")\n .option(\"--json\", \"输出 JSON\")\n .action(infoCommand);\n\n const template = program.command(\"template\").description(\"模板维护命令\");\n template\n .command(\"validate [path]\")\n .description(\"校验模板 manifest 与模板契约\")\n .action(async (templatePath?: string) => {\n if (templatePath) return validateTemplateCommand(templatePath);\n const config = await loadUserConfig();\n const selected = findTemplate(await loadCatalog(config));\n const acquired = await acquireTemplateFromSources(\n resolveTemplateSources(selected, undefined, config.templateSource),\n config.templateRef ?? selected.defaultRef,\n { cacheTtlMinutes: config.cacheTtlMinutes }\n );\n try {\n return await validateTemplateCommand(acquired.root);\n } finally {\n await acquired.cleanup();\n }\n });\n\n const config = program.command(\"config\").description(\"管理用户默认配置\");\n config\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(configListCommand);\n config.command(\"get <key>\").action(configGetCommand);\n config.command(\"set <key> <value>\").action(configSetCommand);\n config.command(\"unset <key>\").action(configUnsetCommand);\n config.command(\"reset\").action(configResetCommand);\n\n const cache = program.command(\"cache\").description(\"管理远程模板缓存\");\n cache\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(cacheListCommand);\n cache.command(\"clear\").action(cacheClearCommand);\n\n return program;\n}\n\nexport async function runCli(argv = process.argv): Promise<void> {\n await createProgram().parseAsync(argv);\n}\n","{\n \"name\": \"@agile-team/jh4j-cloud-cli\",\n \"version\": \"0.5.0\",\n \"description\": \"JH4J Cloud 企业内部标准化项目脚手架\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/ChenyCHENYU/jh4j-cloud-cli.git\"\n },\n \"homepage\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli/issues\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \"^22.12.0 || ^24.0.0\",\n \"pnpm\": \">=11.8.0\"\n },\n \"packageManager\": \"pnpm@11.8.0\",\n \"bin\": {\n \"jh4j\": \"bin/jh4j.js\"\n },\n \"files\": [\n \"bin\",\n \"dist\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"catalog.schema.json\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"start\": \"node bin/jh4j.js\",\n \"check\": \"pnpm typecheck && pnpm test && pnpm build\",\n \"prepack\": \"pnpm check\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.7.0\",\n \"commander\": \"^15.0.0\",\n \"semver\": \"^7.8.5\",\n \"tar\": \"^7.5.19\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.13.3\",\n \"@types/semver\": \"7.7.1\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\",\n \"vitest\": \"4.1.10\"\n }\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\n\nexport const CLI_NAME = \"@agile-team/jh4j-cloud-cli\";\nexport const CLI_VERSION = packageJson.version;\nexport const COMMAND_NAME = \"jh4j\";\nexport const SUPPORTED_NODE_MAJORS = new Set([22, 24]);\nexport const TEMPLATE_SOURCE_ENV = \"JH4J_UI_TEMPLATE_SOURCE\";\nexport const JH4J_HOME_ENV = \"JH4J_HOME\";\nexport const CATALOG_FILE_ENV = \"JH4J_CATALOG_FILE\";\nexport const USER_CONFIG_SCHEMA_VERSION = 1;\n","import { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { CATALOG_FILE_ENV, TEMPLATE_SOURCE_ENV } from \"./constants.js\";\nimport { readJson } from \"./utils/fs.js\";\nimport type { CatalogFile, CatalogTemplate, UserConfig } from \"./types.js\";\n\nconst siblingTemplatePath = fileURLToPath(\n new URL(\"../../jh4j-ui-template/\", import.meta.url)\n);\nconst siblingMobileTemplatePath = fileURLToPath(\n new URL(\"../../../Robot_H5/\", import.meta.url)\n);\nconst remoteTemplateSources = [\n \"https://github.com/ChenyCHENYU/jh4j-ui-template.git\",\n \"https://gitee.com/ycyplus163/jh4j-ui-template.git\"\n];\nconst remoteMobileTemplateSources = [\n \"https://github.com/ChenyCHENYU/Robot_H5.git\",\n \"https://gitee.com/ycyplus163/robot_-h5.git\"\n];\n\nexport const BUILTIN_TEMPLATES: CatalogTemplate[] = [\n {\n id: \"web.jh4j-mf-remote\",\n name: \"JH4J PC 微前端业务模板\",\n description: \"Vue 3 + Vite + Module Federation 标准业务子系统\",\n category: \"frontend\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingTemplatePath)\n ? siblingTemplatePath\n : remoteTemplateSources[0],\n sources: remoteTemplateSources,\n defaultRef: \"main\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"module-federation\", \"pc\"]\n },\n {\n id: \"mobile.robot-h5\",\n name: \"JH4J 移动端 H5 模板\",\n description: \"Vue 3 + Vite 7 + Vant 4 企业级移动端 H5 应用\",\n category: \"mobile\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingMobileTemplatePath)\n ? siblingMobileTemplatePath\n : remoteMobileTemplateSources[0],\n sources: remoteMobileTemplateSources,\n defaultRef: \"v1.6.0\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"vant\", \"h5\", \"mobile\"]\n }\n];\n\nfunction validateCatalogTemplate(template: CatalogTemplate): void {\n if (!template.id || !template.name || !template.category) {\n throw new Error(\"Catalog 模板缺少 id、name 或 category\");\n }\n if (!new Set([\"frontend\", \"backend\", \"mobile\"]).has(template.category)) {\n throw new Error(`Catalog 模板 ${template.id} 的 category 无效`);\n }\n if (!new Set([\"stable\", \"beta\"]).has(template.status)) {\n throw new Error(`Catalog 模板 ${template.id} 的 status 无效`);\n }\n if (!template.defaultRef) {\n throw new Error(`Catalog 模板 ${template.id} 缺少 defaultRef`);\n }\n if (!template.defaultSource && !template.sourceEnvironment) {\n throw new Error(`Catalog 模板 ${template.id} 没有可解析的模板源`);\n }\n if (template.sources?.some((source) => !source.trim())) {\n throw new Error(`Catalog 模板 ${template.id} 包含空的备用源`);\n }\n}\n\nfunction resolveCatalogSource(source: string, catalogDirectory: string): string {\n const isRemote =\n /^(?:https?|ssh|file):\\/\\//.test(source) || source.startsWith(\"git@\");\n return isRemote || path.isAbsolute(source)\n ? source\n : path.resolve(catalogDirectory, source);\n}\n\nexport async function loadCatalog(config?: UserConfig): Promise<CatalogTemplate[]> {\n const configuredFile = process.env[CATALOG_FILE_ENV] || config?.catalogFile;\n if (!configuredFile) return [...BUILTIN_TEMPLATES];\n\n const catalogPath = path.resolve(configuredFile);\n if (!existsSync(catalogPath)) {\n throw new Error(`Catalog 文件不存在: ${catalogPath}`);\n }\n const external = await readJson<CatalogFile>(catalogPath);\n if (external.schemaVersion !== 1 || !Array.isArray(external.templates)) {\n throw new Error(`Catalog 文件格式无效: ${catalogPath}`);\n }\n const catalogDirectory = path.dirname(catalogPath);\n external.templates = external.templates.map((template) => {\n return {\n ...template,\n defaultSource: resolveCatalogSource(\n template.defaultSource,\n catalogDirectory\n ),\n sources: template.sources?.map((source) =>\n resolveCatalogSource(source, catalogDirectory)\n )\n };\n });\n external.templates.forEach(validateCatalogTemplate);\n\n const merged = new Map(BUILTIN_TEMPLATES.map((item) => [item.id, item]));\n external.templates.forEach((item) => merged.set(item.id, item));\n return [...merged.values()];\n}\n\nexport function findTemplate(\n catalog: CatalogTemplate[],\n id?: string\n): CatalogTemplate {\n const selected = id ?? catalog[0]?.id;\n const template = catalog.find((item) => item.id === selected);\n if (!template) {\n throw new Error(\n `模板不存在: ${selected}。可用模板: ${catalog.map((item) => item.id).join(\", \")}`\n );\n }\n return template;\n}\n","import { cp, mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst EXCLUDED_TEMPLATE_PATHS = new Set([\n \".git\",\n \".jhlc\",\n \"dist\",\n \"node_modules\"\n]);\n\nexport async function readJson<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, \"utf8\")) as T;\n}\n\nexport async function writeJson(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function isDirectory(directory: string): Promise<boolean> {\n try {\n return (await stat(directory)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function isDirectoryEmpty(directory: string): Promise<boolean> {\n if (!existsSync(directory)) return true;\n const { readdir } = await import(\"node:fs/promises\");\n return (await readdir(directory)).length === 0;\n}\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n targetRoot: string\n): Promise<void> {\n await mkdir(targetRoot, { recursive: true });\n await cp(sourceRoot, targetRoot, {\n recursive: true,\n force: true,\n filter(source) {\n const relative = path.relative(sourceRoot, source);\n if (!relative) return true;\n const [topLevel] = relative.split(path.sep);\n return !EXCLUDED_TEMPLATE_PATHS.has(topLevel);\n }\n });\n}\n\nexport async function removePath(target: string): Promise<void> {\n await rm(target, { recursive: true, force: true, maxRetries: 3 });\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { x as extractTar } from \"tar\";\nimport type { CatalogTemplate } from \"../types.js\";\nimport { isDirectory } from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n createTemplateCacheStaging,\n isTemplateCacheFresh,\n readTemplateCacheEntry\n} from \"./template-cache.js\";\n\nconst MAX_ARCHIVE_BYTES = 200 * 1024 * 1024;\n\nexport interface AcquiredTemplate {\n root: string;\n source: string;\n cleanup(): Promise<void>;\n}\n\nexport function resolveTemplateSource(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string {\n return resolveTemplateSources(template, override, configuredSource)[0];\n}\n\nexport function resolveTemplateSources(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string[] {\n const exclusiveSource =\n override ||\n (template.sourceEnvironment\n ? process.env[template.sourceEnvironment]\n : undefined) ||\n configuredSource;\n if (exclusiveSource) return [exclusiveSource];\n return [...new Set([template.defaultSource, ...(template.sources ?? [])])];\n}\n\nfunction isGitSource(source: string): boolean {\n return (\n source.startsWith(\"git@\") ||\n source.startsWith(\"ssh://\") ||\n source.startsWith(\"file://\") ||\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.endsWith(\".git\")\n );\n}\n\nfunction isArchiveSource(source: string): boolean {\n const pathname = source.split(/[?#]/, 1)[0].toLowerCase();\n return pathname.endsWith(\".tgz\") || pathname.endsWith(\".tar.gz\") || pathname.endsWith(\".tar\");\n}\n\nasync function getFreshCache(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate | null> {\n const cacheEntry = await readTemplateCacheEntry(source, ref);\n if (\n !options.noCache &&\n cacheEntry &&\n isTemplateCacheFresh(cacheEntry, options.cacheTtlMinutes ?? 60)\n ) {\n return {\n root: cacheEntry.root,\n source: `${source}#${ref} (cache)`,\n async cleanup() {}\n };\n }\n return null;\n}\n\nasync function normalizeExtractedTemplate(\n stagingRoot: string,\n templateRoot: string\n): Promise<void> {\n if (existsSync(path.join(templateRoot, \"template.manifest.json\"))) return;\n const children = await readdir(templateRoot, { withFileTypes: true });\n const candidates = children.filter(\n (entry) =>\n entry.isDirectory() &&\n existsSync(path.join(templateRoot, entry.name, \"template.manifest.json\"))\n );\n if (candidates.length !== 1) {\n throw new Error(\"压缩包根目录或唯一一级目录中未找到 template.manifest.json\");\n }\n const normalizedRoot = path.join(stagingRoot, \".normalized-template\");\n await rename(path.join(templateRoot, candidates[0].name), normalizedRoot);\n await rm(templateRoot, { recursive: true, force: true });\n await rename(normalizedRoot, templateRoot);\n}\n\nasync function acquireArchiveTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate> {\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n const archiveFile = path.join(cacheStaging.stagingRoot, \"template.tgz\");\n try {\n if (source.startsWith(\"http://\") || source.startsWith(\"https://\")) {\n const response = await fetch(source, { signal: AbortSignal.timeout(60_000) });\n if (!response.ok) {\n throw new Error(`模板压缩包下载失败: HTTP ${response.status}`);\n }\n const declaredLength = Number(response.headers.get(\"content-length\") || 0);\n if (declaredLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n const archiveBuffer = Buffer.from(await response.arrayBuffer());\n if (archiveBuffer.byteLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n await writeFile(archiveFile, archiveBuffer);\n } else {\n const { copyFile } = await import(\"node:fs/promises\");\n await copyFile(path.resolve(source), archiveFile);\n }\n await mkdir(cacheStaging.templateRoot, { recursive: true });\n await extractTar({ file: archiveFile, cwd: cacheStaging.templateRoot });\n await normalizeExtractedTemplate(\n cacheStaging.stagingRoot,\n cacheStaging.templateRoot\n );\n await rm(archiveFile, { force: true });\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source} (archive)`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n const localPath = path.resolve(source);\n if (existsSync(localPath)) {\n if (await isDirectory(localPath)) {\n return {\n root: localPath,\n source: localPath,\n async cleanup() {}\n };\n }\n if (isArchiveSource(localPath)) {\n return acquireArchiveTemplate(localPath, ref, options);\n }\n throw new Error(`模板源不是目录或支持的 tar 压缩包: ${localPath}`);\n }\n\n if (isArchiveSource(source)) {\n return acquireArchiveTemplate(source, ref, options);\n }\n\n if (!isGitSource(source)) {\n throw new Error(`模板源不存在: ${source}`);\n }\n\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n try {\n await runCommand(\n \"git\",\n [\n \"-c\",\n \"http.lowSpeedLimit=1024\",\n \"-c\",\n \"http.lowSpeedTime=15\",\n \"clone\",\n \"--depth\",\n \"1\",\n \"--branch\",\n ref,\n source,\n cacheStaging.templateRoot\n ],\n { stdio: \"pipe\", env: { GIT_TERMINAL_PROMPT: \"0\" } }\n );\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source}#${ref}`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplateFromSources(\n sources: string[],\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n if (!sources.length) throw new Error(\"没有可用的模板源\");\n const failures: string[] = [];\n for (const source of [...new Set(sources)]) {\n try {\n return await acquireTemplate(source, ref, options);\n } catch (error) {\n failures.push(`${source}: ${(error as Error).message}`);\n }\n }\n throw new Error(`所有模板源均不可用:\\n- ${failures.join(\"\\n- \")}`);\n}\n","import { spawn } from \"node:child_process\";\n\nexport interface RunCommandOptions {\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport function platformCommand(command: string): string {\n if (process.platform !== \"win32\") return command;\n return command === \"pnpm\" || command === \"npm\" || command === \"npx\"\n ? `${command}.cmd`\n : command;\n}\n\nexport async function runCommand(\n command: string,\n args: string[],\n options: RunCommandOptions = {}\n): Promise<string> {\n const stdio = options.stdio ?? \"inherit\";\n return new Promise((resolve, reject) => {\n const executable = platformCommand(command);\n const isWindowsCommand =\n process.platform === \"win32\" && executable.endsWith(\".cmd\");\n const spawnExecutable = isWindowsCommand\n ? process.env.ComSpec || \"cmd.exe\"\n : executable;\n const spawnArgs = isWindowsCommand\n ? [\"/d\", \"/s\", \"/c\", executable, ...args]\n : args;\n const child = spawn(spawnExecutable, spawnArgs, {\n cwd: options.cwd,\n stdio,\n env: { ...process.env, ...options.env },\n windowsHide: true\n });\n\n let output = \"\";\n if (stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolve(output.trim());\n return;\n }\n reject(\n new Error(\n `${command} ${args.join(\" \")} 执行失败(exit ${code ?? \"unknown\"})${output ? `\\n${output.trim()}` : \"\"}`\n )\n );\n });\n });\n}\n\nexport async function inspectCommand(\n command: string,\n args: string[] = [\"--version\"]\n): Promise<{ ok: boolean; output: string }> {\n try {\n return { ok: true, output: await runCommand(command, args, { stdio: \"pipe\" }) };\n } catch (error) {\n return { ok: false, output: (error as Error).message };\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getJh4jHome } from \"./user-config.js\";\nimport { readJson, removePath, writeJson } from \"../utils/fs.js\";\nimport type { TemplateCacheMetadata } from \"../types.js\";\n\nconst CACHE_SCHEMA_VERSION = 1;\n\nexport interface TemplateCacheEntry {\n key: string;\n root: string;\n metadata: TemplateCacheMetadata;\n sizeBytes: number;\n}\n\nexport function getTemplateCacheRoot(): string {\n return path.join(getJh4jHome(), \"cache\", \"templates\");\n}\n\nexport function getTemplateCacheKey(source: string, ref: string): string {\n return createHash(\"sha256\").update(`${source}\\0${ref}`).digest(\"hex\").slice(0, 20);\n}\n\nfunction getEntryPaths(key: string) {\n const entryRoot = path.join(getTemplateCacheRoot(), key);\n return {\n entryRoot,\n templateRoot: path.join(entryRoot, \"template\"),\n metadataPath: path.join(entryRoot, \"metadata.json\")\n };\n}\n\nexport async function readTemplateCacheEntry(\n source: string,\n ref: string\n): Promise<TemplateCacheEntry | null> {\n const key = getTemplateCacheKey(source, ref);\n const paths = getEntryPaths(key);\n if (!existsSync(paths.templateRoot) || !existsSync(paths.metadataPath)) return null;\n try {\n const metadata = await readJson<TemplateCacheMetadata>(paths.metadataPath);\n if (\n metadata.schemaVersion !== CACHE_SCHEMA_VERSION ||\n metadata.source !== source ||\n metadata.ref !== ref\n ) {\n return null;\n }\n return {\n key,\n root: paths.templateRoot,\n metadata,\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n };\n } catch {\n return null;\n }\n}\n\nexport function isTemplateCacheFresh(\n entry: TemplateCacheEntry,\n ttlMinutes: number\n): boolean {\n if (ttlMinutes <= 0) return false;\n const cachedAt = Date.parse(entry.metadata.cachedAt);\n return Number.isFinite(cachedAt) && Date.now() - cachedAt < ttlMinutes * 60_000;\n}\n\nexport async function createTemplateCacheStaging(\n source: string,\n ref: string\n): Promise<{\n key: string;\n entryRoot: string;\n stagingRoot: string;\n templateRoot: string;\n commit(): Promise<void>;\n cleanup(): Promise<void>;\n}> {\n const key = getTemplateCacheKey(source, ref);\n const cacheRoot = getTemplateCacheRoot();\n await mkdir(cacheRoot, { recursive: true });\n const stagingRoot = path.join(\n cacheRoot,\n `.${key}.tmp-${process.pid}-${Date.now()}`\n );\n const templateRoot = path.join(stagingRoot, \"template\");\n const entryRoot = path.join(cacheRoot, key);\n await mkdir(stagingRoot, { recursive: true });\n\n return {\n key,\n entryRoot,\n stagingRoot,\n templateRoot,\n async commit() {\n await writeJson(path.join(stagingRoot, \"metadata.json\"), {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source,\n ref,\n cachedAt: new Date().toISOString()\n } satisfies TemplateCacheMetadata);\n await removePath(entryRoot);\n await rename(stagingRoot, entryRoot);\n },\n cleanup: () => removePath(stagingRoot)\n };\n}\n\nasync function calculateDirectorySize(directory: string): Promise<number> {\n let total = 0;\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(directory, entry.name);\n if (entry.isDirectory()) total += await calculateDirectorySize(absolute);\n else if (entry.isFile()) total += (await stat(absolute)).size;\n }\n return total;\n}\n\nexport async function listTemplateCache(): Promise<TemplateCacheEntry[]> {\n const cacheRoot = getTemplateCacheRoot();\n if (!existsSync(cacheRoot)) return [];\n const entries: TemplateCacheEntry[] = [];\n for (const directory of await readdir(cacheRoot, { withFileTypes: true })) {\n if (!directory.isDirectory() || directory.name.startsWith(\".\")) continue;\n const paths = getEntryPaths(directory.name);\n if (!existsSync(paths.metadataPath) || !existsSync(paths.templateRoot)) continue;\n try {\n entries.push({\n key: directory.name,\n root: paths.templateRoot,\n metadata: await readJson<TemplateCacheMetadata>(paths.metadataPath),\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n });\n } catch {\n // 损坏条目由 clear 或下一次拉取覆盖。\n }\n }\n return entries.sort((a, b) =>\n b.metadata.cachedAt.localeCompare(a.metadata.cachedAt)\n );\n}\n\nexport async function clearTemplateCache(): Promise<void> {\n await removePath(getTemplateCacheRoot());\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { JH4J_HOME_ENV, USER_CONFIG_SCHEMA_VERSION } from \"../constants.js\";\nimport { readJson, writeJson } from \"../utils/fs.js\";\nimport type { UserConfig } from \"../types.js\";\n\nexport const DEFAULT_USER_CONFIG: UserConfig = {\n schemaVersion: USER_CONFIG_SCHEMA_VERSION,\n autoInstall: false,\n autoGit: true,\n cacheTtlMinutes: 60\n};\n\nexport function getJh4jHome(): string {\n return path.resolve(process.env[JH4J_HOME_ENV] || path.join(os.homedir(), \".jh4j\"));\n}\n\nexport function getUserConfigPath(): string {\n return path.join(getJh4jHome(), \"config.json\");\n}\n\nexport async function loadUserConfig(): Promise<UserConfig> {\n const configPath = getUserConfigPath();\n if (!existsSync(configPath)) return { ...DEFAULT_USER_CONFIG };\n\n const stored = await readJson<Partial<UserConfig>>(configPath);\n if (\n stored.schemaVersion !== undefined &&\n stored.schemaVersion !== USER_CONFIG_SCHEMA_VERSION\n ) {\n throw new Error(\n `不支持的用户配置版本: ${stored.schemaVersion},当前要求 ${USER_CONFIG_SCHEMA_VERSION}`\n );\n }\n return { ...DEFAULT_USER_CONFIG, ...stored };\n}\n\nexport async function saveUserConfig(config: UserConfig): Promise<void> {\n await writeJson(getUserConfigPath(), {\n ...config,\n schemaVersion: USER_CONFIG_SCHEMA_VERSION\n });\n}\n\nconst CONFIG_KEYS = new Set<keyof UserConfig>([\n \"catalogFile\",\n \"templateSource\",\n \"templateRef\",\n \"npmRegistry\",\n \"jhlcRegistry\",\n \"autoInstall\",\n \"autoGit\",\n \"cacheTtlMinutes\"\n]);\n\nexport function parseUserConfigValue(\n key: string,\n rawValue: string\n): [keyof UserConfig, UserConfig[keyof UserConfig]] {\n if (!CONFIG_KEYS.has(key as keyof UserConfig)) {\n throw new Error(`不支持的配置项: ${key}`);\n }\n const typedKey = key as keyof UserConfig;\n if (typedKey === \"autoInstall\" || typedKey === \"autoGit\") {\n const normalized = rawValue.toLowerCase();\n if (!new Set([\"true\", \"false\"]).has(normalized)) {\n throw new Error(`${key} 只能是 true 或 false`);\n }\n return [typedKey, normalized === \"true\"];\n }\n if (typedKey === \"cacheTtlMinutes\") {\n const value = Number(rawValue);\n if (!Number.isInteger(value) || value < 0 || value > 10080) {\n throw new Error(\"cacheTtlMinutes 必须是 0 到 10080 之间的整数\");\n }\n return [typedKey, value];\n }\n return [typedKey, rawValue.trim()];\n}\n","import * as prompts from \"@clack/prompts\";\nimport { findTemplate, loadCatalog } from \"../catalog.js\";\nimport {\n generateProject,\n normalizeProjectName\n} from \"../core/project-generator.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n TemplateCategory\n} from \"../types.js\";\n\nconst CATEGORY_OPTIONS: Array<{\n value: TemplateCategory;\n label: string;\n}> = [\n { value: \"frontend\", label: \"PC 前端 · Vue 3 / 微前端\" },\n { value: \"backend\", label: \"后端服务 · Java / 云原生\" },\n { value: \"mobile\", label: \"移动端 H5 · Vue 3 / Vant\" }\n];\n\nfunction isCategory(value: string): value is TemplateCategory {\n return CATEGORY_OPTIONS.some((item) => item.value === value);\n}\n\nexport function templatesByCategory(\n templates: CatalogTemplate[],\n category: TemplateCategory\n): CatalogTemplate[] {\n return templates.filter((template) => template.category === category);\n}\n\nexport function categoryOptionsFor(\n templates: CatalogTemplate[]\n): Array<{ value: TemplateCategory; label: string }> {\n return CATEGORY_OPTIONS.filter(\n (item) => templatesByCategory(templates, item.value).length > 0\n ).map(({ value, label }) => ({ value, label }));\n}\n\nasync function selectCategory(\n templates: CatalogTemplate[],\n requestedCategory: string | undefined,\n nonInteractive: boolean\n): Promise<TemplateCategory> {\n if (requestedCategory) {\n if (!isCategory(requestedCategory)) {\n throw new Error(\n `项目类型无效: ${requestedCategory}。可用值: frontend、backend、mobile`\n );\n }\n if (!templatesByCategory(templates, requestedCategory).length) {\n throw new Error(`项目类型 ${requestedCategory} 暂无可用模板`);\n }\n return requestedCategory;\n }\n\n const firstAvailable = CATEGORY_OPTIONS.find(\n (item) => templatesByCategory(templates, item.value).length > 0\n );\n if (!firstAvailable) throw new Error(\"Catalog 中没有可用模板\");\n if (nonInteractive) return firstAvailable.value;\n\n const availableOptions = categoryOptionsFor(templates);\n if (availableOptions.length === 1) return availableOptions[0].value;\n\n const selected = await prompts.select({\n message: \"选择项目类型\",\n options: availableOptions.map((item) => ({\n value: item.value,\n label: item.label\n }))\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return selected as TemplateCategory;\n}\n\nasync function selectTemplate(\n templates: CatalogTemplate[],\n options: CreateOptions\n): Promise<CatalogTemplate> {\n if (options.template) {\n const selected = findTemplate(templates, options.template);\n if (options.category && selected.category !== options.category) {\n throw new Error(\n `模板 ${selected.id} 属于 ${selected.category},与 --category ${options.category} 不一致`\n );\n }\n return selected;\n }\n\n const category = await selectCategory(\n templates,\n options.category,\n Boolean(options.yes)\n );\n const candidates = templatesByCategory(templates, category);\n if (options.yes) return findTemplate(candidates);\n if (candidates.length === 1) {\n const selected = candidates[0];\n prompts.log.info(`使用模板:${selected.name}`);\n return selected;\n }\n\n const selected = await prompts.select({\n message: \"选择项目模板\",\n options: candidates.map((template) => ({\n value: template.id,\n label: `${template.name} · ${template.description}`\n }))\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return findTemplate(candidates, String(selected));\n}\n\nexport async function createCommand(\n requestedName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n prompts.intro(\"JH4J Cloud 项目创建\");\n const userConfig = await loadUserConfig();\n const catalog = await loadCatalog(userConfig);\n const template = await selectTemplate(catalog, options);\n\n let projectName = requestedName;\n if (!projectName) {\n if (options.yes) throw new Error(\"非交互模式必须指定项目名称\");\n const defaultProjectName =\n template.category === \"mobile\" ? \"jh4j-mobile-app\" : \"jh4j-ui-app\";\n const answer = await prompts.text({\n message: \"项目名称\",\n placeholder: defaultProjectName,\n defaultValue: defaultProjectName,\n validate(value) {\n return !value || normalizeProjectName(value)\n ? undefined\n : \"请输入至少一个字母或数字,例如 jh4j-mobile-app\";\n }\n });\n if (prompts.isCancel(answer)) throw new Error(\"用户取消创建\");\n projectName = String(answer).trim() || defaultProjectName;\n }\n\n const rawProjectName = projectName;\n projectName = normalizeProjectName(rawProjectName);\n if (!projectName) {\n throw new Error(\"项目名称至少需要包含一个字母或数字\");\n }\n if (projectName !== rawProjectName) {\n prompts.log.info(`项目名称已规范化:${projectName}`);\n }\n\n const result = await generateProject(\n template,\n projectName,\n options,\n process.cwd(),\n userConfig\n );\n if (options.dryRun) {\n prompts.outro(\"Dry Run 完成,未写入任何项目文件\");\n return;\n }\n\n prompts.note(\n [\n `目录: ${result.targetRoot}`,\n `模板: ${result.templateId}@${result.templateVersion}`,\n `来源: ${result.source}`,\n `默认能力: ${result.features.length ? result.features.join(\", \") : \"无\"}`,\n `依赖: ${result.installed ? \"已安装\" : \"未安装(默认由开发者手动安装)\"}`,\n `Git: ${result.gitInitialized ? \"main 已初始化\" : \"未初始化\"}`,\n \"\",\n \"需要调整配置时,直接修改生成项目中的:\",\n \" project.config.json 项目、联调与环境参数\",\n \" .npmrc Registry 配置\",\n \" .env* 各端运行环境配置(如存在)\",\n \"\",\n `cd ${projectName}`,\n ...(!result.installed ? [\"pnpm install\"] : []),\n \"pnpm dev\"\n ].join(\"\\n\"),\n \"创建成功\"\n );\n prompts.outro(\"项目已准备好\");\n}\n","import { existsSync } from \"node:fs\";\nimport { rename, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as prompts from \"@clack/prompts\";\nimport { satisfies } from \"semver\";\nimport { CLI_NAME, CLI_VERSION } from \"../constants.js\";\nimport {\n copyTemplateTree,\n isDirectoryEmpty,\n readJson,\n removePath,\n writeJson\n} from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./template-source.js\";\nimport { loadTemplateManifest } from \"./template-manifest.js\";\nimport { DEFAULT_USER_CONFIG } from \"./user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n ProjectInput,\n TemplateManifest,\n UserConfig\n} from \"../types.js\";\n\nconst ENV_NAMES = [\"dev\", \"sit\", \"uat\", \"pre\", \"prd\"] as const;\ntype PartialProjectInput = Partial<Omit<ProjectInput, \"environments\">> & {\n environments?: Partial<ProjectInput[\"environments\"]>;\n};\n\nfunction cancelled(value: unknown): value is symbol {\n return prompts.isCancel(value);\n}\n\nexport function normalizeProjectName(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n .replace(/^[._-]+/, \"\")\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/-{2,}/g, \"-\")\n .replace(/[-._]+$/, \"\");\n}\n\nfunction ensureProjectName(value: string): string {\n const name = normalizeProjectName(value);\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {\n throw new Error(\"项目名称至少需要包含一个字母或数字\");\n }\n return name;\n}\n\nfunction inferModuleName(projectName: string): string {\n const inferred = projectName\n .replace(/^(?:jh4j|wl)-ui-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return /^[a-z][a-z0-9-]*$/.test(inferred) ? inferred : \"app\";\n}\n\nfunction ensureModuleName(value: string): string {\n const name = value.trim();\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n throw new Error(\"模块标识必须以小写字母开头,只能包含小写字母、数字和连字符\");\n }\n return name;\n}\n\nfunction ensurePort(value: string | number): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1024 || port > 65535) {\n throw new Error(\"开发端口必须是 1024 到 65535 之间的整数\");\n }\n return port;\n}\n\nfunction ensureHttpUrl(value: string, label: string): string {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error();\n return value.replace(/\\/+$/, \"\");\n } catch {\n throw new Error(`${label} 必须是 http/https URL`);\n }\n}\n\nasync function askText(\n message: string,\n initialValue: string,\n validate?: (value: string | undefined) => string | undefined\n): Promise<string> {\n const answer = await prompts.text({\n message,\n placeholder: initialValue,\n defaultValue: initialValue,\n validate\n });\n if (cancelled(answer)) throw new Error(\"用户取消创建\");\n return String(answer).trim() || initialValue;\n}\n\nasync function loadCreateConfig(\n configFile: string | undefined,\n cwd: string\n): Promise<PartialProjectInput> {\n if (!configFile) return {};\n const resolved = path.resolve(cwd, configFile);\n if (!existsSync(resolved)) throw new Error(`创建配置文件不存在: ${resolved}`);\n return readJson<PartialProjectInput>(resolved);\n}\n\nfunction parseFeatureIds(value: string): string[] {\n return [...new Set(value.split(\",\").map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function collectTemplateFeatures(\n manifest: TemplateManifest,\n fileConfig: PartialProjectInput,\n options: CreateOptions\n): Promise<string[]> {\n const available = manifest.features ?? [];\n if (!available.length) return [];\n\n const knownIds = new Set(available.map((feature) => feature.id));\n let selected = options.features\n ? parseFeatureIds(options.features)\n : Array.isArray(fileConfig.features)\n ? fileConfig.features\n : available\n .filter((feature) => feature.defaultEnabled || feature.required)\n .map((feature) => feature.id);\n\n const unknown = selected.filter((id) => !knownIds.has(id));\n if (unknown.length) {\n throw new Error(\n `模板不支持以下能力: ${unknown.join(\", \")}。可用能力: ${[...knownIds].join(\", \")}`\n );\n }\n\n if (options.standards === false) {\n selected = selected.filter((id) => {\n const feature = available.find((item) => item.id === id);\n return feature?.package !== \"@robot-admin/git-standards\";\n });\n }\n\n for (const feature of available) {\n if (feature.required && !selected.includes(feature.id)) {\n selected.push(feature.id);\n }\n }\n return selected;\n}\n\nasync function collectProjectInput(\n projectName: string,\n manifest: TemplateManifest,\n sourceConfig: ProjectInput,\n fileConfig: PartialProjectInput,\n options: CreateOptions,\n userConfig: UserConfig,\n features: string[]\n): Promise<ProjectInput> {\n let moduleName = options.module ?? fileConfig.moduleName ?? inferModuleName(projectName);\n let title = options.title ?? fileConfig.title ?? sourceConfig.title;\n let port: string | number =\n options.port ?? fileConfig.devServerPort ?? sourceConfig.devServerPort;\n let npmRegistry =\n options.npmRegistry ??\n fileConfig.npmRegistry ??\n userConfig.npmRegistry ??\n sourceConfig.npmRegistry;\n let jhlcRegistry =\n options.jhlcRegistry ??\n fileConfig.jhlcRegistry ??\n userConfig.jhlcRegistry ??\n sourceConfig.jhlcRegistry;\n let localBackendUrl =\n options.localBackend ?? fileConfig.localBackendUrl ?? sourceConfig.localBackendUrl;\n let localPublicUrl =\n options.localPublic ?? fileConfig.localPublicUrl ?? sourceConfig.localPublicUrl;\n const environments = structuredClone(sourceConfig.environments);\n for (const [env, value] of Object.entries(fileConfig.environments ?? {})) {\n if (value && environments[env]) {\n environments[env] = { ...environments[env], ...value };\n }\n }\n\n if (!options.yes) {\n title = await askText(\n manifest.category === \"mobile\" ? \"应用标题\" : \"系统标题\",\n title,\n (value) => (value?.trim() ? undefined : \"标题不能为空\")\n );\n port = await askText(\"开发端口\", String(port), (value) => {\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed >= 1024 && parsed <= 65535\n ? undefined\n : \"请输入 1024 到 65535 之间的端口\";\n });\n localBackendUrl = await askText(\n manifest.category === \"mobile\" ? \"本地 API 地址\" : \"本地后端地址\",\n localBackendUrl,\n (value) => {\n try {\n const url = new URL(value ?? \"\");\n return url.protocol === \"http:\" || url.protocol === \"https:\"\n ? undefined\n : \"请输入 http/https 地址\";\n } catch {\n return \"请输入完整的 http/https 地址\";\n }\n }\n );\n }\n\n if (!title.trim()) throw new Error(\"系统标题不能为空\");\n for (const env of ENV_NAMES) {\n if (!environments[env]) throw new Error(`缺少 ${env.toUpperCase()} 环境配置`);\n environments[env] = {\n webUrl: ensureHttpUrl(environments[env].webUrl, `${env.toUpperCase()} 平台地址`),\n apiPrefix: environments[env].apiPrefix.replace(/^\\/+|\\/+$/g, \"\")\n };\n if (!environments[env].apiPrefix) {\n throw new Error(`${env.toUpperCase()} API 前缀不能为空`);\n }\n }\n\n return {\n projectName,\n moduleName: ensureModuleName(moduleName),\n title: title.trim(),\n devServerPort: ensurePort(port),\n npmRegistry: ensureHttpUrl(npmRegistry, \"npm registry\"),\n jhlcRegistry: ensureHttpUrl(jhlcRegistry, \"@jhlc 私有 registry\"),\n localBackendUrl: ensureHttpUrl(localBackendUrl, \"本地后端地址\"),\n localPublicUrl: ensureHttpUrl(localPublicUrl, \"本地 public 地址\"),\n environments,\n features\n };\n}\n\nfunction assertSafeTarget(cwd: string, target: string): void {\n if (path.dirname(target) !== cwd || target === cwd) {\n throw new Error(\"仅允许在当前目录创建一级项目目录\");\n }\n}\n\nasync function promoteStaging(\n stagingRoot: string,\n targetRoot: string,\n force: boolean\n): Promise<void> {\n const targetExists = existsSync(targetRoot);\n if (!targetExists) {\n await rename(stagingRoot, targetRoot);\n return;\n }\n\n if (!(await isDirectoryEmpty(targetRoot)) && !force) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const backupRoot = `${targetRoot}.jh4j-backup-${Date.now()}`;\n await rename(targetRoot, backupRoot);\n try {\n await rename(stagingRoot, targetRoot);\n } catch (error) {\n await rename(backupRoot, targetRoot);\n throw error;\n }\n try {\n await removePath(backupRoot);\n } catch {\n prompts.log.warn(`旧目录备份未能自动清理: ${backupRoot}`);\n }\n}\n\nexport interface GenerateProjectResult {\n targetRoot: string;\n templateId: string;\n templateVersion: string;\n source: string;\n features: string[];\n installed: boolean;\n gitInitialized: boolean;\n}\n\nexport async function generateProject(\n catalogTemplate: CatalogTemplate,\n requestedProjectName: string,\n options: CreateOptions,\n cwd = process.cwd(),\n configuredUserConfig: UserConfig = DEFAULT_USER_CONFIG\n): Promise<GenerateProjectResult> {\n const userConfig = { ...DEFAULT_USER_CONFIG, ...configuredUserConfig };\n const projectName = ensureProjectName(requestedProjectName);\n const resolvedCwd = path.resolve(cwd);\n const targetRoot = path.resolve(resolvedCwd, projectName);\n assertSafeTarget(resolvedCwd, targetRoot);\n if (\n existsSync(targetRoot) &&\n !(await isDirectoryEmpty(targetRoot)) &&\n !options.force\n ) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const ref = options.ref ?? userConfig.templateRef ?? catalogTemplate.defaultRef;\n const sourceValues = resolveTemplateSources(\n catalogTemplate,\n options.source,\n userConfig.templateSource\n );\n const acquisitionSpinner = options.yes\n ? undefined\n : prompts.spinner({ indicator: \"timer\" });\n acquisitionSpinner?.start(\"正在获取并校验模板\");\n let acquired: Awaited<ReturnType<typeof acquireTemplateFromSources>>;\n try {\n acquired = await acquireTemplateFromSources(sourceValues, ref, {\n noCache: options.cache === false,\n cacheTtlMinutes: userConfig.cacheTtlMinutes\n });\n acquisitionSpinner?.stop(\"模板准备完成\");\n } catch (error) {\n acquisitionSpinner?.error(\"模板获取失败\");\n throw error;\n }\n const stagingRoot = path.join(\n resolvedCwd,\n `.${projectName}.jh4j-tmp-${process.pid}-${Date.now()}`\n );\n let promoted = false;\n\n try {\n const manifest = await loadTemplateManifest(acquired.root);\n if (manifest.id !== catalogTemplate.id) {\n throw new Error(\n `模板 ID 不匹配:Catalog=${catalogTemplate.id},Manifest=${manifest.id}`\n );\n }\n if (!satisfies(process.versions.node, manifest.runtime.node)) {\n throw new Error(\n `当前 Node ${process.versions.node} 不满足模板要求 ${manifest.runtime.node}`\n );\n }\n\n const sourceProjectConfig = await readJson<\n Omit<ProjectInput, \"npmRegistry\" | \"jhlcRegistry\">\n >(path.join(acquired.root, \"project.config.json\"));\n const fileConfig = await loadCreateConfig(options.config, resolvedCwd);\n const features = await collectTemplateFeatures(manifest, fileConfig, options);\n const input = await collectProjectInput(\n projectName,\n manifest,\n {\n ...sourceProjectConfig,\n npmRegistry: manifest.defaults.npmRegistry,\n jhlcRegistry: manifest.defaults.jhlcRegistry\n },\n fileConfig,\n options,\n userConfig,\n features\n );\n\n const shouldInstall =\n !options.skipInstall && (options.install === true || userConfig.autoInstall);\n const shouldInitializeGit = !options.skipGit && userConfig.autoGit;\n\n if (options.dryRun) {\n prompts.note(\n [\n `模板: ${manifest.id}@${manifest.version}`,\n `来源: ${acquired.source}`,\n `目标: ${targetRoot}`,\n `模块: ${input.moduleName}`,\n `端口: ${input.devServerPort}`,\n `能力: ${input.features.length ? input.features.join(\", \") : \"无可选能力\"}`,\n `安装依赖: ${shouldInstall ? \"是\" : \"否\"}`,\n `初始化 Git: ${shouldInitializeGit ? \"是\" : \"否\"}`\n ].join(\"\\n\"),\n \"Dry Run\"\n );\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: false,\n gitInitialized: false\n };\n }\n\n await copyTemplateTree(acquired.root, stagingRoot);\n const inputFile = path.join(stagingRoot, \".jh4j-cli-input.json\");\n await writeJson(inputFile, input);\n try {\n await runCommand(\n process.execPath,\n [\n path.join(stagingRoot, \"scripts\", \"setup-project.mjs\"),\n \"--yes\",\n \"--config\",\n inputFile,\n \"--created-by\",\n `${CLI_NAME}@${CLI_VERSION}`\n ],\n { cwd: stagingRoot, stdio: \"pipe\" }\n );\n } finally {\n await rm(inputFile, { force: true });\n }\n\n if (!existsSync(path.join(stagingRoot, manifest.generatedMetadata))) {\n throw new Error(`模板初始化未生成元数据: ${manifest.generatedMetadata}`);\n }\n await promoteStaging(stagingRoot, targetRoot, Boolean(options.force));\n promoted = true;\n\n let gitInitialized = false;\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"init\", \"-b\", \"main\"], {\n cwd: targetRoot,\n stdio: \"pipe\"\n });\n gitInitialized = true;\n }\n\n if (shouldInstall) {\n try {\n await runCommand(\"pnpm\", [\"install\"], { cwd: targetRoot });\n } catch (error) {\n throw new Error(\n `项目已生成,但依赖安装失败;目录已保留在 ${targetRoot}\\n${(error as Error).message}`\n );\n }\n }\n\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"add\", \"-A\"], { cwd: targetRoot, stdio: \"pipe\" });\n try {\n await runCommand(\n \"git\",\n [\"commit\", \"-m\", `feat(init): 基于 ${manifest.id}@${manifest.version} 初始化`],\n {\n cwd: targetRoot,\n stdio: \"pipe\",\n env: { HUSKY: \"0\" }\n }\n );\n } catch (error) {\n prompts.log.warn(`Git 已初始化,但初始提交未完成:${(error as Error).message}`);\n }\n }\n\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: shouldInstall,\n gitInitialized\n };\n } finally {\n if (!promoted && existsSync(stagingRoot)) await removePath(stagingRoot);\n await acquired.cleanup();\n }\n}\n","import path from \"node:path\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { TemplateManifest } from \"../types.js\";\n\nexport async function loadTemplateManifest(\n templateRoot: string\n): Promise<TemplateManifest> {\n const manifest = await readJson<TemplateManifest>(\n path.join(templateRoot, \"template.manifest.json\")\n );\n const errors: string[] = [];\n\n if (manifest.schemaVersion !== 1) errors.push(\"schemaVersion 必须为 1\");\n if (!manifest.id) errors.push(\"缺少模板 id\");\n if (!manifest.name) errors.push(\"缺少模板名称\");\n if (!/^\\d+\\.\\d+\\.\\d+([+-].+)?$/.test(manifest.version ?? \"\")) {\n errors.push(\"模板 version 不是有效的语义化版本\");\n }\n if (!manifest.runtime?.node || !manifest.runtime?.packageManager) {\n errors.push(\"缺少模板运行时约束\");\n }\n if (!manifest.entry?.nonInteractive) {\n errors.push(\"缺少非交互初始化入口\");\n }\n const featureIds = new Set<string>();\n for (const feature of manifest.features ?? []) {\n if (!/^[a-z][a-z0-9-]*$/.test(feature.id)) {\n errors.push(`模板能力 id 无效: ${feature.id}`);\n }\n if (featureIds.has(feature.id)) {\n errors.push(`模板能力 id 重复: ${feature.id}`);\n }\n featureIds.add(feature.id);\n if (!feature.name || !feature.description) {\n errors.push(`模板能力 ${feature.id} 缺少名称或说明`);\n }\n }\n\n if (errors.length) {\n throw new Error(`模板 manifest 无效:\\n- ${errors.join(\"\\n- \")}`);\n }\n return manifest;\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { coerce, gte, satisfies } from \"semver\";\nimport { loadCatalog } from \"../catalog.js\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { resolveTemplateSources } from \"../core/template-source.js\";\nimport { getJh4jHome, loadUserConfig } from \"../core/user-config.js\";\nimport { inspectCommand } from \"../utils/process.js\";\nimport type { CatalogTemplate, UserConfig } from \"../types.js\";\n\nexport interface CheckResult {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nasync function checkHomeWritable(): Promise<CheckResult> {\n const home = getJh4jHome();\n const probe = path.join(home, `.write-probe-${process.pid}`);\n try {\n await mkdir(home, { recursive: true });\n await writeFile(probe, \"ok\", \"utf8\");\n await rm(probe, { force: true });\n return { name: \"JH4J_HOME\", ok: true, detail: home };\n } catch (error) {\n return { name: \"JH4J_HOME\", ok: false, detail: (error as Error).message };\n }\n}\n\nexport async function collectDoctorChecks(\n suppliedConfig?: UserConfig,\n suppliedCatalog?: CatalogTemplate[]\n): Promise<CheckResult[]> {\n const config = suppliedConfig ?? (await loadUserConfig());\n const catalog = suppliedCatalog ?? (await loadCatalog(config));\n const [git, pnpm, home] = await Promise.all([\n inspectCommand(\"git\"),\n inspectCommand(\"pnpm\"),\n checkHomeWritable()\n ]);\n const pnpmVersion = coerce(pnpm.output)?.version;\n const checks: CheckResult[] = [\n {\n name: \"Node.js\",\n ok: satisfies(process.versions.node, \"^22.12.0 || ^24.0.0\"),\n detail: `${process.versions.node}(要求 Node 22.12+ 或 24.x)`\n },\n { name: \"Git\", ok: git.ok, detail: git.output },\n {\n name: \"pnpm\",\n ok: pnpm.ok && Boolean(pnpmVersion && gte(pnpmVersion, \"11.8.0\")),\n detail: pnpm.output\n },\n home\n ];\n\n for (const template of catalog) {\n const sources = resolveTemplateSources(\n template,\n undefined,\n config.templateSource\n );\n const source = sources[0];\n if (!existsSync(source)) {\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.startsWith(\"git@\"),\n detail: `远程候选源(创建时依次验证): ${sources.join(\" → \")}`\n });\n continue;\n }\n try {\n const manifest = await loadTemplateManifest(source);\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n manifest.id === template.id &&\n satisfies(process.versions.node, manifest.runtime.node),\n detail: `${manifest.id}@${manifest.version} (${source})`\n });\n } catch (error) {\n checks.push({\n name: `模板 ${template.id}`,\n ok: false,\n detail: (error as Error).message\n });\n }\n }\n return checks;\n}\n\nexport async function doctorCommand(options: { json?: boolean } = {}): Promise<void> {\n const checks = await collectDoctorChecks();\n const failed = checks.filter((check) => !check.ok);\n if (options.json) {\n console.log(JSON.stringify({ ok: failed.length === 0, checks }, null, 2));\n } else {\n for (const check of checks) {\n console.log(`${check.ok ? \"✓\" : \"✗\"} ${check.name}: ${check.detail}`);\n }\n console.log(`\\n结果: ${checks.length - failed.length} 通过, ${failed.length} 失败`);\n }\n if (failed.length) process.exitCode = 1;\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { ProjectMetadata } from \"../types.js\";\n\nexport async function infoCommand(\n projectPath = process.cwd(),\n options: { json?: boolean } = {}\n): Promise<void> {\n const root = path.resolve(projectPath);\n const metadataPath = path.join(root, \".jhlc\", \"project.json\");\n if (!existsSync(metadataPath)) {\n throw new Error(`当前目录不是 JH4J CLI 创建的项目: ${metadataPath}`);\n }\n const metadata = await readJson<ProjectMetadata>(metadataPath);\n if (options.json) {\n console.log(JSON.stringify({ projectRoot: root, ...metadata }, null, 2));\n return;\n }\n console.log(`项目目录: ${root}`);\n console.log(`模板: ${metadata.template.id}@${metadata.template.version}`);\n console.log(`平台版本: ${metadata.platformVersion ?? \"未声明\"}`);\n console.log(`创建时间: ${metadata.createdAt}`);\n console.log(`创建工具: ${metadata.createdBy}`);\n console.log(\"项目参数:\");\n console.log(JSON.stringify(metadata.parameters, null, 2));\n}\n","import { loadCatalog } from \"../catalog.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\n\nexport async function listCommand(options: { json?: boolean } = {}): Promise<void> {\n const templates = await loadCatalog(await loadUserConfig());\n if (options.json) {\n console.log(JSON.stringify(templates, null, 2));\n return;\n }\n console.table(\n templates.map((template) => ({\n ID: template.id,\n 名称: template.name,\n 类型: template.category,\n 状态: template.status,\n 默认分支: template.defaultRef,\n 标签: template.tags?.join(\", \") ?? \"\"\n }))\n );\n}\n","import path from \"node:path\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { runCommand } from \"../utils/process.js\";\n\nexport async function validateTemplateCommand(templatePath: string): Promise<void> {\n const root = path.resolve(templatePath);\n const manifest = await loadTemplateManifest(root);\n await runCommand(process.execPath, [path.join(root, \"scripts\", \"validate-template.mjs\")], {\n cwd: root\n });\n console.log(`模板可用: ${manifest.id}@${manifest.version}`);\n}\n","import {\n DEFAULT_USER_CONFIG,\n getUserConfigPath,\n loadUserConfig,\n parseUserConfigValue,\n saveUserConfig\n} from \"../core/user-config.js\";\n\nexport async function configListCommand(options: { json?: boolean } = {}): Promise<void> {\n const config = await loadUserConfig();\n if (options.json) console.log(JSON.stringify(config, null, 2));\n else console.table(Object.entries(config).map(([key, value]) => ({ key, value })));\n console.log(`配置文件: ${getUserConfigPath()}`);\n}\n\nexport async function configGetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in config)) throw new Error(`配置项不存在: ${key}`);\n console.log(String((config as unknown as Record<string, unknown>)[key]));\n}\n\nexport async function configSetCommand(key: string, value: string): Promise<void> {\n const config = await loadUserConfig();\n const [typedKey, typedValue] = parseUserConfigValue(key, value);\n (config as unknown as Record<string, unknown>)[typedKey] = typedValue;\n await saveUserConfig(config);\n console.log(`已设置 ${typedKey}=${String(typedValue)}`);\n}\n\nexport async function configUnsetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in DEFAULT_USER_CONFIG) && !(key in config)) {\n throw new Error(`配置项不存在: ${key}`);\n }\n const defaults = DEFAULT_USER_CONFIG as unknown as Record<string, unknown>;\n const mutable = config as unknown as Record<string, unknown>;\n if (key in defaults) mutable[key] = defaults[key];\n else delete mutable[key];\n await saveUserConfig(config);\n console.log(`已重置配置项: ${key}`);\n}\n\nexport async function configResetCommand(): Promise<void> {\n await saveUserConfig({ ...DEFAULT_USER_CONFIG });\n console.log(`用户配置已恢复默认值: ${getUserConfigPath()}`);\n}\n","import {\n clearTemplateCache,\n getTemplateCacheRoot,\n listTemplateCache\n} from \"../core/template-cache.js\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n}\n\nexport async function cacheListCommand(options: { json?: boolean } = {}): Promise<void> {\n const entries = await listTemplateCache();\n if (options.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n if (!entries.length) {\n console.log(`模板缓存为空: ${getTemplateCacheRoot()}`);\n return;\n }\n console.table(\n entries.map((entry) => ({\n Key: entry.key,\n 来源: entry.metadata.source,\n Ref: entry.metadata.ref,\n 缓存时间: entry.metadata.cachedAt,\n 大小: formatBytes(entry.sizeBytes)\n }))\n );\n}\n\nexport async function cacheClearCommand(): Promise<void> {\n await clearTemplateCache();\n console.log(`模板缓存已清理: ${getTemplateCacheRoot()}`);\n}\n","import { runCli } from \"./cli.js\";\n\nrunCli().catch((error) => {\n console.error(`\\n错误: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["path","existsSync","readdir","existsSync","path","path","existsSync","mkdir","readdir","rename","rm","writeFile","existsSync","mkdir","stat","path","path","existsSync","path","existsSync","path","existsSync","mkdir","stat","existsSync","path","readdir","rename","rm","writeFile","mkdir","prompts","existsSync","rename","rm","path","path","path","path","existsSync","rename","rm","selected","existsSync","mkdir","writeFile","rm","path","satisfies","path","mkdir","writeFile","rm","satisfies","existsSync","path","existsSync","path","existsSync","path","path","config"]}
|