@farris/cli 2.2.5 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands/add-app.js +6 -0
- package/lib/commands/add-app.js.map +1 -0
- package/lib/commands/add-lib.js +6 -0
- package/lib/commands/add-lib.js.map +1 -0
- package/lib/commands/add-project.js +194 -0
- package/lib/commands/add-project.js.map +1 -0
- package/lib/commands/build-components.js +57 -50
- package/lib/commands/build-components.js.map +1 -1
- package/lib/commands/build-css.js +38 -38
- package/lib/commands/build-css.js.map +1 -1
- package/lib/commands/build-lib.js +30 -25
- package/lib/commands/build-lib.js.map +1 -1
- package/lib/commands/build.js +19 -14
- package/lib/commands/build.js.map +1 -1
- package/lib/commands/create-app-options.js +72 -74
- package/lib/commands/create-app-options.js.map +1 -1
- package/lib/commands/create-app.js +131 -126
- package/lib/commands/create-app.js.map +1 -1
- package/lib/commands/create-options.js +32 -29
- package/lib/commands/create-options.js.map +1 -1
- package/lib/commands/create.js +277 -224
- package/lib/commands/create.js.map +1 -1
- package/lib/commands/dev-serve.js +18 -18
- package/lib/commands/extract-i18n.js +74 -74
- package/lib/commands/extract-i18n.js.map +1 -1
- package/lib/commands/generate/api.js +124 -124
- package/lib/commands/generate/api.js.map +1 -1
- package/lib/commands/generate/common.js +101 -100
- package/lib/commands/generate/common.js.map +1 -1
- package/lib/commands/generate/component.js +156 -156
- package/lib/commands/generate/component.js.map +1 -1
- package/lib/commands/generate/view.js +168 -168
- package/lib/commands/generate/view.js.map +1 -1
- package/lib/commands/preview-serve.js +16 -16
- package/lib/commands/workspace/add-app.js +15 -180
- package/lib/commands/workspace/add-app.js.map +1 -1
- package/lib/commands/workspace/create.js +62 -379
- package/lib/commands/workspace/create.js.map +1 -1
- package/lib/commands/workspace/inspect.js +30 -30
- package/lib/commands/workspace/inspect.js.map +1 -1
- package/lib/commands/workspace/verify.js +38 -38
- package/lib/commands/workspace/verify.js.map +1 -1
- package/lib/common/agents-doc.js +34 -0
- package/lib/common/agents-doc.js.map +1 -0
- package/lib/common/apply-catalog-deps.js +15 -15
- package/lib/common/apply-catalog-deps.js.map +1 -1
- package/lib/common/component-file-name.js +3 -3
- package/lib/common/constant.js +64 -64
- package/lib/common/constant.js.map +1 -1
- package/lib/common/create-app-target.js +46 -46
- package/lib/common/create-app-target.js.map +1 -1
- package/lib/common/generate-app.js +109 -85
- package/lib/common/generate-app.js.map +1 -1
- package/lib/common/get-dependencies.js +9 -9
- package/lib/common/get-farris-config.js +25 -25
- package/lib/common/get-farris-config.js.map +1 -1
- package/lib/common/get-version.js +6 -6
- package/lib/common/get-vite-config.js +106 -106
- package/lib/common/get-vite-config.js.map +1 -1
- package/lib/common/lib-package-exports.js +24 -24
- package/lib/common/lib-package-exports.js.map +1 -1
- package/lib/common/list-lib-components.js +23 -23
- package/lib/common/list-lib-components.js.map +1 -1
- package/lib/common/output.js +164 -94
- package/lib/common/output.js.map +1 -1
- package/lib/common/project-layout.js +143 -0
- package/lib/common/project-layout.js.map +1 -0
- package/lib/common/safety.js +173 -171
- package/lib/common/safety.js.map +1 -1
- package/lib/common/template-manifest.js +14 -16
- package/lib/common/template-manifest.js.map +1 -1
- package/lib/common/template-renderer.js +114 -114
- package/lib/common/template-renderer.js.map +1 -1
- package/lib/common/transaction.js +83 -83
- package/lib/common/transaction.js.map +1 -1
- package/lib/common/verifier.js +194 -150
- package/lib/common/verifier.js.map +1 -1
- package/lib/common/workspace-contract.js +86 -0
- package/lib/common/workspace-contract.js.map +1 -0
- package/lib/config/vite-app.js +13 -13
- package/lib/config/vite-common.js +20 -20
- package/lib/config/vite-common.js.map +1 -1
- package/lib/config/vite-component.js +32 -32
- package/lib/config/vite-component.js.map +1 -1
- package/lib/config/vite-lib.js +26 -26
- package/lib/index.js +234 -205
- package/lib/index.js.map +1 -1
- package/lib/plugins/create-app-package-json.js +24 -0
- package/lib/plugins/create-app-package-json.js.map +1 -0
- package/lib/plugins/create-component-style.js +44 -44
- package/lib/plugins/create-package-json.js +48 -48
- package/lib/plugins/create-package-json.js.map +1 -1
- package/lib/plugins/dts.js +8 -8
- package/lib/plugins/html-system.js +9 -9
- package/lib/plugins/replace.js +17 -17
- package/lib/plugins/systemjs-bundle.js +15 -15
- package/lib/plugins/systemjs-bundle.js.map +1 -1
- package/package.json +53 -52
- package/templates/create/.gitignore.tpl +12 -0
- package/templates/create/.npmrc.tpl +1 -0
- package/templates/create/AGENTS.md +62 -0
- package/templates/create/CLAUDE.md +1 -0
- package/templates/create/README.md +14 -1
- package/templates/create/package.json +11 -3
- package/templates/create/pnpm-workspace.yaml +2 -1
- package/templates/lib/.eslintrc.cjs +15 -0
- package/templates/lib/.gitignore.tpl +3 -0
- package/templates/lib/.prettierrc.json +8 -0
- package/templates/lib/index.html +1 -1
- package/templates/lib/package.json +39 -4
- package/templates/lib/{components → test/components}/button/button.spec.ts +3 -2
- package/templates/lib/test/components/button/button.spec.tsx +11 -0
- package/templates/lib/tsconfig.json +5 -1
- package/templates/lib/vitest.config.ts +1 -1
- package/templates/mobile/.gitignore.tpl +31 -0
- package/templates/mobile/.gitlab-ci.yml +3 -9
- package/templates/mobile/index.html +1 -1
- package/templates/mobile/package.json +14 -10
- package/templates/mobile/src/main.ts +5 -4
- package/templates/mobile/src/router/index.ts +17 -17
- package/templates/mobile/test/src/components/TheButton.spec.ts +15 -0
- package/templates/mobile/test/src/components/TheButton.spec.tsx +15 -0
- package/templates/mobile/tsconfig.json +3 -2
- package/templates/mobile/vitest.config.ts +2 -1
- package/templates/web/.gitignore.tpl +31 -0
- package/templates/web/.gitlab-ci.yml +3 -9
- package/templates/web/index.html +1 -1
- package/templates/web/package.json +14 -10
- package/templates/web/src/locales/index.ts +5 -0
- package/templates/web/src/locales/zh-CN.json +1 -0
- package/templates/web/src/main.ts +5 -2
- package/templates/web/src/router/index.ts +17 -17
- package/templates/web/src/styles/index.css +0 -0
- package/templates/web/src/styles/index.scss +0 -0
- package/templates/web/test/src/components/TheButton.spec.ts +15 -0
- package/templates/web/test/src/components/TheButton.spec.tsx +15 -0
- package/templates/web/tsconfig.json +3 -2
- package/templates/web/vitest.config.ts +2 -1
- package/lib/common/project-package-name.js +0 -5
- package/lib/common/project-package-name.js.map +0 -1
- package/templates/mobile/.changeset/README.md +0 -4
- package/templates/mobile/.changeset/config.json +0 -11
- package/templates/mobile/project.json +0 -4
- package/templates/mobile/src/components/TheButton.spec.ts +0 -8
- package/templates/web/.changeset/README.md +0 -4
- package/templates/web/.changeset/config.json +0 -11
- package/templates/web/project.json +0 -4
- package/templates/web/src/components/TheButton.spec.ts +0 -8
- package/templates/workspace/app/farris.config.mjs +0 -13
- package/templates/workspace/app/index.html +0 -12
- package/templates/workspace/app/package.json +0 -22
- package/templates/workspace/app/src/App.tsx +0 -11
- package/templates/workspace/app/src/main.ts +0 -12
- package/templates/workspace/app/src/router/index.ts +0 -16
- package/templates/workspace/app/src/views/home/composables/use-home.ts +0 -7
- package/templates/workspace/app/src/views/home/home.component.tsx +0 -15
- package/templates/workspace/app/src/views/home/index.ts +0 -4
- package/templates/workspace/app/tsconfig.json +0 -21
- package/templates/workspace/root/README.md +0 -28
- package/templates/workspace/root/package.json +0 -13
- package/templates/workspace/root/pnpm-workspace.yaml +0 -12
- /package/templates/{workspace/app → mobile}/src/locales/index.ts +0 -0
- /package/templates/{workspace/app → mobile}/src/locales/zh-CN.json +0 -0
- /package/templates/{workspace/app → mobile}/src/styles/index.css +0 -0
- /package/templates/{workspace/app → mobile}/src/styles/index.scss +0 -0
|
@@ -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":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAsBpC;;GAEG;AACH,KAAK,UAAU,UAAU,CAAC,UAAmB;IACzC,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,UAAU,IAAI,iBAAiB,CAAC;IAElD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAW,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,QAAQ,EACR,OAAO,EAEP,IAAI,EACJ,WAAW,EACX,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAWpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,UAA8B,EAAE;IACjF,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9B,WAAW,CAAC,MAAM,CAAC,CAAC;IAEpB,IAAI,CAAC,OAAO,EAAE
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/commands/generate/api.ts"],"names":[],"mappings":"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"}
|