@strapi/strapi
Version:
An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MySQL, MariaDB, PostgreSQL, SQLite
139 lines (136 loc) • 4.89 kB
JavaScript
import chalk from 'chalk';
import { isString, isArray, has } from 'lodash/fp';
import 'boxen';
/**
* Helper functions for the Strapi CLI
*/ const bytesPerKb = 1024;
const sizes = [
'B ',
'KB',
'MB',
'GB',
'TB',
'PB'
];
/**
* Convert bytes to a human readable formatted string, for example "1024" becomes "1KB"
*/ const readableBytes = (bytes, decimals = 1, padStart = 0)=>{
if (!bytes) {
return '0';
}
const i = Math.floor(Math.log(bytes) / Math.log(bytesPerKb));
const result = `${(bytes / bytesPerKb ** i).toFixed(decimals)} ${sizes[i].padStart(2)}`;
return result.padStart(padStart);
};
// Helper to floor a number to a given number of decimal places
function floorToDecimal(value, decimals) {
const factor = 10 ** decimals;
return Math.floor(value * factor) / factor;
}
/**
* Convert elapsed time to a human readable formatted string, for example "1024" becomes "1s"
*/ const readableTime = (elapsedTime, decimals = 1, padStart = 0)=>{
let value;
let unit;
if (elapsedTime >= 60000) {
value = elapsedTime / 60000;
unit = 'm';
} else if (elapsedTime >= 1000) {
value = elapsedTime / 1000;
unit = 's';
} else {
value = elapsedTime;
unit = 'ms';
}
const floored = floorToDecimal(value, decimals);
const result = `${floored.toFixed(decimals)}${unit}`;
return result.padStart(padStart);
};
/**
* Separates transfer progress segments (count, size, elapsed, rate, ETA) instead of nested
* parentheses — easier to scan in a single terminal line.
*/ const TRANSFER_PROGRESS_FIELD_SEP = ' · ';
/**
* Stage / prep timing: plain `readableTime` (e.g. `1.2s`) when no ETA; with ETA, append
* `, ~4.0s remaining` (`~` = approximate). Same base format for every stage; remaining is additive.
*/ const formatElapsedAndMaybeRemainingLabel = (elapsedMs, remainingMs)=>remainingMs != null ? `${readableTime(elapsedMs)}, ~${readableTime(remainingMs)} remaining` : readableTime(elapsedMs);
/**
*
* Display message(s) to console and then call process.exit with code.
* If code is zero, console.log and green text is used for messages, otherwise console.error and red text.
*
*/ const exitWith = (code, message, options = {})=>{
const { logger = console, prc = process } = options;
const log = (message)=>{
if (code === 0) {
logger.log(chalk.green(message));
} else {
logger.error(chalk.red(message));
}
};
if (isString(message)) {
log(message);
} else if (isArray(message)) {
message.forEach((msg)=>log(msg));
}
prc.exit(code);
};
/**
* assert that a URL object has a protocol value
*
*/ const assertUrlHasProtocol = (url, protocol)=>{
if (!url.protocol) {
exitWith(1, `${url.toString()} does not have a protocol`);
}
// if just checking for the existence of a protocol, return
if (!protocol) {
return;
}
if (isString(protocol)) {
if (protocol !== url.protocol) {
exitWith(1, `${url.toString()} must have the protocol ${protocol}`);
}
return;
}
// assume an array
if (!protocol.some((protocol)=>url.protocol === protocol)) {
return exitWith(1, `${url.toString()} must have one of the following protocols: ${protocol.join(',')}`);
}
};
/**
* Passes commander options to conditionCallback(). If it returns true, call isMetCallback otherwise call isNotMetCallback
*/ const ifOptions = (conditionCallback, isMetCallback = async ()=>{}, isNotMetCallback = async ()=>{})=>{
return async (command)=>{
const opts = command.opts();
if (await conditionCallback(opts)) {
await isMetCallback(command);
} else {
await isNotMetCallback(command);
}
};
};
const assertCwdContainsStrapiProject = (name)=>{
const logErrorAndExit = ()=>{
console.log(`You need to run ${chalk.yellow(`strapi ${name}`)} in a Strapi project. Make sure you are in the right directory.`);
process.exit(1);
};
try {
const pkgJSON = require(`${process.cwd()}/package.json`);
if (!has('dependencies.@strapi/strapi', pkgJSON) && !has('devDependencies.@strapi/strapi', pkgJSON)) {
logErrorAndExit();
}
} catch (err) {
logErrorAndExit();
}
};
const runAction = (name, action)=>(...args)=>{
assertCwdContainsStrapiProject(name);
Promise.resolve().then(()=>{
return action(...args);
}).catch((error)=>{
console.error(error);
process.exit(1);
});
};
export { TRANSFER_PROGRESS_FIELD_SEP, assertCwdContainsStrapiProject, assertUrlHasProtocol, exitWith, formatElapsedAndMaybeRemainingLabel, ifOptions, readableBytes, readableTime, runAction };
//# sourceMappingURL=helpers.mjs.map