mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
140 lines
3.9 KiB
TypeScript
140 lines
3.9 KiB
TypeScript
/**
|
|
* How to use it:
|
|
* - cd apps/docs
|
|
* - Add apps/docs/.env file, to set OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL
|
|
* - Use `git add .` to add all changed docs to git staged changes
|
|
* - Run `npm run translate:zh` to translate all zh files to en
|
|
*/
|
|
|
|
import * as process from 'process';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
import { execSync } from 'child_process';
|
|
|
|
import { ChatCompletionMessageParam } from 'openai/resources/chat';
|
|
import OpenAI from 'openai';
|
|
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import 'dotenv/config';
|
|
|
|
const languages = ['zh', 'en'];
|
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
|
|
const ai = new OpenAI({
|
|
apiKey: process.env.OPENAI_API_KEY,
|
|
baseURL: process.env.OPENAI_BASE_URL,
|
|
});
|
|
const model = process.env.OPENAI_MODEL!;
|
|
|
|
const sourceLang = process.argv[2];
|
|
|
|
if (!languages.includes(sourceLang)) {
|
|
console.error(`Invalid language: ${sourceLang}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const targetLangs = languages.filter((_lang) => _lang !== sourceLang);
|
|
|
|
async function translateContent(
|
|
content: string,
|
|
targetLang: string,
|
|
previousTargetContent?: string
|
|
) {
|
|
let systemPrompts = `
|
|
You are a translator.
|
|
You will translate the following content from ${sourceLang} to ${targetLang}.\n
|
|
`;
|
|
|
|
if (previousTargetContent) {
|
|
systemPrompts += `
|
|
The target file is translated previously, here is the content:
|
|
${previousTargetContent}
|
|
Only translate the content that is different in ${sourceLang}.\n
|
|
`;
|
|
}
|
|
|
|
systemPrompts += `
|
|
Constraint:
|
|
- ONLY RETURN THE TRANSLATED CONTENT, NO OTHER TEXT.
|
|
`;
|
|
|
|
const messages: ChatCompletionMessageParam[] = [
|
|
{
|
|
role: 'system',
|
|
content: systemPrompts,
|
|
},
|
|
{ role: 'user', content },
|
|
];
|
|
|
|
const response = await ai.chat.completions.create({
|
|
model,
|
|
messages,
|
|
});
|
|
|
|
return response.choices[0].message.content ?? '';
|
|
}
|
|
|
|
async function translateFiles() {
|
|
// 1. Get Stage Changed Documentations for source language
|
|
const gitDiffOutput = execSync('git diff --cached --name-only', {
|
|
encoding: 'utf-8',
|
|
});
|
|
const allChangedFiles: string[] = gitDiffOutput.split('\n').filter(Boolean);
|
|
|
|
console.log('Get Diff files:', allChangedFiles);
|
|
|
|
const sourceLangFolder = path.join(__dirname, '../src', sourceLang);
|
|
const sourceLangFolderAbs = path.join('apps/docs/src', sourceLang);
|
|
|
|
// Find all *.md, *.mdx files in sourceLangFolder
|
|
const diffMarkdownFiles: string[] = allChangedFiles
|
|
.filter(
|
|
(file) =>
|
|
file.includes(sourceLangFolderAbs) && (file.endsWith('.md') || file.endsWith('.mdx'))
|
|
)
|
|
.map((file) => path.relative(sourceLangFolderAbs, file));
|
|
|
|
console.log('Files to be translated:', diffMarkdownFiles);
|
|
|
|
// 2. For each file, translate it to other language
|
|
await Promise.all(
|
|
diffMarkdownFiles.map(async (file) => {
|
|
for (const targetLang of targetLangs) {
|
|
const targetLangFolder = path.join(__dirname, '../src', targetLang);
|
|
|
|
const sourceFile = path.join(sourceLangFolder, file);
|
|
const targetFile = path.join(targetLangFolder, file);
|
|
|
|
// 2.1. Read the file
|
|
const sourceContent = fs.readFileSync(sourceFile, 'utf-8');
|
|
|
|
console.log(`Translate ${sourceFile} to ${targetFile}`);
|
|
console.log(sourceContent);
|
|
console.log('\n\n\n\n\n');
|
|
|
|
const previousTargetContent = fs.existsSync(targetFile)
|
|
? fs.readFileSync(targetFile, 'utf-8')
|
|
: undefined;
|
|
|
|
// 2.2. Translate the content
|
|
const targetContent = await translateContent(
|
|
sourceContent,
|
|
targetLang,
|
|
previousTargetContent
|
|
);
|
|
|
|
// 2.3. Write the translated file
|
|
fs.writeFileSync(targetFile, targetContent);
|
|
|
|
console.log(`Translated: ${targetFile}`);
|
|
console.log(targetContent);
|
|
console.log('\n\n\n\n\n');
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
translateFiles().catch((err) => {
|
|
console.error('Error generating docs:', err);
|
|
});
|