@topgroup/diginext
Version:
A BUILD SERVER & CLI to deploy apps to any Kubernetes clusters.
262 lines (261 loc) • 11 kB
JavaScript
;
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;