This commit is contained in:
2025-11-17 18:45:35 +01:00
parent 0f58e3bdff
commit 14d6f9aa73
7607 changed files with 1969407 additions and 0 deletions

View 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`);

View 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: "",
},
];

View 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);