@farris/cli 2.1.8 → 2.2.0-beta.1

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 (109) hide show
  1. package/bin/index.js +1 -1
  2. package/lib/commands/build-components.js +48 -39
  3. package/lib/commands/build-components.js.map +1 -1
  4. package/lib/commands/build-css.js +38 -38
  5. package/lib/commands/build-css.js.map +1 -1
  6. package/lib/commands/build-lib.js +25 -25
  7. package/lib/commands/build-lib.js.map +1 -1
  8. package/lib/commands/build.js +15 -14
  9. package/lib/commands/build.js.map +1 -1
  10. package/lib/commands/create-app.js +54 -54
  11. package/lib/commands/dev-serve.js +18 -18
  12. package/lib/commands/extract-i18n.js +74 -74
  13. package/lib/commands/extract-i18n.js.map +1 -1
  14. package/lib/commands/preview-serve.js +16 -16
  15. package/lib/common/component-file-name.js +4 -0
  16. package/lib/common/component-file-name.js.map +1 -0
  17. package/lib/common/constant.js +22 -64
  18. package/lib/common/constant.js.map +1 -1
  19. package/lib/common/generate-app.js +51 -44
  20. package/lib/common/generate-app.js.map +1 -1
  21. package/lib/common/get-dependencies.js +9 -9
  22. package/lib/common/get-farris-config.js +25 -11
  23. package/lib/common/get-farris-config.js.map +1 -1
  24. package/lib/common/get-version.js +6 -6
  25. package/lib/common/get-vite-config.js +49 -105
  26. package/lib/common/get-vite-config.js.map +1 -1
  27. package/lib/common/lib-package-exports.js +21 -0
  28. package/lib/common/lib-package-exports.js.map +1 -0
  29. package/lib/common/list-lib-components.js +24 -0
  30. package/lib/common/list-lib-components.js.map +1 -0
  31. package/lib/common/template-manifest.js +17 -0
  32. package/lib/common/template-manifest.js.map +1 -0
  33. package/lib/config/vite-app.js +13 -13
  34. package/lib/config/vite-common.js +20 -20
  35. package/lib/config/vite-common.js.map +1 -1
  36. package/lib/config/vite-component.js +32 -30
  37. package/lib/config/vite-component.js.map +1 -1
  38. package/lib/config/vite-lib.js +26 -26
  39. package/lib/index.js +87 -175
  40. package/lib/index.js.map +1 -1
  41. package/lib/plugins/create-component-style.js +44 -44
  42. package/lib/plugins/create-package-json.js +48 -33
  43. package/lib/plugins/create-package-json.js.map +1 -1
  44. package/lib/plugins/dts.js +8 -8
  45. package/lib/plugins/html-system.js +9 -9
  46. package/lib/plugins/replace.js +17 -17
  47. package/lib/plugins/systemjs-bundle.js +15 -15
  48. package/lib/plugins/systemjs-bundle.js.map +1 -1
  49. package/package.json +9 -11
  50. package/templates/lib/.changeset/README.md +1 -0
  51. package/templates/lib/.changeset/config.json +11 -0
  52. package/templates/lib/README.md +17 -0
  53. package/templates/lib/components/button/index.ts +7 -0
  54. package/templates/lib/components/button/src/button.scss +10 -0
  55. package/templates/lib/components/button/src/button.vue +12 -0
  56. package/templates/lib/components/common/with-install.ts +9 -0
  57. package/templates/lib/components/index.ts +10 -0
  58. package/templates/lib/farris.config.mjs +13 -0
  59. package/templates/lib/package.json +21 -0
  60. package/templates/lib/tsconfig.json +7 -0
  61. package/templates/mobile/.changeset/README.md +4 -0
  62. package/templates/mobile/.changeset/config.json +11 -0
  63. package/templates/mobile/package.json +4 -1
  64. package/templates/web/.changeset/README.md +4 -0
  65. package/templates/web/.changeset/config.json +11 -0
  66. package/templates/web/package.json +4 -1
  67. package/lib/commands/generate/api.js +0 -188
  68. package/lib/commands/generate/api.js.map +0 -1
  69. package/lib/commands/generate/common.js +0 -101
  70. package/lib/commands/generate/common.js.map +0 -1
  71. package/lib/commands/generate/component.js +0 -164
  72. package/lib/commands/generate/component.js.map +0 -1
  73. package/lib/commands/generate/view.js +0 -198
  74. package/lib/commands/generate/view.js.map +0 -1
  75. package/lib/commands/workspace/add-app.js +0 -181
  76. package/lib/commands/workspace/add-app.js.map +0 -1
  77. package/lib/commands/workspace/create.js +0 -380
  78. package/lib/commands/workspace/create.js.map +0 -1
  79. package/lib/commands/workspace/inspect.js +0 -31
  80. package/lib/commands/workspace/inspect.js.map +0 -1
  81. package/lib/commands/workspace/verify.js +0 -39
  82. package/lib/commands/workspace/verify.js.map +0 -1
  83. package/lib/common/output.js +0 -95
  84. package/lib/common/output.js.map +0 -1
  85. package/lib/common/safety.js +0 -172
  86. package/lib/common/safety.js.map +0 -1
  87. package/lib/common/template-renderer.js +0 -115
  88. package/lib/common/template-renderer.js.map +0 -1
  89. package/lib/common/transaction.js +0 -84
  90. package/lib/common/transaction.js.map +0 -1
  91. package/lib/common/verifier.js +0 -151
  92. package/lib/common/verifier.js.map +0 -1
  93. package/templates/workspace/app/farris.config.mjs +0 -13
  94. package/templates/workspace/app/index.html +0 -12
  95. package/templates/workspace/app/package.json +0 -22
  96. package/templates/workspace/app/src/App.tsx +0 -11
  97. package/templates/workspace/app/src/locales/index.ts +0 -5
  98. package/templates/workspace/app/src/locales/zh-CN.json +0 -1
  99. package/templates/workspace/app/src/main.ts +0 -12
  100. package/templates/workspace/app/src/router/index.ts +0 -16
  101. package/templates/workspace/app/src/styles/index.css +0 -0
  102. package/templates/workspace/app/src/styles/index.scss +0 -0
  103. package/templates/workspace/app/src/views/home/composables/use-home.ts +0 -7
  104. package/templates/workspace/app/src/views/home/home.component.tsx +0 -15
  105. package/templates/workspace/app/src/views/home/index.ts +0 -4
  106. package/templates/workspace/app/tsconfig.json +0 -21
  107. package/templates/workspace/root/README.md +0 -28
  108. package/templates/workspace/root/package.json +0 -13
  109. package/templates/workspace/root/pnpm-workspace.yaml +0 -12
@@ -1,172 +0,0 @@
1
- import { existsSync, lstatSync, readdirSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
- import { WorkspaceStatus } from './constant.js';
4
- // 已知 AI 配置与项目元数据文件/目录(忽略列表)
5
- export const KNOWN_AI_AND_META_ENTRIES = new Set([
6
- '.git',
7
- '.gitignore',
8
- '.agent',
9
- '.agents',
10
- '.cursor',
11
- '.vscode',
12
- '.superpowers',
13
- '.changeset',
14
- '.github',
15
- '.codebuddy',
16
- '.trae',
17
- 'agents.md',
18
- 'claude.md',
19
- 'gemini.md',
20
- '.windsurfrules',
21
- '.cursorrules'
22
- ]);
23
- // 工程证据关键文件
24
- export const PROJECT_EVIDENCE_FILES = [
25
- 'package.json',
26
- 'pnpm-workspace.yaml',
27
- 'vite.config.ts',
28
- 'vite.config.js',
29
- 'vite.config.mjs',
30
- 'farris.config.ts',
31
- 'farris.config.js',
32
- 'farris.config.mjs',
33
- 'tsconfig.json',
34
- 'src',
35
- 'packages',
36
- 'node_modules'
37
- ];
38
- /**
39
- * 校验目标路径安全性,防止目录穿越与非法路径
40
- */
41
- export function validateTargetPath(target) {
42
- if (!target || typeof target !== 'string') {
43
- return { valid: false, resolved: '', error: '目标路径不能为空' };
44
- }
45
- const resolved = resolve(process.cwd(), target);
46
- // 检查是否在非法系统根或包含非法控制字符
47
- if (resolved.includes('\0')) {
48
- return { valid: false, resolved: '', error: '目标路径包含非法字符' };
49
- }
50
- return { valid: true, resolved };
51
- }
52
- /**
53
- * 扫描目标目录状态
54
- */
55
- export function inspectTarget(targetPath) {
56
- const pathValidation = validateTargetPath(targetPath);
57
- if (!pathValidation.valid) {
58
- return {
59
- status: WorkspaceStatus.INVALID_TARGET,
60
- canCreate: false,
61
- target: targetPath,
62
- exists: false,
63
- conflicts: [],
64
- preservedInputEntries: [],
65
- message: pathValidation.error
66
- };
67
- }
68
- const resolvedTarget = pathValidation.resolved;
69
- if (!existsSync(resolvedTarget)) {
70
- return {
71
- status: WorkspaceStatus.MISSING,
72
- canCreate: true,
73
- target: resolvedTarget,
74
- exists: false,
75
- conflicts: [],
76
- preservedInputEntries: []
77
- };
78
- }
79
- const stat = lstatSync(resolvedTarget);
80
- if (!stat.isDirectory()) {
81
- return {
82
- status: WorkspaceStatus.INVALID_TARGET,
83
- canCreate: false,
84
- target: resolvedTarget,
85
- exists: true,
86
- conflicts: [resolvedTarget],
87
- preservedInputEntries: [],
88
- message: '目标路径存在但不是目录'
89
- };
90
- }
91
- const entries = readdirSync(resolvedTarget);
92
- if (entries.length === 0) {
93
- return {
94
- status: WorkspaceStatus.EMPTY,
95
- canCreate: true,
96
- target: resolvedTarget,
97
- exists: true,
98
- conflicts: [],
99
- preservedInputEntries: []
100
- };
101
- }
102
- // 检查是否是现有 workspace
103
- const hasWorkspaceYaml = entries.includes('pnpm-workspace.yaml');
104
- const hasPackageJson = entries.includes('package.json');
105
- const hasPackagesDir = entries.includes('packages');
106
- if (hasWorkspaceYaml) {
107
- return {
108
- status: WorkspaceStatus.EXISTING_WORKSPACE,
109
- canCreate: false,
110
- target: resolvedTarget,
111
- exists: true,
112
- conflicts: ['pnpm-workspace.yaml'],
113
- preservedInputEntries: []
114
- };
115
- }
116
- // 检查是否包含已有工程特征
117
- const projectConflicts = entries.filter((e) => PROJECT_EVIDENCE_FILES.includes(e));
118
- if (projectConflicts.length > 0) {
119
- return {
120
- status: WorkspaceStatus.EXISTING_OR_UNKNOWN_PROJECT,
121
- canCreate: false,
122
- target: resolvedTarget,
123
- exists: true,
124
- conflicts: projectConflicts,
125
- preservedInputEntries: []
126
- };
127
- }
128
- // 分析是否全是 AI 配置或受保护输入
129
- let hasAiOnly = true;
130
- const preservedInputs = [];
131
- for (const entry of entries) {
132
- const lower = entry.toLowerCase();
133
- if (KNOWN_AI_AND_META_ENTRIES.has(lower)) {
134
- continue;
135
- }
136
- hasAiOnly = false;
137
- // 属于非冲突的用户保留文件(如 docs, prd.md, design.md 等)
138
- preservedInputs.push(entry);
139
- }
140
- if (hasAiOnly) {
141
- return {
142
- status: WorkspaceStatus.AI_CONFIG_ONLY,
143
- canCreate: true,
144
- target: resolvedTarget,
145
- exists: true,
146
- conflicts: [],
147
- preservedInputEntries: []
148
- };
149
- }
150
- return {
151
- status: WorkspaceStatus.PRESERVED_INPUT_ONLY,
152
- canCreate: true,
153
- target: resolvedTarget,
154
- exists: true,
155
- conflicts: [],
156
- preservedInputEntries: preservedInputs
157
- };
158
- }
159
- /**
160
- * 预检计划写入的文件与已有文件是否存在冲突
161
- */
162
- export function checkPlannedConflicts(targetDir, plannedRelativeFiles) {
163
- const conflicts = [];
164
- for (const relFile of plannedRelativeFiles) {
165
- const fullPath = resolve(targetDir, relFile);
166
- if (existsSync(fullPath)) {
167
- conflicts.push(relFile);
168
- }
169
- }
170
- return conflicts;
171
- }
172
- //# sourceMappingURL=safety.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/common/safety.ts"],"names":[],"mappings":"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"}
@@ -1,115 +0,0 @@
1
- import { existsSync, readdirSync, statSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
2
- import { join, dirname, relative } from 'node:path';
3
- /**
4
- * 将变量替换为模板内容
5
- */
6
- export function renderTemplateString(content, variables) {
7
- let result = content;
8
- Object.keys(variables).forEach((key) => {
9
- const value = variables[key];
10
- const regexp = new RegExp(`<%=\\s*${key}\\s*%>`, 'g');
11
- let strValue = '';
12
- if (typeof value === 'object' && value !== null) {
13
- if (Array.isArray(value)) {
14
- strValue = JSON.stringify(value);
15
- }
16
- else {
17
- strValue = JSON.stringify(value, null, 2);
18
- }
19
- }
20
- else {
21
- strValue = String(value ?? '');
22
- }
23
- result = result.replace(regexp, () => strValue);
24
- });
25
- return result;
26
- }
27
- /**
28
- * 检测文件内容中未被替换的 <%= xxx %> 占位符
29
- */
30
- export function findUnreplacedPlaceholders(content) {
31
- const matches = content.match(/<%=\s*[\w.-]+\s*%>/g);
32
- return matches ? Array.from(new Set(matches)) : [];
33
- }
34
- /**
35
- * 仅枚举模板渲染后会写入的相对路径,不产生任何文件系统写入。
36
- */
37
- export function collectTemplateOutputPaths(sourceDir, filter) {
38
- const outputs = [];
39
- function walk(currentSrc) {
40
- if (!existsSync(currentSrc)) {
41
- return;
42
- }
43
- for (const entry of readdirSync(currentSrc)) {
44
- const srcPath = join(currentSrc, entry);
45
- const relativePath = relative(sourceDir, srcPath).replace(/\\/g, '/');
46
- if (filter && !filter(relativePath)) {
47
- continue;
48
- }
49
- if (statSync(srcPath).isDirectory()) {
50
- walk(srcPath);
51
- }
52
- else {
53
- outputs.push(relativePath.endsWith('.tpl') ? relativePath.slice(0, -4) : relativePath);
54
- }
55
- }
56
- }
57
- walk(sourceDir);
58
- return outputs;
59
- }
60
- /**
61
- * 递归渲染模板目录到目标目录
62
- */
63
- export function renderTemplateDir(options) {
64
- const { sourceDir, targetDir, variables, skipExisting = false, filter } = options;
65
- const filesCreated = [];
66
- const unreplaced = [];
67
- function walk(currentSrc, currentTarget) {
68
- if (!existsSync(currentSrc)) {
69
- return;
70
- }
71
- const entries = readdirSync(currentSrc);
72
- for (const entry of entries) {
73
- const srcPath = join(currentSrc, entry);
74
- const stat = statSync(srcPath);
75
- const relPath = relative(sourceDir, srcPath).replace(/\\/g, '/');
76
- if (filter && !filter(relPath)) {
77
- continue;
78
- }
79
- if (stat.isDirectory()) {
80
- const nextTarget = join(currentTarget, entry);
81
- walk(srcPath, nextTarget);
82
- }
83
- else {
84
- // 去掉 .tpl 后缀
85
- let targetFileName = entry;
86
- if (targetFileName.endsWith('.tpl')) {
87
- targetFileName = targetFileName.slice(0, -4);
88
- }
89
- const targetFilePath = join(currentTarget, targetFileName);
90
- if (existsSync(targetFilePath) && skipExisting) {
91
- continue;
92
- }
93
- const rawContent = readFileSync(srcPath, 'utf-8');
94
- const rendered = renderTemplateString(rawContent, variables);
95
- const leftovers = findUnreplacedPlaceholders(rendered);
96
- if (leftovers.length > 0) {
97
- leftovers.forEach((p) => {
98
- unreplaced.push({ file: targetFilePath, placeholder: p });
99
- });
100
- }
101
- if (!existsSync(dirname(targetFilePath))) {
102
- mkdirSync(dirname(targetFilePath), { recursive: true });
103
- }
104
- writeFileSync(targetFilePath, rendered, 'utf-8');
105
- filesCreated.push(targetFilePath);
106
- }
107
- }
108
- }
109
- walk(sourceDir, targetDir);
110
- return {
111
- filesCreated,
112
- unreplacedPlaceholders: unreplaced
113
- };
114
- }
115
- //# sourceMappingURL=template-renderer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-renderer.js","sourceRoot":"","sources":["../../src/common/template-renderer.ts"],"names":[],"mappings":"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"}
@@ -1,84 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync, unlinkSync, rmdirSync, readdirSync } from 'node:fs';
2
- export class Transaction {
3
- constructor() {
4
- this.createdFiles = new Set();
5
- this.modifiedFiles = new Map(); // path -> original content
6
- this.createdDirs = new Set();
7
- this.committed = false;
8
- }
9
- /**
10
- * 记录新建目录
11
- */
12
- recordCreatedDir(dirPath) {
13
- if (!this.createdDirs.has(dirPath)) {
14
- this.createdDirs.add(dirPath);
15
- }
16
- }
17
- /**
18
- * 记录即将写入/修改的文件
19
- */
20
- prepareWrite(filePath) {
21
- if (this.createdFiles.has(filePath) || this.modifiedFiles.has(filePath)) {
22
- return;
23
- }
24
- if (existsSync(filePath)) {
25
- const original = readFileSync(filePath, 'utf-8');
26
- this.modifiedFiles.set(filePath, original);
27
- }
28
- else {
29
- this.createdFiles.add(filePath);
30
- }
31
- }
32
- /**
33
- * 提交事务
34
- */
35
- commit() {
36
- this.committed = true;
37
- }
38
- /**
39
- * 回滚事务
40
- */
41
- rollback() {
42
- if (this.committed) {
43
- return { rolledBackFiles: [], errors: [] };
44
- }
45
- const rolledBackFiles = [];
46
- const errors = [];
47
- // 恢复修改的文件
48
- for (const [filePath, originalContent] of this.modifiedFiles.entries()) {
49
- try {
50
- writeFileSync(filePath, originalContent, 'utf-8');
51
- rolledBackFiles.push(filePath);
52
- }
53
- catch (err) {
54
- errors.push(`恢复文件失败: ${filePath}, 原因: ${err.message}`);
55
- }
56
- }
57
- // 删除新建的文件
58
- for (const filePath of this.createdFiles) {
59
- try {
60
- if (existsSync(filePath)) {
61
- unlinkSync(filePath);
62
- rolledBackFiles.push(filePath);
63
- }
64
- }
65
- catch (err) {
66
- errors.push(`删除新建文件失败: ${filePath}, 原因: ${err.message}`);
67
- }
68
- }
69
- // 尝试清理新建的空目录(由深到浅排序)
70
- const sortedDirs = Array.from(this.createdDirs).sort((a, b) => b.length - a.length);
71
- for (const dir of sortedDirs) {
72
- try {
73
- if (existsSync(dir) && readdirSync(dir).length === 0) {
74
- rmdirSync(dir);
75
- }
76
- }
77
- catch {
78
- // 忽略非空目录清理异常
79
- }
80
- }
81
- return { rolledBackFiles, errors };
82
- }
83
- }
84
- //# sourceMappingURL=transaction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/common/transaction.ts"],"names":[],"mappings":"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"}
@@ -1,151 +0,0 @@
1
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
- import { resolve, join } from 'node:path';
3
- import { findUnreplacedPlaceholders } from './template-renderer.js';
4
- /**
5
- * 校验 Workspace 完整性与规范合规性
6
- */
7
- export function verifyWorkspace(targetDir, preservedInputs = []) {
8
- const checks = [];
9
- const errors = [];
10
- const addCheck = (name, passed, message) => {
11
- checks.push({ name, passed, message });
12
- if (!passed && message) {
13
- errors.push(message);
14
- }
15
- };
16
- const resolvedTarget = resolve(process.cwd(), targetDir);
17
- if (!existsSync(resolvedTarget)) {
18
- return {
19
- ok: false,
20
- target: resolvedTarget,
21
- checks: [{ name: 'target_exists', passed: false, message: `目标路径不存在: ${resolvedTarget}` }],
22
- errors: [`目标路径不存在: ${resolvedTarget}`]
23
- };
24
- }
25
- // 1. 检查根 package.json
26
- const rootPkgPath = join(resolvedTarget, 'package.json');
27
- if (!existsSync(rootPkgPath)) {
28
- addCheck('root_package_json', false, '缺少根 package.json');
29
- }
30
- else {
31
- try {
32
- const pkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'));
33
- addCheck('root_package_private', pkg.private === true, '根 package.json 必须声明 "private": true');
34
- addCheck('root_package_scripts', !!(pkg.scripts?.build && pkg.scripts?.dev && pkg.scripts?.typecheck), '根 package.json 必须声明 build, dev, typecheck 脚本');
35
- addCheck('root_package_no_name', !pkg.name, '根 package.json 不应设置 name');
36
- }
37
- catch (e) {
38
- addCheck('root_package_json_valid', false, `根 package.json 解析失败: ${e.message}`);
39
- }
40
- }
41
- // 2. 检查 pnpm-workspace.yaml
42
- const wsYamlPath = join(resolvedTarget, 'pnpm-workspace.yaml');
43
- if (!existsSync(wsYamlPath)) {
44
- addCheck('workspace_yaml', false, '缺少 pnpm-workspace.yaml');
45
- }
46
- else {
47
- const yamlContent = readFileSync(wsYamlPath, 'utf-8');
48
- addCheck('workspace_packages_glob', yamlContent.includes('packages/*'), 'pnpm-workspace.yaml 必须包含 "packages/*"');
49
- addCheck('workspace_catalog', yamlContent.includes('catalog:'), 'pnpm-workspace.yaml 必须声明 catalog 依赖版本');
50
- }
51
- // 3. 检查 packages 目录与子应用
52
- const packagesDir = join(resolvedTarget, 'packages');
53
- if (!existsSync(packagesDir) || !statSync(packagesDir).isDirectory()) {
54
- addCheck('packages_dir', false, '缺少 packages/ 目录');
55
- }
56
- else {
57
- const appDirs = readdirSync(packagesDir).filter((f) => {
58
- const p = join(packagesDir, f);
59
- return statSync(p).isDirectory();
60
- });
61
- if (appDirs.length === 0) {
62
- addCheck('has_sub_apps', false, 'packages/ 目录下未发现任何应用子包');
63
- }
64
- else {
65
- addCheck('has_sub_apps', true);
66
- // 逐个检查子应用
67
- for (const appDir of appDirs) {
68
- const appPath = join(packagesDir, appDir);
69
- const appPkgPath = join(appPath, 'package.json');
70
- const farrisConfigPath = join(appPath, 'farris.config.mjs');
71
- const indexHtmlPath = join(appPath, 'index.html');
72
- const tsconfigPath = join(appPath, 'tsconfig.json');
73
- const mainTsPath = join(appPath, 'src', 'main.ts');
74
- const appTsxPath = join(appPath, 'src', 'App.tsx');
75
- if (!existsSync(appPkgPath)) {
76
- addCheck(`app_${appDir}_package_json`, false, `应用 ${appDir} 缺少 package.json`);
77
- }
78
- else {
79
- try {
80
- const appPkg = JSON.parse(readFileSync(appPkgPath, 'utf-8'));
81
- addCheck(`app_${appDir}_name`, !!appPkg.name, `应用 ${appDir} 的 package.json 缺少 name 字段`);
82
- addCheck(`app_${appDir}_catalog_deps`, appPkg.dependencies?.['@farris/ui-vue'] === 'catalog:', `应用 ${appDir} 的 @farris/ui-vue 依赖必须使用 catalog: 协议`);
83
- }
84
- catch (e) {
85
- addCheck(`app_${appDir}_package_json_valid`, false, `应用 ${appDir} package.json 解析失败: ${e.message}`);
86
- }
87
- }
88
- // 检查 index.html 入口
89
- if (!existsSync(indexHtmlPath)) {
90
- addCheck(`app_${appDir}_index_html`, false, `应用 ${appDir} 缺少 index.html`);
91
- }
92
- else {
93
- const html = readFileSync(indexHtmlPath, 'utf-8');
94
- const hasCorrectEntry = /<script\s+type="module"\s+src="\/src\/main\.ts">\s*<\/script>/.test(html);
95
- const hasWrongEntry = /<script\s+type="module"\s+src="\.\/src\/main\.ts">\s*<\/script>/.test(html);
96
- addCheck(`app_${appDir}_html_entry`, hasCorrectEntry && !hasWrongEntry, `应用 ${appDir} 的 index.html 入口必须为 /src/main.ts,不得写为 ./src/main.ts`);
97
- }
98
- // 检查 farris.config.mjs
99
- if (!existsSync(farrisConfigPath)) {
100
- addCheck(`app_${appDir}_farris_config`, false, `应用 ${appDir} 缺少 farris.config.mjs`);
101
- }
102
- else {
103
- const configContent = readFileSync(farrisConfigPath, 'utf-8');
104
- // 检查相对 base 与 history 组合
105
- const hasRelativeBase = /base\s*:\s*['"]\.\/?['"]/.test(configContent);
106
- const hasHistoryRouter = /routerMode\s*:\s*['"]history['"]/.test(configContent);
107
- if (hasRelativeBase && hasHistoryRouter) {
108
- addCheck(`app_${appDir}_base_router_compatibility`, false, `应用 ${appDir} 配置冲突: 相对路径 base 与 history 路由模式不可同时使用`);
109
- }
110
- else {
111
- addCheck(`app_${appDir}_base_router_compatibility`, true);
112
- }
113
- }
114
- // 检查 TSX 入口与多语言资源骨架
115
- const localesIndexPath = join(appPath, 'src', 'locales', 'index.ts');
116
- const localesZhJsonPath = join(appPath, 'src', 'locales', 'zh-CN.json');
117
- addCheck(`app_${appDir}_tsconfig`, existsSync(tsconfigPath), `应用 ${appDir} 缺少 tsconfig.json`);
118
- addCheck(`app_${appDir}_main_ts`, existsSync(mainTsPath), `应用 ${appDir} 缺少 src/main.ts`);
119
- addCheck(`app_${appDir}_app_tsx`, existsSync(appTsxPath), `应用 ${appDir} 缺少 src/App.tsx`);
120
- addCheck(`app_${appDir}_locales_index`, existsSync(localesIndexPath), `应用 ${appDir} 缺少 src/locales/index.ts`);
121
- addCheck(`app_${appDir}_locales_zh_json`, existsSync(localesZhJsonPath), `应用 ${appDir} 缺少 src/locales/zh-CN.json`);
122
- // 检查未替换占位符
123
- const checkFiles = [appPkgPath, farrisConfigPath, indexHtmlPath, mainTsPath, appTsxPath, localesIndexPath, localesZhJsonPath];
124
- for (const file of checkFiles) {
125
- if (existsSync(file)) {
126
- const content = readFileSync(file, 'utf-8');
127
- const unreplaced = findUnreplacedPlaceholders(content);
128
- if (unreplaced.length > 0) {
129
- addCheck(`app_${appDir}_placeholders_${file}`, false, `文件 ${file} 存在未替换占位符: ${unreplaced.join(', ')}`);
130
- }
131
- }
132
- }
133
- }
134
- }
135
- }
136
- // 4. 检查受保护输入是否依然完好
137
- if (preservedInputs.length > 0) {
138
- for (const entry of preservedInputs) {
139
- const entryPath = join(resolvedTarget, entry);
140
- addCheck(`preserved_input_${entry}`, existsSync(entryPath), `受保护输入文件/目录丢失或被覆盖: ${entry}`);
141
- }
142
- }
143
- const ok = errors.length === 0;
144
- return {
145
- ok,
146
- target: resolvedTarget,
147
- checks,
148
- errors
149
- };
150
- }
151
- //# sourceMappingURL=verifier.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/common/verifier.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- import { fileURLToPath, URL } from 'node:url';
2
-
3
- export default {
4
- base: '<%= base %>',
5
- routerMode: '<%= routerMode %>',
6
- format: '<%= format %>',
7
- minify: true,
8
- externalDependencies: false,
9
- alias: [
10
- { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) }
11
- ],
12
- viteConfig: {}
13
- };
@@ -1,12 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title><%= title %></title>
7
- </head>
8
- <body>
9
- <div id="app"></div>
10
- <script type="module" src="/src/main.ts"></script>
11
- </body>
12
- </html>
@@ -1,22 +0,0 @@
1
- {
2
- "name": "<%= appName %>",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "farris-cli dev",
8
- "build": "farris-cli build",
9
- "preview": "farris-cli preview",
10
- "typecheck": "vue-tsc --noEmit"
11
- },
12
- "dependencies": {
13
- "@farris/ui-vue": "catalog:",
14
- "vue": "catalog:"<%= routerDependency %>
15
- },
16
- "devDependencies": {
17
- "@farris/cli": "catalog:",
18
- "typescript": "catalog:",
19
- "vite": "catalog:",
20
- "vue-tsc": "catalog:"<%= sassDevDependency %>
21
- }
22
- }
@@ -1,11 +0,0 @@
1
- import { defineComponent } from 'vue';<%= appRouterImport %>
2
-
3
- export default defineComponent({
4
- name: 'App',
5
- setup() {
6
- return () => (
7
- <%= appTemplateBody %>
8
- );
9
- }
10
- });
11
-
@@ -1,5 +0,0 @@
1
- import zhCN from './zh-CN.json';
2
-
3
- export const localResources = {
4
- 'zh-CN': zhCN
5
- };
@@ -1,12 +0,0 @@
1
- import { createApp } from 'vue';
2
- import FarrisUI from '@farris/ui-vue';
3
- import '@farris/ui-vue/index.css';<%= styleImport %><%= routerImport %>
4
- import { localResources } from './locales';
5
- import App from './App';
6
-
7
- const app = createApp(App);
8
-
9
- app.use(FarrisUI, { basePath: '', locale: 'zh-CN', localResources });<%= routerUse %>
10
-
11
- app.mount('#app');
12
-