UNPKG

@selfage/bundler_cli

Version:

CLI for bundling and running bundled frontend or backend TypeScript files.

75 lines 14.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_BUNDLED_RESOURCES_FILE = exports.DEFAULT_ENTRIES_CONFIG_FILE = void 0; exports.bundleWebApps = bundleWebApps; exports.bundleWebAppsAndReturnBundledResources = bundleWebAppsAndReturnBundledResources; const fs = require("fs"); const path = require("path"); const stream = require("stream"); const util = require("util"); const yaml = require("yaml"); const zlib = require("zlib"); const bundler_1 = require("./bundler"); const file_extension_stripper_1 = require("./file_extension_stripper"); const files_copier_1 = require("./files_copier"); const web_app_entries_def_1 = require("./web_app_entries_def"); const parser_1 = require("@selfage/message/parser"); let pipeline = util.promisify(stream.pipeline); exports.DEFAULT_ENTRIES_CONFIG_FILE = "web_app_entries.yaml"; exports.DEFAULT_BUNDLED_RESOURCES_FILE = "web_app_resources.yaml"; async function bundleWebApps(entriesConfigFile = exports.DEFAULT_ENTRIES_CONFIG_FILE, bundledResourcesFile = exports.DEFAULT_BUNDLED_RESOURCES_FILE, outDir, options) { let baseDir = path.posix.dirname(entriesConfigFile); let allFiles = await bundleWebAppsAndReturnBundledResources(entriesConfigFile, baseDir, options); let allRelativeFiles = allFiles.map((file) => path.posix.relative(path.posix.dirname(bundledResourcesFile), file)); await fs.promises.writeFile(bundledResourcesFile, yaml.stringify(allRelativeFiles)); if (!outDir || path.posix.normalize(outDir) === path.posix.normalize(baseDir)) { return; } await (0, files_copier_1.copyFilesToDir)(allFiles, baseDir, outDir); } async function bundleWebAppsAndReturnBundledResources(entriesConfigFile, baseDir, options) { let webAppEntries = (0, parser_1.parseMessage)(yaml.parse((await fs.promises.readFile(entriesConfigFile)).toString()), web_app_entries_def_1.WEB_APP_ENTRIES); let allFiles = new Array(); let promises = new Array(); for (let entry of webAppEntries.entries) { promises.push(bundleAndGzip(path.posix.join(baseDir, entry.source), path.posix.join(baseDir, entry.output), baseDir, options, allFiles), writeHtmlFileAndGZip(path.posix.join(baseDir, entry.output), baseDir, allFiles)); } for (let entry of webAppEntries.extraAssets) { promises.push(copyAsset(path.posix.join(baseDir, entry.from), path.posix.join(baseDir, entry.to), allFiles)); } await Promise.all(promises); return allFiles; } async function bundleAndGzip(sourceFile, outputFile, baseDir, options, filesCollector) { let assetFiles = await (0, bundler_1.bundleForBrowserReturnAssetFiles)(sourceFile, outputFile, baseDir, options); let jsFile = (0, file_extension_stripper_1.stripFileExtension)(outputFile) + ".js"; let gzFile = await gzipFile(jsFile); filesCollector.push(...assetFiles, jsFile, gzFile); } async function writeHtmlFileAndGZip(binFile, baseDir, filesCollector) { let binModulePath = (0, file_extension_stripper_1.stripFileExtension)(binFile); let htmlFile = binModulePath + ".html"; let binJsPath = path.posix.relative(baseDir, binModulePath + ".js"); await fs.promises.writeFile(htmlFile, `<!DOCTYPE html> <html> <head><meta charset="UTF-8"></head> <body> <script type="text/javascript" src="/${binJsPath}"></script> </body> </html>`); let gzFile = await gzipFile(htmlFile); filesCollector.push(htmlFile, gzFile); } async function gzipFile(file) { await pipeline(fs.createReadStream(file), zlib.createGzip({ level: 9 }), fs.createWriteStream(file + ".gz")); return file + ".gz"; } async function copyAsset(fromFile, toFile, filesCollector) { if (path.posix.normalize(fromFile) !== path.posix.normalize(toFile)) { await fs.promises.mkdir(path.posix.dirname(toFile), { recursive: true }); await fs.promises.copyFile(fromFile, toFile); } filesCollector.push(toFile); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViX2FwcF9idW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid2ViX2FwcF9idW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQW1CQSxzQ0EyQkM7QUFFRCx3RkF1Q0M7QUF2RkQseUJBQTBCO0FBQzFCLDZCQUE4QjtBQUM5QixpQ0FBa0M7QUFDbEMsNkJBQThCO0FBQzlCLDZCQUE4QjtBQUM5Qiw2QkFBOEI7QUFDOUIsdUNBR21CO0FBQ25CLHVFQUErRDtBQUMvRCxpREFBZ0Q7QUFDaEQsK0RBQXdEO0FBQ3hELG9EQUF1RDtBQUN2RCxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxRQUFBLDJCQUEyQixHQUFHLHNCQUFzQixDQUFDO0FBQ3JELFFBQUEsOEJBQThCLEdBQUcsd0JBQXdCLENBQUM7QUFFOUQsS0FBSyxVQUFVLGFBQWEsQ0FDakMsaUJBQWlCLEdBQUcsbUNBQTJCLEVBQy9DLG9CQUFvQixHQUFHLHNDQUE4QixFQUNyRCxNQUFlLEVBQ2YsT0FBNkI7SUFFN0IsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNwRCxJQUFJLFFBQVEsR0FBRyxNQUFNLHNDQUFzQyxDQUN6RCxpQkFBaUIsRUFDakIsT0FBTyxFQUNQLE9BQU8sQ0FDUixDQUFDO0lBQ0YsSUFBSSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FDcEUsQ0FBQztJQUNGLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQ3pCLG9CQUFvQixFQUNwQixJQUFJLENBQUMsU0FBUyxDQUFDLGdC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aXJlKFwiZnNcIik7XG5pbXBvcnQgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xuaW1wb3J0IHN0cmVhbSA9IHJlcXVpcmUoXCJzdHJlYW1cIik7XG5pbXBvcnQgdXRpbCA9IHJlcXVpcmUoXCJ1dGlsXCIpO1xuaW1wb3J0IHlhbWwgPSByZXF1aXJlKFwieWFtbFwiKTtcbmltcG9ydCB6bGliID0gcmVxdWlyZShcInpsaWJcIik7XG5pbXBvcnQge1xuICBDb21tb25CdW5kbGVPcHRpb25zLFxuICBidW5kbGVGb3JCcm93c2VyUmV0dXJuQXNzZXRGaWxlcyxcbn0gZnJvbSBcIi4vYnVuZGxlclwiO1xuaW1wb3J0IHsgc3RyaXBGaWxlRXh0ZW5zaW9uIH0gZnJvbSBcIi4vZmlsZV9leHRlbnNpb25fc3RyaXBwZXJcIjtcbmltcG9ydCB7IGNvcHlGaWxlc1RvRGlyIH0gZnJvbSBcIi4vZmlsZXNfY29waWVyXCI7XG5pbXBvcnQgeyBXRUJfQVBQX0VOVFJJRVMgfSBmcm9tIFwiLi93ZWJfYXBwX2VudHJpZXNfZGVmXCI7XG5pbXBvcnQgeyBwYXJzZU1lc3NhZ2UgfSBmcm9tIFwiQHNlbGZhZ2UvbWVzc2FnZS9wYXJzZXJcIjtcbmxldCBwaXBlbGluZSA9IHV0aWwucHJvbWlzaWZ5KHN0cmVhbS5waXBlbGluZSk7XG5cbmV4cG9ydCBsZXQgREVGQVVMVF9FTlRSSUVTX0NPTkZJR19GSUxFID0gXCJ3ZWJfYXBwX2VudHJpZXMueWFtbFwiO1xuZXhwb3J0IGxldCBERUZBVUxUX0JVTkRMRURfUkVTT1VSQ0VTX0ZJTEUgPSBcIndlYl9hcHBfcmVzb3VyY2VzLnlhbWxcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1bmRsZVdlYkFwcHMoXG4gIGVudHJpZXNDb25maWdGaWxlID0gREVGQVVMVF9FTlRSSUVTX0NPTkZJR19GSUxFLFxuICBidW5kbGVkUmVzb3VyY2VzRmlsZSA9IERFRkFVTFRfQlVORExFRF9SRVNPVVJDRVNfRklMRSxcbiAgb3V0RGlyPzogc3RyaW5nLFxuICBvcHRpb25zPzogQ29tbW9uQnVuZGxlT3B0aW9ucyxcbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgYmFzZURpciA9IHBhdGgucG9zaXguZGlybmFtZShlbnRyaWVzQ29uZmlnRmlsZSk7XG4gIGxldCBhbGxGaWxlcyA9IGF3YWl0IGJ1bmRsZVdlYkFwcHNBbmRSZXR1cm5CdW5kbGVkUmVzb3VyY2VzKFxuICAgIGVudHJpZXNDb25maWdGaWxlLFxuICAgIGJhc2VEaXIsXG4gICAgb3B0aW9ucyxcbiAgKTtcbiAgbGV0IGFsbFJlbGF0aXZlRmlsZXMgPSBhbGxGaWxlcy5tYXAoKGZpbGUpID0+XG4gICAgcGF0aC5wb3NpeC5yZWxhdGl2ZShwYXRoLnBvc2l4LmRpcm5hbWUoYnVuZGxlZFJlc291cmNlc0ZpbGUpLCBmaWxlKSxcbiAgKTtcbiAgYXdhaXQgZnMucHJvbWlzZXMud3JpdGVGaWxlKFxuICAgIGJ1bmRsZWRSZXNvdXJjZXNGaWxlLFxuICAgIHlhbWwuc3RyaW5naWZ5KGFsbFJlbGF0aXZlRmlsZXMpLFxuICApO1xuXG4gIGlmIChcbiAgICAhb3V0RGlyIHx8XG4gICAgcGF0aC5wb3NpeC5ub3JtYWxpemUob3V0RGlyKSA9PT0gcGF0aC5wb3NpeC5ub3JtYWxpemUoYmFzZURpcilcbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGF3YWl0IGNvcHlGaWxlc1RvRGlyKGFsbEZpbGVzLCBiYXNlRGlyLCBvdXREaXIpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVuZGxlV2ViQXBwc0FuZFJldHVybkJ1bmRsZWRSZXNvdXJjZXMoXG4gIGVudHJpZXNDb25maWdGaWxlOiBzdHJpbmcsXG4gIGJhc2VEaXI6IHN0cmluZyxcbiAgb3B0aW9ucz86IENvbW1vbkJ1bmRsZU9wdGlvbnMsXG4pOiBQcm9taXNlPEFycmF5PHN0cmluZz4+IHtcbiAgbGV0IHdlYkFwcEVudHJpZXMgPSBwYXJzZU1lc3NhZ2UoXG4gICAgeWFtbC5wYXJzZSgoYXdhaXQgZnMucHJvbWlzZXMucmVhZEZpbGUoZW50cmllc0NvbmZpZ0ZpbGUpKS50b1N0cmluZygpKSxcbiAgICBXRUJfQVBQX0VOVFJJRVMsXG4gICk7XG5cbiAgbGV0IGFsbEZpbGVzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgbGV0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dm9pZD4+KCk7XG4gIGZvciAobGV0IGVudHJ5IG9mIHdlYkFwcEVudHJpZXMuZW50cmllcykge1xuICAgIHByb21pc2VzLnB1c2goXG4gICAgICBidW5kbGVBbmRHemlwKFxuICAgICAgICBwYXRoLnBvc2l4LmpvaW4oYmFzZURpciwgZW50cnkuc291cmNlKSxcbiAgICAgICAgcGF0aC5wb3NpeC5qb2luKGJhc2VEaXIsIGVudHJ5Lm91dHB1dCksXG4gICAgICAgIGJhc2VEaXIsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIGFsbEZpbGVzLFxuICAgICAgKSxcbiAgICAgIHdyaXRlSHRtbEZpbGVBbmRHWmlwKFxuICAgICAgICBwYXRoLnBvc2l4LmpvaW4oYmFzZURpciwgZW50cnkub3V0cHV0KSxcbiAgICAgICAgYmFzZURpcixcbiAgICAgICAgYWxsRmlsZXMsXG4gICAgICApLFxuICAgICk7XG4gIH1cbiAgZm9yIChsZXQgZW50cnkgb2Ygd2ViQXBwRW50cmllcy5leHRyYUFzc2V0cykge1xuICAgIHByb21pc2VzLnB1c2goXG4gICAgICBjb3B5QXNzZXQoXG4gICAgICAgIHBhdGgucG9zaXguam9pbihiYXNlRGlyLCBlbnRyeS5mcm9tKSxcbiAgICAgICAgcGF0aC5wb3NpeC5qb2luKGJhc2VEaXIsIGVudHJ5LnRvKSxcbiAgICAgICAgYWxsRmlsZXMsXG4gICAgICApLFxuICAgICk7XG4gIH1cbiAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICByZXR1cm4gYWxsRmlsZXM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGJ1bmRsZUFuZEd6aXAoXG4gIHNvdXJjZUZpbGU6IHN0cmluZyxcbiAgb3V0cHV0RmlsZTogc3RyaW5nLFxuICBiYXNlRGlyOiBzdHJpbmcsXG4gIG9wdGlvbnM6IENvbW1vbkJ1bmRsZU9wdGlvbnMsXG4gIGZpbGVzQ29sbGVjdG9yOiBBcnJheTxzdHJpbmc+LFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGxldCBhc3NldEZpbGVzID0gYXdhaXQgYnVuZGxlRm9yQnJvd3NlclJldHVybkFzc2V0RmlsZXMoXG4gICAgc291cmNlRmlsZSxcbiAgICBvdXRwdXRGaWxlLFxuICAgIGJhc2VEaXIsXG4gICAgb3B0aW9ucyxcbiAgKTtcbiAgbGV0IGpzRmlsZSA9IHN0cmlwRmlsZUV4dGVuc2lvbihvdXRwdXRGaWxlKSArIFwiLmpzXCI7XG4gIGxldCBnekZpbGUgPSBhd2FpdCBnemlwRmlsZShqc0ZpbGUpO1xuICBmaWxlc0NvbGxlY3Rvci5wdXNoKC4uLmFzc2V0RmlsZXMsIGpzRmlsZSwgZ3pGaWxlKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gd3JpdGVIdG1sRmlsZUFuZEdaaXAoXG4gIGJpbkZpbGU6IHN0cmluZyxcbiAgYmFzZURpcjogc3RyaW5nLFxuICBmaWxlc0NvbGxlY3RvcjogQXJyYXk8c3RyaW5nPixcbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgYmluTW9kdWxlUGF0aCA9IHN0cmlwRmlsZUV4dGVuc2lvbihiaW5GaWxlKTtcbiAgbGV0IGh0bWxGaWxlID0gYmluTW9kdWxlUGF0aCArIFwiLmh0bWxcIjtcbiAgbGV0IGJpbkpzUGF0aCA9IHBhdGgucG9zaXgucmVsYXRpdmUoYmFzZURpciwgYmluTW9kdWxlUGF0aCArIFwiLmpzXCIpO1xuICBhd2FpdCBmcy5wcm9taXNlcy53cml0ZUZpbGUoXG4gICAgaHRtbEZpbGUsXG4gICAgYDwhRE9DVFlQRSBodG1sPlxuPGh0bWw+XG4gIDxoZWFkPjxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPjwvaGVhZD5cbiAgPGJvZHk+XG4gICAgPHNjcmlwdCB0eXBlPVwidGV4dC9qYXZhc2NyaXB0XCIgc3JjPVwiLyR7YmluSnNQYXRofVwiPjwvc2NyaXB0PlxuICA8L2JvZHk+XG48L2h0bWw+YCxcbiAgKTtcbiAgbGV0IGd6RmlsZSA9IGF3YWl0IGd6aXBGaWxlKGh0bWxGaWxlKTtcbiAgZmlsZXNDb2xsZWN0b3IucHVzaChodG1sRmlsZSwgZ3pGaWxlKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ3ppcEZpbGUoZmlsZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgYXdhaXQgcGlwZWxpbmUoXG4gICAgZnMuY3JlYXRlUmVhZFN0cmVhbShmaWxlKSxcbiAgICB6bGliLmNyZWF0ZUd6aXAoeyBsZXZlbDogOSB9KSxcbiAgICBmcy5jcmVhdGVXcml0ZVN0cmVhbShmaWxlICsgXCIuZ3pcIiksXG4gICk7XG4gIHJldHVybiBmaWxlICsgXCIuZ3pcIjtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY29weUFzc2V0KFxuICBmcm9tRmlsZTogc3RyaW5nLFxuICB0b0ZpbGU6IHN0cmluZyxcbiAgZmlsZXNDb2xsZWN0b3I6IEFycmF5PHN0cmluZz4sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKHBhdGgucG9zaXgubm9ybWFsaXplKGZyb21GaWxlKSAhPT0gcGF0aC5wb3NpeC5ub3JtYWxpemUodG9GaWxlKSkge1xuICAgIGF3YWl0IGZzLnByb21pc2VzLm1rZGlyKHBhdGgucG9zaXguZGlybmFtZSh0b0ZpbGUpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBhd2FpdCBmcy5wcm9taXNlcy5jb3B5RmlsZShmcm9tRmlsZSwgdG9GaWxlKTtcbiAgfVxuICBmaWxlc0NvbGxlY3Rvci5wdXNoKHRvRmlsZSk7XG59XG4iXX0=