@farris/cli 2.2.4 → 2.2.6

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 (90) hide show
  1. package/lib/commands/build-components.js +50 -50
  2. package/lib/commands/build-components.js.map +1 -1
  3. package/lib/commands/build-css.js +38 -38
  4. package/lib/commands/build-css.js.map +1 -1
  5. package/lib/commands/build-lib.js +25 -25
  6. package/lib/commands/build.js +14 -14
  7. package/lib/commands/build.js.map +1 -1
  8. package/lib/commands/create-app-options.js +74 -74
  9. package/lib/commands/create-app-options.js.map +1 -1
  10. package/lib/commands/create-app.js +126 -126
  11. package/lib/commands/create-app.js.map +1 -1
  12. package/lib/commands/create-options.js +29 -29
  13. package/lib/commands/create-options.js.map +1 -1
  14. package/lib/commands/create.js +224 -202
  15. package/lib/commands/create.js.map +1 -1
  16. package/lib/commands/dev-serve.js +18 -18
  17. package/lib/commands/extract-i18n.js +74 -74
  18. package/lib/commands/extract-i18n.js.map +1 -1
  19. package/lib/commands/generate/api.js +124 -124
  20. package/lib/commands/generate/api.js.map +1 -1
  21. package/lib/commands/generate/common.js +100 -100
  22. package/lib/commands/generate/common.js.map +1 -1
  23. package/lib/commands/generate/component.js +156 -156
  24. package/lib/commands/generate/component.js.map +1 -1
  25. package/lib/commands/generate/view.js +168 -168
  26. package/lib/commands/generate/view.js.map +1 -1
  27. package/lib/commands/preview-serve.js +16 -16
  28. package/lib/commands/workspace/add-app.js +180 -180
  29. package/lib/commands/workspace/add-app.js.map +1 -1
  30. package/lib/commands/workspace/create.js +379 -379
  31. package/lib/commands/workspace/create.js.map +1 -1
  32. package/lib/commands/workspace/inspect.js +30 -30
  33. package/lib/commands/workspace/inspect.js.map +1 -1
  34. package/lib/commands/workspace/verify.js +38 -38
  35. package/lib/commands/workspace/verify.js.map +1 -1
  36. package/lib/common/apply-catalog-deps.js +15 -15
  37. package/lib/common/apply-catalog-deps.js.map +1 -1
  38. package/lib/common/component-file-name.js +3 -3
  39. package/lib/common/constant.js +64 -64
  40. package/lib/common/constant.js.map +1 -1
  41. package/lib/common/create-app-target.js +46 -46
  42. package/lib/common/create-app-target.js.map +1 -1
  43. package/lib/common/generate-app.js +85 -85
  44. package/lib/common/generate-app.js.map +1 -1
  45. package/lib/common/get-dependencies.js +9 -9
  46. package/lib/common/get-farris-config.js +25 -25
  47. package/lib/common/get-farris-config.js.map +1 -1
  48. package/lib/common/get-version.js +6 -6
  49. package/lib/common/get-vite-config.js +106 -106
  50. package/lib/common/get-vite-config.js.map +1 -1
  51. package/lib/common/lib-package-exports.js +24 -24
  52. package/lib/common/lib-package-exports.js.map +1 -1
  53. package/lib/common/list-lib-components.js +23 -23
  54. package/lib/common/list-lib-components.js.map +1 -1
  55. package/lib/common/output.js +94 -94
  56. package/lib/common/output.js.map +1 -1
  57. package/lib/common/project-package-name.js +4 -4
  58. package/lib/common/safety.js +171 -171
  59. package/lib/common/safety.js.map +1 -1
  60. package/lib/common/template-manifest.js +16 -16
  61. package/lib/common/template-manifest.js.map +1 -1
  62. package/lib/common/template-renderer.js +114 -114
  63. package/lib/common/template-renderer.js.map +1 -1
  64. package/lib/common/transaction.js +83 -83
  65. package/lib/common/transaction.js.map +1 -1
  66. package/lib/common/verifier.js +150 -150
  67. package/lib/common/verifier.js.map +1 -1
  68. package/lib/config/vite-app.js +13 -13
  69. package/lib/config/vite-common.js +20 -20
  70. package/lib/config/vite-common.js.map +1 -1
  71. package/lib/config/vite-component.js +32 -32
  72. package/lib/config/vite-component.js.map +1 -1
  73. package/lib/config/vite-lib.js +26 -26
  74. package/lib/index.js +205 -205
  75. package/lib/index.js.map +1 -1
  76. package/lib/plugins/create-component-style.js +44 -44
  77. package/lib/plugins/create-package-json.js +48 -48
  78. package/lib/plugins/create-package-json.js.map +1 -1
  79. package/lib/plugins/dts.js +8 -8
  80. package/lib/plugins/html-system.js +9 -9
  81. package/lib/plugins/replace.js +17 -17
  82. package/lib/plugins/systemjs-bundle.js +15 -15
  83. package/lib/plugins/systemjs-bundle.js.map +1 -1
  84. package/package.json +1 -1
  85. package/templates/create/.npmrc.tpl +1 -0
  86. package/templates/lib/package.json +1 -1
  87. package/templates/mobile/package.json +1 -1
  88. package/templates/mobile/project.json +1 -1
  89. package/templates/web/package.json +1 -1
  90. package/templates/web/project.json +1 -1
@@ -1,75 +1,75 @@
1
- import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'fs';
2
- import { join, basename, dirname, resolve } from 'path';
3
- import { sync } from 'glob';
4
- import { pathToFileURL } from 'url';
5
- /**
6
- * 抽取国际化资源到JSON文件
7
- */
8
- async function loadConfig(configPath) {
9
- const defaultConfigPath = resolve(process.cwd(), 'farris.i18n.mjs');
10
- const finalPath = configPath || defaultConfigPath;
11
- if (!existsSync(finalPath)) {
12
- throw new Error(`配置文件不存在: ${finalPath}`);
13
- }
14
- const fileUrl = pathToFileURL(finalPath).href;
15
- const config = (await import(fileUrl)).default;
16
- return config;
17
- }
18
- async function extractByType(type, config, options) {
19
- console.log(`正在提取 ${type} 资源...`);
20
- const outputDir = options.outDir || config.outDir;
21
- const localeMap = {};
22
- // Process each include pattern
23
- for (const pattern of config.include) {
24
- const localeFiles = sync(pattern, {
25
- cwd: process.cwd(),
26
- absolute: true,
27
- ignore: config.exclude
28
- });
29
- // Process each locale file
30
- localeFiles.forEach(file => {
31
- const componentName = basename(dirname(dirname(dirname(dirname(file)))));
32
- const localeName = basename(file, '.json');
33
- const content = readFileSync(file, 'utf8');
34
- if (!content) {
35
- return;
36
- }
37
- const resources = JSON.parse(content);
38
- if (!localeMap[localeName]) {
39
- localeMap[localeName] = {};
40
- }
41
- // Add component translations under component namespace
42
- Object.assign(localeMap[localeName], resources);
43
- });
44
- }
45
- // Ensure output directory exists
46
- if (!existsSync(outputDir)) {
47
- mkdirSync(outputDir, { recursive: true });
48
- }
49
- // Write each locale to a separate file
50
- Object.entries(localeMap).forEach(([locale, translations]) => {
51
- const outputFile = join(outputDir, `${locale}.json`);
52
- const content = config.minify
53
- ? JSON.stringify(translations)
54
- : JSON.stringify(translations, null, 2);
55
- writeFileSync(outputFile, content);
56
- });
57
- console.log(`${type} 资源提取完成!`);
58
- }
59
- export async function extractI18n(options = {}) {
60
- console.log('正在抽取国际化资源...');
61
- try {
62
- const config = await loadConfig(options.configFile);
63
- // 否则提取所有配置的类型
64
- for (const [type, typeConfig] of Object.entries(config.extract)) {
65
- if (typeConfig) {
66
- await extractByType(type, typeConfig, options);
67
- }
68
- }
69
- }
70
- catch (error) {
71
- console.error(error);
72
- process.exit(1);
73
- }
74
- }
1
+ import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'fs';
2
+ import { join, basename, dirname, resolve } from 'path';
3
+ import { sync } from 'glob';
4
+ import { pathToFileURL } from 'url';
5
+ /**
6
+ * 抽取国际化资源到JSON文件
7
+ */
8
+ async function loadConfig(configPath) {
9
+ const defaultConfigPath = resolve(process.cwd(), 'farris.i18n.mjs');
10
+ const finalPath = configPath || defaultConfigPath;
11
+ if (!existsSync(finalPath)) {
12
+ throw new Error(`配置文件不存在: ${finalPath}`);
13
+ }
14
+ const fileUrl = pathToFileURL(finalPath).href;
15
+ const config = (await import(fileUrl)).default;
16
+ return config;
17
+ }
18
+ async function extractByType(type, config, options) {
19
+ console.log(`正在提取 ${type} 资源...`);
20
+ const outputDir = options.outDir || config.outDir;
21
+ const localeMap = {};
22
+ // Process each include pattern
23
+ for (const pattern of config.include) {
24
+ const localeFiles = sync(pattern, {
25
+ cwd: process.cwd(),
26
+ absolute: true,
27
+ ignore: config.exclude
28
+ });
29
+ // Process each locale file
30
+ localeFiles.forEach(file => {
31
+ const componentName = basename(dirname(dirname(dirname(dirname(file)))));
32
+ const localeName = basename(file, '.json');
33
+ const content = readFileSync(file, 'utf8');
34
+ if (!content) {
35
+ return;
36
+ }
37
+ const resources = JSON.parse(content);
38
+ if (!localeMap[localeName]) {
39
+ localeMap[localeName] = {};
40
+ }
41
+ // Add component translations under component namespace
42
+ Object.assign(localeMap[localeName], resources);
43
+ });
44
+ }
45
+ // Ensure output directory exists
46
+ if (!existsSync(outputDir)) {
47
+ mkdirSync(outputDir, { recursive: true });
48
+ }
49
+ // Write each locale to a separate file
50
+ Object.entries(localeMap).forEach(([locale, translations]) => {
51
+ const outputFile = join(outputDir, `${locale}.json`);
52
+ const content = config.minify
53
+ ? JSON.stringify(translations)
54
+ : JSON.stringify(translations, null, 2);
55
+ writeFileSync(outputFile, content);
56
+ });
57
+ console.log(`${type} 资源提取完成!`);
58
+ }
59
+ export async function extractI18n(options = {}) {
60
+ console.log('正在抽取国际化资源...');
61
+ try {
62
+ const config = await loadConfig(options.configFile);
63
+ // 否则提取所有配置的类型
64
+ for (const [type, typeConfig] of Object.entries(config.extract)) {
65
+ if (typeConfig) {
66
+ await extractByType(type, typeConfig, options);
67
+ }
68
+ }
69
+ }
70
+ catch (error) {
71
+ console.error(error);
72
+ process.exit(1);
73
+ }
74
+ }
75
75
  //# sourceMappingURL=extract-i18n.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract-i18n.js","sourceRoot":"","sources":["../../src/commands/extract-i18n.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extract-i18n.js","sourceRoot":"","sources":["../../src/commands/extract-i18n.ts"],"names":[],"mappings":"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"}
@@ -1,73 +1,73 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { findAppContext, normalizeGeneratorName, toPascalCase, toCamelCase } from './common.js';
4
- import { Transaction } from '../../common/transaction.js';
5
- import { sendJson, logInfo, fail, setJsonMode, createSpinner } from '../../common/output.js';
6
- import { ExitCode } from '../../common/constant.js';
7
- export async function generateApi(rawName, options = {}) {
8
- const isJson = !!options.json;
9
- setJsonMode(isJson);
10
- if (!rawName) {
11
- fail({
12
- command: 'generate.api',
13
- error: '必须指定 API 模块名称: farris-cli generate api <name>',
14
- exitCode: ExitCode.GENERAL_ERROR
15
- });
16
- }
17
- const { endpoint } = options;
18
- if (!endpoint || typeof endpoint !== 'string' || !endpoint.trim()) {
19
- fail({
20
- command: 'generate.api',
21
- error: '必须指定真实 API endpoint (--endpoint <path>),如: --endpoint /api/v1/orders',
22
- exitCode: ExitCode.GENERAL_ERROR
23
- });
24
- }
25
- const normalizedName = normalizeGeneratorName(rawName);
26
- if (!normalizedName.valid) {
27
- fail({
28
- command: 'generate.api',
29
- error: `非法的 API 名称: ${normalizedName.error}`,
30
- exitCode: ExitCode.GENERAL_ERROR
31
- });
32
- }
33
- const name = normalizedName.name;
34
- const pascalName = toPascalCase(name);
35
- const camelName = toCamelCase(name);
36
- const method = (options.method || 'get').toLowerCase();
37
- const appContext = findAppContext(options.cwd || process.cwd());
38
- const apiDir = join(appContext.srcDir, 'api');
39
- const targetApiFile = join(apiDir, `${name}.api.ts`);
40
- const indexPath = join(apiDir, 'index.ts');
41
- const httpClientPath = join(apiDir, 'http-client.ts');
42
- if (existsSync(targetApiFile)) {
43
- fail({
44
- command: 'generate.api',
45
- error: `API 文件已存在: ${targetApiFile}`,
46
- exitCode: ExitCode.TARGET_CONFLICT
47
- });
48
- }
49
- const hasHttpClient = existsSync(httpClientPath);
50
- const clientPath = options.client || './http-client';
51
- if (!hasHttpClient && !options.client && !options.initClient) {
52
- fail({
53
- command: 'generate.api',
54
- error: '未发现现有 HTTP client (src/api/http-client.ts)。请使用 --init-client 初始化标准客户端,或通过 --client <path> 指定已有客户端路径。',
55
- exitCode: ExitCode.GENERAL_ERROR
56
- });
57
- }
58
- const transaction = new Transaction();
59
- const spinner = createSpinner(`正在生成 API: ${name}...`);
60
- spinner.start();
61
- try {
62
- if (!existsSync(apiDir)) {
63
- mkdirSync(apiDir, { recursive: true });
64
- transaction.recordCreatedDir(apiDir);
65
- }
66
- const filesCreated = [];
67
- const filesModified = [];
68
- // 1. 若需要且不存在,初始化标准 http-client.ts
69
- if (!hasHttpClient && options.initClient) {
70
- transaction.prepareWrite(httpClientPath);
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { findAppContext, normalizeGeneratorName, toPascalCase, toCamelCase } from './common.js';
4
+ import { Transaction } from '../../common/transaction.js';
5
+ import { sendJson, logInfo, fail, setJsonMode, createSpinner } from '../../common/output.js';
6
+ import { ExitCode } from '../../common/constant.js';
7
+ export async function generateApi(rawName, options = {}) {
8
+ const isJson = !!options.json;
9
+ setJsonMode(isJson);
10
+ if (!rawName) {
11
+ fail({
12
+ command: 'generate.api',
13
+ error: '必须指定 API 模块名称: farris-cli generate api <name>',
14
+ exitCode: ExitCode.GENERAL_ERROR
15
+ });
16
+ }
17
+ const { endpoint } = options;
18
+ if (!endpoint || typeof endpoint !== 'string' || !endpoint.trim()) {
19
+ fail({
20
+ command: 'generate.api',
21
+ error: '必须指定真实 API endpoint (--endpoint <path>),如: --endpoint /api/v1/orders',
22
+ exitCode: ExitCode.GENERAL_ERROR
23
+ });
24
+ }
25
+ const normalizedName = normalizeGeneratorName(rawName);
26
+ if (!normalizedName.valid) {
27
+ fail({
28
+ command: 'generate.api',
29
+ error: `非法的 API 名称: ${normalizedName.error}`,
30
+ exitCode: ExitCode.GENERAL_ERROR
31
+ });
32
+ }
33
+ const name = normalizedName.name;
34
+ const pascalName = toPascalCase(name);
35
+ const camelName = toCamelCase(name);
36
+ const method = (options.method || 'get').toLowerCase();
37
+ const appContext = findAppContext(options.cwd || process.cwd());
38
+ const apiDir = join(appContext.srcDir, 'api');
39
+ const targetApiFile = join(apiDir, `${name}.api.ts`);
40
+ const indexPath = join(apiDir, 'index.ts');
41
+ const httpClientPath = join(apiDir, 'http-client.ts');
42
+ if (existsSync(targetApiFile)) {
43
+ fail({
44
+ command: 'generate.api',
45
+ error: `API 文件已存在: ${targetApiFile}`,
46
+ exitCode: ExitCode.TARGET_CONFLICT
47
+ });
48
+ }
49
+ const hasHttpClient = existsSync(httpClientPath);
50
+ const clientPath = options.client || './http-client';
51
+ if (!hasHttpClient && !options.client && !options.initClient) {
52
+ fail({
53
+ command: 'generate.api',
54
+ error: '未发现现有 HTTP client (src/api/http-client.ts)。请使用 --init-client 初始化标准客户端,或通过 --client <path> 指定已有客户端路径。',
55
+ exitCode: ExitCode.GENERAL_ERROR
56
+ });
57
+ }
58
+ const transaction = new Transaction();
59
+ const spinner = createSpinner(`正在生成 API: ${name}...`);
60
+ spinner.start();
61
+ try {
62
+ if (!existsSync(apiDir)) {
63
+ mkdirSync(apiDir, { recursive: true });
64
+ transaction.recordCreatedDir(apiDir);
65
+ }
66
+ const filesCreated = [];
67
+ const filesModified = [];
68
+ // 1. 若需要且不存在,初始化标准 http-client.ts
69
+ if (!hasHttpClient && options.initClient) {
70
+ transaction.prepareWrite(httpClientPath);
71
71
  const clientContent = `/**
72
72
  * Farris 标准 HTTP 请求客户端封装
73
73
  */
@@ -106,12 +106,12 @@ export async function request<T = any>(url: string, options: RequestOptions = {}
106
106
 
107
107
  return response.json();
108
108
  }
109
- `;
110
- writeFileSync(httpClientPath, clientContent, 'utf-8');
111
- filesCreated.push(httpClientPath);
112
- }
113
- // 2. 生成 API 文件: src/api/<name>.api.ts
114
- transaction.prepareWrite(targetApiFile);
109
+ `;
110
+ writeFileSync(httpClientPath, clientContent, 'utf-8');
111
+ filesCreated.push(httpClientPath);
112
+ }
113
+ // 2. 生成 API 文件: src/api/<name>.api.ts
114
+ transaction.prepareWrite(targetApiFile);
115
115
  const apiFunctionContent = `import { request } from ${JSON.stringify(clientPath)};
116
116
 
117
117
  export interface ${pascalName}Item {
@@ -137,52 +137,52 @@ export async function get${pascalName}List(params?: ${pascalName}Params): Promis
137
137
  params
138
138
  });
139
139
  }
140
- `;
141
- writeFileSync(targetApiFile, apiFunctionContent, 'utf-8');
142
- filesCreated.push(targetApiFile);
143
- // 3. 维护 src/api/index.ts
144
- transaction.prepareWrite(indexPath);
145
- let indexContent = existsSync(indexPath) ? readFileSync(indexPath, 'utf-8') : '';
146
- const exportStatement = `export * from './${name}.api';\n`;
147
- if (!indexContent.includes(`./${name}.api`)) {
148
- indexContent += exportStatement;
149
- writeFileSync(indexPath, indexContent, 'utf-8');
150
- if (existsSync(indexPath)) {
151
- filesModified.push(indexPath);
152
- }
153
- else {
154
- filesCreated.push(indexPath);
155
- }
156
- }
157
- transaction.commit();
158
- spinner.succeed(`API ${name} 生成成功!`);
159
- if (isJson) {
160
- sendJson({
161
- command: 'generate.api',
162
- ok: true,
163
- apiName: name,
164
- endpoint,
165
- method,
166
- targetApiFile,
167
- filesCreated,
168
- filesModified
169
- });
170
- return;
171
- }
172
- logInfo(`\n✨ 已成功生成 API: src/api/${name}.api.ts`);
173
- filesCreated.forEach((f) => logInfo(` + ${f}`));
174
- if (filesModified.length > 0) {
175
- filesModified.forEach((f) => logInfo(` ~ ${f} (更新导出)`));
176
- }
177
- }
178
- catch (err) {
179
- spinner.fail('生成 API 失败,正在回滚...');
180
- transaction.rollback();
181
- fail({
182
- command: 'generate.api',
183
- error: `生成 API 失败: ${err.message}`,
184
- exitCode: ExitCode.GENERAL_ERROR
185
- });
186
- }
187
- }
140
+ `;
141
+ writeFileSync(targetApiFile, apiFunctionContent, 'utf-8');
142
+ filesCreated.push(targetApiFile);
143
+ // 3. 维护 src/api/index.ts
144
+ transaction.prepareWrite(indexPath);
145
+ let indexContent = existsSync(indexPath) ? readFileSync(indexPath, 'utf-8') : '';
146
+ const exportStatement = `export * from './${name}.api';\n`;
147
+ if (!indexContent.includes(`./${name}.api`)) {
148
+ indexContent += exportStatement;
149
+ writeFileSync(indexPath, indexContent, 'utf-8');
150
+ if (existsSync(indexPath)) {
151
+ filesModified.push(indexPath);
152
+ }
153
+ else {
154
+ filesCreated.push(indexPath);
155
+ }
156
+ }
157
+ transaction.commit();
158
+ spinner.succeed(`API ${name} 生成成功!`);
159
+ if (isJson) {
160
+ sendJson({
161
+ command: 'generate.api',
162
+ ok: true,
163
+ apiName: name,
164
+ endpoint,
165
+ method,
166
+ targetApiFile,
167
+ filesCreated,
168
+ filesModified
169
+ });
170
+ return;
171
+ }
172
+ logInfo(`\n✨ 已成功生成 API: src/api/${name}.api.ts`);
173
+ filesCreated.forEach((f) => logInfo(` + ${f}`));
174
+ if (filesModified.length > 0) {
175
+ filesModified.forEach((f) => logInfo(` ~ ${f} (更新导出)`));
176
+ }
177
+ }
178
+ catch (err) {
179
+ spinner.fail('生成 API 失败,正在回滚...');
180
+ transaction.rollback();
181
+ fail({
182
+ command: 'generate.api',
183
+ error: `生成 API 失败: ${err.message}`,
184
+ exitCode: ExitCode.GENERAL_ERROR
185
+ });
186
+ }
187
+ }
188
188
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/commands/generate/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/commands/generate/api.ts"],"names":[],"mappings":"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"}
@@ -1,101 +1,101 @@
1
- import { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';
2
- import { resolve, join, dirname } from 'node:path';
3
- import { fail } from '../../common/output.js';
4
- import { ExitCode } from '../../common/constant.js';
5
- export function toKebabCase(str) {
6
- return str
7
- .replace(/([a-z])([A-Z])/g, '$1-$2')
8
- .replace(/[\s_]+/g, '-')
9
- .toLowerCase()
10
- .replace(/^-+|-+$/g, '');
11
- }
12
- /**
13
- * 生成器名称必须可安全地映射为文件名和 TypeScript 标识符。
14
- * 先校验原始输入,避免 toKebabCase 保留路径分隔符后造成目录穿越。
15
- */
16
- export function normalizeGeneratorName(value) {
17
- const raw = typeof value === 'string' ? value.trim() : '';
18
- if (!raw) {
19
- return { valid: false, error: '名称不能为空' };
20
- }
21
- if (!/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/.test(raw)) {
22
- return {
23
- valid: false,
24
- error: '名称仅支持字母、数字和短横线,且不能以短横线开头或结尾'
25
- };
26
- }
27
- return { valid: true, name: toKebabCase(raw) };
28
- }
29
- export function toPascalCase(str) {
30
- const kebab = toKebabCase(str);
31
- return kebab
32
- .split('-')
33
- .filter(Boolean)
34
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
35
- .join('');
36
- }
37
- export function toCamelCase(str) {
38
- const pascal = toPascalCase(str);
39
- return pascal.charAt(0).toLowerCase() + pascal.slice(1);
40
- }
41
- export function toReadableTitle(str) {
42
- const kebab = toKebabCase(str);
43
- return kebab
44
- .split('-')
45
- .filter(Boolean)
46
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
47
- .join(' ');
48
- }
49
- /**
50
- * 向上查找当前所在应用目录
51
- */
52
- export function findAppContext(startDir = process.cwd()) {
53
- let current = resolve(startDir);
54
- while (true) {
55
- const pkgPath = join(current, 'package.json');
56
- const srcPath = join(current, 'src');
57
- if (existsSync(pkgPath) && existsSync(srcPath) && statSync(srcPath).isDirectory()) {
58
- try {
59
- const pkgContent = JSON.parse(readFileSync(pkgPath, 'utf-8'));
60
- // 排除根 workspace 的 package.json (根一般有 pnpm-workspace.yaml 且无 src)
61
- return {
62
- appRoot: current,
63
- srcDir: srcPath,
64
- pkgJsonPath: pkgPath,
65
- pkgJson: pkgContent
66
- };
67
- }
68
- catch {
69
- // 继续查找
70
- }
71
- }
72
- const parent = dirname(current);
73
- if (parent === current) {
74
- break;
75
- }
76
- current = parent;
77
- }
78
- // 检查是否在 workspace 根目录执行
79
- const wsYaml = join(startDir, 'pnpm-workspace.yaml');
80
- if (existsSync(wsYaml)) {
81
- const packagesDir = join(startDir, 'packages');
82
- if (existsSync(packagesDir)) {
83
- const apps = readdirSync(packagesDir).filter((d) => statSync(join(packagesDir, d)).isDirectory());
84
- if (apps.length === 1) {
85
- const singleAppDir = join(packagesDir, apps[0]);
86
- return findAppContext(singleAppDir);
87
- }
88
- fail({
89
- command: 'generate',
90
- error: `当前处于 Workspace 根目录,存在多个应用 (${apps.join(', ')})。请先进入具体应用目录 (如 cd packages/${apps[0]}) 后再执行 generate 命令。`,
91
- exitCode: ExitCode.GENERAL_ERROR
92
- });
93
- }
94
- }
95
- fail({
96
- command: 'generate',
97
- error: '未找到合法的前端应用工程目录 (必须包含 package.json 与 src/ 目录)',
98
- exitCode: ExitCode.GENERAL_ERROR
99
- });
100
- }
1
+ import { existsSync, readdirSync, statSync, readFileSync } from 'node:fs';
2
+ import { resolve, join, dirname } from 'node:path';
3
+ import { fail } from '../../common/output.js';
4
+ import { ExitCode } from '../../common/constant.js';
5
+ export function toKebabCase(str) {
6
+ return str
7
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
8
+ .replace(/[\s_]+/g, '-')
9
+ .toLowerCase()
10
+ .replace(/^-+|-+$/g, '');
11
+ }
12
+ /**
13
+ * 生成器名称必须可安全地映射为文件名和 TypeScript 标识符。
14
+ * 先校验原始输入,避免 toKebabCase 保留路径分隔符后造成目录穿越。
15
+ */
16
+ export function normalizeGeneratorName(value) {
17
+ const raw = typeof value === 'string' ? value.trim() : '';
18
+ if (!raw) {
19
+ return { valid: false, error: '名称不能为空' };
20
+ }
21
+ if (!/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/.test(raw)) {
22
+ return {
23
+ valid: false,
24
+ error: '名称仅支持字母、数字和短横线,且不能以短横线开头或结尾'
25
+ };
26
+ }
27
+ return { valid: true, name: toKebabCase(raw) };
28
+ }
29
+ export function toPascalCase(str) {
30
+ const kebab = toKebabCase(str);
31
+ return kebab
32
+ .split('-')
33
+ .filter(Boolean)
34
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
35
+ .join('');
36
+ }
37
+ export function toCamelCase(str) {
38
+ const pascal = toPascalCase(str);
39
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
40
+ }
41
+ export function toReadableTitle(str) {
42
+ const kebab = toKebabCase(str);
43
+ return kebab
44
+ .split('-')
45
+ .filter(Boolean)
46
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
47
+ .join(' ');
48
+ }
49
+ /**
50
+ * 向上查找当前所在应用目录
51
+ */
52
+ export function findAppContext(startDir = process.cwd()) {
53
+ let current = resolve(startDir);
54
+ while (true) {
55
+ const pkgPath = join(current, 'package.json');
56
+ const srcPath = join(current, 'src');
57
+ if (existsSync(pkgPath) && existsSync(srcPath) && statSync(srcPath).isDirectory()) {
58
+ try {
59
+ const pkgContent = JSON.parse(readFileSync(pkgPath, 'utf-8'));
60
+ // 排除根 workspace 的 package.json (根一般有 pnpm-workspace.yaml 且无 src)
61
+ return {
62
+ appRoot: current,
63
+ srcDir: srcPath,
64
+ pkgJsonPath: pkgPath,
65
+ pkgJson: pkgContent
66
+ };
67
+ }
68
+ catch {
69
+ // 继续查找
70
+ }
71
+ }
72
+ const parent = dirname(current);
73
+ if (parent === current) {
74
+ break;
75
+ }
76
+ current = parent;
77
+ }
78
+ // 检查是否在 workspace 根目录执行
79
+ const wsYaml = join(startDir, 'pnpm-workspace.yaml');
80
+ if (existsSync(wsYaml)) {
81
+ const packagesDir = join(startDir, 'packages');
82
+ if (existsSync(packagesDir)) {
83
+ const apps = readdirSync(packagesDir).filter((d) => statSync(join(packagesDir, d)).isDirectory());
84
+ if (apps.length === 1) {
85
+ const singleAppDir = join(packagesDir, apps[0]);
86
+ return findAppContext(singleAppDir);
87
+ }
88
+ fail({
89
+ command: 'generate',
90
+ error: `当前处于 Workspace 根目录,存在多个应用 (${apps.join(', ')})。请先进入具体应用目录 (如 cd packages/${apps[0]}) 后再执行 generate 命令。`,
91
+ exitCode: ExitCode.GENERAL_ERROR
92
+ });
93
+ }
94
+ }
95
+ fail({
96
+ command: 'generate',
97
+ error: '未找到合法的前端应用工程目录 (必须包含 package.json 与 src/ 目录)',
98
+ exitCode: ExitCode.GENERAL_ERROR
99
+ });
100
+ }
101
101
  //# sourceMappingURL=common.js.map