UNPKG

@topgroup/diginext

Version:

A BUILD SERVER & CLI to deploy apps to any Kubernetes clusters.

262 lines (261 loc) 11 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.disableCDN = exports.enableCDN = exports.loadVersionCacheCDNFromEnv = exports.purgeAllCache = exports.purgeProject = exports.startUpload = void 0; const cli_progress_1 = __importDefault(require("cli-progress")); const array_1 = require("diginext-utils/dist/array"); const log_1 = require("diginext-utils/dist/xconsole/log"); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const plugins_1 = require("../../plugins"); const ask_project_and_app_1 = require("../apps/ask-project-and-app"); const ask_for_storage_1 = require("./ask-for-storage"); // config // const defaultPattern = "./{public,.next/static}/**/*.*"; const defaultPattern = "./public/**/*.*"; // const pattern = "./public/**/*.*"; let projectName = "cli-test-project"; let storage; // let projectSlug = ""; // let shouldOptimize = false; // let isProduction = false; const maxConcurrentUploadFiles = 5; // progress bar const progressBar = new cli_progress_1.default.SingleBar({}, cli_progress_1.default.Presets.legacy); let uploadedCount = 0, totalCount = 0; let failedItems = []; let uploadItems = []; async function purgeDirectory(dirPath, options) { // GOOGLE CLOUD if (!dirPath) { (0, log_1.logError)("Không tìm thấy resource path"); return; } // const command = `gcloud compute url-maps invalidate-cdn-cache digitop-cdn-lb --host google-cdn.digitop.vn --path '${dirPath}' --async`; // log(command); // await cliContainerExec(command, options); // Use GOOGLE CDN HELPER API: await (0, plugins_1.invalidateCache)(dirPath); } async function upload(env, onComplete, options) { if (uploadedCount > uploadItems.length - 1) { progressBar.update(uploadedCount); progressBar.stop(); return; } options = options || {}; const version = options.hasOwnProperty("version") ? options.version : ""; let filePath = uploadItems[uploadedCount]; // filePath = filePath.replace("public/", `public${version}/`); if (options.isDebugging) { console.log("-----------------------------------"); console.log("[upload] uploadedCount :>> ", uploadedCount); console.log("[upload] totalCount :>> ", uploadItems.length - 1); console.log("[upload] version :>> ", version); console.log("[upload] filePath :>> ", filePath); console.log("[upload] projectName :>> ", projectName); } uploadedCount++; const checkFinish = (resolve) => { progressBar.update(uploadedCount); if (uploadedCount >= totalCount) { progressBar.stop(); // FINISH UPLOADING... if (failedItems.length > 0) { console.warn(`[WARNING] Unable to upload these files:`); failedItems.forEach((item) => { console.warn(`\n- ${item.path} (${item.reason})`); }); } if (onComplete) onComplete(); } else { upload(env, onComplete, options); } resolve(); }; return new Promise(async (resolve, reject) => { // UPLOAD TO GOOGLE CLOUD STORAGE: let destination = `${projectName}/${env}/${filePath}`; // attach "version" to destination files destination = destination.replace("public/", `public${version}/`); // NOTE: For "Next.js" project only destination = destination.replace(/\.next/g, "_next"); try { // init service const { CloudStorageService } = await Promise.resolve().then(() => __importStar(require("../../services"))); const svc = new CloudStorageService(); // use service to upload const uploadRes = await svc.uploadFileFromFilePath(storage, filePath, destination, { cacheControl: "public, max-age=31536000", contentEncoding: "gzip", }); // console.log("uploadRes :>> ", uploadRes); // await uploadFile(filePath, destination); } catch (e) { console.error(e); console.error(`[ERROR] Unable to upload file to "${storage.name} / ${storage.bucket}" storage: "${filePath}"`); resolve(e); } checkFinish(resolve); }); } function uploadBatch(concurrency, env, onComplete, options) { for (let i = 0; i < concurrency; i++) { upload(env, onComplete, options); } } /** * Upload static files of current working project to Cloud Storage */ async function startUpload(options, onComplete) { const { version = "", env = "dev" } = options; // ask for project const { project } = await (0, ask_project_and_app_1.askForProjectAndApp)(options.targetDirectory, options); // ask for storage storage = await (0, ask_for_storage_1.askForStorage)(); if (options.isDebugging) console.log("storage :>> ", storage); projectName = project.slug; // reset arrays failedItems = []; uploadItems = []; failedItems = []; // parse static directory path: let uploadPathPattern = defaultPattern; if (uploadPathPattern.substring(0, 2) == "./") uploadPathPattern = uploadPathPattern.substring(2); if (options.path) { options.path = options.path.trim(); if (options.path.charAt(0) == "/") { options.path = options.path.substring(1); } else if (options.path.substring(0, 2) == "./") { options.path = options.path.substring(2); } const lastChar = options.path.slice(-1); if (lastChar == "/") options.path = options.path.substring(0, options.path.length - 1); uploadPathPattern = `${options.path}/**/*.*`; } // log(`Uploading "${uploadPathPattern}" to "${DIGITOP_CDN_URL}/${projectName}/${env}"`); const globby = require("globby"); const files = await globby(uploadPathPattern); uploadedCount = 0; totalCount = files.length; uploadItems = [...files]; if (options.isDebugging) { console.log(`[CDN] Start uploading > totalCount :>>`, totalCount); console.log(`[CDN] Start uploading > uploadItems :>>`, uploadItems); } progressBar.start(totalCount, 0); function onFinishUpload() { (0, log_1.logSuccess)(`Finished uploading files to "${env}" CDN of "${projectName}" project.`); if (onComplete) onComplete({ env, project: projectName, items: uploadItems }); process.exit(1); } uploadBatch(maxConcurrentUploadFiles, env, onFinishUpload, { version, isDebugging: options.isDebugging }); // NOTE: max wait time: 8 hours await (0, plugins_1.wait)(8 * 60 * 60 * 1000); } exports.startUpload = startUpload; async function purgeProject(options) { const config = (0, plugins_1.getAppConfig)(); const { slug } = config; const { env } = options; // GOOGLE CLOUD await purgeDirectory(`/${slug}/${env}/*`, options); } exports.purgeProject = purgeProject; async function purgeAllCache(options) { const config = (0, plugins_1.getAppConfig)(); const { slug } = config; // GOOGLE CLOUD await purgeDirectory(`/${slug}/*`, options); // DIGITAL OCEAN // TODO: Implement DigitalOcean SPACE purging cache feature } exports.purgeAllCache = purgeAllCache; const loadVersionCacheCDNFromEnv = (options) => { const { env } = options; // let version = ""; //load .env.prod const envFilePath = (0, plugins_1.resolveEnvFilePath)({ env, ignoreIfNotExisted: false, targetDirectory: options.targetDirectory }); if (fs_1.default.existsSync(envFilePath)) { const rawdata = fs_1.default.readFileSync(envFilePath).toString(); // search NEXT_PUBLIC_VERSION_CDN in env // add NEXT_PUBLIC_VERSION_CDN if not found !!! edited: DO NOT ADD // return version const result = rawdata.match(/(\nNEXT_PUBLIC_VERSION_CDN=\/v[0-9]+)/); if ((0, array_1.firstElement)(result)) { const firstEle = (0, array_1.firstElement)(result); version = firstEle.replace("\nNEXT_PUBLIC_VERSION_CDN=", ""); } else { // fs.appendFileSync(envFilePath, `\nNEXT_PUBLIC_VERSION_CDN=${version}`); } } else { version = "latest"; } return version; }; exports.loadVersionCacheCDNFromEnv = loadVersionCacheCDNFromEnv; function enableCDN(options) { const { env } = options; (0, exports.loadVersionCacheCDNFromEnv)(options); let configFile = path_1.default.resolve("dx.json"); let isFrameworkConfigExisted = fs_1.default.existsSync(path_1.default.resolve("dx.json")); if (!isFrameworkConfigExisted) { console.error("Diginext has't been initialized yet. Run `diginext new {project_name}` or `diginext init`."); return; } let cfg = JSON.parse(fs_1.default.readFileSync(configFile).toString()); cfg.cdn = cfg.cdn ? cfg.cdn : { dev: false, staging: false, prod: false }; cfg.cdn[env] = true; fs_1.default.writeFileSync(configFile, JSON.stringify(cfg, null, 2), "utf8"); } exports.enableCDN = enableCDN; function disableCDN(options) { const { env } = options; let configFile = path_1.default.resolve("dx.json"); let isFrameworkConfigExisted = fs_1.default.existsSync(path_1.default.resolve("dx.json")); if (!isFrameworkConfigExisted) { console.error("Diginext has't been initialized yet. Run `diginext new {project_name}` or `diginext init`."); return; } let cfg = JSON.parse(fs_1.default.readFileSync(configFile).toString()); cfg.cdn = cfg.cdn ? cfg.cdn : { dev: false, staging: false, prod: false }; cfg.cdn[env] = false; fs_1.default.writeFileSync(configFile, JSON.stringify(cfg, null, 2), "utf8"); } exports.disableCDN = disableCDN;