Updates
This commit is contained in:
115
lowcoder/client/scripts/build.js
Normal file
115
lowcoder/client/scripts/build.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import fs from "node:fs";
|
||||
import path, { dirname } from "node:path";
|
||||
import https from "node:https";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import shell from "shelljs";
|
||||
import chalk from "chalk";
|
||||
import axios from "axios";
|
||||
import { buildVars } from "./buildVars.js";
|
||||
|
||||
export function readJson(file) {
|
||||
return JSON.parse(fs.readFileSync(file).toString());
|
||||
}
|
||||
|
||||
export function currentDirName(importMetaUrl) {
|
||||
return dirname(fileURLToPath(importMetaUrl));
|
||||
}
|
||||
|
||||
const builtinPlugins = ["lowcoder-comps"];
|
||||
const curDirName = currentDirName(import.meta.url);
|
||||
|
||||
async function downloadFile(url, dest) {
|
||||
const file = fs.createWriteStream(dest);
|
||||
return new Promise((resolve, reject) => {
|
||||
https
|
||||
.get(url, function (response) {
|
||||
response.pipe(file);
|
||||
file.on("finish", function () {
|
||||
file.close(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
})
|
||||
.on("error", function (err) {
|
||||
fs.unlink(dest);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function downloadBuiltinPlugin(name) {
|
||||
console.log();
|
||||
console.log(chalk.cyan`plugin ${name} downloading...`);
|
||||
|
||||
const packageRes = await axios.get(`https://registry.npmjs.com/${name}/latest`);
|
||||
const tarball = packageRes.data.dist.tarball;
|
||||
const tarballFileName = `${name}.tgz`;
|
||||
const targetDir = `./packages/lowcoder/build/${name}/latest`;
|
||||
|
||||
console.log(chalk.blue`tarball: ${tarball}`);
|
||||
|
||||
shell.mkdir("-p", targetDir);
|
||||
|
||||
await downloadFile(tarball, path.join(process.cwd(), tarballFileName));
|
||||
|
||||
shell.exec(`tar -zxf ${tarballFileName} -C ${targetDir} --strip-components 1`, { fatal: true });
|
||||
shell.rm(tarballFileName);
|
||||
}
|
||||
|
||||
async function buildBuiltinPlugin(name) {
|
||||
console.log();
|
||||
console.log(chalk.cyan`plugin ${name} building...`);
|
||||
|
||||
const targetDir = `./packages/lowcoder/build/${name}/latest`;
|
||||
shell.mkdir("-p", targetDir);
|
||||
|
||||
shell.exec(`yarn workspace ${name} build_only`, { fatal: true });
|
||||
|
||||
const packageJsonFile = path.join(curDirName, `../packages/${name}/package.json`);
|
||||
const packageJSON = readJson(packageJsonFile);
|
||||
const tarballFileName = `./packages/${name}/${name}-${packageJSON.version}.tgz`;
|
||||
|
||||
shell.exec(`tar -zxf ${tarballFileName} -C ${targetDir} --strip-components 1`, { fatal: true });
|
||||
shell.rm(tarballFileName);
|
||||
}
|
||||
|
||||
shell.set("-e");
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
//prettier-ignore
|
||||
shell.env["REACT_APP_COMMIT_ID"] = shell.env["REACT_APP_COMMIT_ID"] || shell.exec("git rev-parse --short HEAD", {silent: true}).trim();
|
||||
|
||||
// Treating warnings as errors when process.env.CI = true.
|
||||
shell.env["CI"] = false;
|
||||
shell.env["NODE_OPTIONS"] = "--max_old_space_size=8192";
|
||||
shell.env["NODE_ENV"] = "production";
|
||||
shell.env["REACT_APP_LOG_LEVEL"] = "error";
|
||||
shell.env["REACT_APP_BUNDLE_BUILTIN_PLUGIN"] = "true";
|
||||
|
||||
buildVars.forEach(({ name, defaultValue }) => {
|
||||
shell.env[name] = shell.env[name] ?? defaultValue;
|
||||
});
|
||||
|
||||
shell.exec(`BUILD_TARGET=browserCheck yarn workspace lowcoder build`, { fatal: true });
|
||||
shell.exec(`yarn workspace lowcoder build`, { fatal: true });
|
||||
|
||||
if (process.env.REACT_APP_BUNDLE_BUILTIN_PLUGIN) {
|
||||
for (const pluginName of builtinPlugins) {
|
||||
await buildBuiltinPlugin(pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv.includes("--internal-deploy")) {
|
||||
const deployDir = shell.env["DEPLOY_DIR"];
|
||||
console.log();
|
||||
console.log(chalk.cyan`deploying...`);
|
||||
shell.exec("docker cp ./packages/lowcoder/build lowcoder-fe:/var/www/", { fatal: true });
|
||||
shell.exec(
|
||||
`docker exec lowcoder-fe /bin/sh -c "cd /var/www/ && rm -rf ${deployDir} && mv build ${deployDir}"`,
|
||||
{ fatal: true }
|
||||
);
|
||||
}
|
||||
|
||||
console.log();
|
||||
console.log(chalk.green`Done! time: ${((Date.now() - start) / 1000).toFixed(2)}s`);
|
||||
58
lowcoder/client/scripts/buildVars.js
Normal file
58
lowcoder/client/scripts/buildVars.js
Normal file
@@ -0,0 +1,58 @@
|
||||
export const buildVars = [
|
||||
{
|
||||
name: "PUBLIC_URL",
|
||||
defaultValue: "/",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_EDITION",
|
||||
defaultValue: "community",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_LANGUAGES",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_COMMIT_ID",
|
||||
defaultValue: "00000",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_API_SERVICE_URL",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_NODE_SERVICE_URL",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_ENV",
|
||||
defaultValue: "production",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_BUILD_ID",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_LOG_LEVEL",
|
||||
defaultValue: "error",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_IMPORT_MAP",
|
||||
defaultValue: "{}",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_SERVER_IPS",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_BUNDLE_BUILTIN_PLUGIN",
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_BUNDLE_TYPE",
|
||||
defaultValue: "app",
|
||||
},
|
||||
{
|
||||
name: "REACT_APP_DISABLE_JS_SANDBOX",
|
||||
defaultValue: "",
|
||||
},
|
||||
];
|
||||
88
lowcoder/client/scripts/translate.js
Normal file
88
lowcoder/client/scripts/translate.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import fs from "node:fs";
|
||||
import path, { dirname } from "node:path";
|
||||
import axios from "axios";
|
||||
|
||||
const translationsDir = './packages/lowcoder/src/i18n/locales'; // Directory where language files are stored
|
||||
const masterLang = 'en'; // Master language code
|
||||
const DEEPL_API_URL = 'https://api.deepl.com/v2/translate';
|
||||
|
||||
// Function to send a request to the DeepL API for translation
|
||||
async function translateText(texts, context, sourceLang = 'en', targetLang = 'de', apiKey) {
|
||||
try {
|
||||
const requestBody = {
|
||||
text: texts,
|
||||
source_lang: sourceLang,
|
||||
target_lang: targetLang,
|
||||
context: context,
|
||||
split_sentences: '1',
|
||||
preserve_formatting: true,
|
||||
formality: 'default',
|
||||
outline_detection: true
|
||||
};
|
||||
|
||||
const response = await axios.post(DEEPL_API_URL, requestBody, {
|
||||
headers: {
|
||||
'Authorization': `DeepL-Auth-Key ${apiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
return response.data.translations.map((translation) => translation.text);
|
||||
} catch (error) {
|
||||
console.error('Translation error:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive function to translate and update untranslated keys
|
||||
async function translateNestedKeys(object, targetObject, context = '', lang, apiKey) {
|
||||
for (const key in object) {
|
||||
if (typeof object[key] === 'string' && (!targetObject[key] || targetObject[key] === object[key])) {
|
||||
console.log(`Translating key: ${context}.${key}`);
|
||||
const translatedTexts = await translateText([object[key]], `${context}.${key}`, masterLang, lang, apiKey);
|
||||
targetObject[key] = translatedTexts[0];
|
||||
} else if (typeof object[key] === 'object' && object[key] !== null && !(object[key] instanceof Array)) {
|
||||
targetObject[key] = targetObject[key] || {};
|
||||
await translateNestedKeys(object[key], targetObject[key], context ? `${context}.${key}` : key, lang, apiKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main function to load translation files and start the translation process
|
||||
async function translateAndUpdate(lang, apiKey) {
|
||||
const sourcePath = path.join(`${masterLang}.ts`);
|
||||
const targetPath = path.join(`${lang}.ts`);
|
||||
|
||||
process.chdir(translationsDir);
|
||||
|
||||
console.log("Current working directory:", process.cwd());
|
||||
console.log(`Translating from ${sourcePath} to ${targetPath}...`);
|
||||
|
||||
try {
|
||||
// Import source and target asynchronously
|
||||
const sourceModule = await import(sourcePath);
|
||||
const targetModule = await import(targetPath);
|
||||
|
||||
// Extract the exported objects assuming default exports
|
||||
const source = sourceModule[masterLang];
|
||||
const target = targetModule[lang] || {};
|
||||
|
||||
console.log(`Source productDesc: ${target.productDesc},`);
|
||||
|
||||
// await translateNestedKeys(source, target, '', lang, apiKey);
|
||||
// fs.writeFileSync(targetPath, `export const ${lang}: typeof ${masterLang} = ${JSON.stringify(target, null, 2)};`, 'utf8');
|
||||
console.log(`Updated ${lang} translation file.`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading translation files or translating:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Get language code and API key from the command line arguments
|
||||
const langCode = process.argv[2] || 'de'; // Default to 'de' if no argument provided
|
||||
const apiKey = process.argv[3]; // Use the provided API key
|
||||
|
||||
console.log(`Translating to ${langCode} with API key: ${apiKey}`);
|
||||
|
||||
// Uncomment the line below to activate translation when you run the script
|
||||
translateAndUpdate(langCode, apiKey).catch(console.error);
|
||||
Reference in New Issue
Block a user