@next-boilerplate/cli-helpers
Version:
CLI helper for Next Boilerplate
328 lines (317 loc) • 10.6 kB
JavaScript
;
var child_process = require('child_process');
var fs = require('fs-extra');
var globby = require('globby');
var path = require('path');
var tar = require('tar');
var index = require('./stores/index.cjs');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var tar__namespace = /*#__PURE__*/_interopNamespaceDefault(tar);
let gchalk = null;
const getChalk = () => {
if (gchalk) return gchalk;
throw new Error("Chalk not loaded");
};
const loadChalk = async () => {
if (gchalk) return gchalk;
const resolvedChalk = await Promise.resolve().then(function () { return require('./index-BjU40ZCI.cjs'); }).then((_chalk) => _chalk.default);
gchalk = resolvedChalk;
return resolvedChalk;
};
const console = globalThis.console;
const black = "#000000";
const text = "#CDCDCD";
const yellow = "#F3F99D";
const orange = "#F9CB8F";
const red = "#F09393";
const green = "#7EE081";
const blue = "#7DCFEA";
const gray = "#686868";
const printColor = (bg, text2) => (...args) => {
const data = args.map((arg) => {
if (typeof arg === "object" && arg) {
const str = arg.toString();
if (str === "[object Object]") {
return JSON.stringify(arg, null, 2);
}
return str;
}
return arg;
}).join(" ");
if (isBrowser()) return data;
try {
const chalk = getChalk();
if (bg && text2) return chalk.bgHex(bg).hex(text2)(data);
if (bg) return chalk.bgHex(bg)(data);
if (text2) return chalk.hex(text2)(data);
} catch (e) {
return data;
}
return data;
};
const _log = printColor(void 0, void 0);
const log = printColor(void 0, text);
const warn = printColor(yellow, black);
const warnText = printColor(void 0, yellow);
const debug = printColor(orange, black);
const debugText = printColor(void 0, orange);
const error = printColor(red, black);
const errorText = printColor(void 0, red);
const success = printColor(green, black);
const successText = printColor(void 0, green);
const info = printColor(blue, black);
const infoText = printColor(void 0, blue);
const subLog = printColor(void 0, gray);
function addPrefixToArgs(prefix, ...args) {
if (typeof prefix === "string") {
return [log(prefix), ...args];
}
if (typeof prefix === "function") {
return [log(prefix()), ...args];
}
return args;
}
const getLoggerEnv = () => process.env.LOGGER_ENV || "production";
const allowDebug = () => getLoggerEnv() === "development";
const isBrowser = () => typeof window !== "undefined";
var utils = /*#__PURE__*/Object.freeze({
__proto__: null,
_log: _log,
addPrefixToArgs: addPrefixToArgs,
allowDebug: allowDebug,
debug: debug,
debugText: debugText,
error: error,
errorText: errorText,
info: info,
infoText: infoText,
isBrowser: isBrowser,
log: log,
subLog: subLog,
success: success,
successText: successText,
warn: warn,
warnText: warnText
});
const logger = {
...console,
isInitialized: false,
init: async () => {
await loadChalk();
logger.isInitialized = true;
},
allowDebug,
_log: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, _log(...args));
console.log(...value);
logger.onLog?.("log", value);
},
log: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, log(...args));
console.log(...value);
logger.onLog?.("log", value);
},
debug: (...args) => {
if (allowDebug()) {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, debug(" DEBUG "), debugText(...args));
console.debug(...value);
logger.onLog?.("debug", value);
}
},
warn: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, warn(" WARN "), warnText(...args));
console.warn(...value);
logger.onLog?.("warn", value);
},
error: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, error(" ERROR "), errorText(...args));
console.error(...value);
logger.onLog?.("error", value);
},
trace: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, error(" ERROR "), errorText(...args));
console.trace(...value);
logger.onLog?.("trace", value);
},
success: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, success(" SUCCESS "), successText(...args));
console.log(...value);
logger.onLog?.("success", value);
},
info: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, info(" INFO "), infoText(...args));
console.log(...value);
logger.onLog?.("info", value);
},
subLog: (...args) => {
warnIfNotInitialized();
const value = addPrefixToArgs(logger.prefix, subLog(...args));
console.log(...value);
logger.onLog?.("subLog", value);
},
utils
};
logger.init();
let alreadyWarned = false;
const warnIfNotInitialized = () => {
if (!logger.isInitialized && !alreadyWarned) {
console.warn("Logger is not initialized yet. Please call and await logger.init()");
alreadyWarned = true;
}
};
const getStoresDirectory = (assetsDirectory) => path.join(assetsDirectory, "stores");
const getStoreDataDirectory = ({ assetsDirectory, store }) => path.join(getStoresDirectory(assetsDirectory), encodeURIComponent(index.getStoreUID(store)), "data");
const loadStores = async ({ assetsDirectory }) => {
const storesDirectory = getStoresDirectory(assetsDirectory);
logger.debug(`Loading stores (${storesDirectory})`);
await fs.ensureDir(storesDirectory);
const formattedStoresDirectory = storesDirectory.replace(/\\/g, "/");
const globbyPath = path.join(formattedStoresDirectory, "*", index.storeConfigFileName).replace(/\\/g, "/");
const stores = await globby.globby(globbyPath);
logger.debug(`Found ${stores.length} stores in ${globbyPath}`);
const storesFilled = [];
for (const store of stores) {
const { data: storeConfig, error } = index.storeConfigSchema.safeParse(await fs.readJson(store));
if (error) {
logger.error(error);
throw new Error(`The config of the store ${store} is invalid`);
}
const fullPath = path.dirname(store);
storesFilled.push({ ...storeConfig, fullPath, uid: index.getStoreUID(storeConfig) });
}
storesFilled.sort((a, b) => index.getStoreUID(a).localeCompare(index.getStoreUID(b)));
return storesFilled;
};
const getStores = async ({ assetsDirectory, search }) => {
let stores = await loadStores({ assetsDirectory });
if (search) {
stores = stores.filter((store) => {
return index.getStoreUID(store).toLowerCase().includes(search.toLowerCase());
});
}
return stores;
};
const handleDownloadStores = async ({
assetsDirectory,
config
}) => {
const stores = await getStores({ assetsDirectory });
const storeToDownload = config.stores?.filter((store) => !stores.some((s) => index.getStoreUID(s) === index.getStoreUID(store)));
if (!storeToDownload || storeToDownload.length === 0) {
return;
}
const npmVersion = await new Promise((resolve, reject) => {
child_process.exec("npm --version", (error, stdout) => {
if (error) {
reject(error);
return;
}
resolve(stdout);
});
}).catch((e) => {
logger.error(`Failed to get the npm version when downloading the stores`);
throw e;
});
logger.debug(`npm version: ${npmVersion}`);
for (const store of storeToDownload) {
await handleDownloadStore({
assetsDirectory,
store
});
}
};
const handleDownloadStore = async ({
assetsDirectory,
override,
store
}) => {
const storesDirectory = getStoresDirectory(assetsDirectory);
const storePath = path.join(storesDirectory, encodeURIComponent(index.getStoreUID(store)));
const storeDataPath = path.join(storePath, "data");
const storeConfigPath = path.join(storePath, index.storeConfigFileName);
await fs.ensureDir(storePath);
await fs.writeJson(storeConfigPath, store);
if (!override && await fs.exists(storeDataPath)) {
const lockFile = path.join(storeDataPath, ".lock");
let i = 0;
while (await fs.exists(lockFile) && i < 60) {
await new Promise((resolve) => setTimeout(resolve, 1e3));
i++;
}
if (await fs.exists(lockFile)) {
logger.warn(`The store ${store.name}@${store.version} installation is pending (may be stuck)`);
return;
} else {
logger.warn(`The store ${store.name}@${store.version} is already installed at ${storeDataPath}`);
return;
}
}
logger.info(`Downloading the store ${store.name}@${store.version}`);
await fs.ensureDir(storeDataPath);
await fs.writeFile(path.join(storeDataPath, ".lock"), "");
await new Promise((resolve, reject) => {
child_process.exec(`npm pack ${store.name}@${store.version}`, { cwd: storePath }, async (error, stdout) => {
if (error) {
reject(error);
return;
}
try {
const tarball = stdout.trim();
const tarballPath = path.join(storePath, tarball);
await tar__namespace.x({ file: tarballPath, cwd: storeDataPath, strip: 1 });
await fs.remove(tarballPath);
await fs.remove(path.join(storeDataPath, ".lock"));
logger.debug(`Downloaded the store ${store.name}@${store.version}`);
resolve();
} catch (e) {
reject(e);
}
});
}).catch(async (e) => {
logger.error(`Failed to download the store ${store.name}@${store.version}`);
await fs.remove(storePath).catch((e2) => {
logger.error(`Failed to remove the store folder ${storePath}`);
throw e2;
});
throw e;
});
};
const handleDeleteStore = async ({
assetsDirectory,
store
}) => {
const storesDirectory = getStoresDirectory(assetsDirectory);
const storePath = path.join(storesDirectory, encodeURIComponent(index.getStoreUID(store)));
await fs.remove(storePath);
logger.info(`Deleted the store ${store.name}@${store.version}`);
};
exports.getStoreDataDirectory = getStoreDataDirectory;
exports.getStores = getStores;
exports.getStoresDirectory = getStoresDirectory;
exports.handleDeleteStore = handleDeleteStore;
exports.handleDownloadStore = handleDownloadStore;
exports.handleDownloadStores = handleDownloadStores;
exports.logger = logger;