chore: format all common files (#431)
This commit is contained in:
parent
8136ddd82d
commit
40088b0a05
|
|
@ -18,46 +18,41 @@ import type {
|
|||
IPlugin,
|
||||
IHooks,
|
||||
IPromptsHookParams,
|
||||
} from "rush-init-project-plugin";
|
||||
} from 'rush-init-project-plugin';
|
||||
import { readFileSync } from 'fs';
|
||||
import path from 'path';
|
||||
import JSON5 from '../../autoinstallers/plugins/node_modules/json5'
|
||||
import JSON5 from '../../autoinstallers/plugins/node_modules/json5';
|
||||
|
||||
const rushJson = JSON5.parse(
|
||||
readFileSync(
|
||||
path.resolve(__dirname, '../../../rush.json')
|
||||
).toString('utf-8')
|
||||
readFileSync(path.resolve(__dirname, '../../../rush.json')).toString('utf-8'),
|
||||
);
|
||||
|
||||
export default class SelectTeamPlugin implements IPlugin {
|
||||
apply(hooks: IHooks): void {
|
||||
hooks.prompts.tap("SelectTeamPlugin", (prompts: IPromptsHookParams) => {
|
||||
|
||||
hooks.prompts.tap('SelectTeamPlugin', (prompts: IPromptsHookParams) => {
|
||||
// Leave only the prefix team-
|
||||
const teamNamePrefix = /^team-/;
|
||||
const choices = rushJson.allowedProjectTags.filter(
|
||||
teamName => teamNamePrefix.test(teamName)
|
||||
).map(
|
||||
teamName => teamName.replace(teamNamePrefix, '')
|
||||
);
|
||||
const choices = rushJson.allowedProjectTags
|
||||
.filter(teamName => teamNamePrefix.test(teamName))
|
||||
.map(teamName => teamName.replace(teamNamePrefix, ''));
|
||||
|
||||
// Unshift an issue, causing the user to display the issue after selecting a template.
|
||||
prompts.promptQueue.unshift({
|
||||
type: "list",
|
||||
name: "team",
|
||||
message: "Select your team",
|
||||
type: 'list',
|
||||
name: 'team',
|
||||
message: 'Select your team',
|
||||
choices,
|
||||
default: 0, // Default choices [0]
|
||||
});
|
||||
|
||||
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
|
||||
const folderDir = answers.packageName.split('/').slice(-1)[0];
|
||||
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
|
||||
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 {
|
||||
if (!cmd) {
|
||||
return undefined;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
|||
const config: IConfig = {
|
||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||
defaultProjectConfiguration: {
|
||||
tags:['level-3']
|
||||
}
|
||||
tags: ['level-3'],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
"react-dom": "~18.2.0",
|
||||
"storybook": "^7.6.7",
|
||||
"stylelint": "^15.11.0",
|
||||
|
||||
"vite-plugin-svgr": "~3.3.0",
|
||||
"vitest": "~3.0.5"
|
||||
},
|
||||
|
|
@ -49,3 +48,4 @@
|
|||
"react-dom": ">=18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
|||
const config: IConfig = {
|
||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||
defaultProjectConfiguration: {
|
||||
tags:['level-3']
|
||||
}
|
||||
tags: ['level-3'],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
"@coze-arch/vitest-config": "workspace:*",
|
||||
"@types/node": "^18",
|
||||
"@vitest/coverage-v8": "~3.0.5",
|
||||
|
||||
"vitest": "~3.0.5",
|
||||
"sucrase": "^3.32.0"
|
||||
"sucrase": "^3.32.0",
|
||||
"vitest": "~3.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
|||
const config: IConfig = {
|
||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||
defaultProjectConfiguration: {
|
||||
tags:['level-4']
|
||||
}
|
||||
tags: ['level-4'],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@coze-arch/eslint-config": "workspace:*",
|
||||
"@coze-arch/stylelint-config": "workspace:*",
|
||||
"@coze-arch/ts-config": "workspace:*",
|
||||
"@coze-arch/vitest-config": "workspace:*",
|
||||
"@coze-arch/stylelint-config": "workspace:*",
|
||||
"@rsbuild/core": "^0.2.18",
|
||||
"@rsbuild/plugin-react": "^0.2.18",
|
||||
"@slardar/web": "1.7.0",
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
"postcss": "^8.4.32",
|
||||
"postcss-loader": "^7.3.3",
|
||||
"tailwindcss": "~3.3.3",
|
||||
|
||||
"vitest": "~3.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
|||
const config: IConfig = {
|
||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||
defaultProjectConfiguration: {
|
||||
tags:['level-4']
|
||||
}
|
||||
tags: ['level-4'],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
"test:cov": "npm run test -- --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coze-arch/bot-api": "workspace:*",
|
||||
"@coze-arch/i18n": "workspace:*",
|
||||
"@coze-arch/logger": "workspace:*",
|
||||
"@douyinfe/semi-icons": "^2.36.0",
|
||||
"@douyinfe/semi-ui": "2.61.0",
|
||||
"immer": "^10.0.3",
|
||||
|
|
@ -23,18 +26,15 @@
|
|||
"react-dom": "~18.2.0",
|
||||
"react-error-boundary": "^4.0.9",
|
||||
"react-router-dom": "^6.11.1",
|
||||
"zustand": "^4.4.7",
|
||||
"@coze-arch/logger": "workspace:*",
|
||||
"@coze-arch/i18n": "workspace:*",
|
||||
"@coze-arch/bot-api": "workspace:*"
|
||||
"zustand": "^4.4.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@douyinfe/semi-rspack-plugin": "~2.48.0",
|
||||
"@edenx/plugin-tailwind": "1.51.0",
|
||||
"@coze-arch/eslint-config": "workspace:*",
|
||||
"@coze-arch/stylelint-config": "workspace:*",
|
||||
"@coze-arch/ts-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/core": "0.4.0",
|
||||
"@rspack/plugin-react-refresh": "0.4.0",
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
"tailwindcss": "~3.3.3",
|
||||
"ts-morph": "^20.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
|
||||
"vitest": "~3.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ browserClient('init', {
|
|||
bid: '',
|
||||
});
|
||||
browserClient('start');
|
||||
reporter.init(browserClient)
|
||||
reporter.init(browserClient);
|
||||
|
||||
const root = createRoot(document.getElementById('root'));
|
||||
root.render(<RouterProvider router={router} />);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import SetDefaultAuthorPlugin from '../_plugins/SetDefaultAuthorPlugin';
|
|||
const config: IConfig = {
|
||||
plugins: [new SetDefaultAuthorPlugin(), new SelectTeamPlugin()],
|
||||
defaultProjectConfiguration: {
|
||||
tags:['level-3']
|
||||
}
|
||||
tags: ['level-3'],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
"description": "{{ description }}",
|
||||
"license": "Apache-2.0",
|
||||
"author": "{{ authorName }}",
|
||||
"maintainers": [
|
||||
],
|
||||
"maintainers": [],
|
||||
"main": "src/index.ts",
|
||||
"unpkg": "./dist/umd/index.js",
|
||||
"module": "./dist/esm/index.js",
|
||||
|
|
@ -63,7 +62,6 @@
|
|||
"storybook": "^7.6.7",
|
||||
"stylelint": "^15.11.0",
|
||||
"tailwindcss": "~3.3.3",
|
||||
|
||||
"vite-plugin-svgr": "~3.3.0",
|
||||
"vitest": "~3.0.5"
|
||||
},
|
||||
|
|
@ -72,3 +70,4 @@
|
|||
"react-dom": ">=18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@
|
|||
"@eslint/compat": "^1.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@
|
|||
"@types/node": "^18.6.3"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,3 +17,4 @@
|
|||
"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 { CliOptions } from '../types/config';
|
||||
|
||||
|
|
@ -14,7 +30,11 @@ export const createProgram = (): Command => {
|
|||
|
||||
program
|
||||
.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('--secret-access-key <key>', '火山引擎 Secret Access Key')
|
||||
.option('--region <region>', '火山引擎服务区域', 'cn-beijing')
|
||||
|
|
@ -48,7 +68,7 @@ export const parseOptions = (program: Command): CliOptions => {
|
|||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
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';
|
||||
|
||||
/**
|
||||
|
|
@ -13,28 +34,63 @@ const DEFAULT_CONFIG: AppConfig = {
|
|||
targetLanguage: 'en',
|
||||
maxRetries: 3,
|
||||
timeout: 30000,
|
||||
concurrency: 3
|
||||
concurrency: 3,
|
||||
},
|
||||
processing: {
|
||||
defaultExtensions: [
|
||||
'ts', 'tsx', 'js', 'jsx', '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'
|
||||
'ts',
|
||||
'tsx',
|
||||
'js',
|
||||
'jsx',
|
||||
'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: {
|
||||
ignorePatterns: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
|
||||
includeUntracked: false
|
||||
}
|
||||
includeUntracked: false,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Load configuration from file
|
||||
*/
|
||||
export const loadConfigFromFile = async (configPath: string): Promise<Partial<AppConfig>> => {
|
||||
export const loadConfigFromFile = async (
|
||||
configPath: string,
|
||||
): Promise<Partial<AppConfig>> => {
|
||||
try {
|
||||
const fs = await import('fs/promises');
|
||||
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
|
||||
*/
|
||||
export const createConfigFromOptions = (options: CliOptions): Partial<AppConfig> => {
|
||||
export const createConfigFromOptions = (
|
||||
options: CliOptions,
|
||||
): Partial<AppConfig> => {
|
||||
const config: Partial<AppConfig> = {};
|
||||
|
||||
// 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>;
|
||||
if (options.accessKeyId) {
|
||||
config.translation!.accessKeyId = options.accessKeyId;
|
||||
|
|
@ -90,10 +154,9 @@ export const createConfigFromOptions = (options: CliOptions): Partial<AppConfig>
|
|||
* merge configuration
|
||||
*/
|
||||
export const mergeConfigs = (...configs: Partial<AppConfig>[]): AppConfig => {
|
||||
return configs.reduce(
|
||||
(merged, config) => deepMerge(merged, config),
|
||||
{ ...DEFAULT_CONFIG }
|
||||
) as AppConfig;
|
||||
return configs.reduce((merged, config) => deepMerge(merged, config), {
|
||||
...DEFAULT_CONFIG,
|
||||
}) as AppConfig;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -118,41 +181,65 @@ export const loadConfig = async (options: CliOptions): Promise<AppConfig> => {
|
|||
/**
|
||||
* verify configuration
|
||||
*/
|
||||
export const validateConfig = (config: AppConfig): { valid: boolean; errors: string[] } => {
|
||||
export const validateConfig = (
|
||||
config: AppConfig,
|
||||
): { valid: boolean; errors: string[] } => {
|
||||
const errors: string[] = [];
|
||||
|
||||
// Verify Volcano Engine Access Key ID
|
||||
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
|
||||
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
|
||||
const validRegions = ['cn-beijing', 'ap-southeast-1', 'us-east-1'];
|
||||
if (!validRegions.includes(config.translation.region)) {
|
||||
console.warn(`未知的区域: ${config.translation.region},建议使用: ${validRegions.join(', ')}`);
|
||||
console.warn(
|
||||
`未知的区域: ${config.translation.region},建议使用: ${validRegions.join(
|
||||
', ',
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Verify language code
|
||||
const validLanguages = ['zh', 'en', 'ja', 'ko', 'fr', 'de', 'es', 'pt', 'ru'];
|
||||
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)) {
|
||||
console.warn(`未知的目标语言: ${config.translation.targetLanguage},建议使用: ${validLanguages.join(', ')}`);
|
||||
console.warn(
|
||||
`未知的目标语言: ${
|
||||
config.translation.targetLanguage
|
||||
},建议使用: ${validLanguages.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
// validation concurrency
|
||||
if (config.translation.concurrency < 1 || config.translation.concurrency > 10) {
|
||||
if (
|
||||
config.translation.concurrency < 1 ||
|
||||
config.translation.concurrency > 10
|
||||
) {
|
||||
errors.push('并发数应该在1-10之间');
|
||||
}
|
||||
|
||||
// verification timeout
|
||||
if (config.translation.timeout < 1000 || config.translation.timeout > 300000) {
|
||||
if (
|
||||
config.translation.timeout < 1000 ||
|
||||
config.translation.timeout > 300000
|
||||
) {
|
||||
errors.push('超时时间应该在1000-300000毫秒之间');
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +249,10 @@ export const validateConfig = (config: AppConfig): { valid: boolean; errors: str
|
|||
/**
|
||||
* 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(` 区域: ${config.translation.region}`);
|
||||
console.log(` 源语言: ${config.translation.sourceLanguage}`);
|
||||
|
|
@ -172,11 +262,23 @@ export const printConfigInfo = (config: AppConfig, verbose: boolean = false): vo
|
|||
console.log(` 输出格式: ${config.processing.outputFormat}`);
|
||||
|
||||
if (verbose) {
|
||||
console.log(` Access Key ID: ${config.translation.accessKeyId ? '已设置' : '未设置'}`);
|
||||
console.log(` Secret Access Key: ${config.translation.secretAccessKey ? '已设置' : '未设置'}`);
|
||||
console.log(
|
||||
` Access Key ID: ${
|
||||
config.translation.accessKeyId ? '已设置' : '未设置'
|
||||
}`,
|
||||
);
|
||||
console.log(
|
||||
` Secret Access Key: ${
|
||||
config.translation.secretAccessKey ? '已设置' : '未设置'
|
||||
}`,
|
||||
);
|
||||
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.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
|
||||
|
||||
import { createProgram, parseOptions, showHelp } from './cli/command';
|
||||
|
|
@ -102,7 +118,9 @@ async function processRepository(
|
|||
console.log(`\n📝 ${file.path}:`);
|
||||
translations.forEach((translation, index) => {
|
||||
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 result = await replaceCommentsInFile(
|
||||
file,
|
||||
operation,
|
||||
);
|
||||
const result = await replaceCommentsInFile(file, operation);
|
||||
|
||||
if (!result.success) {
|
||||
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 {
|
||||
SourceFile,
|
||||
ChineseComment,
|
||||
ParsedComment,
|
||||
FileWithComments,
|
||||
CommentType,
|
||||
MultiLineContext
|
||||
MultiLineContext,
|
||||
} from '../types/index';
|
||||
import { getCommentPatterns } from '../utils/language';
|
||||
import { containsChinese, cleanCommentText } from '../utils/chinese';
|
||||
|
|
@ -74,7 +90,9 @@ const parseSingleLineComments = (
|
|||
// Multiple protections against infinite loops
|
||||
matchCount++;
|
||||
if (matchCount > maxMatches) {
|
||||
console.warn(`⚠️ 单行匹配次数过多,中断处理: ${line.substring(0, 50)}...`);
|
||||
console.warn(
|
||||
`⚠️ 单行匹配次数过多,中断处理: ${line.substring(0, 50)}...`,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +264,6 @@ const parseMultiLineComments = (
|
|||
const commentContent = line.substring(0, endMatch.index!);
|
||||
commentLines.push(commentContent);
|
||||
|
||||
|
||||
comments.push({
|
||||
content: commentLines.join('\n'),
|
||||
startLine: commentStart!.line,
|
||||
|
|
@ -302,7 +319,10 @@ export const filterChineseComments = (
|
|||
for (const comment of comments) {
|
||||
if (comment.type === 'multi-line' && comment.content.includes('\n')) {
|
||||
// Multi-line comments: line-by-line processing
|
||||
const multiLineResults = processMultiLineCommentForChinese(comment, language);
|
||||
const multiLineResults = processMultiLineCommentForChinese(
|
||||
comment,
|
||||
language,
|
||||
);
|
||||
result.push(...multiLineResults);
|
||||
} else if (containsChinese(comment.content)) {
|
||||
// Single-line comments or single-line multi-line comments
|
||||
|
|
@ -350,8 +370,8 @@ const processMultiLineCommentForChinese = (
|
|||
isPartOfMultiLine: true,
|
||||
originalComment: comment,
|
||||
lineIndexInComment: lineIndex,
|
||||
totalLinesInComment: lines.length
|
||||
}
|
||||
totalLinesInComment: lines.length,
|
||||
},
|
||||
};
|
||||
|
||||
result.push(lineComment);
|
||||
|
|
@ -393,7 +413,9 @@ export const detectChineseInFile = (file: SourceFile): ChineseComment[] => {
|
|||
/**
|
||||
* Batch detection of Chinese comments in multiple files
|
||||
*/
|
||||
export const detectChineseInFiles = (files: SourceFile[]): FileWithComments[] => {
|
||||
export const detectChineseInFiles = (
|
||||
files: SourceFile[],
|
||||
): FileWithComments[] => {
|
||||
const results: FileWithComments[] = [];
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
|
|
@ -428,7 +450,9 @@ export const detectChineseInFiles = (files: SourceFile[]): FileWithComments[] =>
|
|||
/**
|
||||
* Get annotation statistics
|
||||
*/
|
||||
export const getCommentStats = (files: SourceFile[]): {
|
||||
export const getCommentStats = (
|
||||
files: SourceFile[],
|
||||
): {
|
||||
totalFiles: number;
|
||||
filesWithComments: number;
|
||||
totalComments: number;
|
||||
|
|
@ -441,12 +465,15 @@ export const getCommentStats = (files: SourceFile[]): {
|
|||
const commentsByType: Record<CommentType, number> = {
|
||||
'single-line': 0,
|
||||
'multi-line': 0,
|
||||
'documentation': 0
|
||||
documentation: 0,
|
||||
};
|
||||
|
||||
files.forEach(file => {
|
||||
const allComments = parseComments(file);
|
||||
const chineseCommentsInFile = filterChineseComments(allComments, file.language);
|
||||
const chineseCommentsInFile = filterChineseComments(
|
||||
allComments,
|
||||
file.language,
|
||||
);
|
||||
|
||||
if (chineseCommentsInFile.length > 0) {
|
||||
filesWithComments++;
|
||||
|
|
@ -465,6 +492,6 @@ export const getCommentStats = (files: SourceFile[]): {
|
|||
filesWithComments,
|
||||
totalComments,
|
||||
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 { 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 { tryCatch } from '../utils/fp';
|
||||
|
||||
/**
|
||||
* 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 () => {
|
||||
const content = await fs.readFile(filePath, 'utf-8');
|
||||
const language = detectLanguage(filePath);
|
||||
|
|
@ -15,7 +37,7 @@ export const readSourceFile = async (filePath: string): Promise<Result<SourceFil
|
|||
return {
|
||||
path: filePath,
|
||||
content,
|
||||
language
|
||||
language,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
|
@ -23,14 +45,17 @@ export const readSourceFile = async (filePath: string): Promise<Result<SourceFil
|
|||
/**
|
||||
* 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(
|
||||
filePaths.map(path => readSourceFile(path))
|
||||
filePaths.map(path => readSourceFile(path)),
|
||||
);
|
||||
|
||||
return results
|
||||
.filter((result): result is PromiseFulfilledResult<Result<SourceFile>> =>
|
||||
result.status === 'fulfilled' && result.value.success
|
||||
.filter(
|
||||
(result): result is PromiseFulfilledResult<Result<SourceFile>> =>
|
||||
result.status === 'fulfilled' && result.value.success,
|
||||
)
|
||||
.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
|
||||
*/
|
||||
export const getSourceFiles = async (config: FileScanConfig): Promise<Result<string[]>> => {
|
||||
export const getSourceFiles = async (
|
||||
config: FileScanConfig,
|
||||
): Promise<Result<string[]>> => {
|
||||
const { root, extensions, includeUntracked } = config;
|
||||
|
||||
return tryCatch(async () => {
|
||||
|
|
@ -66,7 +93,9 @@ export const getSourceFiles = async (config: FileScanConfig): Promise<Result<str
|
|||
/**
|
||||
* 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 () => {
|
||||
const filesResult = await getSourceFiles(config);
|
||||
|
||||
|
|
@ -94,28 +123,32 @@ export const isFileAccessible = async (filePath: string): Promise<boolean> => {
|
|||
/**
|
||||
* Get file statistics
|
||||
*/
|
||||
export const getFileStats = async (filePaths: string[]): Promise<{
|
||||
export const getFileStats = async (
|
||||
filePaths: string[],
|
||||
): Promise<{
|
||||
total: number;
|
||||
accessible: number;
|
||||
textFiles: number;
|
||||
supportedFiles: number;
|
||||
}> => {
|
||||
const accessibilityResults = await Promise.allSettled(
|
||||
filePaths.map(isFileAccessible)
|
||||
filePaths.map(isFileAccessible),
|
||||
);
|
||||
|
||||
const accessible = accessibilityResults.filter(
|
||||
(result): result is PromiseFulfilledResult<boolean> =>
|
||||
result.status === 'fulfilled' && result.value
|
||||
result.status === 'fulfilled' && result.value,
|
||||
).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 {
|
||||
total: filePaths.length,
|
||||
accessible,
|
||||
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 {
|
||||
ProcessingReport,
|
||||
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) {
|
||||
markdown += '\n## ❌ 错误详情\n\n';
|
||||
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 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) {
|
||||
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 {
|
||||
TranslationResult,
|
||||
TranslationContext,
|
||||
|
|
@ -7,7 +23,10 @@ import {
|
|||
import { TranslationConfig } from '../types/config';
|
||||
import { retry, chunk } from '../utils/fp';
|
||||
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
|
||||
|
|
@ -101,7 +120,9 @@ export class TranslationService {
|
|||
return result;
|
||||
} catch (error) {
|
||||
throw new TranslationError(
|
||||
`Translation failed: ${error instanceof Error ? error.message : String(error)}`,
|
||||
`Translation failed: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`,
|
||||
comment,
|
||||
);
|
||||
}
|
||||
|
|
@ -163,7 +184,10 @@ export class TranslationService {
|
|||
const result: TranslationResult = {
|
||||
original: item.comment.content,
|
||||
translated,
|
||||
confidence: this.calculateConfidence(translated, item.comment.content),
|
||||
confidence: this.calculateConfidence(
|
||||
translated,
|
||||
item.comment.content,
|
||||
),
|
||||
};
|
||||
|
||||
// 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
|
||||
*/
|
||||
|
|
@ -183,10 +199,7 @@ export type Result<T, E = Error> =
|
|||
* translation error
|
||||
*/
|
||||
export class TranslationError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public originalComment: string,
|
||||
) {
|
||||
constructor(message: string, public originalComment: string) {
|
||||
super(message);
|
||||
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
|
||||
*/
|
||||
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
|
||||
|
|
@ -31,7 +48,10 @@ export const countChineseCharacters = (text: string): number => {
|
|||
/**
|
||||
* 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;
|
||||
if (totalLength === 0) return false;
|
||||
|
||||
|
|
@ -45,7 +65,7 @@ export const isPrimarilyChinese = (text: string, threshold: number = 0.5): boole
|
|||
export const cleanCommentText = (
|
||||
text: string,
|
||||
commentType: 'single-line' | 'multi-line',
|
||||
language?: string
|
||||
language?: string,
|
||||
): string => {
|
||||
let cleaned = text;
|
||||
|
||||
|
|
@ -100,7 +120,10 @@ export const cleanCommentText = (
|
|||
/**
|
||||
* 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
|
||||
if (!translated || translated.trim().length === 0) {
|
||||
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';
|
||||
|
||||
/**
|
||||
|
|
@ -7,44 +23,44 @@ export const detectLanguage = (filePath: string): SourceFileLanguage => {
|
|||
const ext = filePath.toLowerCase().split('.').pop();
|
||||
|
||||
const languageMap: Record<string, SourceFileLanguage> = {
|
||||
'ts': 'typescript',
|
||||
'tsx': 'typescript',
|
||||
'js': 'javascript',
|
||||
'jsx': 'javascript',
|
||||
'go': 'go',
|
||||
'md': 'markdown',
|
||||
'txt': 'text',
|
||||
'json': 'json',
|
||||
'yaml': 'yaml',
|
||||
'yml': 'yaml',
|
||||
'toml': 'toml',
|
||||
'ini': 'ini',
|
||||
'conf': 'ini',
|
||||
'config': 'ini',
|
||||
'sh': 'shell',
|
||||
'bash': 'shell',
|
||||
'zsh': 'shell',
|
||||
'fish': 'shell',
|
||||
'py': 'python',
|
||||
'css': 'css',
|
||||
'scss': 'css',
|
||||
'sass': 'css',
|
||||
'less': 'css',
|
||||
'html': 'html',
|
||||
'htm': 'html',
|
||||
'xml': 'xml',
|
||||
'php': 'php',
|
||||
'rb': 'ruby',
|
||||
'rs': 'rust',
|
||||
'java': 'java',
|
||||
'c': 'c',
|
||||
'h': 'c',
|
||||
'cpp': 'cpp',
|
||||
'cxx': 'cpp',
|
||||
'cc': 'cpp',
|
||||
'hpp': 'cpp',
|
||||
'cs': 'csharp',
|
||||
'thrift': 'thrift'
|
||||
ts: 'typescript',
|
||||
tsx: 'typescript',
|
||||
js: 'javascript',
|
||||
jsx: 'javascript',
|
||||
go: 'go',
|
||||
md: 'markdown',
|
||||
txt: 'text',
|
||||
json: 'json',
|
||||
yaml: 'yaml',
|
||||
yml: 'yaml',
|
||||
toml: 'toml',
|
||||
ini: 'ini',
|
||||
conf: 'ini',
|
||||
config: 'ini',
|
||||
sh: 'shell',
|
||||
bash: 'shell',
|
||||
zsh: 'shell',
|
||||
fish: 'shell',
|
||||
py: 'python',
|
||||
css: 'css',
|
||||
scss: 'css',
|
||||
sass: 'css',
|
||||
less: 'css',
|
||||
html: 'html',
|
||||
htm: 'html',
|
||||
xml: 'xml',
|
||||
php: 'php',
|
||||
rb: 'ruby',
|
||||
rs: 'rust',
|
||||
java: 'java',
|
||||
c: 'c',
|
||||
h: 'c',
|
||||
cpp: 'cpp',
|
||||
cxx: 'cpp',
|
||||
cc: 'cpp',
|
||||
hpp: 'cpp',
|
||||
cs: 'csharp',
|
||||
thrift: 'thrift',
|
||||
};
|
||||
|
||||
return languageMap[ext || ''] || 'other';
|
||||
|
|
@ -55,19 +71,52 @@ export const detectLanguage = (filePath: string): SourceFileLanguage => {
|
|||
*/
|
||||
export const filterFilesByExtensions = (
|
||||
files: string[],
|
||||
extensions: string[]
|
||||
extensions: string[],
|
||||
): string[] => {
|
||||
if (extensions.length === 0) {
|
||||
// Default supported text file extensions
|
||||
const defaultExtensions = [
|
||||
'.ts', '.tsx', '.js', '.jsx', '.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'
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.js',
|
||||
'.jsx',
|
||||
'.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 =>
|
||||
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
|
||||
*/
|
||||
export const getCommentPatterns = (language: SourceFileLanguage): CommentPattern | null => {
|
||||
export const getCommentPatterns = (
|
||||
language: SourceFileLanguage,
|
||||
): CommentPattern | null => {
|
||||
const commentPatterns: Record<SourceFileLanguage, CommentPattern> = {
|
||||
typescript: {
|
||||
single: /(?:^|[^:])\s*\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
javascript: {
|
||||
single: /(?:^|[^:])\s*\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
go: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
markdown: {
|
||||
single: /<!--(.*)-->/g,
|
||||
multiStart: /<!--/g,
|
||||
multiEnd: /-->/g
|
||||
multiEnd: /-->/g,
|
||||
},
|
||||
text: {
|
||||
single: /^(.*)$/gm, // Every line of a text file can be a comment
|
||||
multiStart: /^/g,
|
||||
multiEnd: /$/g
|
||||
multiEnd: /$/g,
|
||||
},
|
||||
json: {
|
||||
single: /\/\/(.*)$/gm, // JSON usually doesn't support comments, but some tools do
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
yaml: {
|
||||
single: /#(.*)$/gm,
|
||||
multiStart: /^$/g, // YAML does not support multi-line comments
|
||||
multiEnd: /^$/g
|
||||
multiEnd: /^$/g,
|
||||
},
|
||||
toml: {
|
||||
single: /#(.*)$/gm,
|
||||
multiStart: /^$/g, // TOML does not support multi-line comments
|
||||
multiEnd: /^$/g
|
||||
multiEnd: /^$/g,
|
||||
},
|
||||
ini: {
|
||||
single: /[;#](.*)$/gm, // INI file support; and #as comments
|
||||
multiStart: /^$/g, // INI does not support multi-line comments
|
||||
multiEnd: /^$/g
|
||||
multiEnd: /^$/g,
|
||||
},
|
||||
shell: {
|
||||
single: /#(.*)$/gm,
|
||||
multiStart: /^$/g, // Shell scripts do not support multi-line comments
|
||||
multiEnd: /^$/g
|
||||
multiEnd: /^$/g,
|
||||
},
|
||||
python: {
|
||||
single: /#(.*)$/gm,
|
||||
multiStart: /"""[\s\S]*?$/gm, // Python docstring
|
||||
multiEnd: /[\s\S]*?"""/gm
|
||||
multiEnd: /[\s\S]*?"""/gm,
|
||||
},
|
||||
css: {
|
||||
single: /^$/g, // CSS does not support single-line comments
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
html: {
|
||||
single: /^$/g, // HTML does not support single-line comments
|
||||
multiStart: /<!--/g,
|
||||
multiEnd: /-->/g
|
||||
multiEnd: /-->/g,
|
||||
},
|
||||
xml: {
|
||||
single: /^$/g, // XML does not support single-line comments
|
||||
multiStart: /<!--/g,
|
||||
multiEnd: /-->/g
|
||||
multiEnd: /-->/g,
|
||||
},
|
||||
php: {
|
||||
single: /(?:\/\/|#)(.*)$/gm, // PHP supports//and #as single-line comments
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
ruby: {
|
||||
single: /#(.*)$/gm,
|
||||
multiStart: /=begin/g,
|
||||
multiEnd: /=end/g
|
||||
multiEnd: /=end/g,
|
||||
},
|
||||
rust: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
java: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
c: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
cpp: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
csharp: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
thrift: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
other: {
|
||||
single: /\/\/(.*)$/gm,
|
||||
multiStart: /\/\*/g,
|
||||
multiEnd: /\*\//g
|
||||
}
|
||||
multiEnd: /\*\//g,
|
||||
},
|
||||
};
|
||||
|
||||
return commentPatterns[language] || null;
|
||||
|
|
@ -220,14 +271,47 @@ export const isSupportedFile = (filePath: string): boolean => {
|
|||
*/
|
||||
export const isTextFile = (filePath: string): boolean => {
|
||||
const textExtensions = [
|
||||
'.ts', '.tsx', '.js', '.jsx', '.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'
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.js',
|
||||
'.jsx',
|
||||
'.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 =>
|
||||
filePath.toLowerCase().endsWith(ext)
|
||||
);
|
||||
return textExtensions.some(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.
|
||||
|
||||
|
|
@ -304,7 +320,10 @@ function queryParamsToString(params: QueryParams): string {
|
|||
return undefined;
|
||||
}
|
||||
if (Array.isArray(val)) {
|
||||
return `${escapedKey}=${val.map(uriEscape).sort().join(`&${escapedKey}=`)}`;
|
||||
return `${escapedKey}=${val
|
||||
.map(uriEscape)
|
||||
.sort()
|
||||
.join(`&${escapedKey}=`)}`;
|
||||
}
|
||||
return `${escapedKey}=${uriEscape(val)}`;
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,3 +19,4 @@
|
|||
"@types/node": "^18.11.9"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@
|
|||
"typescript": "~5.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,13 +65,11 @@
|
|||
* "This monorepo consumes packages from an Artifactory private NPM registry."
|
||||
*/
|
||||
// "introduction": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Please contact the repository maintainers for help with setting up an Artifactory user account."
|
||||
*/
|
||||
// "obtainAnAccount": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Please open this URL in your web browser:"
|
||||
|
|
@ -79,26 +77,22 @@
|
|||
* The "artifactoryWebsiteUrl" string is printed after this message.
|
||||
*/
|
||||
// "visitWebsite": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Your user name appears in the upper-right corner of the JFrog website."
|
||||
*/
|
||||
// "locateUserName": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Click 'Edit Profile' on the JFrog website. Click the 'Generate API Key'
|
||||
* button if you haven't already done so previously."
|
||||
*/
|
||||
// "locateApiKey": ""
|
||||
|
||||
/**
|
||||
* Overrides the message that normally prompts:
|
||||
* "What is your Artifactory user name?"
|
||||
*/
|
||||
// "userNamePrompt": ""
|
||||
|
||||
/**
|
||||
* Overrides the message that normally prompts:
|
||||
* "What is your Artifactory API key?"
|
||||
|
|
|
|||
|
|
@ -40,24 +40,20 @@
|
|||
* (Required) The name of the the Azure storage account to use for build cache.
|
||||
*/
|
||||
// "storageAccountName": "example",
|
||||
|
||||
/**
|
||||
* (Required) The name of the container in the Azure storage account to use for build cache.
|
||||
*/
|
||||
// "storageContainerName": "my-container",
|
||||
|
||||
/**
|
||||
* The Azure environment the storage account exists in. Defaults to AzurePublicCloud.
|
||||
*
|
||||
* Possible values: "AzurePublicCloud", "AzureChina", "AzureGermany", "AzureGovernment"
|
||||
*/
|
||||
// "azureEnvironment": "AzurePublicCloud",
|
||||
|
||||
/**
|
||||
* An optional prefix for cache item blob names.
|
||||
*/
|
||||
// "blobPrefix": "my-prefix",
|
||||
|
||||
/**
|
||||
* If set to true, allow writing to the cache. Defaults to false.
|
||||
*/
|
||||
|
|
@ -73,25 +69,21 @@
|
|||
* Example: "my-bucket"
|
||||
*/
|
||||
// "s3Bucket": "my-bucket",
|
||||
|
||||
/**
|
||||
* (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.
|
||||
* Examples: "my-bucket.s3.us-east-2.amazonaws.com" or "http://localhost:9000"
|
||||
*/
|
||||
// "s3Endpoint": "https://my-bucket.s3.us-east-2.amazonaws.com",
|
||||
|
||||
/**
|
||||
* (Required) The Amazon S3 region of the bucket to use for build cache.
|
||||
* Example: "us-east-1"
|
||||
*/
|
||||
// "s3Region": "us-east-1",
|
||||
|
||||
/**
|
||||
* An optional prefix ("folder") for cache items. It should not start with "/".
|
||||
*/
|
||||
// "s3Prefix": "my-prefix",
|
||||
|
||||
/**
|
||||
* If set to true, allow writing to the cache. Defaults to false.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* This configuration file manages Rush's cobuild feature.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/cobuild.schema.json",
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@
|
|||
* 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.
|
||||
*/
|
||||
"deploymentProjectNames": [
|
||||
"@coze-studio/app"
|
||||
],
|
||||
"deploymentProjectNames": ["@coze-studio/app"],
|
||||
// solve deploy error: ERROR: Symlink targets not under folder
|
||||
"dependencySettings": [],
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,7 @@
|
|||
},
|
||||
"globalPeerDependencyRules": {},
|
||||
"globalPackageExtensions": {},
|
||||
"globalNeverBuiltDependencies": [
|
||||
"canvas",
|
||||
"better-sqlite3"
|
||||
],
|
||||
"globalNeverBuiltDependencies": ["canvas", "better-sqlite3"],
|
||||
"globalAllowedDeprecatedVersions": {},
|
||||
"globalPatchedDependencies": {},
|
||||
"unsupportedPackageJsonSettings": {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue