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,133 @@
import { execSync } from "child_process";
import fsExtra from "fs-extra";
import { build } from "vite";
import { writeFileSync, existsSync, readFileSync, readdirSync } from "fs";
import { resolve } from "path";
import { pathToFileURL } from "url";
import paths from "../config/paths.js";
import "../util/log.js";
import chalk from "chalk";
const { copySync } = fsExtra;
const packageJSON = JSON.parse(readFileSync(paths.appPackageJson).toString());
function validPackageJSON() {
if (!packageJSON.name) {
return "- package name is required";
}
if (!packageJSON.version) {
return "- package version is required";
}
if (!packageJSON.lowcoder) {
return "- lowcoder field is required in package.json";
}
const lowcoder = packageJSON.lowcoder;
if (!lowcoder.comps || Object.keys(lowcoder.comps).length === 0) {
return "- not found any comps to build";
}
const compErrors = [];
Object.keys(lowcoder.comps).forEach((name) => {
const compManifest = packageJSON.lowcoder.comps[name];
if (!compManifest.icon) {
// compErrors.push(`- comp ${name} must specify an icon`);
return;
}
if (
!compManifest.icon.startsWith("data:") &&
!existsSync(paths.resolveApp(compManifest.icon))
) {
compErrors.push(`- comp ${name}'s icon file ${chalk.cyan(compManifest.icon)} not found`);
return;
}
});
if (compErrors.length > 0) {
return compErrors.join("\n");
}
}
function findReadmeFileName(directory) {
const files = readdirSync(directory);
const readmeFile = files.find(file => file.toLowerCase() === 'readme.md');
return readmeFile ? `${directory}/${readmeFile}` : null;
}
/**
* 1. webpack production build
* 2. generate package.json
* 3. copy locales
* 3. pack tar ball
*/
export default async function buildAction(options) {
const beginTime = performance.now();
process.env.NODE_ENV = "production";
const { outDir } = options;
const err = validPackageJSON();
if (err) {
console.red("Invalid package.json:\n");
console.red(err);
console.log("");
return;
}
const compNames = Object.keys(packageJSON.lowcoder.comps);
console.cyan(`Name : ${packageJSON.name}`);
console.cyan(`Version : ${packageJSON.version}`);
console.cyan(`Comps : ${compNames.length}\n`);
compNames.forEach((i) => {
console.log(` ${i}`);
});
console.log("");
console.cyan("Building...");
const viteConfigURL = pathToFileURL(paths.appViteConfigJs);
const viteConfig = await import(viteConfigURL).default;
console.log(paths.appViteConfigJs);
await build(viteConfig);
// write package.json
packageJSON.lowcoder.entry = "index.js";
writeFileSync(paths.appOutPackageJson, JSON.stringify(packageJSON, null, 2));
// copy locales
if (existsSync(paths.appLocales)) {
copySync(paths.appLocales, resolve(paths.appOutPath, "locales"));
}
// copy icon files
compNames.forEach((name) => {
const compManifest = packageJSON.lowcoder.comps[name];
if (compManifest.icon) {
copySync(paths.resolveApp(compManifest.icon), resolve(paths.appOutPath, compManifest.icon));
}
});
// copy readme file
const readmePath = findReadmeFileName(paths.appPath + '/src');
if (readmePath) {
const destinationPath = resolve(paths.appOutPath, 'readme.md');
copySync(readmePath, destinationPath);
console.log(`Copied README file to: ${destinationPath}`);
} else {
console.warn('README.md file not found.');
}
if (options.publish) {
// publish
execSync("npm publish", {
stdio: "inherit",
cwd: paths.appOutPath,
});
} else {
// pack
const tarOutPath = paths.resolveApp(outDir);
execSync(`npm pack --pack-destination ${tarOutPath}`, {
stdio: "ignore",
cwd: paths.appOutPath,
});
console.green(`Package generated in: ${tarOutPath}`);
}
console.green(`Done in ${Math.round(performance.now() - beginTime)}ms!`);
}

View File

@@ -0,0 +1,109 @@
import path from "path";
import fs from "fs-extra";
import { spawn } from "cross-spawn";
import paths from "../config/paths.js";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const isUsingYarn = (process.env.npm_config_user_agent || "").indexOf("yarn") === 0;
function install(dependencies, registry) {
return new Promise((resolve, reject) => {
let cmd = "npm";
let args = ["install", "--no-audit", "--save", "--save-exact", "--loglevel", "error"];
if (isUsingYarn) {
cmd = "yarn";
args = ["add"];
}
if (registry) {
args.push("--registry", registry);
}
args.push(...dependencies);
const child = spawn(cmd, args, { stdio: "inherit" });
child.on("close", (code) => {
if (code !== 0) {
reject({
command: `${cmd} ${args.join(" ")}`,
});
return;
}
resolve();
});
});
}
async function uninstall(dependencies) {
return new Promise((resolve, reject) => {
let cmd = "npm";
let args = ["uninstall"];
if (isUsingYarn) {
cmd = "yarn";
args = ["remove"];
}
args.push(...dependencies);
const child = spawn(cmd, args, { stdio: "inherit" });
child.on("close", (code) => {
if (code !== 0) {
reject({
command: `${cmd} ${args.join(" ")}`,
});
return;
}
resolve();
});
});
}
/**
* init dir with specified template name
* 1. install template package
* 2. update package.json
* 3. copy template files
* 4. install other dependencies
* 5. uninstall template package
*/
export default async function initAction(options) {
const { template, registry } = options;
const templatePackageName = `lowcoder-cli-template-${template}`;
await install([templatePackageName], registry);
console.log("template package installed");
const templatePackageJsonFile = require.resolve(`${templatePackageName}/package.json`);
const templateDir = path.dirname(templatePackageJsonFile);
const templatePackageJson = fs.readJsonSync(templatePackageJsonFile);
const appPackageJson = fs.readJsonSync(paths.appPackageJson);
appPackageJson.lowcoder = templatePackageJson.lowcoder || {};
appPackageJson.scripts = {
start: "vite",
build: "lowcoder-cli build",
build_publish: "lowcoder-cli build --publish",
};
fs.writeFileSync(paths.appPackageJson, JSON.stringify(appPackageJson, null, 2));
console.log("package.json updated");
const notCopiedFiles = ["package.json", "README.md", "README-template.md", "node_modules"];
fs.copySync(templateDir, "./", {
filter: (src) => notCopiedFiles.every((i) => !src.startsWith(path.join(templateDir, i))),
});
fs.copyFile(path.join(templateDir, "README-template.md"), "./README.md");
console.log("template files copied");
const dependencies = [];
if (template === "typescript") {
dependencies.push("typescript");
}
if (dependencies.length > 0) {
await install(dependencies, registry);
console.log("dependencies installed");
}
await uninstall([templatePackageName]);
console.log("template package uninstalled");
console.log();
console.log("Done! Now, you can run below command to start:");
console.log(` ${isUsingYarn ? "yarn" : "npm"} start`);
console.log();
}