@farris/cli 2.3.8 → 2.3.9

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 (108) hide show
  1. package/lib/commands/add-app.js +5 -5
  2. package/lib/commands/add-lib.js +5 -5
  3. package/lib/commands/add-micro.js +11 -11
  4. package/lib/commands/add-project.js +196 -196
  5. package/lib/commands/add-project.js.map +1 -1
  6. package/lib/commands/build-components.js +60 -60
  7. package/lib/commands/build-components.js.map +1 -1
  8. package/lib/commands/build-css.js +38 -38
  9. package/lib/commands/build-css.js.map +1 -1
  10. package/lib/commands/build-lib.js +30 -30
  11. package/lib/commands/build.js +19 -19
  12. package/lib/commands/build.js.map +1 -1
  13. package/lib/commands/create-app-options.js +85 -85
  14. package/lib/commands/create-app-options.js.map +1 -1
  15. package/lib/commands/create-app.js +131 -131
  16. package/lib/commands/create-app.js.map +1 -1
  17. package/lib/commands/create-options.js +58 -58
  18. package/lib/commands/create-options.js.map +1 -1
  19. package/lib/commands/create.js +341 -341
  20. package/lib/commands/create.js.map +1 -1
  21. package/lib/commands/dev-serve.js +18 -18
  22. package/lib/commands/extract-i18n.js +74 -74
  23. package/lib/commands/extract-i18n.js.map +1 -1
  24. package/lib/commands/generate/api.js +124 -124
  25. package/lib/commands/generate/api.js.map +1 -1
  26. package/lib/commands/generate/common.js +101 -101
  27. package/lib/commands/generate/common.js.map +1 -1
  28. package/lib/commands/generate/component.js +156 -156
  29. package/lib/commands/generate/component.js.map +1 -1
  30. package/lib/commands/generate/view.js +168 -168
  31. package/lib/commands/generate/view.js.map +1 -1
  32. package/lib/commands/preview-serve.js +16 -16
  33. package/lib/commands/workspace/add-app.js +15 -15
  34. package/lib/commands/workspace/add-app.js.map +1 -1
  35. package/lib/commands/workspace/create.js +62 -62
  36. package/lib/commands/workspace/create.js.map +1 -1
  37. package/lib/commands/workspace/inspect.js +30 -30
  38. package/lib/commands/workspace/inspect.js.map +1 -1
  39. package/lib/commands/workspace/verify.js +38 -38
  40. package/lib/commands/workspace/verify.js.map +1 -1
  41. package/lib/common/agents-doc.js +33 -33
  42. package/lib/common/agents-doc.js.map +1 -1
  43. package/lib/common/apply-catalog-deps.js +15 -15
  44. package/lib/common/apply-catalog-deps.js.map +1 -1
  45. package/lib/common/component-file-name.js +3 -3
  46. package/lib/common/constant.js +85 -84
  47. package/lib/common/constant.js.map +1 -1
  48. package/lib/common/create-app-target.js +46 -46
  49. package/lib/common/create-app-target.js.map +1 -1
  50. package/lib/common/generate-app.js +106 -106
  51. package/lib/common/generate-app.js.map +1 -1
  52. package/lib/common/get-dependencies.js +9 -9
  53. package/lib/common/get-farris-config.js +25 -25
  54. package/lib/common/get-farris-config.js.map +1 -1
  55. package/lib/common/get-version.js +6 -6
  56. package/lib/common/get-vite-config.js +192 -192
  57. package/lib/common/get-vite-config.js.map +1 -1
  58. package/lib/common/lib-package-exports.js +24 -24
  59. package/lib/common/lib-package-exports.js.map +1 -1
  60. package/lib/common/list-lib-components.js +23 -23
  61. package/lib/common/list-lib-components.js.map +1 -1
  62. package/lib/common/output.js +164 -164
  63. package/lib/common/output.js.map +1 -1
  64. package/lib/common/project-layout.js +155 -155
  65. package/lib/common/project-layout.js.map +1 -1
  66. package/lib/common/safety.js +172 -172
  67. package/lib/common/safety.js.map +1 -1
  68. package/lib/common/template-manifest.js +18 -18
  69. package/lib/common/template-manifest.js.map +1 -1
  70. package/lib/common/template-renderer.js +114 -114
  71. package/lib/common/template-renderer.js.map +1 -1
  72. package/lib/common/transaction.js +83 -83
  73. package/lib/common/transaction.js.map +1 -1
  74. package/lib/common/verifier.js +187 -187
  75. package/lib/common/verifier.js.map +1 -1
  76. package/lib/common/workspace-contract.js +191 -191
  77. package/lib/common/workspace-contract.js.map +1 -1
  78. package/lib/config/vite-app.js +13 -13
  79. package/lib/config/vite-common.js +20 -20
  80. package/lib/config/vite-common.js.map +1 -1
  81. package/lib/config/vite-component.js +32 -32
  82. package/lib/config/vite-component.js.map +1 -1
  83. package/lib/config/vite-lib.js +26 -26
  84. package/lib/index.js +261 -261
  85. package/lib/plugins/create-app-package-json.js +23 -23
  86. package/lib/plugins/create-component-style.js +44 -44
  87. package/lib/plugins/create-package-json.js +48 -48
  88. package/lib/plugins/create-package-json.js.map +1 -1
  89. package/lib/plugins/dts.js +8 -8
  90. package/lib/plugins/html-system.js +9 -9
  91. package/lib/plugins/mock.js +240 -292
  92. package/lib/plugins/mock.js.map +1 -1
  93. package/lib/plugins/msw-adapter.js +141 -0
  94. package/lib/plugins/msw-adapter.js.map +1 -0
  95. package/lib/plugins/replace.js +17 -17
  96. package/lib/plugins/systemjs-bundle.js +15 -15
  97. package/lib/plugins/systemjs-bundle.js.map +1 -1
  98. package/package.json +6 -1
  99. package/templates/create/AGENTS.md +4 -3
  100. package/templates/micro/mock/README.md +39 -26
  101. package/templates/micro/mock/tsconfig.json +10 -0
  102. package/templates/micro/package.json +1 -0
  103. package/templates/mobile/mock/README.md +39 -26
  104. package/templates/mobile/mock/tsconfig.json +10 -0
  105. package/templates/mobile/package.json +1 -0
  106. package/templates/web/mock/README.md +39 -26
  107. package/templates/web/mock/tsconfig.json +10 -0
  108. package/templates/web/package.json +1 -0
@@ -1,173 +1,173 @@
1
- import { existsSync, lstatSync, readdirSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
- import { WorkspaceStatus } from './constant.js';
4
- import { CONTAINERS } from './project-layout.js';
5
- // 已知 AI 配置与项目元数据文件/目录(忽略列表)
6
- export const KNOWN_AI_AND_META_ENTRIES = new Set([
7
- '.git',
8
- '.gitignore',
9
- '.agent',
10
- '.agents',
11
- '.cursor',
12
- '.vscode',
13
- '.superpowers',
14
- '.changeset',
15
- '.github',
16
- '.codebuddy',
17
- '.trae',
18
- '.gemini',
19
- '.aider.conf.yml',
20
- 'agents.md',
21
- 'claude.md',
22
- 'gemini.md',
23
- '.windsurfrules',
24
- '.cursorrules'
25
- ]);
26
- // 工程证据关键文件。容器目录名一律取自 project-layout,避免字面量漂移
27
- export const PROJECT_EVIDENCE_FILES = [
28
- 'package.json',
29
- 'pnpm-workspace.yaml',
30
- 'vite.config.ts',
31
- 'vite.config.js',
32
- 'vite.config.mjs',
33
- 'farris.config.ts',
34
- 'farris.config.js',
35
- 'farris.config.mjs',
36
- 'tsconfig.json',
37
- 'src',
38
- ...CONTAINERS,
39
- 'node_modules'
40
- ];
41
- /**
42
- * 校验目标路径安全性,防止目录穿越与非法路径
43
- */
44
- export function validateTargetPath(target) {
45
- if (!target || typeof target !== 'string') {
46
- return { valid: false, resolved: '', error: '目标路径不能为空' };
47
- }
48
- const resolved = resolve(process.cwd(), target);
49
- // 检查是否在非法系统根或包含非法控制字符
50
- if (resolved.includes('\0')) {
51
- return { valid: false, resolved: '', error: '目标路径包含非法字符' };
52
- }
53
- return { valid: true, resolved };
54
- }
55
- /**
56
- * 扫描目标目录状态
57
- */
58
- export function inspectTarget(targetPath) {
59
- const pathValidation = validateTargetPath(targetPath);
60
- if (!pathValidation.valid) {
61
- return {
62
- status: WorkspaceStatus.INVALID_TARGET,
63
- canCreate: false,
64
- target: targetPath,
65
- exists: false,
66
- conflicts: [],
67
- preservedInputEntries: [],
68
- message: pathValidation.error
69
- };
70
- }
71
- const resolvedTarget = pathValidation.resolved;
72
- if (!existsSync(resolvedTarget)) {
73
- return {
74
- status: WorkspaceStatus.MISSING,
75
- canCreate: true,
76
- target: resolvedTarget,
77
- exists: false,
78
- conflicts: [],
79
- preservedInputEntries: []
80
- };
81
- }
82
- const stat = lstatSync(resolvedTarget);
83
- if (!stat.isDirectory()) {
84
- return {
85
- status: WorkspaceStatus.INVALID_TARGET,
86
- canCreate: false,
87
- target: resolvedTarget,
88
- exists: true,
89
- conflicts: [resolvedTarget],
90
- preservedInputEntries: [],
91
- message: '目标路径存在但不是目录'
92
- };
93
- }
94
- const entries = readdirSync(resolvedTarget);
95
- if (entries.length === 0) {
96
- return {
97
- status: WorkspaceStatus.EMPTY,
98
- canCreate: true,
99
- target: resolvedTarget,
100
- exists: true,
101
- conflicts: [],
102
- preservedInputEntries: []
103
- };
104
- }
105
- // 检查是否是现有 workspace
106
- const hasWorkspaceYaml = entries.includes('pnpm-workspace.yaml');
107
- if (hasWorkspaceYaml) {
108
- return {
109
- status: WorkspaceStatus.EXISTING_WORKSPACE,
110
- canCreate: false,
111
- target: resolvedTarget,
112
- exists: true,
113
- conflicts: ['pnpm-workspace.yaml'],
114
- preservedInputEntries: []
115
- };
116
- }
117
- // 检查是否包含已有工程特征
118
- const projectConflicts = entries.filter((e) => PROJECT_EVIDENCE_FILES.includes(e));
119
- if (projectConflicts.length > 0) {
120
- return {
121
- status: WorkspaceStatus.EXISTING_OR_UNKNOWN_PROJECT,
122
- canCreate: false,
123
- target: resolvedTarget,
124
- exists: true,
125
- conflicts: projectConflicts,
126
- preservedInputEntries: []
127
- };
128
- }
129
- // 分析是否全是 AI 配置或受保护输入
130
- let hasAiOnly = true;
131
- const preservedInputs = [];
132
- for (const entry of entries) {
133
- const lower = entry.toLowerCase();
134
- if (KNOWN_AI_AND_META_ENTRIES.has(lower)) {
135
- continue;
136
- }
137
- hasAiOnly = false;
138
- // 属于非冲突的用户保留文件(如 docs, prd.md, design.md 等)
139
- preservedInputs.push(entry);
140
- }
141
- if (hasAiOnly) {
142
- return {
143
- status: WorkspaceStatus.AI_CONFIG_ONLY,
144
- canCreate: true,
145
- target: resolvedTarget,
146
- exists: true,
147
- conflicts: [],
148
- preservedInputEntries: []
149
- };
150
- }
151
- return {
152
- status: WorkspaceStatus.PRESERVED_INPUT_ONLY,
153
- canCreate: true,
154
- target: resolvedTarget,
155
- exists: true,
156
- conflicts: [],
157
- preservedInputEntries: preservedInputs
158
- };
159
- }
160
- /**
161
- * 预检计划写入的文件与已有文件是否存在冲突
162
- */
163
- export function checkPlannedConflicts(targetDir, plannedRelativeFiles) {
164
- const conflicts = [];
165
- for (const relFile of plannedRelativeFiles) {
166
- const fullPath = resolve(targetDir, relFile);
167
- if (existsSync(fullPath)) {
168
- conflicts.push(relFile);
169
- }
170
- }
171
- return conflicts;
172
- }
1
+ import { existsSync, lstatSync, readdirSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { WorkspaceStatus } from './constant.js';
4
+ import { CONTAINERS } from './project-layout.js';
5
+ // 已知 AI 配置与项目元数据文件/目录(忽略列表)
6
+ export const KNOWN_AI_AND_META_ENTRIES = new Set([
7
+ '.git',
8
+ '.gitignore',
9
+ '.agent',
10
+ '.agents',
11
+ '.cursor',
12
+ '.vscode',
13
+ '.superpowers',
14
+ '.changeset',
15
+ '.github',
16
+ '.codebuddy',
17
+ '.trae',
18
+ '.gemini',
19
+ '.aider.conf.yml',
20
+ 'agents.md',
21
+ 'claude.md',
22
+ 'gemini.md',
23
+ '.windsurfrules',
24
+ '.cursorrules'
25
+ ]);
26
+ // 工程证据关键文件。容器目录名一律取自 project-layout,避免字面量漂移
27
+ export const PROJECT_EVIDENCE_FILES = [
28
+ 'package.json',
29
+ 'pnpm-workspace.yaml',
30
+ 'vite.config.ts',
31
+ 'vite.config.js',
32
+ 'vite.config.mjs',
33
+ 'farris.config.ts',
34
+ 'farris.config.js',
35
+ 'farris.config.mjs',
36
+ 'tsconfig.json',
37
+ 'src',
38
+ ...CONTAINERS,
39
+ 'node_modules'
40
+ ];
41
+ /**
42
+ * 校验目标路径安全性,防止目录穿越与非法路径
43
+ */
44
+ export function validateTargetPath(target) {
45
+ if (!target || typeof target !== 'string') {
46
+ return { valid: false, resolved: '', error: '目标路径不能为空' };
47
+ }
48
+ const resolved = resolve(process.cwd(), target);
49
+ // 检查是否在非法系统根或包含非法控制字符
50
+ if (resolved.includes('\0')) {
51
+ return { valid: false, resolved: '', error: '目标路径包含非法字符' };
52
+ }
53
+ return { valid: true, resolved };
54
+ }
55
+ /**
56
+ * 扫描目标目录状态
57
+ */
58
+ export function inspectTarget(targetPath) {
59
+ const pathValidation = validateTargetPath(targetPath);
60
+ if (!pathValidation.valid) {
61
+ return {
62
+ status: WorkspaceStatus.INVALID_TARGET,
63
+ canCreate: false,
64
+ target: targetPath,
65
+ exists: false,
66
+ conflicts: [],
67
+ preservedInputEntries: [],
68
+ message: pathValidation.error
69
+ };
70
+ }
71
+ const resolvedTarget = pathValidation.resolved;
72
+ if (!existsSync(resolvedTarget)) {
73
+ return {
74
+ status: WorkspaceStatus.MISSING,
75
+ canCreate: true,
76
+ target: resolvedTarget,
77
+ exists: false,
78
+ conflicts: [],
79
+ preservedInputEntries: []
80
+ };
81
+ }
82
+ const stat = lstatSync(resolvedTarget);
83
+ if (!stat.isDirectory()) {
84
+ return {
85
+ status: WorkspaceStatus.INVALID_TARGET,
86
+ canCreate: false,
87
+ target: resolvedTarget,
88
+ exists: true,
89
+ conflicts: [resolvedTarget],
90
+ preservedInputEntries: [],
91
+ message: '目标路径存在但不是目录'
92
+ };
93
+ }
94
+ const entries = readdirSync(resolvedTarget);
95
+ if (entries.length === 0) {
96
+ return {
97
+ status: WorkspaceStatus.EMPTY,
98
+ canCreate: true,
99
+ target: resolvedTarget,
100
+ exists: true,
101
+ conflicts: [],
102
+ preservedInputEntries: []
103
+ };
104
+ }
105
+ // 检查是否是现有 workspace
106
+ const hasWorkspaceYaml = entries.includes('pnpm-workspace.yaml');
107
+ if (hasWorkspaceYaml) {
108
+ return {
109
+ status: WorkspaceStatus.EXISTING_WORKSPACE,
110
+ canCreate: false,
111
+ target: resolvedTarget,
112
+ exists: true,
113
+ conflicts: ['pnpm-workspace.yaml'],
114
+ preservedInputEntries: []
115
+ };
116
+ }
117
+ // 检查是否包含已有工程特征
118
+ const projectConflicts = entries.filter((e) => PROJECT_EVIDENCE_FILES.includes(e));
119
+ if (projectConflicts.length > 0) {
120
+ return {
121
+ status: WorkspaceStatus.EXISTING_OR_UNKNOWN_PROJECT,
122
+ canCreate: false,
123
+ target: resolvedTarget,
124
+ exists: true,
125
+ conflicts: projectConflicts,
126
+ preservedInputEntries: []
127
+ };
128
+ }
129
+ // 分析是否全是 AI 配置或受保护输入
130
+ let hasAiOnly = true;
131
+ const preservedInputs = [];
132
+ for (const entry of entries) {
133
+ const lower = entry.toLowerCase();
134
+ if (KNOWN_AI_AND_META_ENTRIES.has(lower)) {
135
+ continue;
136
+ }
137
+ hasAiOnly = false;
138
+ // 属于非冲突的用户保留文件(如 docs, prd.md, design.md 等)
139
+ preservedInputs.push(entry);
140
+ }
141
+ if (hasAiOnly) {
142
+ return {
143
+ status: WorkspaceStatus.AI_CONFIG_ONLY,
144
+ canCreate: true,
145
+ target: resolvedTarget,
146
+ exists: true,
147
+ conflicts: [],
148
+ preservedInputEntries: []
149
+ };
150
+ }
151
+ return {
152
+ status: WorkspaceStatus.PRESERVED_INPUT_ONLY,
153
+ canCreate: true,
154
+ target: resolvedTarget,
155
+ exists: true,
156
+ conflicts: [],
157
+ preservedInputEntries: preservedInputs
158
+ };
159
+ }
160
+ /**
161
+ * 预检计划写入的文件与已有文件是否存在冲突
162
+ */
163
+ export function checkPlannedConflicts(targetDir, plannedRelativeFiles) {
164
+ const conflicts = [];
165
+ for (const relFile of plannedRelativeFiles) {
166
+ const fullPath = resolve(targetDir, relFile);
167
+ if (existsSync(fullPath)) {
168
+ conflicts.push(relFile);
169
+ }
170
+ }
171
+ return conflicts;
172
+ }
173
173
  //# sourceMappingURL=safety.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/common/safety.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/common/safety.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,19 @@
1
- import { resolve } from 'node:path';
2
- import { getDirname } from './constant.js';
3
- export function resolveTemplate(input) {
4
- if (input.type === 'lib') {
5
- return { id: 'lib' };
6
- }
7
- // 微应用只做 web(D3):自带微前端契约、交付 iife 单文件
8
- if (input.type === 'micro') {
9
- return { id: 'micro' };
10
- }
11
- if (!input.platform) {
12
- throw new Error('platform is required when type is app');
13
- }
14
- return { id: input.platform };
15
- }
16
- export function getTemplateDir(id) {
17
- return resolve(getDirname(import.meta.url), '../../templates', id);
18
- }
1
+ import { resolve } from 'node:path';
2
+ import { getDirname } from './constant.js';
3
+ export function resolveTemplate(input) {
4
+ if (input.type === 'lib') {
5
+ return { id: 'lib' };
6
+ }
7
+ // 微应用只做 web(D3):自带微前端契约、交付 iife 单文件
8
+ if (input.type === 'micro') {
9
+ return { id: 'micro' };
10
+ }
11
+ if (!input.platform) {
12
+ throw new Error('platform is required when type is app');
13
+ }
14
+ return { id: input.platform };
15
+ }
16
+ export function getTemplateDir(id) {
17
+ return resolve(getDirname(import.meta.url), '../../templates', id);
18
+ }
19
19
  //# sourceMappingURL=template-manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"template-manifest.js","sourceRoot":"","sources":["../../src/common/template-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE;QACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;KACtB;IACD,oCAAoC;IACpC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;QAC1B,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;KACxB;IACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;QACnB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;KAC1D;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAc;IAC3C,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"template-manifest.js","sourceRoot":"","sources":["../../src/common/template-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,oCAAoC;IACpC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAc;IAC3C,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC"}
@@ -1,115 +1,115 @@
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
- }
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
115
  //# sourceMappingURL=template-renderer.js.map