feng3d-cli 0.0.4 → 0.0.5

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.
Files changed (50) hide show
  1. package/README.md +0 -15
  2. package/bin/cli.js +135 -0
  3. package/dist/index.js +792 -9
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.umd.cjs +792 -0
  6. package/dist/index.umd.cjs.map +1 -0
  7. package/{dist → lib}/commands/create.d.ts.map +1 -1
  8. package/{dist → lib}/commands/update.d.ts +1 -0
  9. package/{dist → lib}/commands/update.d.ts.map +1 -1
  10. package/{dist → lib}/index.d.ts +2 -1
  11. package/lib/index.d.ts.map +1 -0
  12. package/{dist → lib}/templates.d.ts +10 -12
  13. package/{dist → lib}/templates.d.ts.map +1 -1
  14. package/{dist → lib}/types/config.d.ts +2 -0
  15. package/{dist → lib}/types/config.d.ts.map +1 -1
  16. package/package.json +20 -22
  17. package/schemas/feng3d.schema.json +5 -0
  18. package/templates/.github/workflows/publish.yml +2 -8
  19. package/templates/feng3d.json +2 -1
  20. package/templates/gitignore +3 -0
  21. package/templates/scripts/postpublish.js +19 -0
  22. package/templates/scripts/prepublish.js +19 -0
  23. package/templates/vite.config.js +49 -0
  24. package/dist/cli.d.ts +0 -7
  25. package/dist/cli.d.ts.map +0 -1
  26. package/dist/cli.js +0 -108
  27. package/dist/cli.js.map +0 -1
  28. package/dist/commands/create.js +0 -125
  29. package/dist/commands/create.js.map +0 -1
  30. package/dist/commands/oss.js +0 -132
  31. package/dist/commands/oss.js.map +0 -1
  32. package/dist/commands/update.js +0 -482
  33. package/dist/commands/update.js.map +0 -1
  34. package/dist/eslint.d.ts +0 -236
  35. package/dist/eslint.d.ts.map +0 -1
  36. package/dist/eslint.js +0 -119
  37. package/dist/eslint.js.map +0 -1
  38. package/dist/index.d.ts.map +0 -1
  39. package/dist/templates.js +0 -151
  40. package/dist/templates.js.map +0 -1
  41. package/dist/types/config.js +0 -50
  42. package/dist/types/config.js.map +0 -1
  43. package/dist/versions.js +0 -60
  44. package/dist/versions.js.map +0 -1
  45. package/templates/vitest.config.ts +0 -8
  46. /package/{dist → lib}/commands/create.d.ts +0 -0
  47. /package/{dist → lib}/commands/oss.d.ts +0 -0
  48. /package/{dist → lib}/commands/oss.d.ts.map +0 -0
  49. /package/{dist → lib}/versions.d.ts +0 -0
  50. /package/{dist → lib}/versions.d.ts.map +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.cjs","sources":["../src/versions.ts","../src/templates.ts","../src/types/config.ts","../src/commands/oss.ts","../src/commands/update.ts","../src/commands/create.ts"],"sourcesContent":["/**\n * feng3d 项目统一依赖版本\n */\nexport const VERSIONS = {\n // TypeScript 相关\n typescript: '5.8.3',\n tslib: '^2.8.1',\n\n // ESLint 相关\n eslint: '9.26.0',\n '@eslint/js': '^9.0.0',\n '@typescript-eslint/eslint-plugin': '8.32.1',\n '@typescript-eslint/parser': '8.32.1',\n 'typescript-eslint': '^8.32.1',\n globals: '^14.0.0',\n\n // 测试相关\n vitest: '^3.1.3',\n '@vitest/coverage-v8': '^3.2.4',\n 'happy-dom': '^20.0.11',\n\n // 构建工具\n vite: '^6.3.5',\n rimraf: '6.0.1',\n 'cross-env': '7.0.3',\n\n // 文档\n typedoc: '^0.28.4',\n\n // Git hooks\n husky: '^9.1.7',\n 'lint-staged': '^15.2.10',\n} as const;\n\n/**\n * 获取 devDependencies 配置\n */\nexport function getDevDependencies(options: {\n includeVitest?: boolean;\n includeTypedoc?: boolean;\n includeCoverage?: boolean;\n} = {}): Record<string, string>\n{\n const deps: Record<string, string> = {\n '@eslint/js': VERSIONS['@eslint/js'],\n '@typescript-eslint/eslint-plugin': VERSIONS['@typescript-eslint/eslint-plugin'],\n '@typescript-eslint/parser': VERSIONS['@typescript-eslint/parser'],\n 'cross-env': VERSIONS['cross-env'],\n eslint: VERSIONS.eslint,\n globals: VERSIONS.globals,\n rimraf: VERSIONS.rimraf,\n tslib: VERSIONS.tslib,\n typescript: VERSIONS.typescript,\n 'typescript-eslint': VERSIONS['typescript-eslint'],\n vite: VERSIONS.vite,\n };\n\n if (options.includeVitest !== false)\n {\n deps.vitest = VERSIONS.vitest;\n }\n\n if (options.includeCoverage)\n {\n deps['@vitest/coverage-v8'] = VERSIONS['@vitest/coverage-v8'];\n }\n\n if (options.includeTypedoc !== false)\n {\n deps.typedoc = VERSIONS.typedoc;\n }\n\n // 默认包含 husky 和 lint-staged\n deps.husky = VERSIONS.husky;\n deps['lint-staged'] = VERSIONS['lint-staged'];\n\n return deps;\n}\n\n","/**\n * 项目模板文件内容\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\n/**\n * 模板目录路径\n */\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.resolve(__dirname, '../templates');\n\n/**\n * 获取 .gitignore 模板内容\n */\nexport function getGitignoreTemplate(): string\n{\n // 模板文件命名为 gitignore(不带点),避免对 templates 目录生效\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'gitignore'), 'utf-8');\n}\n\n/**\n * 获取 .cursorrules 模板内容\n */\nexport function getCursorrrulesTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.cursorrules'), 'utf-8');\n}\n\n/**\n * 获取 tsconfig.json 模板内容(对象形式)\n */\nexport function getTsconfigTemplate(): object\n{\n return fs.readJsonSync(path.join(TEMPLATES_DIR, 'tsconfig.json'));\n}\n\n/**\n * 获取 tsconfig.json 模板内容(字符串形式)\n */\nexport function getTsconfigTemplateString(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'tsconfig.json'), 'utf-8');\n}\n\n/**\n * 获取 vite.config.js 模板内容\n */\nexport function getViteConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'vite.config.js'), 'utf-8');\n}\n\n/**\n * 获取 eslint.config.js 模板内容\n */\nexport function getEslintConfigTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'eslint.config.js'), 'utf-8');\n}\n\n/**\n * 获取 typedoc.json 模板内容(返回对象)\n */\nexport function getTypedocConfig(options: {\n repoName: string;\n}): object\n{\n return JSON.parse(getTypedocConfigTemplate(options));\n}\n\n/**\n * 获取 typedoc.json 模板内容(返回字符串)\n */\nexport function getTypedocConfigTemplate(options: {\n repoName: string;\n}): string\n{\n const templateContent = fs.readFileSync(path.join(TEMPLATES_DIR, 'typedoc.json'), 'utf-8');\n\n return templateContent.replace(/\\{\\{repoName\\}\\}/g, options.repoName);\n}\n\n/**\n * 获取 test/_.test.ts 模板内容(空文件占位)\n */\nexport function getTestIndexTemplate(_options: { name: string }): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'test/_.test.ts'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions publish workflow 模板内容\n */\nexport function getPublishWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/publish.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions pages workflow 模板内容\n */\nexport function getPagesWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/pages.yml'), 'utf-8');\n}\n\n/**\n * 获取 GitHub Actions pull-request workflow 模板内容\n */\nexport function getPullRequestWorkflowTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.github/workflows/pull-request.yml'), 'utf-8');\n}\n\n/**\n * 获取 .husky/pre-commit 模板内容\n */\nexport function getHuskyPreCommitTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.husky/pre-commit'), 'utf-8');\n}\n\n/**\n * 获取 LICENSE 模板内容\n */\nexport function getLicenseTemplate(ctx: { year?: number } = {}): string\n{\n const year = ctx.year || new Date().getFullYear();\n const template = fs.readFileSync(path.join(TEMPLATES_DIR, 'LICENSE'), 'utf-8');\n\n return template.replace('{{year}}', String(year));\n}\n\n/**\n * 获取 .vscode/settings.json 模板内容\n */\nexport function getVscodeSettingsTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, '.vscode/settings.json'), 'utf-8');\n}\n\n/**\n * 获取 scripts/prepublish.js 模板内容\n */\nexport function getPrepublishScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/prepublish.js'), 'utf-8');\n}\n\n/**\n * 获取 scripts/postpublish.js 模板内容\n */\nexport function getPostpublishScriptTemplate(): string\n{\n return fs.readFileSync(path.join(TEMPLATES_DIR, 'scripts/postpublish.js'), 'utf-8');\n}\n\n/**\n * 可能的 schema 路径列表(按优先级排序)\n */\nconst SCHEMA_PATHS = [\n './schemas/feng3d.schema.json',\n './node_modules/feng3d-cli/schemas/feng3d.schema.json',\n];\n\n/**\n * 检测可用的 schema 路径\n * 优先级:当前项目 -> 依赖目录\n */\nexport function detectSchemaPath(projectDir: string): string\n{\n for (const schemaPath of SCHEMA_PATHS)\n {\n const fullPath = path.join(projectDir, schemaPath);\n\n if (fs.existsSync(fullPath))\n {\n return schemaPath;\n }\n }\n\n // 默认返回 node_modules 路径\n return SCHEMA_PATHS[1];\n}\n\n/**\n * 获取 feng3d.json 模板内容\n */\nexport function getFeng3dConfigTemplate(options: { name: string; schemaPath?: string }): object\n{\n const templateContent = fs.readFileSync(path.join(TEMPLATES_DIR, 'feng3d.json'), 'utf-8');\n const content = templateContent.replace(/\\{\\{name\\}\\}/g, options.name);\n const config = JSON.parse(content);\n\n // 如果提供了 schemaPath,则使用它\n if (options.schemaPath)\n {\n config.$schema = options.schemaPath;\n }\n\n return config;\n}\n\n","/**\n * feng3d 项目配置类型定义\n */\n\n/**\n * ESLint 配置选项\n */\nexport interface EslintConfig {\n /** 是否启用 ESLint */\n enabled?: boolean;\n /** 额外需要忽略的目录 */\n ignores?: string[];\n /** 额外的规则覆盖 */\n rules?: Record<string, unknown>;\n}\n\n/**\n * Vitest 配置选项\n */\nexport interface VitestConfig {\n /** 是否启用 vitest */\n enabled?: boolean;\n /** 测试超时时间(0 表示无限制) */\n testTimeout?: number;\n}\n\n/**\n * TypeDoc 配置选项\n */\nexport interface TypedocConfig {\n /** 是否启用 typedoc */\n enabled?: boolean;\n /** 输出目录 */\n outDir?: string;\n}\n\n/**\n * OSS 上传配置\n */\nexport interface OssConfig {\n /** 本地目录 */\n localDir?: string;\n /** OSS 目录(默认使用 package.json 的 name) */\n ossDir?: string;\n}\n\n/**\n * 项目模板选项\n */\nexport interface TemplatesConfig {\n /** 是否创建示例目录 */\n examples?: boolean;\n /** 是否创建测试目录 */\n test?: boolean;\n}\n\n/**\n * 更新配置选项\n */\nexport interface UpdateConfig {\n /** 是否更新 feng3d.json 配置 */\n config?: boolean;\n /** 是否更新 ESLint 配置 */\n eslint?: boolean;\n /** 是否更新 .gitignore */\n gitignore?: boolean;\n /** 是否更新 .cursorrules */\n cursorrules?: boolean;\n /** 是否更新 npm publish workflow */\n publish?: boolean;\n /** 是否更新 GitHub Pages workflow */\n pages?: boolean;\n /** 是否更新 Pull Request CI workflow */\n pullRequest?: boolean;\n /** 是否更新 typedoc.json */\n typedoc?: boolean;\n /** 是否更新 test/_.test.ts */\n test?: boolean;\n /** 是否更新依赖版本 */\n deps?: boolean;\n /** 是否更新 husky pre-commit hook */\n husky?: boolean;\n /** 是否更新 LICENSE 文件 */\n license?: boolean;\n /** 是否更新 .vscode/settings.json */\n vscode?: boolean;\n /** 是否更新 tsconfig.json */\n tsconfig?: boolean;\n /** 是否更新 vite.config.js */\n vite?: boolean;\n}\n\n/**\n * feng3d 项目配置\n */\nexport interface Feng3dConfig {\n /** 项目名称 */\n name?: string;\n /** ESLint 配置 */\n eslint?: EslintConfig;\n /** Vitest 配置 */\n vitest?: VitestConfig;\n /** TypeDoc 配置 */\n typedoc?: TypedocConfig;\n /** OSS 配置 */\n oss?: OssConfig;\n /** 模板配置 */\n templates?: TemplatesConfig;\n /** 更新配置(指定 feng3d-cli update 时默认更新哪些项目) */\n update?: UpdateConfig;\n}\n\n/**\n * 默认更新配置(全部启用)\n */\nexport const DEFAULT_UPDATE_CONFIG: UpdateConfig = {\n config: true,\n eslint: true,\n gitignore: true,\n cursorrules: true,\n publish: true,\n pages: true,\n pullRequest: true,\n typedoc: true,\n test: true,\n deps: true,\n husky: true,\n license: true,\n vscode: true,\n tsconfig: true,\n vite: true,\n};\n\n/**\n * 默认配置\n */\nexport const DEFAULT_CONFIG: Feng3dConfig = {\n eslint: {\n enabled: true,\n ignores: [],\n rules: {},\n },\n vitest: {\n enabled: true,\n testTimeout: 0,\n },\n typedoc: {\n enabled: true,\n outDir: 'public',\n },\n oss: {\n localDir: './public',\n ossDir: '',\n },\n templates: {\n examples: true,\n test: true,\n },\n update: DEFAULT_UPDATE_CONFIG,\n};\n\n","/**\n * OSS 上传命令\n */\n\nimport OSS from 'ali-oss';\nimport fs from 'fs';\nimport path from 'path';\n\n// 定义 JSON 配置文件的路径\nconst configPath = 'C:/Users/Administrator/oss_config.json';\n\n/**\n * 将本地目录中的所有文件上传到指定的 OSS 目录中。\n *\n * @param localDirPath - 本地目录的路径,包含需要上传的文件。\n * @param ossDirPath - OSS 目录的路径,文件将被上传到此目录。\n */\nexport async function ossUploadDir(localDirPath: string, ossDirPath: string): Promise<void>\n{\n // 读取配置文件以获取 OSS 相关的配置信息\n const config = readConfig(configPath);\n\n if (!config)\n {\n console.error('无法读取配置文件');\n\n return;\n }\n\n // 根据配置初始化 OSS 客户端\n const client = initializeOSS(config);\n\n // 收集本地目录中所有需要上传的文件,并计算它们在 OSS 中的目标路径\n const { files, failedFiles } = collectFiles(localDirPath, ossDirPath);\n\n console.log(`总文件数: ${files.length}`);\n\n // 执行文件上传操作,并统计成功和失败的文件数量\n const { successCount, failureCount } = await uploadFiles(files, client, failedFiles);\n\n console.log(`上传完成: 成功 ${successCount} 个, 失败 ${failureCount} 个`);\n if (failureCount > 0)\n {\n console.log('上传失败的文件列表:');\n failedFiles.forEach((file) => console.log(file));\n }\n\n // 打印访问路径\n if (successCount > 0)\n {\n const baseUrl = config.baseUrl || `https://${config.bucket}.${config.region}.aliyuncs.com`;\n const accessUrl = `${baseUrl}/${ossDirPath}/`;\n\n console.log(`\\n📎 访问路径: ${accessUrl}`);\n }\n}\n\n/**\n * 读取并解析 JSON 配置文件\n */\nfunction readConfig(filePath: fs.PathOrFileDescriptor): OSSConfig | null\n{\n try\n {\n // 读取文件内容\n const fileContent = fs.readFileSync(filePath, 'utf8');\n // 解析 JSON 内容\n const config = JSON.parse(fileContent);\n\n return config;\n }\n catch (error)\n {\n console.error('读取或解析配置文件时出错:', error);\n\n return null;\n }\n}\n\ninterface OSSConfig {\n region: string;\n accessKeyId: string;\n accessKeySecret: string;\n bucket: string;\n /** 自定义访问域名,如 https://feng3d.com */\n baseUrl?: string;\n}\n\n/**\n * 初始化 OSS 客户端\n */\nfunction initializeOSS(config: OSSConfig): OSS\n{\n return new OSS({\n region: config.region,\n accessKeyId: config.accessKeyId,\n accessKeySecret: config.accessKeySecret,\n bucket: config.bucket,\n });\n}\n\ninterface FileInfo {\n localFilePath: string;\n ossFilePath: string;\n}\n\n/**\n * 计算文件夹中所有需要上传的文件以及需要上传的地址\n */\nfunction collectFiles(dirPath: string, ossDirPath: string): { files: FileInfo[]; failedFiles: string[] }\n{\n const files: FileInfo[] = [];\n const failedFiles: string[] = [];\n\n function traverseDirectory(currentDirPath: string, currentOssPath: string): void\n {\n const items = fs.readdirSync(currentDirPath);\n\n for (const item of items)\n {\n const localFilePath = path.join(currentDirPath, item);\n const ossFilePath = `${currentOssPath}/${item}`;\n\n if (fs.statSync(localFilePath).isDirectory())\n {\n traverseDirectory(localFilePath, ossFilePath);\n }\n else\n {\n files.push({ localFilePath, ossFilePath });\n }\n }\n }\n\n traverseDirectory(dirPath, ossDirPath);\n\n return { files, failedFiles };\n}\n\n/**\n * 渲染进度条\n */\nfunction renderProgressBar(current: number, total: number, barLength = 30): string\n{\n const percent = current / total;\n const filled = Math.round(barLength * percent);\n const empty = barLength - filled;\n const bar = '█'.repeat(filled) + '░'.repeat(empty);\n const percentText = (percent * 100).toFixed(0).padStart(3, ' ');\n\n return `[${bar}] ${percentText}% (${current}/${total})`;\n}\n\n/**\n * 执行上传一系列文件\n */\nasync function uploadFiles(\n files: FileInfo[],\n client: OSS,\n failedFiles: string[],\n): Promise<{ successCount: number; failureCount: number; uploadedCount: number }>\n{\n let successCount = 0;\n let failureCount = 0;\n let uploadedCount = 0;\n const total = files.length;\n\n // 显示初始进度条\n process.stdout.write(`上传进度: ${renderProgressBar(0, total)}`);\n\n for (const { localFilePath, ossFilePath } of files)\n {\n try\n {\n // 上传文件\n await client.put(ossFilePath, localFilePath);\n successCount++;\n }\n catch (e)\n {\n // 换行后打印错误,再重新显示进度条\n process.stdout.write('\\n');\n console.error(`文件上传失败: ${localFilePath}`, e);\n failedFiles.push(localFilePath);\n failureCount++;\n }\n uploadedCount++;\n // 使用 \\r 回到行首更新进度条\n process.stdout.write(`\\r上传进度: ${renderProgressBar(uploadedCount, total)}`);\n }\n\n // 完成后换行\n process.stdout.write('\\n');\n\n return { successCount, failureCount, uploadedCount };\n}\n\n","/**\n * 更新项目规范命令\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { getDevDependencies, VERSIONS,\n\n} from '../versions.js';\nimport {\n getGitignoreTemplate,\n getCursorrrulesTemplate,\n getEslintConfigTemplate,\n getPublishWorkflowTemplate,\n getPagesWorkflowTemplate,\n getPullRequestWorkflowTemplate,\n getFeng3dConfigTemplate,\n getTypedocConfigTemplate,\n getTestIndexTemplate,\n getHuskyPreCommitTemplate,\n getLicenseTemplate,\n getVscodeSettingsTemplate,\n getTsconfigTemplateString,\n getViteConfigTemplate,\n getPrepublishScriptTemplate,\n getPostpublishScriptTemplate,\n detectSchemaPath,\n} from '../templates.js';\nimport { Feng3dConfig, DEFAULT_CONFIG, DEFAULT_UPDATE_CONFIG, UpdateConfig } from '../types/config.js';\n\nexport interface UpdateOptions {\n directory: string;\n config?: boolean;\n eslint?: boolean;\n gitignore?: boolean;\n cursorrules?: boolean;\n publish?: boolean;\n pages?: boolean;\n pullRequest?: boolean;\n typedoc?: boolean;\n test?: boolean;\n deps?: boolean;\n husky?: boolean;\n license?: boolean;\n vscode?: boolean;\n tsconfig?: boolean;\n vite?: boolean;\n all?: boolean;\n}\n\n/**\n * 模板上下文\n */\ninterface TemplateContext {\n name: string;\n repoName: string;\n}\n\n/**\n * 需要检查是否与模板相同的自动生成文件配置\n * 注意:workflow 文件不在此列表中,因为它们需要提交到仓库才能触发 CI\n */\nconst AUTO_GENERATED_FILES: Array<{\n path: string;\n getTemplate: (ctx: TemplateContext) => string;\n}> = [\n { path: '.cursorrules', getTemplate: () => getCursorrrulesTemplate() },\n { path: 'eslint.config.js', getTemplate: () => getEslintConfigTemplate() },\n { path: 'typedoc.json', getTemplate: (ctx) => getTypedocConfigTemplate({ repoName: ctx.repoName }) },\n { path: 'test/_.test.ts', getTemplate: (ctx) => getTestIndexTemplate({ name: ctx.name }) },\n { path: '.husky/pre-commit', getTemplate: () => getHuskyPreCommitTemplate() },\n { path: '.vscode/settings.json', getTemplate: () => getVscodeSettingsTemplate() },\n { path: 'tsconfig.json', getTemplate: () => getTsconfigTemplateString() },\n { path: 'vite.config.js', getTemplate: () => getViteConfigTemplate() },\n { path: 'scripts/prepublish.js', getTemplate: () => getPrepublishScriptTemplate() },\n { path: 'scripts/postpublish.js', getTemplate: () => getPostpublishScriptTemplate() },\n];\n\n/**\n * 检查文件是否在 .gitignore 的自动生成文件列表中\n */\nasync function isFileInGitignore(projectDir: string, filePath: string): Promise<boolean>\n{\n const gitignorePath = path.join(projectDir, '.gitignore');\n\n if (!await fs.pathExists(gitignorePath))\n {\n return false;\n }\n\n const gitignoreContent = await fs.readFile(gitignorePath, 'utf-8');\n const escapedPath = filePath.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`^${escapedPath}$`, 'm');\n\n return regex.test(gitignoreContent);\n}\n\n/**\n * 更新 feng3d.json 配置文件\n */\nasync function updateFeng3dConfig(projectDir: string): Promise<void>\n{\n const configPath = path.join(projectDir, 'feng3d.json');\n const schemaPath = detectSchemaPath(projectDir);\n\n // 从 package.json 读取项目名称\n const packageJsonPath = path.join(projectDir, 'package.json');\n const packageJson = await fs.readJson(packageJsonPath);\n const name = packageJson.name || path.basename(projectDir);\n\n // 检查文件是否在 .gitignore 中(自动生成的文件直接覆盖)\n const isInGitignore = await isFileInGitignore(projectDir, 'feng3d.json');\n\n if (!await fs.pathExists(configPath) || isInGitignore)\n {\n // 创建或覆盖 feng3d.json\n const configTemplate = getFeng3dConfigTemplate({ name, schemaPath });\n\n await fs.writeJson(configPath, configTemplate, { spaces: 4 });\n console.log(chalk.gray(isInGitignore ? ' 覆盖: feng3d.json(在忽略列表中)' : ' 创建: feng3d.json'));\n }\n else\n {\n // 更新现有的 feng3d.json(保留用户自定义配置)\n try\n {\n const configData = await fs.readJson(configPath);\n let updated = false;\n\n // 更新 $schema 路径\n if (configData.$schema !== schemaPath)\n {\n configData.$schema = schemaPath;\n updated = true;\n }\n\n // 更新 name(如果与 package.json 不同)\n if (configData.name !== name)\n {\n configData.name = name;\n updated = true;\n }\n\n if (updated)\n {\n await fs.writeJson(configPath, configData, { spaces: 4 });\n console.log(chalk.gray(' 更新: feng3d.json'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: feng3d.json(无需更新)'));\n }\n }\n catch (error)\n {\n // 文件损坏,重新创建\n const configTemplate = getFeng3dConfigTemplate({ name, schemaPath });\n\n await fs.writeJson(configPath, configTemplate, { spaces: 4 });\n console.log(chalk.gray(' 重建: feng3d.json'));\n }\n }\n}\n\n/**\n * 读取项目的 feng3d.json 配置文件\n */\nasync function loadProjectConfig(projectDir: string): Promise<Feng3dConfig>\n{\n const configPath = path.join(projectDir, 'feng3d.json');\n\n if (!await fs.pathExists(configPath))\n {\n return DEFAULT_CONFIG;\n }\n\n try\n {\n const configData = await fs.readJson(configPath);\n\n return { ...DEFAULT_CONFIG, ...configData };\n }\n catch (error)\n {\n console.log(chalk.yellow(` 警告: 无法加载 feng3d.json,使用默认配置 (${error})`));\n\n return DEFAULT_CONFIG;\n }\n}\n\n/**\n * 检查是否有任何 CLI 更新选项被指定\n */\nfunction hasAnyUpdateOption(options: UpdateOptions): boolean\n{\n return !!(options.config || options.eslint || options.gitignore || options.cursorrules ||\n options.publish || options.pages || options.pullRequest || options.typedoc ||\n options.test || options.deps || options.husky || options.license || options.vscode ||\n options.tsconfig);\n}\n\n/**\n * 合并 CLI 选项和配置文件中的更新选项\n * CLI 选项优先级高于配置文件\n */\nfunction mergeUpdateOptions(cliOptions: UpdateOptions, configUpdate: UpdateConfig): UpdateConfig\n{\n // 如果用户指定了 --all,则全部更新\n if (cliOptions.all)\n {\n return DEFAULT_UPDATE_CONFIG;\n }\n\n // 如果用户指定了任何特定选项,则只使用 CLI 选项\n if (hasAnyUpdateOption(cliOptions))\n {\n return {\n config: cliOptions.config || false,\n eslint: cliOptions.eslint || false,\n gitignore: cliOptions.gitignore || false,\n cursorrules: cliOptions.cursorrules || false,\n publish: cliOptions.publish || false,\n pages: cliOptions.pages || false,\n pullRequest: cliOptions.pullRequest || false,\n typedoc: cliOptions.typedoc || false,\n test: cliOptions.test || false,\n deps: cliOptions.deps || false,\n husky: cliOptions.husky || false,\n license: cliOptions.license || false,\n vscode: cliOptions.vscode || false,\n tsconfig: cliOptions.tsconfig || false,\n };\n }\n\n // 否则使用配置文件中的设置\n return { ...DEFAULT_UPDATE_CONFIG, ...configUpdate };\n}\n\n/**\n * 更新项目的规范配置\n */\nexport async function updateProject(options: UpdateOptions): Promise<void>\n{\n const projectDir = path.resolve(options.directory);\n\n // 检查是否是有效的项目目录\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n if (!await fs.pathExists(packageJsonPath))\n {\n throw new Error(`${projectDir} 不是有效的项目目录(未找到 package.json)`);\n }\n\n // 加载项目配置\n const config = await loadProjectConfig(projectDir);\n\n // 合并 CLI 选项和配置文件中的更新选项\n const updateConfig = mergeUpdateOptions(options, config.update || {});\n\n // 更新 feng3d.json 配置\n if (updateConfig.config)\n {\n await updateFeng3dConfig(projectDir);\n }\n\n // 获取项目信息用于模板\n const packageJson = await fs.readJson(packageJsonPath);\n const name = packageJson.name || path.basename(projectDir);\n const repoName = name.replace(/^@[^/]+\\//, ''); // 移除 scope 前缀\n const templateContext: TemplateContext = { name, repoName };\n\n // 更新 .gitignore(仅在文件不存在时创建)\n if (updateConfig.gitignore)\n {\n const gitignorePath = path.join(projectDir, '.gitignore');\n\n if (!await fs.pathExists(gitignorePath))\n {\n await fs.writeFile(gitignorePath, getGitignoreTemplate());\n console.log(chalk.gray(' 创建: .gitignore'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: .gitignore(已存在)'));\n }\n }\n\n // 更新 .cursorrules\n if (updateConfig.cursorrules)\n {\n await fs.writeFile(path.join(projectDir, '.cursorrules'), getCursorrrulesTemplate());\n console.log(chalk.gray(' 更新: .cursorrules'));\n }\n\n // 更新 eslint.config.js(根据配置决定是否启用)\n if (updateConfig.eslint)\n {\n if (config.eslint?.enabled !== false)\n {\n await createEslintConfigFile(projectDir);\n console.log(chalk.gray(' 更新: eslint.config.js'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: eslint.config.js(配置中已禁用)'));\n }\n }\n\n // 更新 .github/workflows/publish.yml\n if (updateConfig.publish)\n {\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/publish.yml'), getPublishWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/publish.yml'));\n }\n\n // 更新 .github/workflows/pages.yml\n if (updateConfig.pages)\n {\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/pages.yml'), getPagesWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/pages.yml'));\n }\n\n // 更新 .github/workflows/pull-request.yml\n if (updateConfig.pullRequest)\n {\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/pull-request.yml'), getPullRequestWorkflowTemplate());\n console.log(chalk.gray(' 更新: .github/workflows/pull-request.yml'));\n }\n\n // 更新 typedoc.json(根据配置决定是否启用)\n if (updateConfig.typedoc)\n {\n if (config.typedoc?.enabled !== false)\n {\n const typedocContent = getTypedocConfigTemplate({ repoName });\n\n await fs.writeFile(path.join(projectDir, 'typedoc.json'), typedocContent);\n console.log(chalk.gray(' 更新: typedoc.json'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: typedoc.json(配置中已禁用)'));\n }\n }\n\n // 更新 test/index.test.ts(根据配置决定是否启用)\n if (updateConfig.test)\n {\n if (config.vitest?.enabled !== false)\n {\n const testDir = path.join(projectDir, 'test');\n const testFilePath = path.join(testDir, '_.test.ts');\n\n // 检查测试目录是否有其他文件\n let hasOtherFiles = false;\n\n if (await fs.pathExists(testDir))\n {\n const files = await fs.readdir(testDir);\n\n // 排除 _.test.ts 本身,检查是否有其他文件\n hasOtherFiles = files.some(file => file !== '_.test.ts');\n }\n\n // 只有在测试目录没有其他文件时才生成\n if (!hasOtherFiles)\n {\n await fs.ensureDir(testDir);\n const testContent = getTestIndexTemplate({ name });\n\n await fs.writeFile(testFilePath, testContent);\n console.log(chalk.gray(' 更新: test/_.test.ts'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: test/_.test.ts(测试目录已有其他文件)'));\n }\n }\n else\n {\n console.log(chalk.gray(' 跳过: test/_.test.ts(vitest 配置中已禁用)'));\n }\n }\n\n // 更新依赖版本(根据配置决定包含哪些依赖)\n if (updateConfig.deps)\n {\n await updateDependencies(projectDir, config);\n console.log(chalk.gray(' 更新: package.json devDependencies'));\n }\n\n // 更新 husky pre-commit hook\n if (updateConfig.husky)\n {\n await fs.ensureDir(path.join(projectDir, '.husky'));\n await fs.writeFile(path.join(projectDir, '.husky/pre-commit'), getHuskyPreCommitTemplate());\n console.log(chalk.gray(' 更新: .husky/pre-commit'));\n\n // 更新 package.json 添加 husky 配置\n await updateHuskyConfig(projectDir);\n }\n\n // 更新 LICENSE 文件(仅在不存在时创建)\n if (updateConfig.license)\n {\n const licensePath = path.join(projectDir, 'LICENSE');\n\n if (!await fs.pathExists(licensePath))\n {\n await fs.writeFile(licensePath, getLicenseTemplate());\n console.log(chalk.gray(' 创建: LICENSE'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: LICENSE(已存在)'));\n }\n }\n\n // 更新 .vscode/settings.json\n if (updateConfig.vscode)\n {\n await fs.ensureDir(path.join(projectDir, '.vscode'));\n await fs.writeFile(path.join(projectDir, '.vscode/settings.json'), getVscodeSettingsTemplate());\n console.log(chalk.gray(' 更新: .vscode/settings.json'));\n }\n\n // feng3d-cli 项目:不更新 tsconfig.json 和 vite.config.js(有自定义配置),也不添加到 .gitignore\n const isFeng3dCli = name === 'feng3d-cli';\n\n // 更新 tsconfig.json(仅在忽略列表中时覆盖,feng3d-cli 跳过)\n if (updateConfig.tsconfig && !isFeng3dCli)\n {\n const tsconfigPath = path.join(projectDir, 'tsconfig.json');\n const isIgnored = await isFileInGitignore(projectDir, 'tsconfig.json');\n\n if (isIgnored || !await fs.pathExists(tsconfigPath))\n {\n await fs.writeFile(tsconfigPath, getTsconfigTemplateString());\n console.log(chalk.gray(isIgnored ? ' 覆盖: tsconfig.json(在忽略列表中)' : ' 创建: tsconfig.json'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: tsconfig.json(已存在且不在忽略列表中)'));\n }\n }\n\n // 更新 vite.config.js(仅在忽略列表中时覆盖,feng3d-cli 跳过)\n if (updateConfig.vite && !isFeng3dCli)\n {\n const viteConfigPath = path.join(projectDir, 'vite.config.js');\n const isIgnored = await isFileInGitignore(projectDir, 'vite.config.js');\n\n if (isIgnored || !await fs.pathExists(viteConfigPath))\n {\n await fs.writeFile(viteConfigPath, getViteConfigTemplate());\n console.log(chalk.gray(isIgnored ? ' 覆盖: vite.config.js(在忽略列表中)' : ' 创建: vite.config.js'));\n }\n else\n {\n console.log(chalk.gray(' 跳过: vite.config.js(已存在且不在忽略列表中)'));\n }\n }\n\n // 更新发布脚本(仅在不存在时创建,不添加到忽略列表)\n const scriptsDir = path.join(projectDir, 'scripts');\n const prepublishPath = path.join(scriptsDir, 'prepublish.js');\n const postpublishPath = path.join(scriptsDir, 'postpublish.js');\n\n if (!await fs.pathExists(prepublishPath))\n {\n await fs.ensureDir(scriptsDir);\n await fs.writeFile(prepublishPath, getPrepublishScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/prepublish.js'));\n }\n\n if (!await fs.pathExists(postpublishPath))\n {\n await fs.ensureDir(scriptsDir);\n await fs.writeFile(postpublishPath, getPostpublishScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/postpublish.js'));\n }\n\n // 同步 .gitignore,检查自动生成的文件是否被修改\n await syncGitignoreForModifiedFiles(projectDir, templateContext, name);\n}\n\n/**\n * 创建 ESLint 配置文件\n */\nexport async function createEslintConfigFile(projectDir: string): Promise<void>\n{\n await fs.writeFile(path.join(projectDir, 'eslint.config.js'), getEslintConfigTemplate());\n}\n\n/**\n * 检测 JSON 文件的缩进风格\n */\nfunction detectIndent(content: string): string\n{\n const match = content.match(/^[ \\t]+/m);\n\n return match ? match[0] : ' ';\n}\n\n/**\n * 更新 package.json 中的 devDependencies 版本\n */\nasync function updateDependencies(projectDir: string, config: Feng3dConfig): Promise<void>\n{\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 读取原始内容以检测缩进风格\n const originalContent = await fs.readFile(packageJsonPath, 'utf-8');\n const indent = detectIndent(originalContent);\n const hasTrailingNewline = originalContent.endsWith('\\n');\n\n const packageJson = JSON.parse(originalContent);\n\n const standardDeps = getDevDependencies({\n includeVitest: config.vitest?.enabled !== false,\n includeTypedoc: config.typedoc?.enabled !== false,\n });\n\n // 添加或更新 devDependencies\n let updated = false;\n\n if (!packageJson.devDependencies)\n {\n packageJson.devDependencies = {};\n }\n\n for (const [key, value] of Object.entries(standardDeps))\n {\n if (!(key in packageJson.devDependencies))\n {\n packageJson.devDependencies[key] = value;\n updated = true;\n console.log(chalk.gray(` 添加: devDependencies.${key} = \"${value}\"`));\n }\n else if (packageJson.devDependencies[key] !== value)\n {\n packageJson.devDependencies[key] = value;\n updated = true;\n console.log(chalk.gray(` 更新: devDependencies.${key} = \"${value}\"`));\n }\n }\n\n // 添加标准 scripts\n if (!packageJson.scripts)\n {\n packageJson.scripts = {};\n }\n\n const standardScripts: Record<string, string> = {\n clean: 'rimraf lib dist public',\n build: 'vite build && tsc',\n lint: 'eslint . --ext .js,.ts --max-warnings 0',\n lintfix: 'npm run lint -- --fix',\n docs: 'typedoc',\n upload_oss: 'npm run docs && npx feng3d-cli oss_upload_dir',\n update: 'npx feng3d-cli update && npm install',\n prepublishOnly: 'node scripts/prepublish.js',\n postpublish: 'node scripts/postpublish.js',\n };\n\n for (const [key, value] of Object.entries(standardScripts))\n {\n if (!(key in packageJson.scripts))\n {\n packageJson.scripts[key] = value;\n updated = true;\n console.log(chalk.gray(` 添加: scripts.${key}`));\n }\n }\n\n // 只有在有更新时才写入文件\n if (updated)\n {\n let newContent = JSON.stringify(packageJson, null, indent);\n\n if (hasTrailingNewline)\n {\n newContent += '\\n';\n }\n await fs.writeFile(packageJsonPath, newContent);\n }\n}\n\n/**\n * 更新 package.json 添加 husky 配置\n */\nasync function updateHuskyConfig(projectDir: string): Promise<void>\n{\n const packageJsonPath = path.join(projectDir, 'package.json');\n\n // 读取原始内容以检测缩进风格\n const originalContent = await fs.readFile(packageJsonPath, 'utf-8');\n const indent = detectIndent(originalContent);\n const hasTrailingNewline = originalContent.endsWith('\\n');\n\n const packageJson = JSON.parse(originalContent);\n let updated = false;\n\n // 添加 husky 和 lint-staged 依赖\n if (!packageJson.devDependencies)\n {\n packageJson.devDependencies = {};\n }\n if (!packageJson.devDependencies.husky)\n {\n packageJson.devDependencies.husky = VERSIONS.husky;\n updated = true;\n console.log(chalk.gray(` 添加: devDependencies.husky = \"${VERSIONS.husky}\"`));\n }\n if (!packageJson.devDependencies['lint-staged'])\n {\n packageJson.devDependencies['lint-staged'] = VERSIONS['lint-staged'];\n updated = true;\n console.log(chalk.gray(` 添加: devDependencies.lint-staged = \"${VERSIONS['lint-staged']}\"`));\n }\n\n // 添加 prepare 脚本\n if (!packageJson.scripts)\n {\n packageJson.scripts = {};\n }\n if (packageJson.scripts.prepare !== 'husky')\n {\n packageJson.scripts.prepare = 'husky';\n updated = true;\n console.log(chalk.gray(' 添加: scripts.prepare = \"husky\"'));\n }\n\n // 添加 lint-staged 配置\n if (!packageJson['lint-staged'])\n {\n packageJson['lint-staged'] = {\n '*.{js,ts}': ['eslint --fix --max-warnings 0'],\n };\n updated = true;\n console.log(chalk.gray(' 添加: lint-staged 配置'));\n }\n\n // 只有在有更新时才写入文件\n if (updated)\n {\n let newContent = JSON.stringify(packageJson, null, indent);\n\n if (hasTrailingNewline)\n {\n newContent += '\\n';\n }\n await fs.writeFile(packageJsonPath, newContent);\n }\n}\n\n/**\n * 自动生成文件的注释说明\n */\nconst AUTO_GENERATED_COMMENT = `# 以下文件可由 feng3d-cli 自动生成,无需提交\n# 运行 \\`feng3d-cli update\\` 可重新生成`;\n\n/**\n * 同步 .gitignore,确保自动生成的文件在忽略列表中\n */\nasync function syncGitignoreForModifiedFiles(projectDir: string, _ctx: TemplateContext, projectName: string): Promise<void>\n{\n const gitignorePath = path.join(projectDir, '.gitignore');\n\n if (!await fs.pathExists(gitignorePath))\n {\n return;\n }\n\n let gitignoreContent = await fs.readFile(gitignorePath, 'utf-8');\n let modified = false;\n\n // feng3d-cli 项目跳过 tsconfig.json 和 vite.config.js\n const isFeng3dCli = projectName === 'feng3d-cli';\n const skipFiles = isFeng3dCli ? ['tsconfig.json', 'vite.config.js'] : [];\n\n // 需要添加到 .gitignore 的文件列表\n const filesToAdd: string[] = [];\n\n // 检查 feng3d.json 是否在 .gitignore 中\n const feng3dConfigPath = 'feng3d.json';\n const escapedFeng3dPath = feng3dConfigPath.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const feng3dRegex = new RegExp(`^${escapedFeng3dPath}$`, 'm');\n\n if (!feng3dRegex.test(gitignoreContent))\n {\n filesToAdd.push(feng3dConfigPath);\n }\n\n // 检查其他自动生成的文件是否在 .gitignore 中\n // 只有当文件内容与模板一致时才添加到忽略列表\n for (const file of AUTO_GENERATED_FILES)\n {\n // 跳过 feng3d-cli 项目的特殊文件\n if (skipFiles.includes(file.path))\n {\n continue;\n }\n\n const escapedPath = file.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`^${escapedPath}$`, 'm');\n\n if (!regex.test(gitignoreContent))\n {\n // 检查文件是否存在且内容与模板一致\n const filePath = path.join(projectDir, file.path);\n\n if (await fs.pathExists(filePath))\n {\n const fileContent = await fs.readFile(filePath, 'utf-8');\n const templateContent = file.getTemplate(_ctx);\n\n // 只有内容与模板一致时才添加到忽略列表\n if (fileContent.trim() === templateContent.trim())\n {\n filesToAdd.push(file.path);\n }\n }\n }\n }\n\n // 添加需要添加的文件\n if (filesToAdd.length > 0)\n {\n // 检查是否已有注释说明\n const hasComment = gitignoreContent.includes('# 以下文件可由 feng3d-cli 自动生成');\n\n if (!hasComment)\n {\n // 添加注释和文件\n gitignoreContent = gitignoreContent.trim() + '\\n\\n' + AUTO_GENERATED_COMMENT + '\\n' + filesToAdd.join('\\n') + '\\n';\n }\n else\n {\n // 在注释后添加文件\n for (const filePath of filesToAdd)\n {\n gitignoreContent = gitignoreContent.trim() + '\\n' + filePath + '\\n';\n }\n }\n modified = true;\n\n for (const filePath of filesToAdd)\n {\n console.log(chalk.gray(` 添加到 .gitignore: ${filePath}`));\n }\n }\n\n // 清理多余的空行\n if (modified)\n {\n gitignoreContent = gitignoreContent.replace(/\\n\\n+/g, '\\n\\n').trim() + '\\n';\n await fs.writeFile(gitignorePath, gitignoreContent);\n }\n}\n","/**\n * 创建新项目命令\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { getDevDependencies } from '../versions.js';\nimport {\n getGitignoreTemplate,\n getCursorrrulesTemplate,\n getTsconfigTemplate,\n getTypedocConfig,\n getPublishWorkflowTemplate,\n getFeng3dConfigTemplate,\n getPrepublishScriptTemplate,\n getPostpublishScriptTemplate,\n} from '../templates.js';\nimport { createEslintConfigFile } from './update.js';\n\nexport interface CreateOptions {\n directory: string;\n examples?: boolean;\n vitest?: boolean;\n}\n\n/**\n * 创建符合 feng3d 规范的新项目\n */\nexport async function createProject(name: string, options: CreateOptions): Promise<void>\n{\n const projectDir = path.join(options.directory, name);\n\n // 检查目录是否已存在\n if (await fs.pathExists(projectDir))\n {\n throw new Error(`目录 ${projectDir} 已存在`);\n }\n\n // 创建项目目录\n await fs.ensureDir(projectDir);\n await fs.ensureDir(path.join(projectDir, 'src'));\n\n console.log(chalk.gray(` 创建目录: ${projectDir}`));\n\n // 创建 package.json\n const packageJson = createPackageJson(name, options);\n\n await fs.writeJson(path.join(projectDir, 'package.json'), packageJson, { spaces: 4 });\n console.log(chalk.gray(' 创建: package.json'));\n\n // 创建 tsconfig.json\n await fs.writeJson(path.join(projectDir, 'tsconfig.json'), getTsconfigTemplate(), { spaces: 4 });\n console.log(chalk.gray(' 创建: tsconfig.json'));\n\n // 创建 .gitignore\n await fs.writeFile(path.join(projectDir, '.gitignore'), getGitignoreTemplate());\n console.log(chalk.gray(' 创建: .gitignore'));\n\n // 创建 .cursorrules\n await fs.writeFile(path.join(projectDir, '.cursorrules'), getCursorrrulesTemplate());\n console.log(chalk.gray(' 创建: .cursorrules'));\n\n // 创建 eslint.config.js\n await createEslintConfigFile(projectDir);\n console.log(chalk.gray(' 创建: eslint.config.js'));\n\n // 创建 typedoc.json\n const typedocConfig = getTypedocConfig({ repoName: name });\n\n await fs.writeJson(path.join(projectDir, 'typedoc.json'), typedocConfig, { spaces: 4 });\n console.log(chalk.gray(' 创建: typedoc.json'));\n\n // 创建 src/index.ts\n await fs.writeFile(path.join(projectDir, 'src/index.ts'), `/**\\n * @feng3d/${name}\\n */\\n\\nexport {};\\n`);\n console.log(chalk.gray(' 创建: src/index.ts'));\n\n // 创建 README.md\n await fs.writeFile(path.join(projectDir, 'README.md'), `# @feng3d/${name}\\n`);\n console.log(chalk.gray(' 创建: README.md'));\n\n // 创建示例目录\n if (options.examples !== false)\n {\n await fs.ensureDir(path.join(projectDir, 'examples'));\n console.log(chalk.gray(' 创建: examples/'));\n }\n\n // 创建测试目录\n if (options.vitest !== false)\n {\n await fs.ensureDir(path.join(projectDir, 'test'));\n console.log(chalk.gray(' 创建: test/'));\n }\n\n // 创建 .github/workflows 目录和 publish.yml\n await fs.ensureDir(path.join(projectDir, '.github/workflows'));\n await fs.writeFile(path.join(projectDir, '.github/workflows/publish.yml'), getPublishWorkflowTemplate());\n console.log(chalk.gray(' 创建: .github/workflows/publish.yml'));\n\n // 创建 scripts 目录和发布脚本\n await fs.ensureDir(path.join(projectDir, 'scripts'));\n await fs.writeFile(path.join(projectDir, 'scripts/prepublish.js'), getPrepublishScriptTemplate());\n await fs.writeFile(path.join(projectDir, 'scripts/postpublish.js'), getPostpublishScriptTemplate());\n console.log(chalk.gray(' 创建: scripts/prepublish.js'));\n console.log(chalk.gray(' 创建: scripts/postpublish.js'));\n\n // 创建 feng3d.json 配置文件\n await fs.writeJson(path.join(projectDir, 'feng3d.json'), getFeng3dConfigTemplate({ name }), { spaces: 4 });\n console.log(chalk.gray(' 创建: feng3d.json'));\n}\n\n/**\n * 创建 package.json 内容\n */\nfunction createPackageJson(name: string, options: CreateOptions): object\n{\n const scripts: Record<string, string> = {\n dev: 'cd examples && npm run dev',\n clean: 'rimraf lib dist public',\n build: 'vite build && tsc',\n types: 'tsc',\n watch: 'tsc -w',\n lint: 'eslint . --ext .js,.ts --max-warnings 0',\n lintfix: 'npm run lint -- --fix',\n docs: 'typedoc',\n release: 'npm run clean && npm run lint && npm test && npm run build && npm run docs && npm publish',\n prepublishOnly: 'node scripts/prepublish.js',\n postpublish: 'node scripts/postpublish.js',\n };\n\n if (options.vitest !== false)\n {\n scripts.test = 'vitest run';\n scripts['test:watch'] = 'vitest';\n }\n\n return {\n name: `@feng3d/${name}`,\n version: '0.0.1',\n description: '',\n homepage: `https://feng3d.com/${name}/`,\n author: 'feng',\n type: 'module',\n main: './src/index.ts',\n types: './src/index.ts',\n module: './src/index.ts',\n exports: {\n '.': {\n types: './src/index.ts',\n import: './src/index.ts',\n require: './src/index.ts',\n },\n },\n scripts,\n repository: {\n type: 'git',\n url: `https://github.com/feng3d-labs/${name}.git`,\n },\n publishConfig: {\n access: 'public',\n },\n files: ['src', 'dist', 'lib'],\n devDependencies: getDevDependencies({\n includeVitest: options.vitest !== false,\n includeTypedoc: true,\n }),\n };\n}\n\n"],"names":["__dirname","fileURLToPath","fs","configPath"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFvF"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFvF"}
@@ -17,6 +17,7 @@ export interface UpdateOptions {
17
17
  license?: boolean;
18
18
  vscode?: boolean;
19
19
  tsconfig?: boolean;
20
+ vite?: boolean;
20
21
  all?: boolean;
21
22
  }
22
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0BH,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AA2LD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+MzE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9E"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6BH,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AA8LD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsPzE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9E"}
@@ -2,9 +2,10 @@
2
2
  * feng3d-cli
3
3
  * feng3d 命令行工具
4
4
  */
5
- export { eslintConfig, createEslintConfig } from './eslint.js';
6
5
  export { VERSIONS, getDevDependencies } from './versions.js';
7
6
  export * from './templates.js';
8
7
  export * from './types/config.js';
9
8
  export { ossUploadDir } from './commands/oss.js';
9
+ export { createProject } from './commands/create.js';
10
+ export { updateProject } from './commands/update.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC7D,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
@@ -18,9 +18,9 @@ export declare function getTsconfigTemplate(): object;
18
18
  */
19
19
  export declare function getTsconfigTemplateString(): string;
20
20
  /**
21
- * 获取 vitest.config.ts 模板内容
21
+ * 获取 vite.config.js 模板内容
22
22
  */
23
- export declare function getVitestConfigTemplate(): string;
23
+ export declare function getViteConfigTemplate(): string;
24
24
  /**
25
25
  * 获取 eslint.config.js 模板内容
26
26
  */
@@ -69,6 +69,14 @@ export declare function getLicenseTemplate(ctx?: {
69
69
  * 获取 .vscode/settings.json 模板内容
70
70
  */
71
71
  export declare function getVscodeSettingsTemplate(): string;
72
+ /**
73
+ * 获取 scripts/prepublish.js 模板内容
74
+ */
75
+ export declare function getPrepublishScriptTemplate(): string;
76
+ /**
77
+ * 获取 scripts/postpublish.js 模板内容
78
+ */
79
+ export declare function getPostpublishScriptTemplate(): string;
72
80
  /**
73
81
  * 检测可用的 schema 路径
74
82
  * 优先级:当前项目 -> 依赖目录
@@ -81,14 +89,4 @@ export declare function getFeng3dConfigTemplate(options: {
81
89
  name: string;
82
90
  schemaPath?: string;
83
91
  }): object;
84
- /** @deprecated 请使用 getGitignoreTemplate() 函数 */
85
- export declare const gitignoreTemplate: string;
86
- /** @deprecated 请使用 getCursorrrulesTemplate() 函数 */
87
- export declare const cursorrrulesTemplate: string;
88
- /** @deprecated 请使用 getTsconfigTemplate() 函数 */
89
- export declare const tsconfigTemplate: object;
90
- /** @deprecated 请使用 getVitestConfigTemplate() 函数 */
91
- export declare const vitestConfigTemplate: string;
92
- /** @deprecated 请使用 getTypedocConfig() 函数 */
93
- export declare const createTypedocConfig: typeof getTypedocConfig;
94
92
  //# sourceMappingURL=templates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACtC,QAAQ,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAGT;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAKT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAGvE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAGnD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAGjD;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAGvD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAMtE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAc3D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAa9F;AAGD,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,QAAyB,CAAC;AACxD,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,QAA4B,CAAC;AAC9D,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,QAAwB,CAAC;AACtD,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,QAA4B,CAAC;AAC9D,4CAA4C;AAC5C,eAAO,MAAM,mBAAmB,yBAAmB,CAAC"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAG9C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAGhD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACtC,QAAQ,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAGT;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAKT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAGvE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAGnD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAGjD;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAGvD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAMtE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAGrD;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAc3D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAa9F"}
@@ -80,6 +80,8 @@ export interface UpdateConfig {
80
80
  vscode?: boolean;
81
81
  /** 是否更新 tsconfig.json */
82
82
  tsconfig?: boolean;
83
+ /** 是否更新 vite.config.js */
84
+ vite?: boolean;
83
85
  }
84
86
  /**
85
87
  * feng3d 项目配置
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,kBAAkB;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,kBAAkB;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,WAAW;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,eAAe;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wBAAwB;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sBAAsB;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,WAAW;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,gBAAgB;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,iBAAiB;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,aAAa;IACb,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,WAAW;IACX,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAenC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,YAuB5B,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,kBAAkB;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,kBAAkB;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,WAAW;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,eAAe;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wBAAwB;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,eAAe;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sBAAsB;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,WAAW;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,gBAAgB;IAChB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,iBAAiB;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,aAAa;IACb,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,WAAW;IACX,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,YAAY,CAAC;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAgBnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,YAuB5B,CAAC"}
package/package.json CHANGED
@@ -1,44 +1,40 @@
1
1
  {
2
2
  "name": "feng3d-cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "feng3d 项目通用标准,包含代码规范、配置模板和 CLI 工具",
5
5
  "homepage": "https://feng3d.com/feng3d-cli/",
6
6
  "author": "feng",
7
7
  "license": "MIT",
8
8
  "type": "module",
9
- "main": "./dist/index.js",
10
- "types": "./dist/index.d.ts",
9
+ "main": "./dist/index.umd.cjs",
10
+ "types": "./lib/index.d.ts",
11
+ "module": "./dist/index.js",
11
12
  "bin": {
12
- "feng3d-cli": "./dist/cli.js"
13
+ "feng3d-cli": "./bin/cli.js"
13
14
  },
14
15
  "exports": {
15
16
  ".": {
16
- "types": "./dist/index.d.ts",
17
- "import": "./dist/index.js"
18
- },
19
- "./eslint": {
20
- "types": "./dist/eslint.d.ts",
21
- "import": "./dist/eslint.js"
17
+ "types": "./src/index.ts",
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/index.umd.cjs"
22
20
  }
23
21
  },
24
22
  "scripts": {
25
- "clean": "rimraf \"{lib,dist,public}\"",
26
- "build": "tsc",
27
- "dev": "tsc -w",
23
+ "clean": "rimraf lib dist public",
24
+ "build": "vite build && tsc",
25
+ "watch": "vite build --watch",
28
26
  "test": "vitest run",
29
27
  "test:watch": "vitest",
30
- "types": "tsc",
31
- "watch": "tsc -w",
32
28
  "lint": "eslint . --ext .js,.ts --max-warnings 0",
33
29
  "lintfix": "npm run lint -- --fix",
34
30
  "docs": "typedoc",
35
- "upload_oss": "npm run build && npm run docs && node dist/cli.js oss_upload_dir",
36
- "update": "npm run build && node dist/cli.js update && npm install",
37
- "release": "npm run clean && npm run lint && npm run build && npm run docs && npm publish",
38
- "prepublishOnly": "npm run lint && npm test && npm run build",
39
- "publish:manual": "npm publish",
40
- "prepare": "husky",
41
- "postinstall": "npm run build && node dist/cli.js update || exit 0"
31
+ "upload_oss": "npm run build && npm run docs && node bin/cli.js oss_upload_dir",
32
+ "postinstall": "npm run build && node bin/cli.js update || exit 0",
33
+ "update": "npm run build && node bin/cli.js update && npm install",
34
+ "prepublishOnly": "node scripts/prepublish.js",
35
+ "release": "npm run clean && npm run lint && npm test && npm run build && npm run docs && npm publish",
36
+ "postpublish": "node scripts/postpublish.js",
37
+ "prepare": "husky"
42
38
  },
43
39
  "publishConfig": {
44
40
  "access": "public"
@@ -48,7 +44,9 @@
48
44
  "url": "https://github.com/feng3d-labs/feng3d-cli.git"
49
45
  },
50
46
  "files": [
47
+ "bin",
51
48
  "dist",
49
+ "lib",
52
50
  "templates",
53
51
  "schemas"
54
52
  ],
@@ -181,6 +181,11 @@
181
181
  "type": "boolean",
182
182
  "description": "是否更新 tsconfig.json",
183
183
  "default": true
184
+ },
185
+ "vite": {
186
+ "type": "boolean",
187
+ "description": "是否更新 vite.config.js",
188
+ "default": true
184
189
  }
185
190
  },
186
191
  "additionalProperties": false
@@ -58,17 +58,11 @@ jobs:
58
58
  - name: Install dependencies
59
59
  run: npm install
60
60
 
61
- - name: Build
62
- run: npm run build
63
-
64
- - name: Run lint
65
- run: npm run lint
66
-
67
61
  - name: Run tests
68
62
  run: npm test
69
63
 
70
- - name: Publish to NPM
71
- run: npm publish
64
+ - name: Release to NPM
65
+ run: npm run release
72
66
  env:
73
67
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
74
68
 
@@ -36,7 +36,8 @@
36
36
  "husky": true,
37
37
  "license": true,
38
38
  "vscode": true,
39
- "tsconfig": true
39
+ "tsconfig": true,
40
+ "vite": true
40
41
  }
41
42
  }
42
43
 
@@ -21,3 +21,6 @@ test/_.test.ts
21
21
  .husky/pre-commit
22
22
  .vscode/settings.json
23
23
  tsconfig.json
24
+ vite.config.js
25
+ scripts/prepublish.js
26
+ scripts/postpublish.js
@@ -0,0 +1,19 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ const pkgpath = path.resolve('package.json');
5
+
6
+ let pkg = fs.readFileSync(pkgpath, 'utf8');
7
+
8
+ pkg = pkg
9
+ .replace(`"types": "./lib/index.d.ts"`, `"types": "./src/index.ts"`)
10
+ //
11
+ .replace(`"module": "./dist/index.js"`, `"module": "./src/index.ts"`)
12
+ .replace(`"main": "./dist/index.umd.cjs"`, `"main": "./src/index.ts"`)
13
+ //
14
+ .replace(`"import": "./dist/index.js"`, `"import": "./src/index.ts"`)
15
+ .replace(`"require": "./dist/index.umd.cjs"`, `"require": "./src/index.ts"`)
16
+ ;
17
+
18
+ fs.writeFileSync(pkgpath, pkg, 'utf8');
19
+
@@ -0,0 +1,19 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ const pkgpath = path.resolve('package.json');
5
+
6
+ let pkg = fs.readFileSync(pkgpath, 'utf8');
7
+
8
+ pkg = pkg
9
+ .replace(`"types": "./src/index.ts"`, `"types": "./lib/index.d.ts"`)
10
+ //
11
+ .replace(`"module": "./src/index.ts"`, `"module": "./dist/index.js"`)
12
+ .replace(`"main": "./src/index.ts"`, `"main": "./dist/index.umd.cjs"`)
13
+ //
14
+ .replace(`"import": "./src/index.ts"`, `"import": "./dist/index.js"`)
15
+ .replace(`"require": "./src/index.ts"`, `"require": "./dist/index.umd.cjs"`)
16
+ ;
17
+
18
+ fs.writeFileSync(pkgpath, pkg, 'utf8');
19
+
@@ -0,0 +1,49 @@
1
+ // @see https://cn.vitejs.dev/guide/build.html#library-mode
2
+
3
+ import { resolve } from 'path';
4
+ import { defineConfig } from 'vite';
5
+ import pkg from './package.json';
6
+
7
+ const namespace = 'feng3d';
8
+ const external = pkg.standalone ? [] : Object.keys(pkg.dependencies || []);
9
+ const globals = () => namespace;
10
+
11
+ export default defineConfig({
12
+ build: {
13
+ lib: {
14
+ // Could also be a dictionary or array of multiple entry points
15
+ entry: resolve(__dirname, 'src/index.ts'),
16
+ name: namespace,
17
+ // the proper extensions will be added
18
+ fileName: 'index',
19
+ },
20
+ minify: false,
21
+ sourcemap: true,
22
+ rollupOptions: {
23
+ // 确保外部化处理那些你不想打包进库的依赖
24
+ external,
25
+ output: {
26
+ // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
27
+ globals,
28
+ },
29
+ },
30
+ },
31
+ plugins: [
32
+ shaderToString(),
33
+ ],
34
+ });
35
+
36
+ function shaderToString()
37
+ {
38
+ return {
39
+ name: 'vite-plugin-string',
40
+ async transform(source, id)
41
+ {
42
+ if (!['glsl', 'wgsl', 'vert', 'frag', 'vs', 'fs'].includes(id.split('.').pop())) return;
43
+
44
+ const esm = `export default \`${source}\`;`;
45
+
46
+ return { code: esm, map: { mappings: '' } };
47
+ },
48
+ };
49
+ }
package/dist/cli.d.ts DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * feng3d-cli
4
- * feng3d 命令行工具,包含项目规范、OSS 上传等功能
5
- */
6
- export {};
7
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/cli.js DELETED
@@ -1,108 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * feng3d-cli
4
- * feng3d 命令行工具,包含项目规范、OSS 上传等功能
5
- */
6
- import fs from 'fs';
7
- import { Command } from 'commander';
8
- import chalk from 'chalk';
9
- import { createProject } from './commands/create.js';
10
- import { updateProject } from './commands/update.js';
11
- import { ossUploadDir } from './commands/oss.js';
12
- const program = new Command();
13
- program
14
- .name('feng3d-cli')
15
- .description('feng3d 命令行工具')
16
- .version('0.0.1');
17
- program
18
- .command('create <name>')
19
- .description('创建符合 feng3d 规范的新项目')
20
- .option('-d, --directory <dir>', '项目目录', '.')
21
- .option('--no-examples', '不创建示例目录')
22
- .option('--no-vitest', '不包含 vitest 测试配置')
23
- .action(async (name, options) => {
24
- console.log(chalk.blue(`\n🚀 创建项目: ${name}\n`));
25
- try {
26
- await createProject(name, options);
27
- console.log(chalk.green(`\n✅ 项目 ${name} 创建成功!\n`));
28
- }
29
- catch (error) {
30
- console.error(chalk.red(`\n❌ 创建失败: ${error}\n`));
31
- process.exit(1);
32
- }
33
- });
34
- program
35
- .command('update')
36
- .description('更新当前项目的规范配置')
37
- .option('-d, --directory <dir>', '项目目录', '.')
38
- .option('--config', '仅更新 feng3d.json 配置')
39
- .option('--eslint', '仅更新 ESLint 配置')
40
- .option('--gitignore', '仅更新 .gitignore')
41
- .option('--cursorrules', '仅更新 .cursorrules')
42
- .option('--publish', '仅更新 npm publish workflow')
43
- .option('--pages', '仅更新 GitHub Pages workflow')
44
- .option('--pull-request', '仅更新 Pull Request CI workflow')
45
- .option('--typedoc', '仅更新 typedoc.json')
46
- .option('--test', '仅更新 test/_.test.ts')
47
- .option('--deps', '仅更新依赖版本')
48
- .option('--husky', '仅更新 husky pre-commit hook')
49
- .option('--license', '仅更新 LICENSE 文件')
50
- .option('--vscode', '仅更新 .vscode/settings.json')
51
- .option('--tsconfig', '仅更新 tsconfig.json')
52
- .option('--all', '更新所有配置')
53
- .action(async (options) => {
54
- console.log(chalk.blue('\n🔄 更新项目规范配置\n'));
55
- try {
56
- await updateProject(options);
57
- console.log(chalk.green('\n✅ 规范配置更新成功!\n'));
58
- }
59
- catch (error) {
60
- console.error(chalk.red(`\n❌ 更新失败: ${error}\n`));
61
- process.exit(1);
62
- }
63
- });
64
- program
65
- .command('check')
66
- .description('检查当前项目是否符合 feng3d 规范')
67
- .option('-d, --directory <dir>', '项目目录', '.')
68
- .action(async () => {
69
- console.log(chalk.blue('\n🔍 检查项目规范\n'));
70
- // TODO: 实现规范检查
71
- console.log(chalk.yellow('暂未实现'));
72
- });
73
- program
74
- .command('oss_upload_dir')
75
- .description('上传文件夹到阿里云 OSS')
76
- .option('-l, --local_dir <string>', '本地目录', './public')
77
- .option('-o, --oss_dir <string>', 'OSS 目录', '')
78
- .action(async (options) => {
79
- const localDir = options.local_dir;
80
- let ossDir = options.oss_dir;
81
- if (!fs.existsSync(localDir)) {
82
- console.log(chalk.red(`\n❌ 本地目录 ${localDir} 不存在!\n`));
83
- return;
84
- }
85
- if (!ossDir) {
86
- // 获取当前目录下 package.json 的 name 字段
87
- try {
88
- const packageJson = fs.readFileSync('package.json', 'utf-8');
89
- const packageJsonObj = JSON.parse(packageJson);
90
- ossDir = packageJsonObj.name.split('/').pop();
91
- }
92
- catch {
93
- console.log(chalk.red('\n❌ 无法读取 package.json 获取项目名称\n'));
94
- return;
95
- }
96
- }
97
- console.log(chalk.blue(`\n📤 上传文件夹到阿里云 OSS: ${localDir} -> ${ossDir}\n`));
98
- try {
99
- await ossUploadDir(localDir, ossDir);
100
- console.log(chalk.green('\n✅ 上传完成!\n'));
101
- }
102
- catch (error) {
103
- console.error(chalk.red(`\n❌ 上传失败: ${error}\n`));
104
- process.exit(1);
105
- }
106
- });
107
- program.parse();
108
- //# sourceMappingURL=cli.js.map