rjweb-server
Version:
Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS
341 lines (340 loc) • 12.9 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var import__ = require(".");
var import_rjutils_collection = require("rjutils-collection");
var import_logger = require("./classes/logger");
var import_server = __toESM(require("./classes/server"));
var import_child_process = require("child_process");
var import_https = __toESM(require("https"));
var import_yargs = __toESM(require("yargs"));
var import_posix = __toESM(require("path/posix"));
var import_path = __toESM(require("path"));
var import_fs = __toESM(require("fs"));
const prefix = `\u26A1 ${import_logger.colors.fg.white}[RJWEB ${import__.Version.split(".")[0]}]${import_logger.colors.fg.gray}:${import_logger.colors.reset}`;
const coloredPath = (path2) => {
let output = [];
for (const part of path2.split("/")) {
output.push(`${import_logger.colors.fg.blue}${part}`);
}
return output.join(`${import_logger.colors.fg.cyan}/`);
};
const pR = (location) => {
return import_path.default.join(process.cwd(), location);
};
const isX = (type, path2) => {
let infos;
try {
infos = import_fs.default.statSync(path2);
} catch {
return false;
}
if (type === "dir")
return infos.isDirectory();
else
return infos.isFile();
};
import_yargs.default.scriptName("rjweb").usage("$0 <command> [args]").version(import__.Version).command(
"serve <folder>",
"Serve a Folder",
(cmd) => cmd.positional("folder", {
type: "string",
description: "The Folder to serve",
demandOption: true
}).option("port", {
type: "number",
description: "The port on which to serve",
alias: ["p"],
default: 8080
}).option("hideHTML", {
type: "boolean",
description: "Whether to remove html file endings",
alias: ["html", "h", "hH"],
default: false
}).option("compress", {
type: "boolean",
description: "Whether to compress outgoing data",
alias: ["C"],
default: true
}).option("cors", {
type: "boolean",
description: "Whether to enable * CORS headers",
alias: ["c"],
default: false
}).option("proxy", {
type: "boolean",
description: "Whether to enable using X-Forwarded-For Header",
alias: ["P"],
default: false
}).option("bind", {
type: "string",
description: "Where to bind the Server to",
alias: ["b"],
default: "0.0.0.0"
}).option("404-file", {
type: "string",
description: "The file to print when a route is not found",
alias: ["404"],
default: ""
}).option("dashboard", {
type: "boolean",
description: "Whether to enable the built-in dashboard (/rjweb-dashboard)",
alias: ["d", "dash"],
default: false
}).option("dashboard-password", {
type: "string",
description: "The password for the dashboard",
alias: ["dP", "pass"],
default: ""
}),
(args) => {
if (!isX("dir", pR(args.folder ?? "//")))
return console.error(`${prefix} ${import_logger.colors.fg.red}Couldnt find ${import_logger.colors.fg.cyan}${args.folder}`);
if (args["404File"] && !isX("file", pR(args["404File"] ?? "//")))
return console.error(`${prefix} ${import_logger.colors.fg.red}Couldnt find ${import_logger.colors.fg.cyan}${args["404File"]}`);
const server = new import_server.default({
port: args.port,
dashboard: {
enabled: args.dashboard,
password: args.dashboardPassword
},
httpCompression: {
enabled: args.compress
},
cors: args.cors,
proxy: {
enabled: args.proxy
},
bind: args.bind
}, []);
server.path(
"/",
(path2) => path2.static(pR(args.folder), {
hideHTML: args.hideHTML
})
);
server.on("httpRequest", (ctr) => {
console.log(`${prefix} ${import_logger.colors.fg.gray}${ctr.client.ip} ${import_logger.colors.fg.green}HTTP ${ctr.url.method} ${import_logger.colors.fg.cyan}${coloredPath(ctr.url.path)}`);
});
if (args["404File"])
server.on("route404", (ctr) => {
ctr.status(import__.Status.NOT_FOUND).printFile(pR(args["404File"]));
});
server.start().then((port) => {
console.log(`${prefix} ${import_logger.colors.fg.green}Started on Port ${import_logger.colors.fg.cyan}${port}`);
}).catch((err) => {
console.error(`${prefix} ${import_logger.colors.fg.red}An Error occured while starting the Server:`);
console.error(`${import_logger.colors.fg.cyan}${err.stack}`);
process.exit(1);
});
}
).command(
"generate <folder>",
"Generate a template Project",
(cmd) => cmd.positional("folder", {
type: "string",
description: "The Folder to generate the template in",
demandOption: true
}).option("template", {
type: "string",
description: "Which template to use",
alias: ["E"],
default: "choose"
}).option("variant", {
type: "string",
description: "The Variant of the template to use",
alias: ["V"],
default: "choose"
}),
async (args) => {
const { default: inquirer } = await import("inquirer");
console.log(`${prefix} ${import_logger.colors.fg.gray}Fetching Templates from GitHub...`);
const templates = [];
JSON.parse((await new Promise((resolve, reject) => {
const chunks = [];
import_https.default.get({
path: "/repos/0x7d8/NPM_WEB-SERVER/contents/templates",
host: "api.github.com",
port: 443,
headers: {
"User-Agent": `rjweb-server@cli ${import__.Version}`,
"Accept": "application/vnd.github.v3+json"
}
}, (res) => {
res.on("data", (data) => {
chunks.push(data);
}).once("error", reject).once("end", () => {
resolve(Buffer.concat(chunks));
});
});
})).toString()).filter((t) => t.type === "dir").forEach((template2) => {
const variant2 = template2.name.match(/\[.*\] /)[0].replace(/\[|\]/g, "").trim();
const name = template2.name.replace(/\[.*\] /, "");
if (templates.some((t) => t.name === name)) {
const index = templates.findIndex((t) => t.name === name);
templates[index].variants.push({
name: variant2,
git: template2
});
} else {
templates.push({
name,
variants: [
{
name: variant2,
git: template2
}
]
});
}
});
let template = "", variant = "";
if (args.template !== "choose" && templates.some((t) => t.name === args.template)) {
template = args.template;
console.log(`${prefix} ${import_logger.colors.fg.gray}Using ${import_logger.colors.fg.cyan}${template}`);
} else {
if (args.template !== "choose")
console.log(`${prefix} ${import_logger.colors.fg.cyan}${args.template} ${import_logger.colors.fg.red}is not a valid template!`);
await inquirer.prompt([
{
name: "Template",
type: "list",
prefix,
choices: templates.map((t) => t.name),
askAnswered: true
}
]).then((answers) => {
template = answers.Template;
});
}
if (args.variant !== "choose" && templates.some((t) => t.name === args.variant)) {
variant = args.variant;
console.log(`${prefix} ${import_logger.colors.fg.gray}Using Variant ${import_logger.colors.fg.cyan}${variant}`);
} else {
if (args.variant !== "choose")
console.log(`${prefix} ${import_logger.colors.fg.cyan}${args.template} ${import_logger.colors.fg.red}is not a valid template!`);
await inquirer.prompt([
{
name: "Variant",
type: "list",
prefix,
choices: templates.find((t) => t.name === template).variants.map((v) => v.name),
askAnswered: true
}
]).then((answers) => {
variant = answers.Variant;
});
}
if (!import_fs.default.existsSync(import_path.default.join(process.cwd(), args.folder))) {
await import_fs.default.promises.mkdir(import_path.default.join(process.cwd(), args.folder));
}
console.log(`${prefix} ${import_logger.colors.fg.gray}Generating Template Project...`);
const handleDirectory = async (directory) => {
const files = JSON.parse((await new Promise((resolve, reject) => {
const chunks = [];
import_https.default.get({
path: new URL(directory).pathname,
host: "api.github.com",
port: 443,
headers: {
"User-Agent": `rjweb-server@cli ${import__.Version}`,
"Accept": "application/vnd.github.v3+json"
}
}, (res) => {
res.on("data", (data) => {
chunks.push(data);
}).once("error", reject).once("end", () => {
resolve(Buffer.concat(chunks));
});
});
})).toString());
if (Array.isArray(files)) {
for (const file of files) {
if (file.type === "dir") {
if (!import_fs.default.existsSync(import_posix.default.join(process.cwd(), args.folder, file.path.replace(`templates/[${variant}] ${template}`, "")))) {
await import_fs.default.promises.mkdir(import_posix.default.join(process.cwd(), args.folder, file.path.replace(`templates/[${variant}] ${template}`, "")));
}
}
await handleDirectory(file.url);
}
} else {
const file = files;
if (file.name === "yarn.lock")
return;
console.log(`${prefix} ${import_logger.colors.fg.green}Downloaded ${import_logger.colors.fg.cyan}${import_path.default.join(args.folder, file.path.replace(`templates/[${variant}] ${template}`, ""))}`);
await import_fs.default.promises.writeFile(import_path.default.join(process.cwd(), args.folder, file.path.replace(`templates/[${variant}] ${template}`, "")), Buffer.from(file.content, "base64").toString());
}
};
await handleDirectory(templates.find((t) => t.name === template).variants.find((v) => v.name === variant).git.url);
console.log("");
console.log(`${prefix} ${import_logger.colors.fg.green}Template Project Generated!`);
console.log("");
let availablePackageManagers = [];
try {
(0, import_child_process.execSync)("npm --version", {
stdio: "ignore"
});
availablePackageManagers.push("npm");
} catch {
}
try {
(0, import_child_process.execSync)("yarn --version", {
stdio: "ignore"
});
availablePackageManagers.push("yarn");
} catch {
}
try {
(0, import_child_process.execSync)("pnpm --version", {
stdio: "ignore"
});
availablePackageManagers.push("pnpm");
} catch {
}
let continueWith = "npm";
await inquirer.prompt([
{
name: "Continue with",
type: "list",
prefix,
choices: availablePackageManagers,
askAnswered: true
}
]).then((answers) => {
continueWith = answers["Continue with"];
});
const spinner = new import_rjutils_collection.Spinner();
const runInterval = () => {
process.stdout.write(`\r${prefix} ${import_logger.colors.fg.yellow}${spinner.get()} ${import_logger.colors.fg.gray}Installing Dependencies with ${import_logger.colors.fg.cyan}${continueWith}${import_logger.colors.fg.gray}...`);
};
const interval = setInterval(runInterval, 175);
runInterval();
process.chdir(import_path.default.join(process.cwd(), args.folder));
(0, import_child_process.exec)(`${continueWith} install`, () => {
clearInterval(interval);
process.stdout.write("\n");
console.log(`${prefix} ${import_logger.colors.fg.green}Installed Dependencies!${import_logger.colors.reset}`);
});
}
).help().argv;