nadle
Version:
A type-safe, Gradle-inspired task runner for Node.js. Sharp tasks. Fast builds.
244 lines (233 loc) • 8.69 kB
JavaScript
// packages/nadle/src/core/utilities/utils.ts
import Path from "path";
import c from "tinyrainbow";
// packages/nadle/src/core/utilities/constants.ts
var ESC = "\x1B[";
var ERASE_DOWN = `${ESC}J`;
var ERASE_SCROLLBACK = `${ESC}3J`;
var CURSOR_TO_START = `${ESC}1;1H`;
var HIDE_CURSOR = `${ESC}?25l`;
var CLEAR_SCREEN = "\x1Bc";
var COLON = ":";
var DOT = ".";
var UNDERSCORE = "_";
var CROSS = "\xD7";
var CHECK = "\u2713";
var DASH = "-";
var CURVE_ARROW = "\u21A9";
var RIGHT_ARROW = "\u2192";
var VERTICAL_BAR = "|";
var LINES = {
UP_RIGHT: "\u2514",
VERTICAL: "\u2502",
HORIZONTAL: "\u2500",
VERTICAL_RIGHT: "\u251C"
};
var DEFAULT_CACHE_DIR_NAME = "node_modules/.cache/nadle";
// packages/nadle/src/core/utilities/utils.ts
function noop() {
}
function capitalize(str) {
if (str.length === 0) {
return str;
}
return str.charAt(0).toUpperCase() + str.slice(1);
}
var MILLISECONDS_PER_SECOND = 1e3;
var MILLISECONDS_PER_MINUTE = 60 * MILLISECONDS_PER_SECOND;
var MILLISECONDS_PER_HOUR = 60 * MILLISECONDS_PER_MINUTE;
function formatTime(ms) {
const hours = Math.floor(ms / MILLISECONDS_PER_HOUR);
const minutes = Math.floor(ms % MILLISECONDS_PER_HOUR / MILLISECONDS_PER_MINUTE);
const seconds = Math.floor(ms % MILLISECONDS_PER_MINUTE / MILLISECONDS_PER_SECOND);
const milliseconds = Math.floor(ms % MILLISECONDS_PER_SECOND);
if (hours > 0) {
if (minutes > 0) {
return `${hours}h${minutes}m`;
}
return `${hours}h`;
}
if (minutes > 0) {
if (seconds > 0) {
return `${minutes}m${seconds}s`;
}
return `${minutes}m`;
}
if (seconds > 0) {
return `${seconds}s`;
}
return `${milliseconds}ms`;
}
function normalizeGlobPath(path) {
if (path.startsWith(DOT)) {
return path;
}
return `.${Path.sep}${path}`;
}
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function bindObject(obj, keys) {
return Object.fromEntries(
keys.map((key) => {
const value = obj[key];
if (typeof value !== "function") {
throw new Error(`Property ${String(key)} is not a function`);
}
return [key, value.bind(obj)];
})
);
}
function highlight(text) {
return c.bold(c.yellow(text));
}
// packages/nadle/src/core/utilities/maybe-array.ts
var MaybeArray;
((MaybeArray2) => {
function toArray(value) {
return Array.isArray(value) ? value : [value];
}
MaybeArray2.toArray = toArray;
})(MaybeArray || (MaybeArray = {}));
// packages/nadle/src/core/utilities/nadle-error.ts
var NadleError = class extends Error {
constructor(message, errorCode = 1, options) {
super(message, options);
this.name = "NadleError";
this.errorCode = errorCode;
}
};
var ConfigurationError = class extends NadleError {
constructor(message) {
super(message, 2);
this.name = "ConfigurationError";
}
};
var TaskNotFoundError = class extends NadleError {
constructor(message) {
super(message, 3);
this.name = "TaskNotFoundError";
}
};
var CyclicDependencyError = class extends NadleError {
constructor(message) {
super(message, 4);
this.name = "CyclicDependencyError";
}
};
var TaskExecutionError = class extends NadleError {
constructor(message, options) {
super(message, 1, options);
this.name = "TaskExecutionError";
}
};
// packages/nadle/src/core/utilities/consola.ts
import { isCI, isTest } from "std-env";
import { LogLevels, createConsola } from "consola";
var [BasicReporter] = createConsola({ fancy: false }).options.reporters;
var [FancyReporter] = createConsola({ fancy: true }).options.reporters;
var CIReporter = class {
log(logObj, ctx) {
BasicReporter.log({ ...logObj, type: "" }, ctx);
}
};
function createConsolaReporters() {
if (isTest) {
return [BasicReporter];
}
if (isCI) {
return [new CIReporter()];
}
return [FancyReporter];
}
function createPlainReporters() {
return [new CIReporter()];
}
function createNadleConsola(logLevel = "log") {
return createConsola({ level: LogLevels[logLevel], formatOptions: { date: false }, reporters: createConsolaReporters() });
}
var SupportLogLevels = ["error", "log", "info", "debug"];
// packages/nadle/src/core/utilities/messages.ts
import { CONFIG_FILE_PATTERN } from "@nadle/project-resolver";
var Messages = {
InvalidConfigureUsage: () => `configure function can only be called from the root workspace.`,
SpecifiedConfigFileNotFound: (filePath) => `Config file not found at ${highlight(filePath)}. Please check the path.`,
InvalidWorkerConfig: (type, value) => `Invalid value for --${type}-workers. Expect to be an integer or a percentage (e.g., 50%). Got: ${highlight(value)}`,
ConfigFileNotFound: (projectPath) => `No ${CONFIG_FILE_PATTERN}} found in ${highlight(projectPath)} directory or parent directories. Please use --config to specify a custom path.`,
CycleDetected: (cyclePath) => `Cycle detected in task ${cyclePath}. Please resolve the cycle before executing tasks.`,
DuplicatedTaskName: (taskName, workspaceId) => `Task ${highlight(taskName)} already registered in workspace ${highlight(workspaceId)}`,
NoTasksFound: () => `No tasks were specified. Please specify one or more tasks to execute, or use the ${highlight("--list")} option to view available tasks.`,
PassthroughArgsNotice: (args, taskLabels) => `Passing extra arguments [${args.join(" ")}] to ${taskLabels.length} tasks: ${taskLabels.join(", ")}`,
UnresolvedTaskWithoutSuggestions: (taskNameInput, targetWorkspaceId) => `Task ${highlight(taskNameInput)} not found in ${highlight(targetWorkspaceId)} workspace.`,
InvalidTaskName: (taskName) => `Invalid task name: ${highlight(taskName)}. Task names must contain only letters, numbers, and dashes; start with a letter, and not end with a dash.`,
UnresolvedTaskWithSuggestions: (options) => `Task ${highlight(options.taskNameInput)} not found in ${highlight(options.targetWorkspaceId)}${options.fallbackWorkspaceId ? ` nor ${highlight(options.fallbackWorkspaceId)}` : ""} workspace. ${options.suggestions}`,
UnresolvedTaskPattern: (options) => `No task matching pattern ${highlight(options.pattern)} found in ${highlight(options.targetWorkspaceId)}${options.fallbackWorkspaceId ? ` nor ${highlight(options.fallbackWorkspaceId)}` : ""} workspace.`,
EmptyWorkspaceLabel: (workspaceId) => `Workspace ${highlight(workspaceId)} alias can not be empty.`,
UnresolvedWorkspace: (workspaceInput, suggestions) => `Workspace ${highlight(workspaceInput)} not found. ${suggestions}`,
WorkspaceNotFound: (workspaceInput, availableWorkspaces) => `Workspace ${highlight(workspaceInput)} not found. Available workspaces: ${availableWorkspaces}.`,
WorkspaceIdNotFound: (workspaceId, availableWorkspaces) => `Workspace with id ${highlight(workspaceId)} not found. Available workspaces: ${availableWorkspaces}.`,
DuplicatedWorkspaceLabelWithOtherLabel: (workspaceId, workspaceLabel, duplicatedWorkspaceId) => `Workspace ${highlight(workspaceId)} has a duplicated label ${highlight(workspaceLabel)} with workspace ${highlight(duplicatedWorkspaceId)}. Please check the alias configuration in the configuration file.`,
DuplicatedWorkspaceLabelWithOtherId: (workspaceId, workspaceLabel, duplicatedWorkspaceId) => `Workspace ${highlight(workspaceId)} has a label ${highlight(workspaceLabel)} that is the same as workspace ${highlight(duplicatedWorkspaceId)}'s id. Please check the alias configuration in the configuration file.`
};
// packages/nadle/src/core/utilities/fs.ts
import Fs from "fs/promises";
async function isPathExists(path) {
try {
await Fs.access(path);
return true;
} catch {
return false;
}
}
// packages/nadle/src/core/nadle-context.ts
import AsyncHooks from "async_hooks";
var nadleContext = new AsyncHooks.AsyncLocalStorage();
function runWithInstance(instance, fn) {
return nadleContext.run(instance, fn);
}
function getCurrentInstance() {
const instance = nadleContext.getStore();
if (!instance) {
throw new Error("No active Nadle instance \u2014 tasks must be registered during config loading");
}
return instance;
}
export {
ERASE_DOWN,
ERASE_SCROLLBACK,
CURSOR_TO_START,
HIDE_CURSOR,
CLEAR_SCREEN,
COLON,
UNDERSCORE,
CROSS,
CHECK,
DASH,
CURVE_ARROW,
RIGHT_ARROW,
VERTICAL_BAR,
LINES,
DEFAULT_CACHE_DIR_NAME,
noop,
capitalize,
formatTime,
normalizeGlobPath,
clamp,
bindObject,
highlight,
Messages,
isPathExists,
MaybeArray,
NadleError,
ConfigurationError,
TaskNotFoundError,
CyclicDependencyError,
TaskExecutionError,
runWithInstance,
getCurrentInstance,
LogLevels,
createPlainReporters,
createNadleConsola,
SupportLogLevels
};