gz-cli-front 0.0.0-stage → 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/create.ts","../src/services/config.ts","../src/utils/pkg-manager.ts","../src/utils/template.ts","../src/utils/cache.ts","../src/utils/http.ts","../src/utils/system-proxy.ts","../src/utils/git-repository.ts","../src/utils/template-downloader.ts","../src/utils/stable-spinner.ts","../src/pre/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'node:module';\nimport { create } from './commands/create.js';\nimport { checkNodeVersion } from './pre/index.js';\n\n// 1. 前置检查:Node.js 版本\ncheckNodeVersion();\n\nconst program = new Command();\nconst require = createRequire(import.meta.url);\nconst packageMetadata: unknown = require('../package.json');\nconst packageVersion = getPackageVersion(packageMetadata);\n\nprogram\n .name('gz-cli-front')\n .description('前端脚手架工具')\n .version(packageVersion);\n\n// 将 init 设为默认命令,参数改为可选 [project-name]\nprogram\n .command('init [project-name]', { isDefault: true })\n .description('创建一个新项目')\n .option('--pm <package-manager>', '指定包管理器:npm、pnpm 或 yarn')\n .option('--proxy <url>', '指定本次初始化使用的 HTTP(S) 代理')\n .option('--no-proxy', '强制直连,不读取环境变量或系统代理')\n .option('--refresh', '忽略模板配置和模板缓存,强制从远程仓库刷新')\n .action((projectName, options) => {\n void create(projectName, options);\n });\n\nprogram\n .command('create [project-name]')\n .description('创建一个新项目(兼容旧命令)')\n .option('--pm <package-manager>', '指定包管理器:npm、pnpm 或 yarn')\n .option('--proxy <url>', '指定本次初始化使用的 HTTP(S) 代理')\n .option('--no-proxy', '强制直连,不读取环境变量或系统代理')\n .option('--refresh', '忽略模板配置和模板缓存,强制从远程仓库刷新')\n .action((projectName, options) => {\n void create(projectName, options);\n });\n\nprogram.parse(process.argv);\n\nfunction getPackageVersion(value: unknown): string {\n if (typeof value !== 'object' || value === null) {\n throw new Error('无法读取 gz-cli-front 版本号。');\n }\n\n const version = (value as Record<string, unknown>).version;\n if (typeof version !== 'string' || !version.trim()) {\n throw new Error('gz-cli-front package.json 中缺少有效版本号。');\n }\n return version;\n}\n","import { confirm, input, select } from '@inquirer/prompts';\nimport chalk from 'chalk';\nimport { execa } from 'execa';\nimport fs from 'fs-extra';\nimport ora from 'ora';\nimport path from 'path';\nimport { performance } from 'node:perf_hooks';\nimport { loadCliConfig } from '../services/config.js';\nimport {\n detectPackageManager,\n isPackageManager,\n updateProjectPackageJson,\n type PackageManager,\n} from '../utils/pkg-manager.js';\nimport {\n fetchTemplates,\n replaceTemplateVariables,\n type FetchTemplatesResult,\n type TemplateMeta,\n} from '../utils/template.js';\nimport { downloadTemplate, type TemplateDownloadTiming } from '../utils/template-downloader.js';\nimport { configureNetwork, type NetworkRoute } from '../utils/http.js';\nimport { createStableSpinner } from '../utils/stable-spinner.js';\n\nexport interface InitOptions {\n pm?: string;\n proxy?: string | false;\n refresh?: boolean;\n}\n\ninterface InitContext {\n projectName: string;\n template: TemplateMeta;\n packageManager: PackageManager;\n}\n\ninterface TemplateTiming {\n configRoute: NetworkRoute | 'ssh' | 'cache' | 'stale-cache';\n copyMs: number;\n fetchConfigMs: number;\n parseConfigMs: number;\n templateRoute: NetworkRoute | 'ssh' | 'cache' | 'stale-cache' | 'git';\n downloadMs: number;\n extractMs: number;\n renderMs: number;\n}\n\nexport async function create(projectName?: string, options: InitOptions = {}): Promise<void> {\n try {\n configureNetwork({\n forceDirect: options.proxy === false,\n proxy: typeof options.proxy === 'string' ? options.proxy : undefined,\n });\n const templateTiming = createTemplateTiming();\n const context = await createInitContext(projectName, options, templateTiming);\n const targetPath = path.resolve(process.cwd(), context.projectName);\n\n if (!(await prepareTargetDirectory(targetPath, context.projectName))) {\n return;\n }\n\n const install = await confirm({\n message: '是否自动安装依赖?',\n default: true,\n });\n\n await downloadAndGenerate(context, targetPath, templateTiming, options);\n await installDependencies(install, targetPath, context.packageManager);\n await initializeGit(targetPath);\n printNextSteps(context, install);\n } catch (error: unknown) {\n if (isUserCancellation(error)) {\n console.log(chalk.yellow('\\n已取消操作。'));\n return;\n }\n\n console.error(chalk.red(`创建项目失败:${getErrorMessage(error)}`));\n }\n}\n\nasync function createInitContext(\n projectName: string | undefined,\n options: InitOptions,\n templateTiming: TemplateTiming,\n): Promise<InitContext> {\n const finalProjectName = await getProjectName(projectName);\n const templates = await loadTemplates(templateTiming, options);\n const template = await chooseTemplate(templates);\n\n return {\n projectName: finalProjectName,\n template,\n packageManager: resolvePackageManager(options.pm),\n };\n}\n\nasync function getProjectName(projectName?: string): Promise<string> {\n if (projectName?.trim()) {\n return projectName.trim();\n }\n\n return input({\n message: '请输入项目名称:',\n validate: (value) => value.trim() ? true : '项目名称不能为空',\n });\n}\n\nasync function loadTemplates(\n templateTiming: TemplateTiming,\n options: InitOptions,\n): Promise<TemplateMeta[]> {\n const spinner = createStableSpinner();\n try {\n const config = await loadCliConfig();\n spinner.start('正在获取远程模板配置...');\n const result = await fetchTemplates(config.templateRegistry, {\n forceRefresh: options.refresh === true,\n });\n assignFetchTiming(templateTiming, result);\n spinner.succeed('远程模板配置获取成功');\n if (result.staleCache) {\n console.log(chalk.yellow('远程模板配置暂时不可用,已使用本地缓存。'));\n }\n return result.templates;\n } catch (error: unknown) {\n if (spinner.isSpinning) {\n spinner.fail('获取远程模板配置失败');\n } else {\n console.error(chalk.red('获取远程模板配置失败'));\n }\n const message = error instanceof Error && error.message\n ? error.message\n : '未知错误';\n throw new Error(`获取远程模板配置失败,请检查网络或模板配置地址。\\n${message}`);\n }\n}\n\nasync function chooseTemplate(templates: TemplateMeta[]): Promise<TemplateMeta> {\n return select({\n message: '请选择项目模板:',\n choices: templates.map((template) => ({\n name: `${template.label} (${template.name}) - ${template.description}`,\n value: template,\n })),\n default: templates.find((template) => template.type === 'micro') ?? templates[0],\n });\n}\n\nfunction resolvePackageManager(requestedPackageManager?: string): PackageManager {\n if (requestedPackageManager !== undefined) {\n if (!isPackageManager(requestedPackageManager)) {\n throw new Error(\n `不支持的 packageManager: ${requestedPackageManager}\\n支持: npm、pnpm、yarn`,\n );\n }\n return requestedPackageManager;\n }\n\n const packageManager = detectPackageManager();\n if (packageManager === 'npm') {\n console.log(chalk.yellow('未检测到 pnpm 或 yarn,自动使用 npm。'));\n }\n return packageManager;\n}\n\nasync function prepareTargetDirectory(targetPath: string, projectName: string): Promise<boolean> {\n if (!(await fs.pathExists(targetPath))) {\n return true;\n }\n\n const overwrite = await confirm({\n message: `目录 ${projectName} 已存在,是否覆盖?`,\n default: false,\n });\n\n if (!overwrite) {\n console.log(chalk.yellow('已取消创建。'));\n return false;\n }\n\n await fs.remove(targetPath);\n return true;\n}\n\nasync function downloadAndGenerate(\n context: InitContext,\n targetPath: string,\n templateTiming: TemplateTiming,\n options: InitOptions,\n): Promise<void> {\n const { template, projectName, packageManager } = context;\n const spinner = createStableSpinner();\n const downloadStartedAt = performance.now();\n try {\n spinner.start(`正在下载模板 ${template.label}...`);\n const downloadTiming = await downloadTemplate(template, targetPath, {\n forceRefresh: options.refresh === true,\n });\n assignDownloadTiming(templateTiming, downloadTiming);\n } catch (error: unknown) {\n templateTiming.downloadMs = Math.round(performance.now() - downloadStartedAt);\n await fs.remove(targetPath);\n if (spinner.isSpinning) {\n spinner.fail('模板下载失败');\n } else {\n console.error(chalk.red('模板下载失败'));\n }\n printTemplateTiming(templateTiming);\n const message = error instanceof Error && error.message\n ? error.message\n : '未知错误';\n throw new Error(`模板下载失败,请检查仓库地址或网络连接。\\n${message}`);\n }\n\n try {\n spinner.text = '正在替换模板变量...';\n const startedAt = performance.now();\n await replaceTemplateVariables(targetPath, { projectName });\n await updateProjectPackageJson(targetPath, projectName, packageManager);\n templateTiming.renderMs = Math.round(performance.now() - startedAt);\n spinner.succeed('模板下载并生成完成');\n printTemplateTiming(templateTiming);\n } catch {\n await fs.remove(targetPath);\n spinner.fail('模板下载或变量替换失败');\n throw new Error('模板变量替换失败,请检查模板文件内容。');\n }\n}\n\nfunction createTemplateTiming(): TemplateTiming {\n return {\n configRoute: 'direct',\n copyMs: 0,\n fetchConfigMs: 0,\n parseConfigMs: 0,\n templateRoute: 'direct',\n downloadMs: 0,\n extractMs: 0,\n renderMs: 0,\n };\n}\n\nfunction assignFetchTiming(\n templateTiming: TemplateTiming,\n result: FetchTemplatesResult,\n): void {\n templateTiming.fetchConfigMs = result.fetchMs;\n templateTiming.parseConfigMs = result.parseMs;\n templateTiming.configRoute = result.route;\n}\n\nfunction assignDownloadTiming(\n templateTiming: TemplateTiming,\n downloadTiming: TemplateDownloadTiming,\n): void {\n templateTiming.copyMs = downloadTiming.copyMs;\n templateTiming.downloadMs = downloadTiming.downloadMs;\n templateTiming.extractMs = downloadTiming.extractMs;\n templateTiming.templateRoute = downloadTiming.route;\n}\n\nfunction printTemplateTiming(templateTiming: TemplateTiming): void {\n console.log('\\n[template]');\n console.log(`fetch config: ${templateTiming.fetchConfigMs} ms (${formatRoute(templateTiming.configRoute)})`);\n console.log(`parse config: ${templateTiming.parseConfigMs} ms`);\n console.log(`download: ${templateTiming.downloadMs} ms (${formatRoute(templateTiming.templateRoute)})`);\n console.log(`extract: ${templateTiming.extractMs} ms`);\n console.log(`copy: ${templateTiming.copyMs} ms`);\n console.log(`render: ${templateTiming.renderMs} ms`);\n}\n\nfunction formatRoute(route: TemplateTiming['configRoute'] | TemplateTiming['templateRoute']): string {\n if (route === 'proxy-environment') {\n return 'remote, 环境变量代理';\n }\n if (route === 'proxy-system') {\n return 'remote, 系统代理';\n }\n if (route === 'direct') {\n return 'remote, 直连';\n }\n if (route === 'ssh') {\n return 'remote, Git/SSH';\n }\n return route.replace('-', ' ');\n}\n\nasync function installDependencies(\n install: boolean,\n targetPath: string,\n packageManager: PackageManager,\n): Promise<void> {\n if (!install) {\n return;\n }\n\n const installCommand = packageManager === 'yarn' ? [] : ['install'];\n const spinner = ora(`正在安装依赖 (${packageManager} ${installCommand.join(' ')})...`).start();\n try {\n await execa(packageManager, installCommand, { cwd: targetPath });\n spinner.succeed('依赖安装成功');\n } catch {\n spinner.warn('依赖安装失败,请进入项目目录后手动安装');\n }\n}\n\nasync function initializeGit(targetPath: string): Promise<void> {\n const spinner = ora('正在初始化 Git 仓库...').start();\n try {\n await execa('git', ['init'], { cwd: targetPath });\n spinner.succeed('Git 仓库初始化成功');\n } catch {\n spinner.warn('Git 仓库初始化失败,请确认 Git 已安装');\n }\n}\n\nfunction printNextSteps(context: InitContext, installed: boolean): void {\n const { projectName, packageManager } = context;\n const installCommand = packageManager === 'yarn' ? 'yarn' : `${packageManager} install`;\n const devCommand = packageManager === 'npm' ? 'npm run dev' : `${packageManager} dev`;\n\n console.log(chalk.green(`\\n项目 ${projectName} 创建成功!`));\n console.log('\\n接下来你可以:\\n');\n console.log(chalk.cyan(` cd ${projectName}`));\n if (!installed) {\n console.log(chalk.cyan(` ${installCommand}`));\n }\n console.log(chalk.cyan(` ${devCommand}`));\n}\n\nfunction isUserCancellation(error: unknown): boolean {\n return error instanceof Error && /User force closed|User cancelled/i.test(error.message);\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error && error.message ? ` ${error.message}` : '';\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { CliConfig } from '../types/config.js';\n\nconst CONFIG_FILE_NAME = 'gz-cli-front.config.json';\n\nexport async function loadCliConfig(): Promise<CliConfig> {\n const configPath = await findConfigPath();\n const config: unknown = await fs.readJson(configPath);\n\n if (!isCliConfig(config)) {\n throw new Error(`CLI 配置文件无效:${configPath}`);\n }\n\n return config;\n}\n\nasync function findConfigPath(): Promise<string> {\n const moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\n const configPaths = [\n path.resolve(moduleDirectory, 'config', CONFIG_FILE_NAME),\n path.resolve(moduleDirectory, '..', 'config', CONFIG_FILE_NAME),\n path.resolve(moduleDirectory, '..', '..', 'config', CONFIG_FILE_NAME),\n ];\n\n for (const configPath of configPaths) {\n if (await fs.pathExists(configPath)) {\n return configPath;\n }\n }\n\n throw new Error('未找到 gz-cli-front 配置文件。');\n}\n\nfunction isCliConfig(value: unknown): value is CliConfig {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const templateRegistry = (value as Record<string, unknown>).templateRegistry;\n if (typeof templateRegistry !== 'object' || templateRegistry === null) {\n return false;\n }\n\n return isTemplateRegistryConfig(templateRegistry as Record<string, unknown>);\n}\n\nfunction isTemplateRegistryConfig(value: Record<string, unknown>): boolean {\n if (!isNonEmptyString(value.url)) {\n return false;\n }\n\n if (value.source === undefined || value.source === 'http') {\n return true;\n }\n\n return value.source === 'git'\n && isNonEmptyString(value.file)\n && (value.version === undefined || isNonEmptyString(value.version));\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { spawnSync } from 'node:child_process';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn';\n\nconst PACKAGE_MANAGERS: readonly PackageManager[] = ['pnpm', 'yarn', 'npm'];\n\nexport function detectPackageManager(): PackageManager {\n return PACKAGE_MANAGERS.find(isPackageManagerAvailable) ?? 'npm';\n}\n\nexport function isPackageManager(value: string): value is PackageManager {\n return PACKAGE_MANAGERS.includes(value as PackageManager);\n}\n\nexport async function updateProjectPackageJson(\n targetDir: string,\n projectName: string,\n packageManager: PackageManager,\n): Promise<void> {\n const packageJsonPath = path.join(targetDir, 'package.json');\n if (!(await fs.pathExists(packageJsonPath))) {\n return;\n }\n\n const packageJson: Record<string, unknown> = await fs.readJson(packageJsonPath);\n packageJson.name = projectName;\n\n if (Object.prototype.hasOwnProperty.call(packageJson, 'packageManager')) {\n packageJson.packageManager = packageManager;\n }\n\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });\n}\n\nfunction isPackageManagerAvailable(packageManager: PackageManager): boolean {\n const result = spawnSync(packageManager, ['--version'], {\n shell: process.platform === 'win32',\n stdio: 'ignore',\n });\n\n return result.status === 0;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { performance } from 'node:perf_hooks';\nimport type { TemplateRegistryConfig } from '../types/config.js';\nimport type { TemplateMeta, TemplateSource, TemplateType } from '../types/template.js';\nimport {\n getTemplateRegistryCachePath,\n isCacheFresh,\n TEMPLATE_REGISTRY_CACHE_TTL_MS,\n} from './cache.js';\nimport { requestBuffer, type NetworkRoute } from './http.js';\nimport { ensureGitRepository } from './git-repository.js';\n\nconst TEXT_FILE_EXTENSIONS = new Set([\n '.json', '.ts', '.tsx', '.js', '.jsx', '.md', '.html', '.css', '.less', '.scss', '.env',\n]);\nconst IGNORED_DIRECTORIES = new Set(['node_modules', 'dist', '.git']);\nconst TEMPLATE_DEBUG_ENV = 'GZ_CLI_FRONT_DEBUG';\nconst TEMPLATE_REGISTRY_TIMEOUT_MS = 5_000;\n\ninterface TemplateRegistryCache {\n body: string;\n fetchedAt: number;\n url: string;\n}\n\nexport interface FetchTemplatesOptions {\n forceRefresh?: boolean;\n}\n\nexport interface FetchTemplatesResult {\n cacheHit: boolean;\n fetchMs: number;\n parseMs: number;\n route: NetworkRoute | 'ssh' | 'cache' | 'stale-cache';\n staleCache: boolean;\n templates: TemplateMeta[];\n}\n\nexport type { TemplateMeta, TemplateSource, TemplateType } from '../types/template.js';\n\nexport async function fetchTemplates(\n templateRegistry: TemplateRegistryConfig | string,\n options: FetchTemplatesOptions = {},\n): Promise<FetchTemplatesResult> {\n const registry = typeof templateRegistry === 'string'\n ? { url: templateRegistry } satisfies TemplateRegistryConfig\n : templateRegistry;\n\n if (registry.source === 'git') {\n return fetchTemplatesFromGit(registry, options);\n }\n\n return fetchTemplatesFromHttp(registry.url, options);\n}\n\nasync function fetchTemplatesFromHttp(\n templateRegistryUrl: string,\n options: FetchTemplatesOptions,\n): Promise<FetchTemplatesResult> {\n const cachePath = getTemplateRegistryCachePath(templateRegistryUrl);\n const cacheStartedAt = performance.now();\n let cached = await readRegistryCache(cachePath, templateRegistryUrl);\n const cacheReadMs = Math.round(performance.now() - cacheStartedAt);\n debugTemplateRequest(templateRegistryUrl, cachePath, options.forceRefresh === true);\n\n if (!options.forceRefresh && cached\n && isCacheFresh(cached.fetchedAt, TEMPLATE_REGISTRY_CACHE_TTL_MS)) {\n try {\n return parseTemplates(cached.body, true, false, cacheReadMs, 'cache');\n } catch {\n await fs.remove(cachePath);\n cached = undefined;\n }\n }\n\n const fetchStartedAt = performance.now();\n try {\n const response = await requestBuffer(templateRegistryUrl, {\n retries: 1,\n timeoutMs: TEMPLATE_REGISTRY_TIMEOUT_MS,\n });\n const body = response.body.toString('utf8');\n const result = parseTemplates(body, false, false, response.elapsedMs, response.route);\n try {\n await writeRegistryCache(cachePath, {\n body,\n fetchedAt: Date.now(),\n url: templateRegistryUrl,\n });\n } catch (error: unknown) {\n if (process.env[TEMPLATE_DEBUG_ENV] === '1') {\n console.log(`template config cache write failed: ${getErrorMessage(error)}`);\n }\n }\n return result;\n } catch (error: unknown) {\n if (!options.forceRefresh && cached) {\n return parseTemplates(\n cached.body,\n true,\n true,\n Math.round(performance.now() - fetchStartedAt),\n 'stale-cache',\n );\n }\n throw createTemplateRequestError(templateRegistryUrl, error);\n }\n}\n\nasync function fetchTemplatesFromGit(\n registry: Extract<TemplateRegistryConfig, { source: 'git' }>,\n options: FetchTemplatesOptions,\n): Promise<FetchTemplatesResult> {\n const cacheKey = `git:${registry.url}#${registry.version ?? 'latest'}:${registry.file}`;\n const fallbackCachePath = getTemplateRegistryCachePath(cacheKey);\n const fallbackCache = await readRegistryCache(fallbackCachePath, cacheKey);\n const startedAt = performance.now();\n\n try {\n const result = await ensureGitRepository(registry.url, {\n forceRefresh: options.forceRefresh,\n namespace: 'registry',\n ttlMs: TEMPLATE_REGISTRY_CACHE_TTL_MS,\n version: registry.version,\n });\n const registryFile = resolveRegistryFile(result.path, registry.file);\n const body = await fs.readFile(registryFile, 'utf8');\n const parsed = parseTemplates(\n body,\n result.cacheHit,\n result.staleCache,\n result.elapsedMs,\n result.route,\n );\n if (!result.cacheHit || !fallbackCache) {\n await writeRegistryCache(fallbackCachePath, {\n body,\n fetchedAt: Date.now(),\n url: cacheKey,\n }).catch(() => undefined);\n }\n return parsed;\n } catch (error: unknown) {\n if (!options.forceRefresh && fallbackCache) {\n return parseTemplates(\n fallbackCache.body,\n true,\n true,\n Math.round(performance.now() - startedAt),\n 'stale-cache',\n );\n }\n throw new Error(`模板注册仓库读取失败\\nerror: ${getErrorMessage(error)}`);\n }\n}\n\nfunction resolveRegistryFile(repositoryPath: string, registryFile: string): string {\n const resolvedRepository = path.resolve(repositoryPath);\n const resolvedFile = path.resolve(repositoryPath, registryFile);\n if (resolvedFile !== resolvedRepository\n && !resolvedFile.startsWith(`${resolvedRepository}${path.sep}`)) {\n throw new Error(`模板注册文件必须位于注册仓库内:${registryFile}`);\n }\n return resolvedFile;\n}\n\nfunction parseTemplates(\n body: string,\n cacheHit: boolean,\n staleCache: boolean,\n fetchMs: number,\n route: FetchTemplatesResult['route'],\n): FetchTemplatesResult {\n const parseStartedAt = performance.now();\n let data: unknown;\n\n try {\n data = JSON.parse(body);\n } catch (error: unknown) {\n throw new Error(`模板配置 JSON 解析失败:${getErrorMessage(error)}`);\n }\n if (!Array.isArray(data) || data.length === 0) {\n throw new Error('模板注册表为空');\n }\n\n const templates = data.filter(isTemplateMeta);\n if (templates.length === 0) {\n throw new Error('模板注册表中没有有效模板');\n }\n\n return {\n cacheHit,\n fetchMs,\n parseMs: Math.round(performance.now() - parseStartedAt),\n route,\n staleCache,\n templates,\n };\n}\n\nfunction debugTemplateRequest(\n templateRegistryUrl: string,\n cachePath: string,\n forceRefresh: boolean,\n): void {\n if (process.env[TEMPLATE_DEBUG_ENV] !== '1') {\n return;\n }\n\n console.log('template config url:', templateRegistryUrl);\n console.log('template config client: undici fetch');\n console.log(`template config timeout: ${TEMPLATE_REGISTRY_TIMEOUT_MS} ms`);\n console.log('template config cache:', cachePath);\n console.log('template config force refresh:', forceRefresh);\n}\n\nfunction createTemplateRequestError(templateRegistryUrl: string, error: unknown): Error {\n return new Error(\n `模板配置请求失败\\nurl: ${templateRegistryUrl}\\nerror: ${getErrorMessage(error)}`,\n );\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '未知错误';\n }\n\n const cause = 'cause' in error ? error.cause : undefined;\n const causeMessage = cause instanceof Error ? cause.message : String(cause ?? '');\n return causeMessage ? `${error.message} (${causeMessage})` : error.message;\n}\n\nasync function readRegistryCache(\n cachePath: string,\n templateRegistryUrl: string,\n): Promise<TemplateRegistryCache | undefined> {\n try {\n const cache: unknown = await fs.readJson(cachePath);\n if (!isRecord(cache)\n || cache.url !== templateRegistryUrl\n || typeof cache.body !== 'string'\n || typeof cache.fetchedAt !== 'number') {\n return undefined;\n }\n return {\n body: cache.body,\n fetchedAt: cache.fetchedAt,\n url: cache.url,\n };\n } catch {\n return undefined;\n }\n}\n\nasync function writeRegistryCache(\n cachePath: string,\n cache: TemplateRegistryCache,\n): Promise<void> {\n await fs.ensureDir(path.dirname(cachePath));\n await fs.writeJson(cachePath, cache);\n}\n\nexport async function replaceTemplateVariables(\n targetDir: string,\n variables: Readonly<Record<string, string>>,\n): Promise<void> {\n await visitDirectory(targetDir, async (filePath) => {\n if (!shouldProcessFile(filePath)) {\n return;\n }\n\n const content = await fs.readFile(filePath, 'utf8');\n const replaced = Object.entries(variables).reduce(\n (result, [key, value]) => result.split(`{{ ${key} }}`).join(value),\n content,\n );\n\n if (replaced !== content) {\n await fs.writeFile(filePath, replaced, 'utf8');\n }\n });\n}\n\nasync function visitDirectory(\n directory: string,\n onFile: (filePath: string) => Promise<void>,\n): Promise<void> {\n const entries = await fs.readdir(directory, { withFileTypes: true });\n for (const entry of entries) {\n const entryPath = path.join(directory, entry.name);\n if (entry.isDirectory()) {\n if (!IGNORED_DIRECTORIES.has(entry.name)) {\n await visitDirectory(entryPath, onFile);\n }\n } else if (entry.isFile()) {\n await onFile(entryPath);\n }\n }\n}\n\nfunction shouldProcessFile(filePath: string): boolean {\n const filename = path.basename(filePath);\n return TEXT_FILE_EXTENSIONS.has(path.extname(filename)) || filename.startsWith('.env');\n}\n\nfunction isTemplateMeta(value: unknown): value is TemplateMeta {\n if (!isRecord(value)) {\n return false;\n }\n\n return isString(value.name)\n && isString(value.label)\n && isString(value.description)\n && isTemplateType(value.type)\n && isTemplateLocation(value)\n && (value.version === undefined || isString(value.version));\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction isTemplateType(value: unknown): value is TemplateType {\n return value === 'main' || value === 'micro';\n}\n\nfunction isTemplateLocation(value: Record<string, unknown>): boolean {\n if (value.source !== undefined && !isTemplateSource(value.source)) {\n return false;\n }\n\n if (isString(value.url)) {\n return true;\n }\n\n return value.source === undefined && isString(value.repo);\n}\n\nfunction isTemplateSource(value: unknown): value is TemplateSource {\n return value === 'github' || value === 'gitlab' || value === 'git';\n}\n","import { createHash } from 'node:crypto';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport const TEMPLATE_REGISTRY_CACHE_TTL_MS = 5 * 60 * 1000;\nexport const TEMPLATE_ARCHIVE_CACHE_TTL_MS = 10 * 60 * 1000;\n\nexport function getTemplateRegistryCachePath(url: string): string {\n return path.join(getCacheDirectory(), 'registry', `${createCacheKey(url)}.json`);\n}\n\nexport function getTemplateArchiveCachePath(source: string): string {\n return path.join(getCacheDirectory(), 'templates', `${createCacheKey(source)}.tar.gz`);\n}\n\nexport function getGitRepositoryCachePath(\n namespace: 'registry' | 'templates',\n source: string,\n): string {\n return path.join(getCacheDirectory(), namespace, `git-${createCacheKey(source)}`);\n}\n\nexport function isCacheFresh(updatedAt: number, ttlMs: number): boolean {\n return Date.now() - updatedAt < ttlMs;\n}\n\nfunction getCacheDirectory(): string {\n const configuredDirectory = process.env.GZ_CLI_FRONT_CACHE_DIR?.trim();\n return configuredDirectory || path.join(os.homedir(), '.gz-cli-front', 'cache');\n}\n\nfunction createCacheKey(value: string): string {\n return createHash('sha256').update(value).digest('hex').slice(0, 24);\n}\n","import { setTimeout as delay } from 'node:timers/promises';\nimport {\n EnvHttpProxyAgent,\n ProxyAgent,\n fetch as undiciFetch,\n type Dispatcher,\n} from 'undici';\nimport { getSystemProxy } from './system-proxy.js';\n\nexport interface NetworkOptions {\n forceDirect?: boolean;\n proxy?: string;\n}\n\nexport interface HttpRequestOptions {\n headers?: Readonly<Record<string, string>>;\n retries: number;\n timeoutMs: number;\n}\n\nexport interface HttpResponseData {\n body: Buffer;\n elapsedMs: number;\n route: NetworkRoute;\n status: number;\n}\n\nexport type NetworkRoute = 'direct' | 'proxy-environment' | 'proxy-system';\n\nlet networkOptions: NetworkOptions = {};\n\nexport function configureNetwork(options: NetworkOptions): void {\n if (options.proxy) {\n validateProxyUrl(options.proxy);\n }\n networkOptions = { ...options };\n}\n\nexport async function requestBuffer(\n url: string,\n options: HttpRequestOptions,\n): Promise<HttpResponseData> {\n const startedAt = performance.now();\n let lastError: unknown;\n const proxyConfig = await resolveProxyConfig(url);\n\n for (let attempt = 0; attempt <= options.retries; attempt += 1) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n const dispatcher = proxyConfig.createDispatcher?.();\n\n debugNetworkRoute(url, proxyConfig.route, attempt + 1, options.retries + 1);\n\n try {\n const response = await undiciFetch(url, {\n ...(dispatcher ? { dispatcher } : {}),\n headers: options.headers,\n redirect: 'follow',\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`);\n }\n\n return {\n body: Buffer.from(await response.arrayBuffer()),\n elapsedMs: Math.round(performance.now() - startedAt),\n route: proxyConfig.route,\n status: response.status,\n };\n } catch (error: unknown) {\n lastError = error;\n if (attempt < options.retries) {\n await delay(250 * (attempt + 1));\n }\n } finally {\n clearTimeout(timeout);\n await dispatcher?.destroy();\n }\n }\n\n throw createRequestError(url, options, proxyConfig.route, lastError);\n}\n\ninterface ResolvedProxyConfig {\n createDispatcher?: () => Dispatcher;\n proxyUrl?: string;\n route: NetworkRoute;\n}\n\nasync function resolveProxyConfig(url: string): Promise<ResolvedProxyConfig> {\n const target = new URL(url);\n\n if (networkOptions.forceDirect) {\n return { route: 'direct' };\n }\n\n if (networkOptions.proxy) {\n const proxyUrl = networkOptions.proxy;\n return {\n createDispatcher: () => new ProxyAgent({ uri: proxyUrl }),\n proxyUrl,\n route: 'proxy-environment',\n };\n }\n\n const httpProxy = readEnvironmentVariable('http_proxy', 'HTTP_PROXY');\n const httpsProxy = readEnvironmentVariable('https_proxy', 'HTTPS_PROXY');\n const noProxy = readEnvironmentVariable('no_proxy', 'NO_PROXY');\n const environmentProxy = target.protocol === 'https:'\n ? httpsProxy ?? httpProxy\n : httpProxy;\n\n if (noProxy && shouldBypassProxy(target, noProxy)) {\n return { route: 'direct' };\n }\n\n if (environmentProxy) {\n return {\n createDispatcher: () => new EnvHttpProxyAgent({\n httpProxy,\n httpsProxy,\n noProxy,\n }),\n proxyUrl: environmentProxy,\n route: 'proxy-environment',\n };\n }\n\n const systemProxy = await getSystemProxy(target);\n if (systemProxy.noProxy && shouldBypassProxy(target, systemProxy.noProxy)) {\n return { route: 'direct' };\n }\n if (systemProxy.proxyUrl) {\n return {\n createDispatcher: () => new ProxyAgent({ uri: systemProxy.proxyUrl! }),\n proxyUrl: systemProxy.proxyUrl,\n route: 'proxy-system',\n };\n }\n\n return { route: 'direct' };\n}\n\nexport interface GitNetworkConfig {\n args: string[];\n route: NetworkRoute | 'ssh';\n}\n\nexport async function resolveGitNetworkConfig(repositoryUrl: string): Promise<GitNetworkConfig> {\n if (!/^https?:\\/\\//i.test(repositoryUrl)) {\n return { args: [], route: 'ssh' };\n }\n\n const proxyConfig = await resolveProxyConfig(repositoryUrl);\n if (proxyConfig.proxyUrl) {\n return {\n args: ['-c', `http.proxy=${proxyConfig.proxyUrl}`],\n route: proxyConfig.route,\n };\n }\n\n return {\n args: networkOptions.forceDirect ? ['-c', 'http.proxy='] : [],\n route: 'direct',\n };\n}\n\nfunction readEnvironmentVariable(primaryName: string, fallbackName: string): string | undefined {\n const value = process.env[primaryName] ?? process.env[fallbackName];\n return value?.trim() || undefined;\n}\n\nfunction shouldBypassProxy(target: URL, noProxy: string): boolean {\n const hostname = target.hostname.toLowerCase();\n const port = Number.parseInt(target.port, 10)\n || (target.protocol === 'https:' ? 443 : 80);\n\n return noProxy.split(/[,\\s]/).some((rawEntry) => {\n const entry = rawEntry.trim().toLowerCase();\n if (!entry) {\n return false;\n }\n if (entry === '*') {\n return true;\n }\n\n const parsed = entry.match(/^(.+):(\\d+)$/);\n const entryHostname = parsed ? parsed[1] : entry;\n const entryPort = parsed ? Number.parseInt(parsed[2], 10) : 0;\n if (entryPort && entryPort !== port) {\n return false;\n }\n\n if (!/^[.*]/.test(entryHostname)) {\n return hostname === entryHostname;\n }\n return hostname.endsWith(entryHostname.replace(/^\\*/, ''));\n });\n}\n\nexport function formatNetworkRoute(route: NetworkRoute): string {\n if (route === 'proxy-environment') {\n return '环境变量代理';\n }\n if (route === 'proxy-system') {\n return '系统代理';\n }\n return '直连';\n}\n\nfunction createRequestError(\n url: string,\n options: HttpRequestOptions,\n route: NetworkRoute,\n error: unknown,\n): Error {\n const cause = getErrorMessage(error);\n return new Error(\n `请求失败\\nurl: ${url}\\nerror: ${cause}\\nnetwork: ${formatNetworkRoute(route)}\\ntimeout: ${options.timeoutMs} ms\\nattempts: ${options.retries + 1}`,\n );\n}\n\nfunction validateProxyUrl(proxyUrl: string): void {\n try {\n const parsed = new URL(proxyUrl);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error();\n }\n } catch {\n throw new Error('无效的代理地址,请使用 http://host:port 或 https://host:port 格式。');\n }\n}\n\nfunction debugNetworkRoute(\n url: string,\n route: NetworkRoute,\n attempt: number,\n attempts: number,\n): void {\n if (process.env.GZ_CLI_FRONT_DEBUG !== '1') {\n return;\n }\n\n console.log(`[network] host: ${new URL(url).host}`);\n console.log(`[network] route: ${formatNetworkRoute(route)}`);\n console.log(`[network] attempt: ${attempt}/${attempts}`);\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '未知错误';\n }\n const cause = 'cause' in error ? error.cause : undefined;\n const causeMessage = cause instanceof Error ? cause.message : String(cause ?? '');\n return causeMessage ? `${error.message} (${causeMessage})` : error.message;\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\nconst WINDOWS_INTERNET_SETTINGS = String.raw`HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings`;\nconst SYSTEM_PROXY_TIMEOUT_MS = 1_500;\n\nexport interface SystemProxyConfig {\n noProxy?: string;\n proxyUrl?: string;\n}\n\nconst systemProxyCache = new Map<string, Promise<SystemProxyConfig>>();\n\nexport function getSystemProxy(target: URL): Promise<SystemProxyConfig> {\n const cacheKey = `${process.platform}:${target.protocol}`;\n const cached = systemProxyCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const request = detectSystemProxy(target).catch(() => ({}));\n systemProxyCache.set(cacheKey, request);\n return request;\n}\n\nasync function detectSystemProxy(target: URL): Promise<SystemProxyConfig> {\n if (process.platform === 'win32') {\n return detectWindowsProxy(target);\n }\n if (process.platform === 'darwin') {\n return detectMacOsProxy(target);\n }\n if (process.platform === 'linux') {\n return detectLinuxProxy(target);\n }\n return {};\n}\n\nasync function detectWindowsProxy(target: URL): Promise<SystemProxyConfig> {\n const [enabledOutput, serverOutput, overrideOutput] = await Promise.all([\n queryWindowsRegistry('ProxyEnable'),\n queryWindowsRegistry('ProxyServer'),\n queryWindowsRegistry('ProxyOverride'),\n ]);\n const enabled = readRegistryValue(enabledOutput, 'ProxyEnable');\n if (enabled !== '0x1' && enabled !== '1') {\n return {};\n }\n\n const proxyServer = readRegistryValue(serverOutput, 'ProxyServer');\n if (!proxyServer) {\n return {};\n }\n\n const proxyAddress = selectWindowsProxy(proxyServer, target.protocol);\n if (!proxyAddress) {\n return {};\n }\n\n const proxyOverride = readRegistryValue(overrideOutput, 'ProxyOverride');\n return {\n noProxy: proxyOverride?.split(';').filter((entry) => entry !== '<local>').join(','),\n proxyUrl: normalizeProxyUrl(proxyAddress),\n };\n}\n\nasync function queryWindowsRegistry(valueName: string): Promise<string> {\n try {\n const result = await execFileAsync(\n 'reg.exe',\n ['query', WINDOWS_INTERNET_SETTINGS, '/v', valueName],\n { timeout: SYSTEM_PROXY_TIMEOUT_MS, windowsHide: true },\n );\n return result.stdout;\n } catch {\n return '';\n }\n}\n\nfunction readRegistryValue(output: string, valueName: string): string | undefined {\n const line = output.split(/\\r?\\n/).find((entry) => entry.includes(valueName));\n return line?.match(/REG_\\w+\\s+(.+)$/)?.[1]?.trim();\n}\n\nfunction selectWindowsProxy(proxyServer: string, protocol: string): string | undefined {\n if (!proxyServer.includes('=')) {\n return proxyServer;\n }\n\n const proxies = new Map(\n proxyServer.split(';').flatMap((entry) => {\n const [key, value] = entry.split('=', 2).map((part) => part.trim());\n return key && value ? [[key.toLowerCase(), value] as const] : [];\n }),\n );\n const protocolName = protocol.replace(':', '');\n return proxies.get(protocolName) ?? proxies.get('http');\n}\n\nasync function detectMacOsProxy(target: URL): Promise<SystemProxyConfig> {\n try {\n const result = await execFileAsync('scutil', ['--proxy'], {\n timeout: SYSTEM_PROXY_TIMEOUT_MS,\n });\n const prefix = target.protocol === 'https:' ? 'HTTPS' : 'HTTP';\n if (readScutilValue(result.stdout, `${prefix}Enable`) !== '1') {\n return {};\n }\n const host = readScutilValue(result.stdout, `${prefix}Proxy`);\n const port = readScutilValue(result.stdout, `${prefix}Port`);\n return host && port ? { proxyUrl: `http://${host}:${port}` } : {};\n } catch {\n return {};\n }\n}\n\nfunction readScutilValue(output: string, key: string): string | undefined {\n return output.match(new RegExp(`^\\\\s*${key}\\\\s*:\\\\s*(.+)$`, 'm'))?.[1]?.trim();\n}\n\nasync function detectLinuxProxy(target: URL): Promise<SystemProxyConfig> {\n try {\n const mode = stripQuotes(await queryGSettings('org.gnome.system.proxy', 'mode'));\n if (mode !== 'manual') {\n return {};\n }\n\n const protocol = target.protocol === 'https:' ? 'https' : 'http';\n const [hostValue, portValue, ignoredHostsValue] = await Promise.all([\n queryGSettings(`org.gnome.system.proxy.${protocol}`, 'host'),\n queryGSettings(`org.gnome.system.proxy.${protocol}`, 'port'),\n queryGSettings('org.gnome.system.proxy', 'ignore-hosts'),\n ]);\n const host = stripQuotes(hostValue);\n const port = Number.parseInt(portValue.trim(), 10);\n if (!host || !Number.isInteger(port) || port <= 0) {\n return {};\n }\n\n return {\n noProxy: Array.from(\n ignoredHostsValue.matchAll(/'([^']+)'/g),\n (match) => match[1],\n ).join(','),\n proxyUrl: `http://${host}:${port}`,\n };\n } catch {\n return {};\n }\n}\n\nasync function queryGSettings(schema: string, key: string): Promise<string> {\n const result = await execFileAsync('gsettings', ['get', schema, key], {\n timeout: SYSTEM_PROXY_TIMEOUT_MS,\n });\n return result.stdout;\n}\n\nfunction stripQuotes(value: string): string {\n return value.trim().replace(/^['\"]|['\"]$/g, '');\n}\n\nfunction normalizeProxyUrl(proxyAddress: string): string {\n return /^[a-z][a-z\\d+.-]*:\\/\\//i.test(proxyAddress)\n ? proxyAddress\n : `http://${proxyAddress}`;\n}\n","import { execa } from 'execa';\nimport fs from 'fs-extra';\nimport { randomUUID } from 'node:crypto';\nimport path from 'node:path';\nimport { performance } from 'node:perf_hooks';\nimport { setTimeout as delay } from 'node:timers/promises';\nimport { getGitRepositoryCachePath, isCacheFresh } from './cache.js';\nimport {\n formatNetworkRoute,\n resolveGitNetworkConfig,\n type NetworkRoute,\n} from './http.js';\n\nconst GIT_OPERATION_ATTEMPTS = 2;\nconst GIT_AUTH_TIMEOUT_MS = 60_000;\nconst GIT_SSH_CLONE_TIMEOUT_MS = 20_000;\ntype GitOperationStage = 'clone';\n\nexport interface GitRepositoryOptions {\n forceRefresh?: boolean;\n namespace: 'registry' | 'templates';\n ttlMs: number;\n version?: string;\n}\n\nexport interface GitRepositoryResult {\n cacheHit: boolean;\n elapsedMs: number;\n path: string;\n route: NetworkRoute | 'ssh' | 'cache' | 'stale-cache';\n staleCache: boolean;\n}\n\nexport async function ensureGitRepository(\n repositoryUrl: string,\n options: GitRepositoryOptions,\n): Promise<GitRepositoryResult> {\n const version = normalizeVersion(options.version);\n const repositoryPath = getRepositoryCachePath(repositoryUrl, options.namespace, version);\n const startedAt = performance.now();\n const cacheExists = await isValidGitCache(repositoryPath);\n\n if (await canUseGitCache(repositoryPath, cacheExists, version, options)) {\n return createCacheResult(repositoryPath, startedAt, false);\n }\n\n const temporaryPath = `${repositoryPath}.${randomUUID()}.tmp`;\n const candidates = getRepositoryCandidates(repositoryUrl);\n let lastError: unknown;\n await fs.ensureDir(path.dirname(repositoryPath));\n\n for (const [index, candidate] of candidates.entries()) {\n try {\n const network = await resolveGitNetworkConfig(candidate);\n const isSshCandidate = network.route === 'ssh';\n const timeoutMs = isSshCandidate ? GIT_SSH_CLONE_TIMEOUT_MS : GIT_AUTH_TIMEOUT_MS;\n debugGitRepository(candidate, network.route, timeoutMs);\n await cloneRepository(\n candidate,\n temporaryPath,\n version,\n network.args,\n timeoutMs,\n isSshCandidate ? 1 : GIT_OPERATION_ATTEMPTS,\n );\n await replaceCacheDirectory(temporaryPath, repositoryPath);\n return {\n cacheHit: false,\n elapsedMs: Math.round(performance.now() - startedAt),\n path: repositoryPath,\n route: network.route,\n staleCache: false,\n };\n } catch (error: unknown) {\n lastError = error;\n await fs.remove(temporaryPath);\n if (index < candidates.length - 1) {\n if (process.env.GZ_CLI_FRONT_DEBUG === '1') {\n console.log('[git] SSH 不可用,正在尝试 HTTPS...');\n }\n continue;\n }\n }\n }\n\n if (cacheExists && !options.forceRefresh) {\n return createCacheResult(repositoryPath, startedAt, true);\n }\n throw createGitError(repositoryUrl, lastError, 'clone');\n}\n\nfunction getRepositoryCachePath(\n repositoryUrl: string,\n namespace: GitRepositoryOptions['namespace'],\n version: string | undefined,\n): string {\n return getGitRepositoryCachePath(\n namespace,\n `${getRepositoryIdentity(repositoryUrl)}#${version ?? 'latest'}`,\n );\n}\n\nfunction getRepositoryCandidates(repositoryUrl: string): string[] {\n return [repositoryUrl];\n}\n\nfunction getRepositoryIdentity(repositoryUrl: string): string {\n try {\n const parsed = new URL(repositoryUrl);\n const repositoryPath = parsed.pathname.replace(/^\\/|\\/$/g, '').replace(/\\.git$/i, '');\n return `${parsed.hostname.toLowerCase()}/${repositoryPath}`;\n } catch {\n const sshMatch = repositoryUrl.match(/^[^@]+@([^:]+):(.+)$/);\n if (!sshMatch) {\n return repositoryUrl;\n }\n return `${sshMatch[1].toLowerCase()}/${sshMatch[2].replace(/\\.git$/i, '')}`;\n }\n}\n\nasync function canUseGitCache(\n repositoryPath: string,\n cacheExists: boolean,\n version: string | undefined,\n options: GitRepositoryOptions,\n): Promise<boolean> {\n if (options.forceRefresh || !cacheExists) {\n return false;\n }\n const stats = await fs.stat(repositoryPath);\n return Boolean(version) || isCacheFresh(stats.mtimeMs, options.ttlMs);\n}\n\nfunction debugGitRepository(\n repositoryUrl: string,\n route: NetworkRoute | 'ssh',\n timeoutMs: number,\n): void {\n if (process.env.GZ_CLI_FRONT_DEBUG !== '1') {\n return;\n }\n\n const routeLabel = route === 'ssh' ? 'Git/SSH' : formatNetworkRoute(route);\n console.log(`[git] host: ${getRepositoryHost(repositoryUrl)}`);\n console.log(`[git] route: ${routeLabel}`);\n console.log(`[git] timeout: ${timeoutMs} ms`);\n}\n\nfunction getRepositoryHost(repositoryUrl: string): string {\n try {\n return new URL(repositoryUrl).host;\n } catch {\n return repositoryUrl.match(/^[^@]+@([^:]+):/)?.[1] ?? 'unknown';\n }\n}\n\nasync function cloneRepository(\n repositoryUrl: string,\n targetPath: string,\n version: string | undefined,\n networkArgs: string[],\n timeoutMs: number,\n attempts: number,\n): Promise<void> {\n const args = [\n ...networkArgs,\n 'clone',\n '--quiet',\n '--depth',\n '1',\n '--single-branch',\n ];\n if (version) {\n args.push('--branch', version);\n }\n args.push(repositoryUrl, targetPath);\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n try {\n await execa('git', args, {\n forceKillAfterDelay: 1_000,\n stdin: 'inherit',\n stdout: 'pipe',\n stderr: ['pipe', 'inherit'],\n timeout: timeoutMs,\n windowsHide: true,\n });\n return;\n } catch (error: unknown) {\n if (attempt === attempts || !isTransientGitError(error)) {\n throw error;\n }\n if (process.env.GZ_CLI_FRONT_DEBUG === '1') {\n console.log(`[git] transient failure, retry: ${attempt + 1}/${attempts}`);\n }\n await fs.remove(targetPath);\n await delay(300);\n }\n }\n}\n\nfunction isTransientGitError(error: unknown): boolean {\n if (typeof error === 'object' && error !== null\n && (error as Record<string, unknown>).timedOut === true) {\n return true;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return [\n /SSL\\/TLS connection failed/i,\n /failed to receive handshake/i,\n /connection (?:was )?reset/i,\n /remote end hung up unexpectedly/i,\n /early EOF/i,\n /failed to connect/i,\n /could not resolve host/i,\n /timed out|timeout/i,\n ].some((pattern) => pattern.test(message));\n}\n\nasync function replaceCacheDirectory(sourcePath: string, targetPath: string): Promise<void> {\n const backupPath = `${targetPath}.${randomUUID()}.bak`;\n const targetExists = await fs.pathExists(targetPath);\n if (targetExists) {\n await fs.move(targetPath, backupPath);\n }\n\n try {\n await fs.move(sourcePath, targetPath);\n await fs.remove(backupPath);\n } catch (error: unknown) {\n await fs.remove(targetPath);\n if (await fs.pathExists(backupPath)) {\n await fs.move(backupPath, targetPath);\n }\n throw error;\n }\n}\n\nasync function isValidGitCache(repositoryPath: string): Promise<boolean> {\n return fs.pathExists(path.join(repositoryPath, '.git'));\n}\n\nfunction createCacheResult(\n repositoryPath: string,\n startedAt: number,\n staleCache: boolean,\n): GitRepositoryResult {\n return {\n cacheHit: true,\n elapsedMs: Math.round(performance.now() - startedAt),\n path: repositoryPath,\n route: staleCache ? 'stale-cache' : 'cache',\n staleCache,\n };\n}\n\nfunction normalizeVersion(version: string | undefined): string | undefined {\n return version && version !== 'latest' ? version : undefined;\n}\n\nfunction createGitError(\n repositoryUrl: string,\n error: unknown,\n stage: GitOperationStage,\n): Error {\n const message = getGitErrorMessage(error);\n const safeRepository = sanitizeRepositoryUrl(repositoryUrl);\n debugGitFailure(stage, message);\n if (isGitTimeoutError(error, message)) {\n return new Error(\n `Git 仓库连接超时(阶段:${stage},${GIT_AUTH_TIMEOUT_MS} ms):${safeRepository}\\n请检查当前网络或代理设置后重试。`,\n );\n }\n\n if (isGitPermissionError(message)) {\n return new Error(\n `无法访问 Git 仓库(阶段:${stage}):${safeRepository}\\n请检查仓库地址、网络连接及当前 Git 凭据后重试。`,\n );\n }\n\n return new Error(\n `Git 仓库访问失败(阶段:${stage}):${safeRepository}\\n请确认已安装 Git,且当前 Git/SSH 账号拥有仓库 Read 权限。\\n${message}`,\n );\n}\n\nfunction getGitErrorMessage(error: unknown): string {\n return redactCredentials(error instanceof Error ? error.message : '未知错误');\n}\n\nfunction debugGitFailure(stage: GitOperationStage, message: string): void {\n if (process.env.GZ_CLI_FRONT_DEBUG !== '1') {\n return;\n }\n\n console.error(`[git] failed stage: ${stage}`);\n console.error(`[git] error: ${message}`);\n}\n\nfunction isGitTimeoutError(error: unknown, message: string): boolean {\n if (typeof error === 'object' && error !== null\n && (error as Record<string, unknown>).timedOut === true) {\n return true;\n }\n return /timed out|timeout/i.test(message);\n}\n\nfunction isGitPermissionError(message: string): boolean {\n return [\n /authentication failed/i,\n /permission denied/i,\n /repository not found/i,\n /could not read username/i,\n /unable to get (?:password|username) from user/i,\n /terminal prompts disabled/i,\n /user interaction is disabled/i,\n /interactive prompts are disabled/i,\n /credential.*(?:failed|unavailable)/i,\n /access denied/i,\n /http (?:error )?40[13]/i,\n /status code: 40[13]/i,\n ].some((pattern) => pattern.test(message));\n}\n\nfunction redactCredentials(message: string): string {\n return message\n .replace(/http\\.proxy=\\S+/gi, 'http.proxy=***')\n .replace(/(https?:\\/\\/)[^@\\s/]+@/gi, '$1***@');\n}\n\nfunction sanitizeRepositoryUrl(repositoryUrl: string): string {\n try {\n const parsed = new URL(repositoryUrl);\n parsed.username = '';\n parsed.password = '';\n return parsed.toString();\n } catch {\n return repositoryUrl;\n }\n}\n","import fs from 'fs-extra';\nimport { randomUUID } from 'node:crypto';\nimport path from 'path';\nimport { performance } from 'node:perf_hooks';\nimport { x as extractTar } from 'tar';\nimport type { TemplateMeta, TemplateSource } from '../types/template.js';\nimport {\n getTemplateArchiveCachePath,\n isCacheFresh,\n TEMPLATE_ARCHIVE_CACHE_TTL_MS,\n} from './cache.js';\nimport { requestBuffer, type NetworkRoute } from './http.js';\nimport { ensureGitRepository } from './git-repository.js';\n\nconst TEMPLATE_DOWNLOAD_TIMEOUT_MS = 12_000;\n\nexport interface TemplateDownloadTiming {\n cacheHit: boolean;\n copyMs: number;\n downloadMs: number;\n extractMs: number;\n route: NetworkRoute | 'ssh' | 'cache' | 'stale-cache' | 'git';\n}\n\nexport interface DownloadTemplateOptions {\n forceRefresh?: boolean;\n}\n\ntype TemplateDownloader = (\n template: TemplateMeta,\n targetDir: string,\n options: DownloadTemplateOptions,\n) => Promise<TemplateDownloadTiming>;\n\nconst DOWNLOADERS: Readonly<Record<TemplateSource, TemplateDownloader>> = {\n github: downloadFromGitHub,\n gitlab: downloadFromGit,\n git: downloadFromGit,\n};\n\nexport async function downloadTemplate(\n template: TemplateMeta,\n targetDir: string,\n options: DownloadTemplateOptions = {},\n): Promise<TemplateDownloadTiming> {\n const source = template.source ?? 'github';\n return DOWNLOADERS[source](template, targetDir, options);\n}\n\nasync function downloadFromGitHub(\n template: TemplateMeta,\n targetDir: string,\n options: DownloadTemplateOptions,\n): Promise<TemplateDownloadTiming> {\n const repository = normalizeGitHubRepository(getTemplateUrl(template));\n const version = template.version && template.version !== 'latest'\n ? template.version\n : undefined;\n const sourceKey = `${repository}${version ? `#${version}` : '#latest'}`;\n const archivePath = getTemplateArchiveCachePath(sourceKey);\n const archive = await ensureGitHubArchive(\n repository,\n version,\n archivePath,\n options.forceRefresh === true,\n );\n\n const extractStartedAt = performance.now();\n await fs.ensureDir(targetDir);\n try {\n await extractTar({\n cwd: targetDir,\n file: archivePath,\n preservePaths: false,\n strict: true,\n strip: 1,\n });\n } catch (error: unknown) {\n if (!archive.cacheHit) {\n throw error;\n }\n\n await fs.remove(archivePath);\n await fs.emptyDir(targetDir);\n return downloadFromGitHub(template, targetDir, { forceRefresh: true });\n }\n\n return {\n cacheHit: archive.cacheHit,\n copyMs: 0,\n downloadMs: archive.downloadMs,\n extractMs: Math.round(performance.now() - extractStartedAt),\n route: archive.route,\n };\n}\n\nasync function downloadFromGit(\n template: TemplateMeta,\n targetDir: string,\n options: DownloadTemplateOptions,\n): Promise<TemplateDownloadTiming> {\n if (!template.url) {\n throw new Error(`${template.source} 模板必须提供 Git clone URL。`);\n }\n\n const repository = await ensureGitRepository(template.url, {\n forceRefresh: options.forceRefresh,\n namespace: 'templates',\n ttlMs: TEMPLATE_ARCHIVE_CACHE_TTL_MS,\n version: template.version,\n });\n const copyStartedAt = performance.now();\n await fs.copy(repository.path, targetDir, {\n filter: (sourcePath) => path.basename(sourcePath) !== '.git',\n });\n\n return {\n cacheHit: repository.cacheHit,\n copyMs: Math.round(performance.now() - copyStartedAt),\n downloadMs: repository.elapsedMs,\n extractMs: 0,\n route: repository.route,\n };\n}\n\ninterface GitHubArchiveResult {\n cacheHit: boolean;\n downloadMs: number;\n route: NetworkRoute | 'cache';\n}\n\nasync function ensureGitHubArchive(\n repository: string,\n version: string | undefined,\n archivePath: string,\n forceRefresh: boolean,\n): Promise<GitHubArchiveResult> {\n const startedAt = performance.now();\n if (!forceRefresh && await canUseArchiveCache(archivePath, Boolean(version))) {\n return {\n cacheHit: true,\n downloadMs: Math.round(performance.now() - startedAt),\n route: 'cache',\n };\n }\n\n const archiveRequest = createGitHubArchiveRequest(repository, version);\n const response = await requestBuffer(archiveRequest.url, {\n headers: archiveRequest.headers,\n retries: 1,\n timeoutMs: TEMPLATE_DOWNLOAD_TIMEOUT_MS,\n });\n const temporaryPath = `${archivePath}.${randomUUID()}.tmp`;\n\n await fs.ensureDir(path.dirname(archivePath));\n try {\n await fs.writeFile(temporaryPath, response.body);\n await fs.move(temporaryPath, archivePath, { overwrite: true });\n } finally {\n await fs.remove(temporaryPath);\n }\n\n return {\n cacheHit: false,\n downloadMs: Math.round(performance.now() - startedAt),\n route: response.route,\n };\n}\n\ninterface GitHubArchiveRequest {\n headers: Readonly<Record<string, string>>;\n url: string;\n}\n\nfunction createGitHubArchiveRequest(\n repository: string,\n version: string | undefined,\n): GitHubArchiveRequest {\n const token = process.env.GITHUB_TOKEN?.trim();\n if (token) {\n return {\n headers: createGitHubApiHeaders(token),\n url: `https://api.github.com/repos/${repository}/tarball${version ? `/${encodeURIComponent(version)}` : ''}`,\n };\n }\n\n return {\n headers: { 'user-agent': 'gz-cli-front' },\n url: `https://codeload.github.com/${repository}/tar.gz/${encodeURIComponent(version ?? 'HEAD')}`,\n };\n}\n\nasync function canUseArchiveCache(archivePath: string, immutableVersion: boolean): Promise<boolean> {\n try {\n const stats = await fs.stat(archivePath);\n return stats.isFile()\n && (immutableVersion || isCacheFresh(stats.mtimeMs, TEMPLATE_ARCHIVE_CACHE_TTL_MS));\n } catch {\n return false;\n }\n}\n\nfunction normalizeGitHubRepository(repository: string): string {\n const normalized = repository\n .replace(/^https:\\/\\/github\\.com\\//i, '')\n .replace(/\\.git$/i, '')\n .replace(/^\\/+|\\/+$/g, '');\n\n if (!/^[^/\\s]+\\/[^/\\s]+$/.test(normalized)) {\n throw new Error(`无效的 GitHub 模板地址:${repository}`);\n }\n\n return normalized;\n}\n\nfunction createGitHubApiHeaders(token: string): Readonly<Record<string, string>> {\n return {\n accept: 'application/vnd.github+json',\n authorization: `Bearer ${token}`,\n 'user-agent': 'gz-cli-front',\n 'x-github-api-version': '2022-11-28',\n };\n}\n\nfunction getTemplateUrl(template: TemplateMeta): string {\n if (template.url) {\n return template.url;\n }\n if (template.repo) {\n return template.repo;\n }\n throw new Error('模板配置缺少 url。');\n}\n","import chalk from 'chalk';\nimport { clearLine, cursorTo } from 'node:readline';\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\nconst SPINNER_INTERVAL_MS = 80;\nconst RESTORE_CURSOR = '\\u001B[u';\nconst SAVE_CURSOR = '\\u001B[s';\n\nexport interface StableSpinner {\n readonly isSpinning: boolean;\n text: string;\n fail(text?: string): void;\n start(text?: string): void;\n succeed(text?: string): void;\n}\n\nexport function createStableSpinner(): StableSpinner {\n return new StableTextSpinner(process.stderr);\n}\n\nclass StableTextSpinner implements StableSpinner {\n private frameIndex = 0;\n private interval: NodeJS.Timeout | undefined;\n private readonly stream: NodeJS.WriteStream;\n private value = '';\n\n constructor(stream: NodeJS.WriteStream) {\n this.stream = stream;\n }\n\n get isSpinning(): boolean {\n return this.interval !== undefined;\n }\n\n get text(): string {\n return this.value;\n }\n\n set text(value: string) {\n this.value = value;\n if (this.isSpinning) {\n this.renderLine();\n }\n }\n\n start(text?: string): void {\n if (text !== undefined) {\n this.value = text;\n }\n if (!this.stream.isTTY || this.isSpinning) {\n if (!this.stream.isTTY && this.value) {\n this.stream.write(`- ${this.value}\\n`);\n }\n return;\n }\n\n this.stream.write(\n `${chalk.cyan(SPINNER_FRAMES[this.frameIndex])} ${this.value}${SAVE_CURSOR}`,\n );\n this.interval = setInterval(() => this.renderFrame(), SPINNER_INTERVAL_MS);\n }\n\n succeed(text?: string): void {\n this.persist(chalk.green('✔'), text);\n }\n\n fail(text?: string): void {\n this.persist(chalk.red('✖'), text);\n }\n\n private renderLine(): void {\n this.restoreAndClearLine();\n this.stream.write(`${chalk.cyan(SPINNER_FRAMES[this.frameIndex])} ${this.value}${SAVE_CURSOR}`);\n }\n\n private renderFrame(): void {\n this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;\n this.stream.write(\n `${RESTORE_CURSOR}\\r${chalk.cyan(SPINNER_FRAMES[this.frameIndex])}${RESTORE_CURSOR}`,\n );\n }\n\n private persist(symbol: string, text?: string): void {\n const finalText = text ?? this.value;\n this.stop();\n this.stream.write(`${symbol}${finalText ? ` ${finalText}` : ''}\\n`);\n }\n\n private stop(): boolean {\n if (!this.interval) {\n return false;\n }\n\n clearInterval(this.interval);\n this.interval = undefined;\n this.restoreAndClearLine();\n return true;\n }\n\n private restoreAndClearLine(): void {\n this.stream.write(RESTORE_CURSOR);\n cursorTo(this.stream, 0);\n clearLine(this.stream, 0);\n }\n}\n","import chalk from 'chalk';\n\n/**\n * 检查当前 Node.js 版本是否符合要求\n * 要求 Node.js 版本 >= 22.19.0\n */\nexport function checkNodeVersion() {\n const currentVersion = process.version;\n // 去掉版本号前的 'v',例如 'v22.5.1' -> '22.5.1'\n const version = currentVersion.replace(/^v/, '');\n const [major] = version.split('.').map(Number);\n\n if (major < 22) {\n console.error(chalk.red(`\\n❌ 错误:当前 Node.js 版本 (${currentVersion}) 过低!`));\n console.error(chalk.yellow('⚠️ 请升级 Node.js 版本,不低于 v22.19.0'));\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["chalk","execa","fs","path","performance","fs","path","fs","path","performance","path","fs","path","performance","delay","performance","fs","path","delay","performance","fs","getErrorMessage","path","fs","randomUUID","path","performance","performance","fs","path","randomUUID","path","chalk","getErrorMessage","fs","performance","execa","chalk","require"]}
package/package.json CHANGED
@@ -1,6 +1,46 @@
1
1
  {
2
2
  "name": "gz-cli-front",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "一个轻量级的现代前端脚手架工具",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "gz-cli-front": "bin/gz-cli-front.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "bin"
13
+ ],
14
+ "scripts": {
15
+ "dev": "tsup --watch",
16
+ "build": "tsup && node scripts/copy-assets.js",
17
+ "prepublishOnly": "npm run test:release",
18
+ "test": "echo \"Error: no test specified\" && exit 1",
19
+ "test:auth-error": "npm run build && node scripts/test-private-auth.js",
20
+ "test:git-compat": "node --no-warnings --loader ts-node/esm scripts/test-git-credential-compat.ts",
21
+ "test:private-access": "node --no-warnings --loader ts-node/esm scripts/test-private-access.ts",
22
+ "test:smoke": "npm run test:git-compat && npm run test:private-access && node scripts/test-private-auth.js && npm pack --dry-run",
23
+ "test:release": "npm run build && npm run test:smoke"
24
+ },
25
+ "keywords": [],
26
+ "author": "chenhui996",
27
+ "license": "ISC",
28
+ "devDependencies": {
29
+ "@types/node": "^25.5.0",
30
+ "cpy-cli": "^7.0.0",
31
+ "ts-node": "^10.9.2",
32
+ "tsup": "^8.5.1",
33
+ "typescript": "^5.9.3"
34
+ },
35
+ "dependencies": {
36
+ "@inquirer/prompts": "^8.3.2",
37
+ "@types/fs-extra": "^11.0.4",
38
+ "chalk": "^4.1.2",
39
+ "commander": "^14.0.3",
40
+ "execa": "^9.6.1",
41
+ "fs-extra": "^11.3.4",
42
+ "ora": "^5.4.1",
43
+ "tar": "^7.5.20",
44
+ "undici": "^7.28.0"
45
+ }
46
+ }