chore: format all common files (#431)
This commit is contained in:
parent
8136ddd82d
commit
40088b0a05
|
|
@ -18,46 +18,41 @@ import type {
|
||||||
IPlugin,
|
IPlugin,
|
||||||
IHooks,
|
IHooks,
|
||||||
IPromptsHookParams,
|
IPromptsHookParams,
|
||||||
} from "rush-init-project-plugin";
|
} from 'rush-init-project-plugin';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import JSON5 from '../../autoinstallers/plugins/node_modules/json5'
|
import JSON5 from '../../autoinstallers/plugins/node_modules/json5';
|
||||||
|
|
||||||
const rushJson = JSON5.parse(
|
const rushJson = JSON5.parse(
|
||||||
readFileSync(
|
readFileSync(path.resolve(__dirname, '../../../rush.json')).toString('utf-8'),
|
||||||
path.resolve(__dirname, '../../../rush.json')
|
|
||||||
).toString('utf-8')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export default class SelectTeamPlugin implements IPlugin {
|
export default class SelectTeamPlugin implements IPlugin {
|
||||||
apply(hooks: IHooks): void {
|
apply(hooks: IHooks): void {
|
||||||
hooks.prompts.tap("SelectTeamPlugin", (prompts: IPromptsHookParams) => {
|
hooks.prompts.tap('SelectTeamPlugin', (prompts: IPromptsHookParams) => {
|
||||||
|
|
||||||
// Leave only the prefix team-
|
// Leave only the prefix team-
|
||||||
const teamNamePrefix = /^team-/;
|
const teamNamePrefix = /^team-/;
|
||||||
const choices = rushJson.allowedProjectTags.filter(
|
const choices = rushJson.allowedProjectTags
|
||||||
teamName => teamNamePrefix.test(teamName)
|
.filter(teamName => teamNamePrefix.test(teamName))
|
||||||
).map(
|
.map(teamName => teamName.replace(teamNamePrefix, ''));
|
||||||
teamName => teamName.replace(teamNamePrefix, '')
|
|
||||||
);
|
|
||||||
|
|
||||||
// Unshift an issue, causing the user to display the issue after selecting a template.
|
// Unshift an issue, causing the user to display the issue after selecting a template.
|
||||||
prompts.promptQueue.unshift({
|
prompts.promptQueue.unshift({
|
||||||
type: "list",
|
type: 'list',
|
||||||
name: "team",
|
name: 'team',
|
||||||
message: "Select your team",
|
message: 'Select your team',
|
||||||
choices,
|
choices,
|
||||||
default: 0, // Default choices [0]
|
default: 0, // Default choices [0]
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectFolderPrompt = prompts.promptQueue.find(
|
const projectFolderPrompt = prompts.promptQueue.find(
|
||||||
item => item.name === 'projectFolder'
|
item => item.name === 'projectFolder',
|
||||||
);
|
);
|
||||||
projectFolderPrompt.default = (answers) => {
|
projectFolderPrompt.default = answers => {
|
||||||
// Remove the scope from the folder name, such as @code-arch/foo - > foo
|
// Remove the scope from the folder name, such as @code-arch/foo - > foo
|
||||||
const folderDir = answers.packageName.split('/').slice(-1)[0];
|
const folderDir = answers.packageName.split('/').slice(-1)[0];
|
||||||
return `frontend/packages/${answers.team}/${folderDir}`;
|
return `frontend/packages/${answers.team}/${folderDir}`;
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,11 @@ import type { ILogger } from 'rush-init-project-plugin';
|
||||||
// eslint-disable-next-line @infra/no-deep-relative-import
|
// eslint-disable-next-line @infra/no-deep-relative-import
|
||||||
import { spawnSync } from 'child_process';
|
import { spawnSync } from 'child_process';
|
||||||
|
|
||||||
const exec = (logger: ILogger, cmd: string, args: string[]): string | undefined => {
|
const exec = (
|
||||||
|
logger: ILogger,
|
||||||
|
cmd: string,
|
||||||
|
args: string[],
|
||||||
|
): string | undefined => {
|
||||||
try {
|
try {
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
||||||
const config: IConfig = {
|
const config: IConfig = {
|
||||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||||
defaultProjectConfiguration: {
|
defaultProjectConfiguration: {
|
||||||
tags:['level-3']
|
tags: ['level-3'],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@
|
||||||
"react-dom": "~18.2.0",
|
"react-dom": "~18.2.0",
|
||||||
"storybook": "^7.6.7",
|
"storybook": "^7.6.7",
|
||||||
"stylelint": "^15.11.0",
|
"stylelint": "^15.11.0",
|
||||||
|
|
||||||
"vite-plugin-svgr": "~3.3.0",
|
"vite-plugin-svgr": "~3.3.0",
|
||||||
"vitest": "~3.0.5"
|
"vitest": "~3.0.5"
|
||||||
},
|
},
|
||||||
|
|
@ -49,3 +48,4 @@
|
||||||
"react-dom": ">=18.2.0"
|
"react-dom": ">=18.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
||||||
const config: IConfig = {
|
const config: IConfig = {
|
||||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||||
defaultProjectConfiguration: {
|
defaultProjectConfiguration: {
|
||||||
tags:['level-3']
|
tags: ['level-3'],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
"@coze-arch/vitest-config": "workspace:*",
|
"@coze-arch/vitest-config": "workspace:*",
|
||||||
"@types/node": "^18",
|
"@types/node": "^18",
|
||||||
"@vitest/coverage-v8": "~3.0.5",
|
"@vitest/coverage-v8": "~3.0.5",
|
||||||
|
"sucrase": "^3.32.0",
|
||||||
|
"vitest": "~3.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"vitest": "~3.0.5",
|
|
||||||
"sucrase": "^3.32.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
||||||
const config: IConfig = {
|
const config: IConfig = {
|
||||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||||
defaultProjectConfiguration: {
|
defaultProjectConfiguration: {
|
||||||
tags:['level-4']
|
tags: ['level-4'],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@coze-arch/eslint-config": "workspace:*",
|
"@coze-arch/eslint-config": "workspace:*",
|
||||||
|
"@coze-arch/stylelint-config": "workspace:*",
|
||||||
"@coze-arch/ts-config": "workspace:*",
|
"@coze-arch/ts-config": "workspace:*",
|
||||||
"@coze-arch/vitest-config": "workspace:*",
|
"@coze-arch/vitest-config": "workspace:*",
|
||||||
"@coze-arch/stylelint-config": "workspace:*",
|
|
||||||
"@rsbuild/core": "^0.2.18",
|
"@rsbuild/core": "^0.2.18",
|
||||||
"@rsbuild/plugin-react": "^0.2.18",
|
"@rsbuild/plugin-react": "^0.2.18",
|
||||||
"@slardar/web": "1.7.0",
|
"@slardar/web": "1.7.0",
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
"postcss": "^8.4.32",
|
"postcss": "^8.4.32",
|
||||||
"postcss-loader": "^7.3.3",
|
"postcss-loader": "^7.3.3",
|
||||||
"tailwindcss": "~3.3.3",
|
"tailwindcss": "~3.3.3",
|
||||||
|
|
||||||
"vitest": "~3.0.5"
|
"vitest": "~3.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
||||||
const config: IConfig = {
|
const config: IConfig = {
|
||||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||||
defaultProjectConfiguration: {
|
defaultProjectConfiguration: {
|
||||||
tags:['level-4']
|
tags: ['level-4'],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@
|
||||||
"test:cov": "npm run test -- --coverage"
|
"test:cov": "npm run test -- --coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@coze-arch/bot-api": "workspace:*",
|
||||||
|
"@coze-arch/i18n": "workspace:*",
|
||||||
|
"@coze-arch/logger": "workspace:*",
|
||||||
"@douyinfe/semi-icons": "^2.36.0",
|
"@douyinfe/semi-icons": "^2.36.0",
|
||||||
"@douyinfe/semi-ui": "2.61.0",
|
"@douyinfe/semi-ui": "2.61.0",
|
||||||
"immer": "^10.0.3",
|
"immer": "^10.0.3",
|
||||||
|
|
@ -23,18 +26,15 @@
|
||||||
"react-dom": "~18.2.0",
|
"react-dom": "~18.2.0",
|
||||||
"react-error-boundary": "^4.0.9",
|
"react-error-boundary": "^4.0.9",
|
||||||
"react-router-dom": "^6.11.1",
|
"react-router-dom": "^6.11.1",
|
||||||
"zustand": "^4.4.7",
|
"zustand": "^4.4.7"
|
||||||
"@coze-arch/logger": "workspace:*",
|
|
||||||
"@coze-arch/i18n": "workspace:*",
|
|
||||||
"@coze-arch/bot-api": "workspace:*"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@douyinfe/semi-rspack-plugin": "~2.48.0",
|
|
||||||
"@edenx/plugin-tailwind": "1.51.0",
|
|
||||||
"@coze-arch/eslint-config": "workspace:*",
|
"@coze-arch/eslint-config": "workspace:*",
|
||||||
|
"@coze-arch/stylelint-config": "workspace:*",
|
||||||
"@coze-arch/ts-config": "workspace:*",
|
"@coze-arch/ts-config": "workspace:*",
|
||||||
"@coze-arch/vitest-config": "workspace:*",
|
"@coze-arch/vitest-config": "workspace:*",
|
||||||
"@coze-arch/stylelint-config": "workspace:*",
|
"@douyinfe/semi-rspack-plugin": "~2.48.0",
|
||||||
|
"@edenx/plugin-tailwind": "1.51.0",
|
||||||
"@rspack/cli": "0.4.0",
|
"@rspack/cli": "0.4.0",
|
||||||
"@rspack/core": "0.4.0",
|
"@rspack/core": "0.4.0",
|
||||||
"@rspack/plugin-react-refresh": "0.4.0",
|
"@rspack/plugin-react-refresh": "0.4.0",
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
"tailwindcss": "~3.3.3",
|
"tailwindcss": "~3.3.3",
|
||||||
"ts-morph": "^20.0.0",
|
"ts-morph": "^20.0.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
|
|
||||||
"vitest": "~3.0.5"
|
"vitest": "~3.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ browserClient('init', {
|
||||||
bid: '',
|
bid: '',
|
||||||
});
|
});
|
||||||
browserClient('start');
|
browserClient('start');
|
||||||
reporter.init(browserClient)
|
reporter.init(browserClient);
|
||||||
|
|
||||||
const root = createRoot(document.getElementById('root'));
|
const root = createRoot(document.getElementById('root'));
|
||||||
root.render(<RouterProvider router={router} />);
|
root.render(<RouterProvider router={router} />);
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
||||||
const config: IConfig = {
|
const config: IConfig = {
|
||||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||||
defaultProjectConfiguration: {
|
defaultProjectConfiguration: {
|
||||||
tags:['level-3']
|
tags: ['level-3'],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
"description": "{{ description }}",
|
"description": "{{ description }}",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"author": "{{ authorName }}",
|
"author": "{{ authorName }}",
|
||||||
"maintainers": [
|
"maintainers": [],
|
||||||
],
|
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"unpkg": "./dist/umd/index.js",
|
"unpkg": "./dist/umd/index.js",
|
||||||
"module": "./dist/esm/index.js",
|
"module": "./dist/esm/index.js",
|
||||||
|
|
@ -63,7 +62,6 @@
|
||||||
"storybook": "^7.6.7",
|
"storybook": "^7.6.7",
|
||||||
"stylelint": "^15.11.0",
|
"stylelint": "^15.11.0",
|
||||||
"tailwindcss": "~3.3.3",
|
"tailwindcss": "~3.3.3",
|
||||||
|
|
||||||
"vite-plugin-svgr": "~3.3.0",
|
"vite-plugin-svgr": "~3.3.0",
|
||||||
"vitest": "~3.0.5"
|
"vitest": "~3.0.5"
|
||||||
},
|
},
|
||||||
|
|
@ -72,3 +70,4 @@
|
||||||
"react-dom": ">=18.2.0"
|
"react-dom": ">=18.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@
|
||||||
"@eslint/compat": "^1.2.2"
|
"@eslint/compat": "^1.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,4 @@
|
||||||
"@types/node": "^18.6.3"
|
"@types/node": "^18.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,4 @@
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import { Command } from 'commander';
|
import { Command } from 'commander';
|
||||||
import { CliOptions } from '../types/config';
|
import { CliOptions } from '../types/config';
|
||||||
|
|
||||||
|
|
@ -14,7 +30,11 @@ export const createProgram = (): Command => {
|
||||||
|
|
||||||
program
|
program
|
||||||
.requiredOption('-r, --root <directory>', '需要处理的根目录')
|
.requiredOption('-r, --root <directory>', '需要处理的根目录')
|
||||||
.option('-e, --exts <extensions>', '文件扩展名,用逗号分隔 (例: ts,js,go)', '')
|
.option(
|
||||||
|
'-e, --exts <extensions>',
|
||||||
|
'文件扩展名,用逗号分隔 (例: ts,js,go)',
|
||||||
|
'',
|
||||||
|
)
|
||||||
.option('--access-key-id <key>', '火山引擎 Access Key ID')
|
.option('--access-key-id <key>', '火山引擎 Access Key ID')
|
||||||
.option('--secret-access-key <key>', '火山引擎 Secret Access Key')
|
.option('--secret-access-key <key>', '火山引擎 Secret Access Key')
|
||||||
.option('--region <region>', '火山引擎服务区域', 'cn-beijing')
|
.option('--region <region>', '火山引擎服务区域', 'cn-beijing')
|
||||||
|
|
@ -48,7 +68,7 @@ export const parseOptions = (program: Command): CliOptions => {
|
||||||
dryRun: options.dryRun,
|
dryRun: options.dryRun,
|
||||||
verbose: options.verbose,
|
verbose: options.verbose,
|
||||||
output: options.output,
|
output: options.output,
|
||||||
config: options.config
|
config: options.config,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,25 @@
|
||||||
import { AppConfig, CliOptions, TranslationConfig, ProcessingConfig } from '../types/config';
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
AppConfig,
|
||||||
|
CliOptions,
|
||||||
|
TranslationConfig,
|
||||||
|
ProcessingConfig,
|
||||||
|
} from '../types/config';
|
||||||
import { deepMerge } from '../utils/fp';
|
import { deepMerge } from '../utils/fp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -13,28 +34,63 @@ const DEFAULT_CONFIG: AppConfig = {
|
||||||
targetLanguage: 'en',
|
targetLanguage: 'en',
|
||||||
maxRetries: 3,
|
maxRetries: 3,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
concurrency: 3
|
concurrency: 3,
|
||||||
},
|
},
|
||||||
processing: {
|
processing: {
|
||||||
defaultExtensions: [
|
defaultExtensions: [
|
||||||
'ts', 'tsx', 'js', 'jsx', 'go', 'md', 'txt', 'json',
|
'ts',
|
||||||
'yaml', 'yml', 'toml', 'ini', 'conf', 'config',
|
'tsx',
|
||||||
'sh', 'bash', 'zsh', 'fish', 'py', 'css', 'scss', 'sass', 'less',
|
'js',
|
||||||
'html', 'htm', 'xml', 'php', 'rb', 'rs', 'java', 'c', 'h',
|
'jsx',
|
||||||
'cpp', 'cxx', 'cc', 'hpp', 'cs', 'thrift'
|
'go',
|
||||||
|
'md',
|
||||||
|
'txt',
|
||||||
|
'json',
|
||||||
|
'yaml',
|
||||||
|
'yml',
|
||||||
|
'toml',
|
||||||
|
'ini',
|
||||||
|
'conf',
|
||||||
|
'config',
|
||||||
|
'sh',
|
||||||
|
'bash',
|
||||||
|
'zsh',
|
||||||
|
'fish',
|
||||||
|
'py',
|
||||||
|
'css',
|
||||||
|
'scss',
|
||||||
|
'sass',
|
||||||
|
'less',
|
||||||
|
'html',
|
||||||
|
'htm',
|
||||||
|
'xml',
|
||||||
|
'php',
|
||||||
|
'rb',
|
||||||
|
'rs',
|
||||||
|
'java',
|
||||||
|
'c',
|
||||||
|
'h',
|
||||||
|
'cpp',
|
||||||
|
'cxx',
|
||||||
|
'cc',
|
||||||
|
'hpp',
|
||||||
|
'cs',
|
||||||
|
'thrift',
|
||||||
],
|
],
|
||||||
outputFormat: 'console'
|
outputFormat: 'console',
|
||||||
},
|
},
|
||||||
git: {
|
git: {
|
||||||
ignorePatterns: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
|
ignorePatterns: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
|
||||||
includeUntracked: false
|
includeUntracked: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load configuration from file
|
* Load configuration from file
|
||||||
*/
|
*/
|
||||||
export const loadConfigFromFile = async (configPath: string): Promise<Partial<AppConfig>> => {
|
export const loadConfigFromFile = async (
|
||||||
|
configPath: string,
|
||||||
|
): Promise<Partial<AppConfig>> => {
|
||||||
try {
|
try {
|
||||||
const fs = await import('fs/promises');
|
const fs = await import('fs/promises');
|
||||||
const configContent = await fs.readFile(configPath, 'utf-8');
|
const configContent = await fs.readFile(configPath, 'utf-8');
|
||||||
|
|
@ -48,11 +104,19 @@ export const loadConfigFromFile = async (configPath: string): Promise<Partial<Ap
|
||||||
/**
|
/**
|
||||||
* Create configuration from command line options
|
* Create configuration from command line options
|
||||||
*/
|
*/
|
||||||
export const createConfigFromOptions = (options: CliOptions): Partial<AppConfig> => {
|
export const createConfigFromOptions = (
|
||||||
|
options: CliOptions,
|
||||||
|
): Partial<AppConfig> => {
|
||||||
const config: Partial<AppConfig> = {};
|
const config: Partial<AppConfig> = {};
|
||||||
|
|
||||||
// translation configuration
|
// translation configuration
|
||||||
if (options.accessKeyId || options.secretAccessKey || options.region || options.sourceLanguage || options.targetLanguage) {
|
if (
|
||||||
|
options.accessKeyId ||
|
||||||
|
options.secretAccessKey ||
|
||||||
|
options.region ||
|
||||||
|
options.sourceLanguage ||
|
||||||
|
options.targetLanguage
|
||||||
|
) {
|
||||||
config.translation = {} as Partial<TranslationConfig>;
|
config.translation = {} as Partial<TranslationConfig>;
|
||||||
if (options.accessKeyId) {
|
if (options.accessKeyId) {
|
||||||
config.translation!.accessKeyId = options.accessKeyId;
|
config.translation!.accessKeyId = options.accessKeyId;
|
||||||
|
|
@ -90,10 +154,9 @@ export const createConfigFromOptions = (options: CliOptions): Partial<AppConfig>
|
||||||
* merge configuration
|
* merge configuration
|
||||||
*/
|
*/
|
||||||
export const mergeConfigs = (...configs: Partial<AppConfig>[]): AppConfig => {
|
export const mergeConfigs = (...configs: Partial<AppConfig>[]): AppConfig => {
|
||||||
return configs.reduce(
|
return configs.reduce((merged, config) => deepMerge(merged, config), {
|
||||||
(merged, config) => deepMerge(merged, config),
|
...DEFAULT_CONFIG,
|
||||||
{ ...DEFAULT_CONFIG }
|
}) as AppConfig;
|
||||||
) as AppConfig;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -118,41 +181,65 @@ export const loadConfig = async (options: CliOptions): Promise<AppConfig> => {
|
||||||
/**
|
/**
|
||||||
* verify configuration
|
* verify configuration
|
||||||
*/
|
*/
|
||||||
export const validateConfig = (config: AppConfig): { valid: boolean; errors: string[] } => {
|
export const validateConfig = (
|
||||||
|
config: AppConfig,
|
||||||
|
): { valid: boolean; errors: string[] } => {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
// Verify Volcano Engine Access Key ID
|
// Verify Volcano Engine Access Key ID
|
||||||
if (!config.translation.accessKeyId) {
|
if (!config.translation.accessKeyId) {
|
||||||
errors.push('火山引擎 Access Key ID 未设置,请通过环境变量VOLC_ACCESS_KEY_ID或--access-key-id参数提供');
|
errors.push(
|
||||||
|
'火山引擎 Access Key ID 未设置,请通过环境变量VOLC_ACCESS_KEY_ID或--access-key-id参数提供',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Volcano Engine Secret Access Key
|
// Verify Volcano Engine Secret Access Key
|
||||||
if (!config.translation.secretAccessKey) {
|
if (!config.translation.secretAccessKey) {
|
||||||
errors.push('火山引擎 Secret Access Key 未设置,请通过环境变量VOLC_SECRET_ACCESS_KEY或--secret-access-key参数提供');
|
errors.push(
|
||||||
|
'火山引擎 Secret Access Key 未设置,请通过环境变量VOLC_SECRET_ACCESS_KEY或--secret-access-key参数提供',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validation area
|
// validation area
|
||||||
const validRegions = ['cn-beijing', 'ap-southeast-1', 'us-east-1'];
|
const validRegions = ['cn-beijing', 'ap-southeast-1', 'us-east-1'];
|
||||||
if (!validRegions.includes(config.translation.region)) {
|
if (!validRegions.includes(config.translation.region)) {
|
||||||
console.warn(`未知的区域: ${config.translation.region},建议使用: ${validRegions.join(', ')}`);
|
console.warn(
|
||||||
|
`未知的区域: ${config.translation.region},建议使用: ${validRegions.join(
|
||||||
|
', ',
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify language code
|
// Verify language code
|
||||||
const validLanguages = ['zh', 'en', 'ja', 'ko', 'fr', 'de', 'es', 'pt', 'ru'];
|
const validLanguages = ['zh', 'en', 'ja', 'ko', 'fr', 'de', 'es', 'pt', 'ru'];
|
||||||
if (!validLanguages.includes(config.translation.sourceLanguage)) {
|
if (!validLanguages.includes(config.translation.sourceLanguage)) {
|
||||||
console.warn(`未知的源语言: ${config.translation.sourceLanguage},建议使用: ${validLanguages.join(', ')}`);
|
console.warn(
|
||||||
|
`未知的源语言: ${
|
||||||
|
config.translation.sourceLanguage
|
||||||
|
},建议使用: ${validLanguages.join(', ')}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!validLanguages.includes(config.translation.targetLanguage)) {
|
if (!validLanguages.includes(config.translation.targetLanguage)) {
|
||||||
console.warn(`未知的目标语言: ${config.translation.targetLanguage},建议使用: ${validLanguages.join(', ')}`);
|
console.warn(
|
||||||
|
`未知的目标语言: ${
|
||||||
|
config.translation.targetLanguage
|
||||||
|
},建议使用: ${validLanguages.join(', ')}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validation concurrency
|
// validation concurrency
|
||||||
if (config.translation.concurrency < 1 || config.translation.concurrency > 10) {
|
if (
|
||||||
|
config.translation.concurrency < 1 ||
|
||||||
|
config.translation.concurrency > 10
|
||||||
|
) {
|
||||||
errors.push('并发数应该在1-10之间');
|
errors.push('并发数应该在1-10之间');
|
||||||
}
|
}
|
||||||
|
|
||||||
// verification timeout
|
// verification timeout
|
||||||
if (config.translation.timeout < 1000 || config.translation.timeout > 300000) {
|
if (
|
||||||
|
config.translation.timeout < 1000 ||
|
||||||
|
config.translation.timeout > 300000
|
||||||
|
) {
|
||||||
errors.push('超时时间应该在1000-300000毫秒之间');
|
errors.push('超时时间应该在1000-300000毫秒之间');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,7 +249,10 @@ export const validateConfig = (config: AppConfig): { valid: boolean; errors: str
|
||||||
/**
|
/**
|
||||||
* Print configuration information
|
* Print configuration information
|
||||||
*/
|
*/
|
||||||
export const printConfigInfo = (config: AppConfig, verbose: boolean = false): void => {
|
export const printConfigInfo = (
|
||||||
|
config: AppConfig,
|
||||||
|
verbose: boolean = false,
|
||||||
|
): void => {
|
||||||
console.log('🔧 当前配置:');
|
console.log('🔧 当前配置:');
|
||||||
console.log(` 区域: ${config.translation.region}`);
|
console.log(` 区域: ${config.translation.region}`);
|
||||||
console.log(` 源语言: ${config.translation.sourceLanguage}`);
|
console.log(` 源语言: ${config.translation.sourceLanguage}`);
|
||||||
|
|
@ -172,11 +262,23 @@ export const printConfigInfo = (config: AppConfig, verbose: boolean = false): vo
|
||||||
console.log(` 输出格式: ${config.processing.outputFormat}`);
|
console.log(` 输出格式: ${config.processing.outputFormat}`);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
console.log(` Access Key ID: ${config.translation.accessKeyId ? '已设置' : '未设置'}`);
|
console.log(
|
||||||
console.log(` Secret Access Key: ${config.translation.secretAccessKey ? '已设置' : '未设置'}`);
|
` Access Key ID: ${
|
||||||
|
config.translation.accessKeyId ? '已设置' : '未设置'
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
` Secret Access Key: ${
|
||||||
|
config.translation.secretAccessKey ? '已设置' : '未设置'
|
||||||
|
}`,
|
||||||
|
);
|
||||||
console.log(` 超时时间: ${config.translation.timeout}ms`);
|
console.log(` 超时时间: ${config.translation.timeout}ms`);
|
||||||
console.log(` 默认扩展名: ${config.processing.defaultExtensions.join(', ')}`);
|
console.log(
|
||||||
|
` 默认扩展名: ${config.processing.defaultExtensions.join(', ')}`,
|
||||||
|
);
|
||||||
console.log(` 忽略模式: ${config.git.ignorePatterns.join(', ')}`);
|
console.log(` 忽略模式: ${config.git.ignorePatterns.join(', ')}`);
|
||||||
console.log(` 包含未跟踪文件: ${config.git.includeUntracked ? '是' : '否'}`);
|
console.log(
|
||||||
|
` 包含未跟踪文件: ${config.git.includeUntracked ? '是' : '否'}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { createProgram, parseOptions, showHelp } from './cli/command';
|
import { createProgram, parseOptions, showHelp } from './cli/command';
|
||||||
|
|
@ -102,7 +118,9 @@ async function processRepository(
|
||||||
console.log(`\n📝 ${file.path}:`);
|
console.log(`\n📝 ${file.path}:`);
|
||||||
translations.forEach((translation, index) => {
|
translations.forEach((translation, index) => {
|
||||||
console.log(
|
console.log(
|
||||||
` ${index + 1}. "${translation.original}" → "${translation.translated}"`,
|
` ${index + 1}. "${translation.original}" → "${
|
||||||
|
translation.translated
|
||||||
|
}"`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -116,10 +134,7 @@ async function processRepository(
|
||||||
);
|
);
|
||||||
const operation = { file: file.path, replacements };
|
const operation = { file: file.path, replacements };
|
||||||
|
|
||||||
const result = await replaceCommentsInFile(
|
const result = await replaceCommentsInFile(file, operation);
|
||||||
file,
|
|
||||||
operation,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.error || '文件替换失败');
|
throw new Error(result.error || '文件替换失败');
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SourceFile,
|
SourceFile,
|
||||||
ChineseComment,
|
ChineseComment,
|
||||||
ParsedComment,
|
ParsedComment,
|
||||||
FileWithComments,
|
FileWithComments,
|
||||||
CommentType,
|
CommentType,
|
||||||
MultiLineContext
|
MultiLineContext,
|
||||||
} from '../types/index';
|
} from '../types/index';
|
||||||
import { getCommentPatterns } from '../utils/language';
|
import { getCommentPatterns } from '../utils/language';
|
||||||
import { containsChinese, cleanCommentText } from '../utils/chinese';
|
import { containsChinese, cleanCommentText } from '../utils/chinese';
|
||||||
|
|
@ -74,7 +90,9 @@ const parseSingleLineComments = (
|
||||||
// Multiple protections against infinite loops
|
// Multiple protections against infinite loops
|
||||||
matchCount++;
|
matchCount++;
|
||||||
if (matchCount > maxMatches) {
|
if (matchCount > maxMatches) {
|
||||||
console.warn(`⚠️ 单行匹配次数过多,中断处理: ${line.substring(0, 50)}...`);
|
console.warn(
|
||||||
|
`⚠️ 单行匹配次数过多,中断处理: ${line.substring(0, 50)}...`,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,7 +264,6 @@ const parseMultiLineComments = (
|
||||||
const commentContent = line.substring(0, endMatch.index!);
|
const commentContent = line.substring(0, endMatch.index!);
|
||||||
commentLines.push(commentContent);
|
commentLines.push(commentContent);
|
||||||
|
|
||||||
|
|
||||||
comments.push({
|
comments.push({
|
||||||
content: commentLines.join('\n'),
|
content: commentLines.join('\n'),
|
||||||
startLine: commentStart!.line,
|
startLine: commentStart!.line,
|
||||||
|
|
@ -302,7 +319,10 @@ export const filterChineseComments = (
|
||||||
for (const comment of comments) {
|
for (const comment of comments) {
|
||||||
if (comment.type === 'multi-line' && comment.content.includes('\n')) {
|
if (comment.type === 'multi-line' && comment.content.includes('\n')) {
|
||||||
// Multi-line comments: line-by-line processing
|
// Multi-line comments: line-by-line processing
|
||||||
const multiLineResults = processMultiLineCommentForChinese(comment, language);
|
const multiLineResults = processMultiLineCommentForChinese(
|
||||||
|
comment,
|
||||||
|
language,
|
||||||
|
);
|
||||||
result.push(...multiLineResults);
|
result.push(...multiLineResults);
|
||||||
} else if (containsChinese(comment.content)) {
|
} else if (containsChinese(comment.content)) {
|
||||||
// Single-line comments or single-line multi-line comments
|
// Single-line comments or single-line multi-line comments
|
||||||
|
|
@ -350,8 +370,8 @@ const processMultiLineCommentForChinese = (
|
||||||
isPartOfMultiLine: true,
|
isPartOfMultiLine: true,
|
||||||
originalComment: comment,
|
originalComment: comment,
|
||||||
lineIndexInComment: lineIndex,
|
lineIndexInComment: lineIndex,
|
||||||
totalLinesInComment: lines.length
|
totalLinesInComment: lines.length,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
result.push(lineComment);
|
result.push(lineComment);
|
||||||
|
|
@ -393,7 +413,9 @@ export const detectChineseInFile = (file: SourceFile): ChineseComment[] => {
|
||||||
/**
|
/**
|
||||||
* Batch detection of Chinese comments in multiple files
|
* Batch detection of Chinese comments in multiple files
|
||||||
*/
|
*/
|
||||||
export const detectChineseInFiles = (files: SourceFile[]): FileWithComments[] => {
|
export const detectChineseInFiles = (
|
||||||
|
files: SourceFile[],
|
||||||
|
): FileWithComments[] => {
|
||||||
const results: FileWithComments[] = [];
|
const results: FileWithComments[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
|
@ -428,7 +450,9 @@ export const detectChineseInFiles = (files: SourceFile[]): FileWithComments[] =>
|
||||||
/**
|
/**
|
||||||
* Get annotation statistics
|
* Get annotation statistics
|
||||||
*/
|
*/
|
||||||
export const getCommentStats = (files: SourceFile[]): {
|
export const getCommentStats = (
|
||||||
|
files: SourceFile[],
|
||||||
|
): {
|
||||||
totalFiles: number;
|
totalFiles: number;
|
||||||
filesWithComments: number;
|
filesWithComments: number;
|
||||||
totalComments: number;
|
totalComments: number;
|
||||||
|
|
@ -441,12 +465,15 @@ export const getCommentStats = (files: SourceFile[]): {
|
||||||
const commentsByType: Record<CommentType, number> = {
|
const commentsByType: Record<CommentType, number> = {
|
||||||
'single-line': 0,
|
'single-line': 0,
|
||||||
'multi-line': 0,
|
'multi-line': 0,
|
||||||
'documentation': 0
|
documentation: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
const allComments = parseComments(file);
|
const allComments = parseComments(file);
|
||||||
const chineseCommentsInFile = filterChineseComments(allComments, file.language);
|
const chineseCommentsInFile = filterChineseComments(
|
||||||
|
allComments,
|
||||||
|
file.language,
|
||||||
|
);
|
||||||
|
|
||||||
if (chineseCommentsInFile.length > 0) {
|
if (chineseCommentsInFile.length > 0) {
|
||||||
filesWithComments++;
|
filesWithComments++;
|
||||||
|
|
@ -465,6 +492,6 @@ export const getCommentStats = (files: SourceFile[]): {
|
||||||
filesWithComments,
|
filesWithComments,
|
||||||
totalComments,
|
totalComments,
|
||||||
chineseComments,
|
chineseComments,
|
||||||
commentsByType
|
commentsByType,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { SourceFile, FileScanConfig, Result } from '../types/index';
|
import { SourceFile, FileScanConfig, Result } from '../types/index';
|
||||||
import { detectLanguage, filterFilesByExtensions, isTextFile } from '../utils/language';
|
import {
|
||||||
|
detectLanguage,
|
||||||
|
filterFilesByExtensions,
|
||||||
|
isTextFile,
|
||||||
|
} from '../utils/language';
|
||||||
import { getGitTrackedFiles, getAllGitFiles } from '../utils/git';
|
import { getGitTrackedFiles, getAllGitFiles } from '../utils/git';
|
||||||
import { tryCatch } from '../utils/fp';
|
import { tryCatch } from '../utils/fp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the file contents and create a SourceFile object
|
* Read the file contents and create a SourceFile object
|
||||||
*/
|
*/
|
||||||
export const readSourceFile = async (filePath: string): Promise<Result<SourceFile>> => {
|
export const readSourceFile = async (
|
||||||
|
filePath: string,
|
||||||
|
): Promise<Result<SourceFile>> => {
|
||||||
return tryCatch(async () => {
|
return tryCatch(async () => {
|
||||||
const content = await fs.readFile(filePath, 'utf-8');
|
const content = await fs.readFile(filePath, 'utf-8');
|
||||||
const language = detectLanguage(filePath);
|
const language = detectLanguage(filePath);
|
||||||
|
|
@ -15,7 +37,7 @@ export const readSourceFile = async (filePath: string): Promise<Result<SourceFil
|
||||||
return {
|
return {
|
||||||
path: filePath,
|
path: filePath,
|
||||||
content,
|
content,
|
||||||
language
|
language,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -23,14 +45,17 @@ export const readSourceFile = async (filePath: string): Promise<Result<SourceFil
|
||||||
/**
|
/**
|
||||||
* Batch reading of source files
|
* Batch reading of source files
|
||||||
*/
|
*/
|
||||||
export const readSourceFiles = async (filePaths: string[]): Promise<SourceFile[]> => {
|
export const readSourceFiles = async (
|
||||||
|
filePaths: string[],
|
||||||
|
): Promise<SourceFile[]> => {
|
||||||
const results = await Promise.allSettled(
|
const results = await Promise.allSettled(
|
||||||
filePaths.map(path => readSourceFile(path))
|
filePaths.map(path => readSourceFile(path)),
|
||||||
);
|
);
|
||||||
|
|
||||||
return results
|
return results
|
||||||
.filter((result): result is PromiseFulfilledResult<Result<SourceFile>> =>
|
.filter(
|
||||||
result.status === 'fulfilled' && result.value.success
|
(result): result is PromiseFulfilledResult<Result<SourceFile>> =>
|
||||||
|
result.status === 'fulfilled' && result.value.success,
|
||||||
)
|
)
|
||||||
.map(result => (result.value as { success: true; data: SourceFile }).data);
|
.map(result => (result.value as { success: true; data: SourceFile }).data);
|
||||||
};
|
};
|
||||||
|
|
@ -38,7 +63,9 @@ export const readSourceFiles = async (filePaths: string[]): Promise<SourceFile[]
|
||||||
/**
|
/**
|
||||||
* Get the source code file in the Git repository
|
* Get the source code file in the Git repository
|
||||||
*/
|
*/
|
||||||
export const getSourceFiles = async (config: FileScanConfig): Promise<Result<string[]>> => {
|
export const getSourceFiles = async (
|
||||||
|
config: FileScanConfig,
|
||||||
|
): Promise<Result<string[]>> => {
|
||||||
const { root, extensions, includeUntracked } = config;
|
const { root, extensions, includeUntracked } = config;
|
||||||
|
|
||||||
return tryCatch(async () => {
|
return tryCatch(async () => {
|
||||||
|
|
@ -66,7 +93,9 @@ export const getSourceFiles = async (config: FileScanConfig): Promise<Result<str
|
||||||
/**
|
/**
|
||||||
* Scan and read all source code files
|
* Scan and read all source code files
|
||||||
*/
|
*/
|
||||||
export const scanSourceFiles = async (config: FileScanConfig): Promise<Result<SourceFile[]>> => {
|
export const scanSourceFiles = async (
|
||||||
|
config: FileScanConfig,
|
||||||
|
): Promise<Result<SourceFile[]>> => {
|
||||||
return tryCatch(async () => {
|
return tryCatch(async () => {
|
||||||
const filesResult = await getSourceFiles(config);
|
const filesResult = await getSourceFiles(config);
|
||||||
|
|
||||||
|
|
@ -94,28 +123,32 @@ export const isFileAccessible = async (filePath: string): Promise<boolean> => {
|
||||||
/**
|
/**
|
||||||
* Get file statistics
|
* Get file statistics
|
||||||
*/
|
*/
|
||||||
export const getFileStats = async (filePaths: string[]): Promise<{
|
export const getFileStats = async (
|
||||||
|
filePaths: string[],
|
||||||
|
): Promise<{
|
||||||
total: number;
|
total: number;
|
||||||
accessible: number;
|
accessible: number;
|
||||||
textFiles: number;
|
textFiles: number;
|
||||||
supportedFiles: number;
|
supportedFiles: number;
|
||||||
}> => {
|
}> => {
|
||||||
const accessibilityResults = await Promise.allSettled(
|
const accessibilityResults = await Promise.allSettled(
|
||||||
filePaths.map(isFileAccessible)
|
filePaths.map(isFileAccessible),
|
||||||
);
|
);
|
||||||
|
|
||||||
const accessible = accessibilityResults.filter(
|
const accessible = accessibilityResults.filter(
|
||||||
(result): result is PromiseFulfilledResult<boolean> =>
|
(result): result is PromiseFulfilledResult<boolean> =>
|
||||||
result.status === 'fulfilled' && result.value
|
result.status === 'fulfilled' && result.value,
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
const textFiles = filePaths.filter(isTextFile).length;
|
const textFiles = filePaths.filter(isTextFile).length;
|
||||||
const supportedFiles = filePaths.filter(path => detectLanguage(path) !== 'other').length;
|
const supportedFiles = filePaths.filter(
|
||||||
|
path => detectLanguage(path) !== 'other',
|
||||||
|
).length;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
total: filePaths.length,
|
total: filePaths.length,
|
||||||
accessible,
|
accessible,
|
||||||
textFiles,
|
textFiles,
|
||||||
supportedFiles
|
supportedFiles,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ProcessingReport,
|
ProcessingReport,
|
||||||
ProcessingStats,
|
ProcessingStats,
|
||||||
|
|
@ -203,13 +219,17 @@ export const generateMarkdownReport = (report: ProcessingReport): string => {
|
||||||
? '⏭️'
|
? '⏭️'
|
||||||
: '🔄';
|
: '🔄';
|
||||||
|
|
||||||
markdown += `| ${detail.file} | ${status} | ${detail.commentCount} | ${duration} | ${detail.errorMessage || '-'} |\n`;
|
markdown += `| ${detail.file} | ${status} | ${
|
||||||
|
detail.commentCount
|
||||||
|
} | ${duration} | ${detail.errorMessage || '-'} |\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (stats.errors.length > 0) {
|
if (stats.errors.length > 0) {
|
||||||
markdown += '\n## ❌ 错误详情\n\n';
|
markdown += '\n## ❌ 错误详情\n\n';
|
||||||
stats.errors.forEach((error, index) => {
|
stats.errors.forEach((error, index) => {
|
||||||
markdown += `${index + 1}. **${error.file}**\n \`\`\`\n ${error.error}\n \`\`\`\n\n`;
|
markdown += `${index + 1}. **${error.file}**\n \`\`\`\n ${
|
||||||
|
error.error
|
||||||
|
}\n \`\`\`\n\n`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,7 +296,9 @@ export class ProgressDisplay {
|
||||||
const speed = current / elapsed;
|
const speed = current / elapsed;
|
||||||
const eta = speed > 0 ? (this.total - current) / speed : 0;
|
const eta = speed > 0 ? (this.total - current) / speed : 0;
|
||||||
|
|
||||||
let line = `进度: ${current}/${this.total} (${percentage}%) | 耗时: ${elapsed.toFixed(1)}s`;
|
let line = `进度: ${current}/${
|
||||||
|
this.total
|
||||||
|
} (${percentage}%) | 耗时: ${elapsed.toFixed(1)}s`;
|
||||||
|
|
||||||
if (eta > 0) {
|
if (eta > 0) {
|
||||||
line += ` | 预计剩余: ${eta.toFixed(1)}s`;
|
line += ` | 预计剩余: ${eta.toFixed(1)}s`;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TranslationResult,
|
TranslationResult,
|
||||||
TranslationContext,
|
TranslationContext,
|
||||||
|
|
@ -7,7 +23,10 @@ import {
|
||||||
import { TranslationConfig } from '../types/config';
|
import { TranslationConfig } from '../types/config';
|
||||||
import { retry, chunk } from '../utils/fp';
|
import { retry, chunk } from '../utils/fp';
|
||||||
import { isValidTranslation } from '../utils/chinese';
|
import { isValidTranslation } from '../utils/chinese';
|
||||||
import { translate as volcTranslate, TranslateConfig as VolcTranslateConfig } from '../volc/translate';
|
import {
|
||||||
|
translate as volcTranslate,
|
||||||
|
TranslateConfig as VolcTranslateConfig,
|
||||||
|
} from '../volc/translate';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translation services
|
* Translation services
|
||||||
|
|
@ -101,7 +120,9 @@ export class TranslationService {
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new TranslationError(
|
throw new TranslationError(
|
||||||
`Translation failed: ${error instanceof Error ? error.message : String(error)}`,
|
`Translation failed: ${
|
||||||
|
error instanceof Error ? error.message : String(error)
|
||||||
|
}`,
|
||||||
comment,
|
comment,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -163,7 +184,10 @@ export class TranslationService {
|
||||||
const result: TranslationResult = {
|
const result: TranslationResult = {
|
||||||
original: item.comment.content,
|
original: item.comment.content,
|
||||||
translated,
|
translated,
|
||||||
confidence: this.calculateConfidence(translated, item.comment.content),
|
confidence: this.calculateConfidence(
|
||||||
|
translated,
|
||||||
|
item.comment.content,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// cache results
|
// cache results
|
||||||
|
|
@ -190,7 +214,11 @@ export class TranslationService {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
console.warn(`批量翻译失败: ${error instanceof Error ? error.message : String(error)}`);
|
console.warn(
|
||||||
|
`批量翻译失败: ${
|
||||||
|
error instanceof Error ? error.message : String(error)
|
||||||
|
}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source file language type
|
* Source file language type
|
||||||
*/
|
*/
|
||||||
|
|
@ -183,10 +199,7 @@ export type Result<T, E = Error> =
|
||||||
* translation error
|
* translation error
|
||||||
*/
|
*/
|
||||||
export class TranslationError extends Error {
|
export class TranslationError extends Error {
|
||||||
constructor(
|
constructor(message: string, public originalComment: string) {
|
||||||
message: string,
|
|
||||||
public originalComment: string,
|
|
||||||
) {
|
|
||||||
super(message);
|
super(message);
|
||||||
this.name = 'TranslationError';
|
this.name = 'TranslationError';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unicode Range Regular Expressions for Chinese Characters
|
* Unicode Range Regular Expressions for Chinese Characters
|
||||||
*/
|
*/
|
||||||
const CHINESE_REGEX = /[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]/;
|
const CHINESE_REGEX = /[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]/;
|
||||||
const CHINESE_EXTRACT_REGEX = /[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff\u3000-\u303f\uff00-\uffef]+/g;
|
const CHINESE_EXTRACT_REGEX =
|
||||||
|
/[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff\u3000-\u303f\uff00-\uffef]+/g;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect whether the text contains Chinese characters
|
* Detect whether the text contains Chinese characters
|
||||||
|
|
@ -31,7 +48,10 @@ export const countChineseCharacters = (text: string): number => {
|
||||||
/**
|
/**
|
||||||
* Detect whether the text is mainly composed of Chinese
|
* Detect whether the text is mainly composed of Chinese
|
||||||
*/
|
*/
|
||||||
export const isPrimarilyChinese = (text: string, threshold: number = 0.5): boolean => {
|
export const isPrimarilyChinese = (
|
||||||
|
text: string,
|
||||||
|
threshold: number = 0.5,
|
||||||
|
): boolean => {
|
||||||
const totalLength = text.length;
|
const totalLength = text.length;
|
||||||
if (totalLength === 0) return false;
|
if (totalLength === 0) return false;
|
||||||
|
|
||||||
|
|
@ -45,7 +65,7 @@ export const isPrimarilyChinese = (text: string, threshold: number = 0.5): boole
|
||||||
export const cleanCommentText = (
|
export const cleanCommentText = (
|
||||||
text: string,
|
text: string,
|
||||||
commentType: 'single-line' | 'multi-line',
|
commentType: 'single-line' | 'multi-line',
|
||||||
language?: string
|
language?: string,
|
||||||
): string => {
|
): string => {
|
||||||
let cleaned = text;
|
let cleaned = text;
|
||||||
|
|
||||||
|
|
@ -100,7 +120,10 @@ export const cleanCommentText = (
|
||||||
/**
|
/**
|
||||||
* Verify whether the translation result is valid.
|
* Verify whether the translation result is valid.
|
||||||
*/
|
*/
|
||||||
export const isValidTranslation = (original: string, translated: string): boolean => {
|
export const isValidTranslation = (
|
||||||
|
original: string,
|
||||||
|
translated: string,
|
||||||
|
): boolean => {
|
||||||
// basic verification
|
// basic verification
|
||||||
if (!translated || translated.trim().length === 0) {
|
if (!translated || translated.trim().length === 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import { SourceFileLanguage, CommentPattern } from '../types/index';
|
import { SourceFileLanguage, CommentPattern } from '../types/index';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -7,44 +23,44 @@ export const detectLanguage = (filePath: string): SourceFileLanguage => {
|
||||||
const ext = filePath.toLowerCase().split('.').pop();
|
const ext = filePath.toLowerCase().split('.').pop();
|
||||||
|
|
||||||
const languageMap: Record<string, SourceFileLanguage> = {
|
const languageMap: Record<string, SourceFileLanguage> = {
|
||||||
'ts': 'typescript',
|
ts: 'typescript',
|
||||||
'tsx': 'typescript',
|
tsx: 'typescript',
|
||||||
'js': 'javascript',
|
js: 'javascript',
|
||||||
'jsx': 'javascript',
|
jsx: 'javascript',
|
||||||
'go': 'go',
|
go: 'go',
|
||||||
'md': 'markdown',
|
md: 'markdown',
|
||||||
'txt': 'text',
|
txt: 'text',
|
||||||
'json': 'json',
|
json: 'json',
|
||||||
'yaml': 'yaml',
|
yaml: 'yaml',
|
||||||
'yml': 'yaml',
|
yml: 'yaml',
|
||||||
'toml': 'toml',
|
toml: 'toml',
|
||||||
'ini': 'ini',
|
ini: 'ini',
|
||||||
'conf': 'ini',
|
conf: 'ini',
|
||||||
'config': 'ini',
|
config: 'ini',
|
||||||
'sh': 'shell',
|
sh: 'shell',
|
||||||
'bash': 'shell',
|
bash: 'shell',
|
||||||
'zsh': 'shell',
|
zsh: 'shell',
|
||||||
'fish': 'shell',
|
fish: 'shell',
|
||||||
'py': 'python',
|
py: 'python',
|
||||||
'css': 'css',
|
css: 'css',
|
||||||
'scss': 'css',
|
scss: 'css',
|
||||||
'sass': 'css',
|
sass: 'css',
|
||||||
'less': 'css',
|
less: 'css',
|
||||||
'html': 'html',
|
html: 'html',
|
||||||
'htm': 'html',
|
htm: 'html',
|
||||||
'xml': 'xml',
|
xml: 'xml',
|
||||||
'php': 'php',
|
php: 'php',
|
||||||
'rb': 'ruby',
|
rb: 'ruby',
|
||||||
'rs': 'rust',
|
rs: 'rust',
|
||||||
'java': 'java',
|
java: 'java',
|
||||||
'c': 'c',
|
c: 'c',
|
||||||
'h': 'c',
|
h: 'c',
|
||||||
'cpp': 'cpp',
|
cpp: 'cpp',
|
||||||
'cxx': 'cpp',
|
cxx: 'cpp',
|
||||||
'cc': 'cpp',
|
cc: 'cpp',
|
||||||
'hpp': 'cpp',
|
hpp: 'cpp',
|
||||||
'cs': 'csharp',
|
cs: 'csharp',
|
||||||
'thrift': 'thrift'
|
thrift: 'thrift',
|
||||||
};
|
};
|
||||||
|
|
||||||
return languageMap[ext || ''] || 'other';
|
return languageMap[ext || ''] || 'other';
|
||||||
|
|
@ -55,19 +71,52 @@ export const detectLanguage = (filePath: string): SourceFileLanguage => {
|
||||||
*/
|
*/
|
||||||
export const filterFilesByExtensions = (
|
export const filterFilesByExtensions = (
|
||||||
files: string[],
|
files: string[],
|
||||||
extensions: string[]
|
extensions: string[],
|
||||||
): string[] => {
|
): string[] => {
|
||||||
if (extensions.length === 0) {
|
if (extensions.length === 0) {
|
||||||
// Default supported text file extensions
|
// Default supported text file extensions
|
||||||
const defaultExtensions = [
|
const defaultExtensions = [
|
||||||
'.ts', '.tsx', '.js', '.jsx', '.go', '.md', '.txt', '.json',
|
'.ts',
|
||||||
'.yaml', '.yml', '.toml', '.ini', '.conf', '.config',
|
'.tsx',
|
||||||
'.sh', '.bash', '.zsh', '.fish', '.py', '.css', '.scss', '.sass', '.less',
|
'.js',
|
||||||
'.html', '.htm', '.xml', '.php', '.rb', '.rs', '.java', '.c', '.h',
|
'.jsx',
|
||||||
'.cpp', '.cxx', '.cc', '.hpp', '.cs', '.thrift'
|
'.go',
|
||||||
|
'.md',
|
||||||
|
'.txt',
|
||||||
|
'.json',
|
||||||
|
'.yaml',
|
||||||
|
'.yml',
|
||||||
|
'.toml',
|
||||||
|
'.ini',
|
||||||
|
'.conf',
|
||||||
|
'.config',
|
||||||
|
'.sh',
|
||||||
|
'.bash',
|
||||||
|
'.zsh',
|
||||||
|
'.fish',
|
||||||
|
'.py',
|
||||||
|
'.css',
|
||||||
|
'.scss',
|
||||||
|
'.sass',
|
||||||
|
'.less',
|
||||||
|
'.html',
|
||||||
|
'.htm',
|
||||||
|
'.xml',
|
||||||
|
'.php',
|
||||||
|
'.rb',
|
||||||
|
'.rs',
|
||||||
|
'.java',
|
||||||
|
'.c',
|
||||||
|
'.h',
|
||||||
|
'.cpp',
|
||||||
|
'.cxx',
|
||||||
|
'.cc',
|
||||||
|
'.hpp',
|
||||||
|
'.cs',
|
||||||
|
'.thrift',
|
||||||
];
|
];
|
||||||
return files.filter(file =>
|
return files.filter(file =>
|
||||||
defaultExtensions.some(ext => file.toLowerCase().endsWith(ext))
|
defaultExtensions.some(ext => file.toLowerCase().endsWith(ext)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,123 +134,125 @@ export const filterFilesByExtensions = (
|
||||||
/**
|
/**
|
||||||
* Obtain comment modes for different programming languages
|
* Obtain comment modes for different programming languages
|
||||||
*/
|
*/
|
||||||
export const getCommentPatterns = (language: SourceFileLanguage): CommentPattern | null => {
|
export const getCommentPatterns = (
|
||||||
|
language: SourceFileLanguage,
|
||||||
|
): CommentPattern | null => {
|
||||||
const commentPatterns: Record<SourceFileLanguage, CommentPattern> = {
|
const commentPatterns: Record<SourceFileLanguage, CommentPattern> = {
|
||||||
typescript: {
|
typescript: {
|
||||||
single: /(?:^|[^:])\s*\/\/(.*)$/gm,
|
single: /(?:^|[^:])\s*\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
javascript: {
|
javascript: {
|
||||||
single: /(?:^|[^:])\s*\/\/(.*)$/gm,
|
single: /(?:^|[^:])\s*\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
go: {
|
go: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
markdown: {
|
markdown: {
|
||||||
single: /<!--(.*)-->/g,
|
single: /<!--(.*)-->/g,
|
||||||
multiStart: /<!--/g,
|
multiStart: /<!--/g,
|
||||||
multiEnd: /-->/g
|
multiEnd: /-->/g,
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
single: /^(.*)$/gm, // Every line of a text file can be a comment
|
single: /^(.*)$/gm, // Every line of a text file can be a comment
|
||||||
multiStart: /^/g,
|
multiStart: /^/g,
|
||||||
multiEnd: /$/g
|
multiEnd: /$/g,
|
||||||
},
|
},
|
||||||
json: {
|
json: {
|
||||||
single: /\/\/(.*)$/gm, // JSON usually doesn't support comments, but some tools do
|
single: /\/\/(.*)$/gm, // JSON usually doesn't support comments, but some tools do
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
yaml: {
|
yaml: {
|
||||||
single: /#(.*)$/gm,
|
single: /#(.*)$/gm,
|
||||||
multiStart: /^$/g, // YAML does not support multi-line comments
|
multiStart: /^$/g, // YAML does not support multi-line comments
|
||||||
multiEnd: /^$/g
|
multiEnd: /^$/g,
|
||||||
},
|
},
|
||||||
toml: {
|
toml: {
|
||||||
single: /#(.*)$/gm,
|
single: /#(.*)$/gm,
|
||||||
multiStart: /^$/g, // TOML does not support multi-line comments
|
multiStart: /^$/g, // TOML does not support multi-line comments
|
||||||
multiEnd: /^$/g
|
multiEnd: /^$/g,
|
||||||
},
|
},
|
||||||
ini: {
|
ini: {
|
||||||
single: /[;#](.*)$/gm, // INI file support; and #as comments
|
single: /[;#](.*)$/gm, // INI file support; and #as comments
|
||||||
multiStart: /^$/g, // INI does not support multi-line comments
|
multiStart: /^$/g, // INI does not support multi-line comments
|
||||||
multiEnd: /^$/g
|
multiEnd: /^$/g,
|
||||||
},
|
},
|
||||||
shell: {
|
shell: {
|
||||||
single: /#(.*)$/gm,
|
single: /#(.*)$/gm,
|
||||||
multiStart: /^$/g, // Shell scripts do not support multi-line comments
|
multiStart: /^$/g, // Shell scripts do not support multi-line comments
|
||||||
multiEnd: /^$/g
|
multiEnd: /^$/g,
|
||||||
},
|
},
|
||||||
python: {
|
python: {
|
||||||
single: /#(.*)$/gm,
|
single: /#(.*)$/gm,
|
||||||
multiStart: /"""[\s\S]*?$/gm, // Python docstring
|
multiStart: /"""[\s\S]*?$/gm, // Python docstring
|
||||||
multiEnd: /[\s\S]*?"""/gm
|
multiEnd: /[\s\S]*?"""/gm,
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
single: /^$/g, // CSS does not support single-line comments
|
single: /^$/g, // CSS does not support single-line comments
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
html: {
|
html: {
|
||||||
single: /^$/g, // HTML does not support single-line comments
|
single: /^$/g, // HTML does not support single-line comments
|
||||||
multiStart: /<!--/g,
|
multiStart: /<!--/g,
|
||||||
multiEnd: /-->/g
|
multiEnd: /-->/g,
|
||||||
},
|
},
|
||||||
xml: {
|
xml: {
|
||||||
single: /^$/g, // XML does not support single-line comments
|
single: /^$/g, // XML does not support single-line comments
|
||||||
multiStart: /<!--/g,
|
multiStart: /<!--/g,
|
||||||
multiEnd: /-->/g
|
multiEnd: /-->/g,
|
||||||
},
|
},
|
||||||
php: {
|
php: {
|
||||||
single: /(?:\/\/|#)(.*)$/gm, // PHP supports//and #as single-line comments
|
single: /(?:\/\/|#)(.*)$/gm, // PHP supports//and #as single-line comments
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
ruby: {
|
ruby: {
|
||||||
single: /#(.*)$/gm,
|
single: /#(.*)$/gm,
|
||||||
multiStart: /=begin/g,
|
multiStart: /=begin/g,
|
||||||
multiEnd: /=end/g
|
multiEnd: /=end/g,
|
||||||
},
|
},
|
||||||
rust: {
|
rust: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
java: {
|
java: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
c: {
|
c: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
cpp: {
|
cpp: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
csharp: {
|
csharp: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
thrift: {
|
thrift: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
},
|
},
|
||||||
other: {
|
other: {
|
||||||
single: /\/\/(.*)$/gm,
|
single: /\/\/(.*)$/gm,
|
||||||
multiStart: /\/\*/g,
|
multiStart: /\/\*/g,
|
||||||
multiEnd: /\*\//g
|
multiEnd: /\*\//g,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return commentPatterns[language] || null;
|
return commentPatterns[language] || null;
|
||||||
|
|
@ -220,14 +271,47 @@ export const isSupportedFile = (filePath: string): boolean => {
|
||||||
*/
|
*/
|
||||||
export const isTextFile = (filePath: string): boolean => {
|
export const isTextFile = (filePath: string): boolean => {
|
||||||
const textExtensions = [
|
const textExtensions = [
|
||||||
'.ts', '.tsx', '.js', '.jsx', '.go', '.md', '.txt', '.json',
|
'.ts',
|
||||||
'.css', '.scss', '.sass', '.less', '.html', '.htm', '.xml',
|
'.tsx',
|
||||||
'.yaml', '.yml', '.toml', '.ini', '.conf', '.config',
|
'.js',
|
||||||
'.sh', '.bash', '.zsh', '.fish', '.py', '.java', '.c', '.cpp', '.h', '.hpp', '.cs',
|
'.jsx',
|
||||||
'.php', '.rb', '.rs', '.kt', '.swift', '.dart', '.scala', '.thrift'
|
'.go',
|
||||||
|
'.md',
|
||||||
|
'.txt',
|
||||||
|
'.json',
|
||||||
|
'.css',
|
||||||
|
'.scss',
|
||||||
|
'.sass',
|
||||||
|
'.less',
|
||||||
|
'.html',
|
||||||
|
'.htm',
|
||||||
|
'.xml',
|
||||||
|
'.yaml',
|
||||||
|
'.yml',
|
||||||
|
'.toml',
|
||||||
|
'.ini',
|
||||||
|
'.conf',
|
||||||
|
'.config',
|
||||||
|
'.sh',
|
||||||
|
'.bash',
|
||||||
|
'.zsh',
|
||||||
|
'.fish',
|
||||||
|
'.py',
|
||||||
|
'.java',
|
||||||
|
'.c',
|
||||||
|
'.cpp',
|
||||||
|
'.h',
|
||||||
|
'.hpp',
|
||||||
|
'.cs',
|
||||||
|
'.php',
|
||||||
|
'.rb',
|
||||||
|
'.rs',
|
||||||
|
'.kt',
|
||||||
|
'.swift',
|
||||||
|
'.dart',
|
||||||
|
'.scala',
|
||||||
|
'.thrift',
|
||||||
];
|
];
|
||||||
|
|
||||||
return textExtensions.some(ext =>
|
return textExtensions.some(ext => filePath.toLowerCase().endsWith(ext));
|
||||||
filePath.toLowerCase().endsWith(ext)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 coze-dev Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (year) Beijing Volcano Engine Technology Ltd.
|
Copyright (year) Beijing Volcano Engine Technology Ltd.
|
||||||
|
|
||||||
|
|
@ -304,7 +320,10 @@ function queryParamsToString(params: QueryParams): string {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (Array.isArray(val)) {
|
if (Array.isArray(val)) {
|
||||||
return `${escapedKey}=${val.map(uriEscape).sort().join(`&${escapedKey}=`)}`;
|
return `${escapedKey}=${val
|
||||||
|
.map(uriEscape)
|
||||||
|
.sort()
|
||||||
|
.join(`&${escapedKey}=`)}`;
|
||||||
}
|
}
|
||||||
return `${escapedKey}=${uriEscape(val)}`;
|
return `${escapedKey}=${uriEscape(val)}`;
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,4 @@
|
||||||
"@types/node": "^18.11.9"
|
"@types/node": "^18.11.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,4 @@
|
||||||
"typescript": "~5.8.2"
|
"typescript": "~5.8.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,13 +65,11 @@
|
||||||
* "This monorepo consumes packages from an Artifactory private NPM registry."
|
* "This monorepo consumes packages from an Artifactory private NPM registry."
|
||||||
*/
|
*/
|
||||||
// "introduction": "",
|
// "introduction": "",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the message that normally says:
|
* Overrides the message that normally says:
|
||||||
* "Please contact the repository maintainers for help with setting up an Artifactory user account."
|
* "Please contact the repository maintainers for help with setting up an Artifactory user account."
|
||||||
*/
|
*/
|
||||||
// "obtainAnAccount": "",
|
// "obtainAnAccount": "",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the message that normally says:
|
* Overrides the message that normally says:
|
||||||
* "Please open this URL in your web browser:"
|
* "Please open this URL in your web browser:"
|
||||||
|
|
@ -79,26 +77,22 @@
|
||||||
* The "artifactoryWebsiteUrl" string is printed after this message.
|
* The "artifactoryWebsiteUrl" string is printed after this message.
|
||||||
*/
|
*/
|
||||||
// "visitWebsite": "",
|
// "visitWebsite": "",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the message that normally says:
|
* Overrides the message that normally says:
|
||||||
* "Your user name appears in the upper-right corner of the JFrog website."
|
* "Your user name appears in the upper-right corner of the JFrog website."
|
||||||
*/
|
*/
|
||||||
// "locateUserName": "",
|
// "locateUserName": "",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the message that normally says:
|
* Overrides the message that normally says:
|
||||||
* "Click 'Edit Profile' on the JFrog website. Click the 'Generate API Key'
|
* "Click 'Edit Profile' on the JFrog website. Click the 'Generate API Key'
|
||||||
* button if you haven't already done so previously."
|
* button if you haven't already done so previously."
|
||||||
*/
|
*/
|
||||||
// "locateApiKey": ""
|
// "locateApiKey": ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the message that normally prompts:
|
* Overrides the message that normally prompts:
|
||||||
* "What is your Artifactory user name?"
|
* "What is your Artifactory user name?"
|
||||||
*/
|
*/
|
||||||
// "userNamePrompt": ""
|
// "userNamePrompt": ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the message that normally prompts:
|
* Overrides the message that normally prompts:
|
||||||
* "What is your Artifactory API key?"
|
* "What is your Artifactory API key?"
|
||||||
|
|
|
||||||
|
|
@ -40,24 +40,20 @@
|
||||||
* (Required) The name of the the Azure storage account to use for build cache.
|
* (Required) The name of the the Azure storage account to use for build cache.
|
||||||
*/
|
*/
|
||||||
// "storageAccountName": "example",
|
// "storageAccountName": "example",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Required) The name of the container in the Azure storage account to use for build cache.
|
* (Required) The name of the container in the Azure storage account to use for build cache.
|
||||||
*/
|
*/
|
||||||
// "storageContainerName": "my-container",
|
// "storageContainerName": "my-container",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Azure environment the storage account exists in. Defaults to AzurePublicCloud.
|
* The Azure environment the storage account exists in. Defaults to AzurePublicCloud.
|
||||||
*
|
*
|
||||||
* Possible values: "AzurePublicCloud", "AzureChina", "AzureGermany", "AzureGovernment"
|
* Possible values: "AzurePublicCloud", "AzureChina", "AzureGermany", "AzureGovernment"
|
||||||
*/
|
*/
|
||||||
// "azureEnvironment": "AzurePublicCloud",
|
// "azureEnvironment": "AzurePublicCloud",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optional prefix for cache item blob names.
|
* An optional prefix for cache item blob names.
|
||||||
*/
|
*/
|
||||||
// "blobPrefix": "my-prefix",
|
// "blobPrefix": "my-prefix",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to true, allow writing to the cache. Defaults to false.
|
* If set to true, allow writing to the cache. Defaults to false.
|
||||||
*/
|
*/
|
||||||
|
|
@ -73,25 +69,21 @@
|
||||||
* Example: "my-bucket"
|
* Example: "my-bucket"
|
||||||
*/
|
*/
|
||||||
// "s3Bucket": "my-bucket",
|
// "s3Bucket": "my-bucket",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Required unless s3Bucket is specified) The Amazon S3 endpoint of the bucket to use for build cache.
|
* (Required unless s3Bucket is specified) The Amazon S3 endpoint of the bucket to use for build cache.
|
||||||
* This should not include any path; use the s3Prefix to set the path.
|
* This should not include any path; use the s3Prefix to set the path.
|
||||||
* Examples: "my-bucket.s3.us-east-2.amazonaws.com" or "http://localhost:9000"
|
* Examples: "my-bucket.s3.us-east-2.amazonaws.com" or "http://localhost:9000"
|
||||||
*/
|
*/
|
||||||
// "s3Endpoint": "https://my-bucket.s3.us-east-2.amazonaws.com",
|
// "s3Endpoint": "https://my-bucket.s3.us-east-2.amazonaws.com",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Required) The Amazon S3 region of the bucket to use for build cache.
|
* (Required) The Amazon S3 region of the bucket to use for build cache.
|
||||||
* Example: "us-east-1"
|
* Example: "us-east-1"
|
||||||
*/
|
*/
|
||||||
// "s3Region": "us-east-1",
|
// "s3Region": "us-east-1",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optional prefix ("folder") for cache items. It should not start with "/".
|
* An optional prefix ("folder") for cache items. It should not start with "/".
|
||||||
*/
|
*/
|
||||||
// "s3Prefix": "my-prefix",
|
// "s3Prefix": "my-prefix",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to true, allow writing to the cache. Defaults to false.
|
* If set to true, allow writing to the cache. Defaults to false.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@
|
||||||
* If the main project should include other unrelated Rush projects, add it to the "projectSettings" section,
|
* If the main project should include other unrelated Rush projects, add it to the "projectSettings" section,
|
||||||
* and then specify those projects in the "additionalProjectsToInclude" list.
|
* and then specify those projects in the "additionalProjectsToInclude" list.
|
||||||
*/
|
*/
|
||||||
"deploymentProjectNames": [
|
"deploymentProjectNames": ["@coze-studio/app"],
|
||||||
"@coze-studio/app"
|
|
||||||
],
|
|
||||||
// solve deploy error: ERROR: Symlink targets not under folder
|
// solve deploy error: ERROR: Symlink targets not under folder
|
||||||
"dependencySettings": [],
|
"dependencySettings": [],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,7 @@
|
||||||
},
|
},
|
||||||
"globalPeerDependencyRules": {},
|
"globalPeerDependencyRules": {},
|
||||||
"globalPackageExtensions": {},
|
"globalPackageExtensions": {},
|
||||||
"globalNeverBuiltDependencies": [
|
"globalNeverBuiltDependencies": ["canvas", "better-sqlite3"],
|
||||||
"canvas",
|
|
||||||
"better-sqlite3"
|
|
||||||
],
|
|
||||||
"globalAllowedDeprecatedVersions": {},
|
"globalAllowedDeprecatedVersions": {},
|
||||||
"globalPatchedDependencies": {},
|
"globalPatchedDependencies": {},
|
||||||
"unsupportedPackageJsonSettings": {}
|
"unsupportedPackageJsonSettings": {}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue