UNPKG

@storm-software/git-tools

Version:

Tools for managing Git repositories within a Nx workspace.

1,411 lines (1,398 loc) 80.1 kB
import { DEFAULT_MONOREPO_COMMIT_QUESTIONS } from './chunk-JCEVFJCA.js'; import { DEFAULT_COMMIT_TYPES } from './chunk-3GGWHKRP.js'; import defu from 'defu'; import { loadConfig } from 'c12'; import 'date-fns/formatDistanceToNow'; import chalk from 'chalk'; import { existsSync } from 'node:fs'; import { join } from 'node:path'; import * as z from 'zod/mini'; import { readFile } from 'node:fs/promises'; import axios2 from 'axios'; import DefaultChangelogRenderer from 'nx/release/changelog-renderer'; import { DEFAULT_CONVENTIONAL_COMMITS_CONFIG } from 'nx/src/command-line/release/config/conventional-commits'; import { major } from 'semver'; import '@nx/devkit'; import 'nx/src/command-line/release/utils/print-changes'; import 'nx/src/command-line/release/utils/shared'; import 'nx/src/tasks-runner/utils'; import 'prettier'; import 'node:child_process'; import 'node:os'; import 'nx/src/command-line/release/utils/remote-release-clients/github'; import 'yaml'; import 'nx/src/command-line/release/utils/exec-command.js'; import 'nx/src/command-line/release/utils/git'; // ../config-tools/src/utilities/correct-paths.ts var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; function normalizeWindowsPath(input = "") { if (!input) { return input; } return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); } var _UNC_REGEX = /^[/\\]{2}/; var _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; var _DRIVE_LETTER_RE = /^[A-Za-z]:$/; var correctPaths = function(path) { if (!path || path.length === 0) { return "."; } path = normalizeWindowsPath(path); const isUNCPath = path?.match(_UNC_REGEX); const isPathAbsolute = isAbsolute(path); const trailingSeparator = path[path.length - 1] === "/"; path = normalizeString(path, !isPathAbsolute); if (path.length === 0) { if (isPathAbsolute) { return "/"; } return trailingSeparator ? "./" : "."; } if (trailingSeparator) { path += "/"; } if (_DRIVE_LETTER_RE.test(path)) { path += "/"; } if (isUNCPath) { if (!isPathAbsolute) { return `//./${path}`; } return `//${path}`; } return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; }; var joinPaths = function(...segments) { let path = ""; for (const seg of segments) { if (!seg) { continue; } if (path.length > 0) { const pathTrailing = path[path.length - 1] === "/"; const segLeading = seg[0] === "/"; const both = pathTrailing && segLeading; if (both) { path += seg.slice(1); } else { path += pathTrailing || segLeading ? seg : `/${seg}`; } } else { path += seg; } } return correctPaths(path); }; function normalizeString(path, allowAboveRoot) { let res = ""; let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; let char = null; for (let index = 0; index <= path.length; ++index) { if (index < path.length) { char = path[index]; } else if (char === "/") { break; } else { char = "/"; } if (char === "/") { if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf("/"); if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); } lastSlash = index; dots = 0; continue; } else if (res.length > 0) { res = ""; lastSegmentLength = 0; lastSlash = index; dots = 0; continue; } } if (allowAboveRoot) { res += res.length > 0 ? "/.." : ".."; lastSegmentLength = 2; } } else { if (res.length > 0) { res += `/${path.slice(lastSlash + 1, index)}`; } else { res = path.slice(lastSlash + 1, index); } lastSegmentLength = index - lastSlash - 1; } lastSlash = index; dots = 0; } else if (char === "." && dots !== -1) { ++dots; } else { dots = -1; } } return res; } var isAbsolute = function(p) { return _IS_ABSOLUTE_RE.test(p); }; // src/utilities/omit.ts function omit(obj, keys) { const result = { ...obj }; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key && key in result) { delete result[key]; } } return result; } // ../config-tools/src/types.ts var LogLevel = { SILENT: 0, FATAL: 10, ERROR: 20, WARN: 30, SUCCESS: 35, INFO: 40, DEBUG: 60, TRACE: 70, ALL: 100 }; var LogLevelLabel = { SILENT: "silent", FATAL: "fatal", ERROR: "error", WARN: "warn", SUCCESS: "success", INFO: "info", DEBUG: "debug", TRACE: "trace", ALL: "all" }; // ../config-tools/src/utilities/colors.ts var DEFAULT_COLOR_CONFIG = { dark: { brand: "#2dd4bf", success: "#10b981", info: "#58a6ff", warning: "#f3d371", danger: "#D8314A", fatal: "#a40e26"} }; var chalkDefault = { hex: (_) => (message) => message, bgHex: (_) => ({ whiteBright: (message) => message, white: (message) => message }), white: (message) => message, whiteBright: (message) => message, gray: (message) => message, bold: { hex: (_) => (message) => message, bgHex: (_) => ({ whiteBright: (message) => message, white: (message) => message }), whiteBright: (message) => message, white: (message) => message }, dim: { hex: (_) => (message) => message, gray: (message) => message } }; var getChalk = () => { let _chalk = chalk; if (!_chalk?.hex || !_chalk?.bold?.hex || !_chalk?.bgHex || !_chalk?.whiteBright || !_chalk?.white) { _chalk = chalkDefault; } return _chalk; }; // ../config-tools/src/logger/is-unicode-supported.ts function isUnicodeSupported() { if (process.platform !== "win32") { return process.env.TERM !== "linux"; } return Boolean(process.env.WT_SESSION) || // Windows Terminal Boolean(process.env.TERMINUS_SUBLIME) || // Terminus (<0.2.27) process.env.ConEmuTask === "{cmd::Cmder}" || // ConEmu and cmder process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERM === "rxvt-unicode" || process.env.TERM === "rxvt-unicode-256color" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm"; } // ../config-tools/src/logger/console-icons.ts var useIcon = (c, fallback) => isUnicodeSupported() ? c : fallback; var CONSOLE_ICONS = { [LogLevelLabel.ERROR]: useIcon("\u2718", "\xD7"), [LogLevelLabel.FATAL]: useIcon("\u{1F480}", "\xD7"), [LogLevelLabel.WARN]: useIcon("\u26A0", "\u203C"), [LogLevelLabel.INFO]: useIcon("\u2139", "i"), [LogLevelLabel.SUCCESS]: useIcon("\u2714", "\u221A"), [LogLevelLabel.DEBUG]: useIcon("\u{1F6E0}", "D"), [LogLevelLabel.TRACE]: useIcon("\u{1F6E0}", "T"), [LogLevelLabel.ALL]: useIcon("\u2709", "\u2192") }; // ../config-tools/src/logger/format-timestamp.ts var formatTimestamp = (date = /* @__PURE__ */ new Date()) => { return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`; }; // ../config-tools/src/logger/get-log-level.ts var getLogLevel = (label) => { switch (label) { case "all": return LogLevel.ALL; case "trace": return LogLevel.TRACE; case "debug": return LogLevel.DEBUG; case "info": return LogLevel.INFO; case "warn": return LogLevel.WARN; case "error": return LogLevel.ERROR; case "fatal": return LogLevel.FATAL; case "silent": return LogLevel.SILENT; default: return LogLevel.INFO; } }; var getLogLevelLabel = (logLevel = LogLevel.INFO) => { if (logLevel >= LogLevel.ALL) { return LogLevelLabel.ALL; } if (logLevel >= LogLevel.TRACE) { return LogLevelLabel.TRACE; } if (logLevel >= LogLevel.DEBUG) { return LogLevelLabel.DEBUG; } if (logLevel >= LogLevel.INFO) { return LogLevelLabel.INFO; } if (logLevel >= LogLevel.WARN) { return LogLevelLabel.WARN; } if (logLevel >= LogLevel.ERROR) { return LogLevelLabel.ERROR; } if (logLevel >= LogLevel.FATAL) { return LogLevelLabel.FATAL; } if (logLevel <= LogLevel.SILENT) { return LogLevelLabel.SILENT; } return LogLevelLabel.INFO; }; // ../config-tools/src/logger/console.ts var getLogFn = (logLevel = LogLevel.INFO, config = {}, _chalk = getChalk()) => { const colors = !config.colors?.dark && !config.colors?.["base"] && !config.colors?.["base"]?.dark ? DEFAULT_COLOR_CONFIG : config.colors?.dark && typeof config.colors.dark === "string" ? config.colors : config.colors?.["base"]?.dark && typeof config.colors["base"].dark === "string" ? config.colors["base"].dark : config.colors?.["base"] ? config.colors?.["base"] : DEFAULT_COLOR_CONFIG; const configLogLevel = config.logLevel || process.env.STORM_LOG_LEVEL || LogLevelLabel.INFO; if (logLevel > getLogLevel(configLogLevel) || logLevel <= LogLevel.SILENT || getLogLevel(configLogLevel) <= LogLevel.SILENT) { return (_) => { }; } if (typeof logLevel === "number" && LogLevel.FATAL >= logLevel) { return (message) => { console.error( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.fatal ?? DEFAULT_COLOR_CONFIG.dark.fatal)(`[${CONSOLE_ICONS[LogLevelLabel.FATAL]} Fatal] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } if (typeof logLevel === "number" && LogLevel.ERROR >= logLevel) { return (message) => { console.error( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.danger ?? DEFAULT_COLOR_CONFIG.dark.danger)(`[${CONSOLE_ICONS[LogLevelLabel.ERROR]} Error] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } if (typeof logLevel === "number" && LogLevel.WARN >= logLevel) { return (message) => { console.warn( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.warning ?? DEFAULT_COLOR_CONFIG.dark.warning)(`[${CONSOLE_ICONS[LogLevelLabel.WARN]} Warn] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } if (typeof logLevel === "number" && LogLevel.SUCCESS >= logLevel) { return (message) => { console.info( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.success ?? DEFAULT_COLOR_CONFIG.dark.success)(`[${CONSOLE_ICONS[LogLevelLabel.SUCCESS]} Success] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } if (typeof logLevel === "number" && LogLevel.INFO >= logLevel) { return (message) => { console.info( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.info ?? DEFAULT_COLOR_CONFIG.dark.info)(`[${CONSOLE_ICONS[LogLevelLabel.INFO]} Info] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } if (typeof logLevel === "number" && LogLevel.DEBUG >= logLevel) { return (message) => { console.debug( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.info ?? DEFAULT_COLOR_CONFIG.dark.info)(`[${CONSOLE_ICONS[LogLevelLabel.DEBUG]} Debug] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } if (typeof logLevel === "number" && LogLevel.TRACE >= logLevel) { return (message) => { console.debug( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.info ?? DEFAULT_COLOR_CONFIG.dark.info)(`[${CONSOLE_ICONS[LogLevelLabel.TRACE]} Trace] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; } return (message) => { console.log( ` ${_chalk.gray(formatTimestamp())} ${_chalk.hex(colors.brand ?? DEFAULT_COLOR_CONFIG.dark.brand)(`[${CONSOLE_ICONS[LogLevelLabel.ALL]} System] `)}${_chalk.bold.whiteBright(formatLogMessage(message))} ` ); }; }; var writeWarning = (message, config) => getLogFn(LogLevel.WARN, config)(message); var writeTrace = (message, config) => getLogFn(LogLevel.TRACE, config)(message); var MAX_DEPTH = 4; var formatLogMessage = (message, options = {}, depth2 = 0) => { if (depth2 > MAX_DEPTH) { return "<max depth>"; } const prefix = options.prefix ?? "-"; const skip = options.skip ?? []; return typeof message === "undefined" || message === null || !message && typeof message !== "boolean" ? "<none>" : typeof message === "string" ? message : Array.isArray(message) ? ` ${message.map((item, index) => ` ${prefix}> #${index} = ${formatLogMessage(item, { prefix: `${prefix}-`, skip }, depth2 + 1)}`).join("\n")}` : typeof message === "object" ? ` ${Object.keys(message).filter((key) => !skip.includes(key)).map( (key) => ` ${prefix}> ${key} = ${_isFunction(message[key]) ? "<function>" : typeof message[key] === "object" ? formatLogMessage( message[key], { prefix: `${prefix}-`, skip }, depth2 + 1 ) : message[key]}` ).join("\n")}` : message; }; var _isFunction = (value) => { try { return value instanceof Function || typeof value === "function" || !!(value?.constructor && value?.call && value?.apply); } catch { return false; } }; var MAX_PATH_SEARCH_DEPTH = 30; var depth = 0; function findFolderUp(startPath, endFileNames = [], endDirectoryNames = []) { const _startPath = startPath ?? process.cwd(); if (endDirectoryNames.some( (endDirName) => existsSync(join(_startPath, endDirName)) )) { return _startPath; } if (endFileNames.some((endFileName) => existsSync(join(_startPath, endFileName)))) { return _startPath; } if (_startPath !== "/" && depth++ < MAX_PATH_SEARCH_DEPTH) { const parent = join(_startPath, ".."); return findFolderUp(parent, endFileNames, endDirectoryNames); } return void 0; } // ../config-tools/src/utilities/find-workspace-root.ts var rootFiles = [ "storm-workspace.json", "storm-workspace.yaml", "storm-workspace.yml", "storm-workspace.js", "storm-workspace.ts", ".storm-workspace.json", ".storm-workspace.yaml", ".storm-workspace.yml", ".storm-workspace.js", ".storm-workspace.ts", "lerna.json", "nx.json", "turbo.json", "npm-workspace.json", "yarn-workspace.json", "pnpm-workspace.json", "npm-workspace.yaml", "yarn-workspace.yaml", "pnpm-workspace.yaml", "npm-workspace.yml", "yarn-workspace.yml", "pnpm-workspace.yml", "npm-lock.json", "yarn-lock.json", "pnpm-lock.json", "npm-lock.yaml", "yarn-lock.yaml", "pnpm-lock.yaml", "npm-lock.yml", "yarn-lock.yml", "pnpm-lock.yml", "bun.lockb" ]; var rootDirectories = [ ".storm-workspace", ".nx", ".git", ".github", ".vscode", ".verdaccio" ]; function findWorkspaceRootSafe(pathInsideMonorepo) { if (process.env.STORM_WORKSPACE_ROOT || process.env.NX_WORKSPACE_ROOT_PATH) { return correctPaths( process.env.STORM_WORKSPACE_ROOT ?? process.env.NX_WORKSPACE_ROOT_PATH ); } return correctPaths( findFolderUp( pathInsideMonorepo ?? process.cwd(), rootFiles, rootDirectories ) ); } function findWorkspaceRoot(pathInsideMonorepo) { const result = findWorkspaceRootSafe(pathInsideMonorepo); if (!result) { throw new Error( `Cannot find workspace root upwards from known path. Files search list includes: ${rootFiles.join( "\n" )} Path: ${pathInsideMonorepo ? pathInsideMonorepo : process.cwd()}` ); } return result; } // ../config/src/constants.ts var STORM_DEFAULT_DOCS = "https://docs.stormsoftware.com"; var STORM_DEFAULT_HOMEPAGE = "https://stormsoftware.com"; var STORM_DEFAULT_LICENSING = "https://stormsoftware.com/license"; var STORM_DEFAULT_LICENSE = "Apache-2.0"; var STORM_DEFAULT_ERROR_CODES_FILE = "tools/errors/codes.json"; var STORM_DEFAULT_BANNER_ALT = "The workspace's banner image"; var schemaRegistry = z.registry(); var colorSchema = z.string().check( z.length(7), z.toLowerCase(), z.regex(/^#([0-9a-f]{3}){1,2}$/i), z.trim() ); schemaRegistry.add(colorSchema, { description: "A base schema for describing the format of colors" }); var darkColorSchema = z._default(colorSchema, "#151718"); schemaRegistry.add(darkColorSchema, { description: "The dark background color of the workspace" }); var lightColorSchema = z._default(colorSchema, "#cbd5e1"); schemaRegistry.add(lightColorSchema, { description: "The light background color of the workspace" }); var brandColorSchema = z._default(colorSchema, "#1fb2a6"); schemaRegistry.add(brandColorSchema, { description: "The primary brand specific color of the workspace" }); var alternateColorSchema = z.optional(colorSchema); schemaRegistry.add(alternateColorSchema, { description: "The alternate brand specific color of the workspace" }); var accentColorSchema = z.optional(colorSchema); schemaRegistry.add(accentColorSchema, { description: "The secondary brand specific color of the workspace" }); var linkColorSchema = z._default(colorSchema, "#3fa6ff"); schemaRegistry.add(linkColorSchema, { description: "The color used to display hyperlink text" }); var helpColorSchema = z._default(colorSchema, "#818cf8"); schemaRegistry.add(helpColorSchema, { description: "The second brand specific color of the workspace" }); var successColorSchema = z._default(colorSchema, "#45b27e"); schemaRegistry.add(successColorSchema, { description: "The success color of the workspace" }); var infoColorSchema = z._default(colorSchema, "#38bdf8"); schemaRegistry.add(infoColorSchema, { description: "The informational color of the workspace" }); var warningColorSchema = z._default(colorSchema, "#f3d371"); schemaRegistry.add(warningColorSchema, { description: "The warning color of the workspace" }); var dangerColorSchema = z._default(colorSchema, "#d8314a"); schemaRegistry.add(dangerColorSchema, { description: "The danger color of the workspace" }); var fatalColorSchema = z.optional(colorSchema); schemaRegistry.add(fatalColorSchema, { description: "The fatal color of the workspace" }); var positiveColorSchema = z._default(colorSchema, "#4ade80"); schemaRegistry.add(positiveColorSchema, { description: "The positive number color of the workspace" }); var negativeColorSchema = z._default(colorSchema, "#ef4444"); schemaRegistry.add(negativeColorSchema, { description: "The negative number color of the workspace" }); var gradientStopsSchema = z.optional(z.array(colorSchema)); schemaRegistry.add(gradientStopsSchema, { description: "The color stops for the base gradient color pattern used in the workspace" }); var darkColorsSchema = z.object({ foreground: lightColorSchema, background: darkColorSchema, brand: brandColorSchema, alternate: alternateColorSchema, accent: accentColorSchema, link: linkColorSchema, help: helpColorSchema, success: successColorSchema, info: infoColorSchema, warning: warningColorSchema, danger: dangerColorSchema, fatal: fatalColorSchema, positive: positiveColorSchema, negative: negativeColorSchema, gradient: gradientStopsSchema }); var lightColorsSchema = z.object({ foreground: darkColorSchema, background: lightColorSchema, brand: brandColorSchema, alternate: alternateColorSchema, accent: accentColorSchema, link: linkColorSchema, help: helpColorSchema, success: successColorSchema, info: infoColorSchema, warning: warningColorSchema, danger: dangerColorSchema, fatal: fatalColorSchema, positive: positiveColorSchema, negative: negativeColorSchema, gradient: gradientStopsSchema }); var multiColorsSchema = z.object({ dark: darkColorsSchema, light: lightColorsSchema }); var singleColorsSchema = z.object({ dark: darkColorSchema, light: lightColorSchema, brand: brandColorSchema, alternate: alternateColorSchema, accent: accentColorSchema, link: linkColorSchema, help: helpColorSchema, success: successColorSchema, info: infoColorSchema, warning: warningColorSchema, danger: dangerColorSchema, fatal: fatalColorSchema, positive: positiveColorSchema, negative: negativeColorSchema, gradient: gradientStopsSchema }); var registryUrlConfigSchema = z.optional(z.url()); schemaRegistry.add(registryUrlConfigSchema, { description: "A remote registry URL used to publish distributable packages" }); var registrySchema = z._default( z.object({ github: registryUrlConfigSchema, npm: registryUrlConfigSchema, cargo: registryUrlConfigSchema, cyclone: registryUrlConfigSchema, container: registryUrlConfigSchema }), {} ); schemaRegistry.add(registrySchema, { description: "A list of remote registry URLs used by Storm Software" }); var colorsSchema = z.union([singleColorsSchema, multiColorsSchema]); schemaRegistry.add(colorsSchema, { description: "Colors used for various workspace elements" }); var themeColorsSchema = z.record( z.union([z.union([z.literal("base"), z.string()]), z.string()]), colorsSchema ); schemaRegistry.add(themeColorsSchema, { description: "Storm theme config values used for styling various package elements" }); var extendsSchema = z.optional( z.union([z.string().check(z.trim()), z.array(z.string().check(z.trim()))]) ); schemaRegistry.add(extendsSchema, { description: "The path to a base config file to use as a configuration preset file. Documentation can be found at https://github.com/unjs/c12#extending-configuration." }); var workspaceBotNameSchema = z.string().check(z.trim()); schemaRegistry.add(workspaceBotNameSchema, { description: "The workspace bot user's name (this is the bot that will be used to perform various tasks)" }); var workspaceBotEmailSchema = z.string().check(z.trim()); schemaRegistry.add(workspaceBotEmailSchema, { description: "The email of the workspace bot" }); var workspaceBotSchema = z.object({ name: workspaceBotNameSchema, email: workspaceBotEmailSchema }); schemaRegistry.add(workspaceBotSchema, { description: "The workspace's bot user's config used to automated various operations tasks" }); var workspaceReleaseBannerUrlSchema = z.optional( z.string().check(z.trim(), z.url()) ); schemaRegistry.add(workspaceReleaseBannerUrlSchema, { description: "A URL to a banner image used to display the workspace's release" }); var workspaceReleaseBannerAltSchema = z._default( z.string().check(z.trim()), STORM_DEFAULT_BANNER_ALT ); schemaRegistry.add(workspaceReleaseBannerAltSchema, { description: "The alt text for the workspace's release banner image" }); var workspaceReleaseBannerSchema = z.object({ url: workspaceReleaseBannerUrlSchema, alt: workspaceReleaseBannerAltSchema }); schemaRegistry.add(workspaceReleaseBannerSchema, { description: "The workspace's banner image used during the release process" }); var workspaceReleaseHeaderSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceReleaseHeaderSchema, { description: "A header message appended to the start of the workspace's release notes" }); var workspaceReleaseFooterSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceReleaseFooterSchema, { description: "A footer message appended to the end of the workspace's release notes" }); var workspaceReleaseSchema = z.object({ banner: z.union([ workspaceReleaseBannerSchema, z.string().check(z.trim(), z.url()) ]), header: workspaceReleaseHeaderSchema, footer: workspaceReleaseFooterSchema }); schemaRegistry.add(workspaceReleaseSchema, { description: "The workspace's release config used during the release process" }); var workspaceSocialsTwitterSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceSocialsTwitterSchema, { description: "A Twitter/X account associated with the organization/project" }); var workspaceSocialsDiscordSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceSocialsDiscordSchema, { description: "A Discord account associated with the organization/project" }); var workspaceSocialsTelegramSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceSocialsTelegramSchema, { description: "A Telegram account associated with the organization/project" }); var workspaceSocialsSlackSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceSocialsSlackSchema, { description: "A Slack account associated with the organization/project" }); var workspaceSocialsMediumSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceSocialsMediumSchema, { description: "A Medium account associated with the organization/project" }); var workspaceSocialsGithubSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceSocialsGithubSchema, { description: "A GitHub account associated with the organization/project" }); var workspaceSocialsSchema = z.object({ twitter: workspaceSocialsTwitterSchema, discord: workspaceSocialsDiscordSchema, telegram: workspaceSocialsTelegramSchema, slack: workspaceSocialsSlackSchema, medium: workspaceSocialsMediumSchema, github: workspaceSocialsGithubSchema }); schemaRegistry.add(workspaceSocialsSchema, { description: "The workspace's account config used to store various social media links" }); var workspaceDirectoryCacheSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceDirectoryCacheSchema, { description: "The directory used to store the environment's cached file data" }); var workspaceDirectoryDataSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceDirectoryDataSchema, { description: "The directory used to store the environment's data files" }); var workspaceDirectoryConfigSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceDirectoryConfigSchema, { description: "The directory used to store the environment's configuration files" }); var workspaceDirectoryTempSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceDirectoryTempSchema, { description: "The directory used to store the environment's temp files" }); var workspaceDirectoryLogSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(workspaceDirectoryLogSchema, { description: "The directory used to store the environment's log files" }); var workspaceDirectoryBuildSchema = z._default( z.string().check(z.trim()), "dist" ); schemaRegistry.add(workspaceDirectoryBuildSchema, { description: "The directory used to store the workspace's distributable files after a build (relative to the workspace root)" }); var workspaceDirectorySchema = z.object({ cache: workspaceDirectoryCacheSchema, data: workspaceDirectoryDataSchema, config: workspaceDirectoryConfigSchema, temp: workspaceDirectoryTempSchema, log: workspaceDirectoryLogSchema, build: workspaceDirectoryBuildSchema }); schemaRegistry.add(workspaceDirectorySchema, { description: "Various directories used by the workspace to store data, cache, and configuration files" }); var variantSchema = z._default( z.enum(["minimal", "monorepo"]), "monorepo" ); schemaRegistry.add(variantSchema, { description: "The variant of the workspace. This can be used to enable or disable certain features or configurations." }); var errorCodesFileSchema = z._default( z.string().check(z.trim()), STORM_DEFAULT_ERROR_CODES_FILE ); schemaRegistry.add(errorCodesFileSchema, { description: "The path to the workspace's error codes JSON file" }); var errorUrlSchema = z.optional(z.url()); schemaRegistry.add(errorUrlSchema, { description: "A URL to a page that looks up the workspace's error messages given a specific error code" }); var errorSchema = z.object({ codesFile: errorCodesFileSchema, url: errorUrlSchema }); schemaRegistry.add(errorSchema, { description: "The workspace's error config used when creating error details during a system error" }); var organizationNameSchema = z.optional( z.string().check(z.trim(), z.toLowerCase()) ); schemaRegistry.add(organizationNameSchema, { description: "The name of the organization" }); var organizationDescriptionSchema = z.optional( z.string().check(z.trim()) ); schemaRegistry.add(organizationDescriptionSchema, { description: "A description of the organization" }); var organizationLogoSchema = z.optional(z.url()); schemaRegistry.add(organizationLogoSchema, { description: "A URL to the organization's logo image" }); var organizationIconSchema = z.optional(z.url()); schemaRegistry.add(organizationIconSchema, { description: "A URL to the organization's icon image" }); var organizationUrlSchema = z.optional(z.url()); schemaRegistry.add(organizationUrlSchema, { description: "A URL to a page that provides more information about the organization" }); var organizationSchema = z.object({ name: organizationNameSchema, description: organizationDescriptionSchema, logo: organizationLogoSchema, icon: organizationIconSchema, url: organizationUrlSchema }); schemaRegistry.add(organizationSchema, { description: "The workspace's organization details" }); var schemaNameSchema = z._default( z.string().check(z.trim(), z.toLowerCase()), "https://public.storm-cdn.com/schemas/storm-workspace.schema.json" ); schemaRegistry.add(schemaNameSchema, { description: "The URL or file path to the JSON schema file that describes the Storm configuration file" }); var nameSchema = z.string().check(z.trim(), z.toLowerCase()); schemaRegistry.add(nameSchema, { description: "The name of the workspace/project/service/package/scope using this configuration" }); var namespaceSchema = z.string().check(z.trim(), z.toLowerCase()); schemaRegistry.add(namespaceSchema, { description: "The namespace of the workspace/project/service/package/scope using this configuration" }); var orgSchema = z.union([ organizationSchema, z.string().check(z.trim(), z.toLowerCase()) ]); schemaRegistry.add(orgSchema, { description: "The organization of the workspace. This can be a string or an object containing the organization's details" }); var repositorySchema = z.string().check(z.trim(), z.toLowerCase()); schemaRegistry.add(repositorySchema, { description: "The repo URL of the workspace (i.e. the GitHub repository URL)" }); var licenseSchema = z._default( z.string().check(z.trim()), "Apache-2.0" ); schemaRegistry.add(licenseSchema, { description: "The license type of the package" }); var homepageSchema = z.optional(z.url()); schemaRegistry.add(homepageSchema, { description: "The homepage of the workspace" }); var docsSchema = z.optional(z.url()); schemaRegistry.add(docsSchema, { description: "The documentation site for the workspace" }); var portalSchema = z.optional(z.url()); schemaRegistry.add(portalSchema, { description: "The development portal site for the workspace" }); var licensingSchema = z.optional(z.url()); schemaRegistry.add(licensingSchema, { description: "The licensing site for the workspace" }); var contactSchema = z.optional(z.url()); schemaRegistry.add(contactSchema, { description: "The contact site for the workspace" }); var supportSchema = z.optional(z.url()); schemaRegistry.add(supportSchema, { description: "The support site for the workspace. If not provided, this is defaulted to the `contact` config value" }); var branchSchema = z._default( z.string().check(z.trim(), z.toLowerCase()), "main" ); schemaRegistry.add(branchSchema, { description: "The branch of the workspace" }); var preidSchema = z.optional( z.string().check(z.trim(), z.toLowerCase()) ); schemaRegistry.add(preidSchema, { description: "A tag specifying the version pre-release identifier" }); var ownerSchema = z.optional( z.string().check(z.trim(), z.toLowerCase()) ); schemaRegistry.add(ownerSchema, { description: "The owner of the package" }); var modeSchema = z._default( z.enum(["development", "test", "production"]).check(z.trim(), z.toLowerCase()), "production" ); schemaRegistry.add(modeSchema, { description: "The current runtime environment mode for the package" }); var workspaceRootSchema = z.string().check(z.trim(), z.toLowerCase()); schemaRegistry.add(workspaceRootSchema, { description: "The root directory of the workspace" }); var skipCacheSchema = z._default(z.boolean(), false); schemaRegistry.add(skipCacheSchema, { description: "Should all known types of workspace caching be skipped?" }); var packageManagerSchema = z._default( z.enum(["npm", "yarn", "pnpm", "bun"]), "npm" ); schemaRegistry.add(packageManagerSchema, { description: "The JavaScript/TypeScript package manager used by the repository" }); var timezoneSchema = z._default( z.string().check(z.trim()), "America/New_York" ); schemaRegistry.add(timezoneSchema, { description: "The default timezone of the workspace" }); var localeSchema = z._default(z.string().check(z.trim()), "en-US"); schemaRegistry.add(localeSchema, { description: "The default locale of the workspace" }); var logLevelSchema = z._default( z.enum([ "silent", "fatal", "error", "warn", "success", "info", "debug", "trace", "all" ]), "info" ); schemaRegistry.add(logLevelSchema, { description: "The log level used to filter out lower priority log messages. If not provided, this is defaulted using the `environment` config value (if `environment` is set to `production` then `level` is `error`, else `level` is `debug`)." }); var skipConfigLoggingSchema = z._default(z.boolean(), true); schemaRegistry.add(skipConfigLoggingSchema, { description: "Should the logging of the current Storm Workspace configuration be skipped?" }); var configFileSchema = z._default( z.nullable(z.string().check(z.trim())), null ); schemaRegistry.add(configFileSchema, { description: "The filepath of the Storm config. When this field is null, no config file was found in the current workspace." }); var extensionsSchema = z._default(z.record(z.string(), z.any()), {}); schemaRegistry.add(extensionsSchema, { description: "Configuration of each used extension" }); var workspaceConfigSchema = z.object({ $schema: schemaNameSchema, extends: extendsSchema, name: nameSchema, variant: variantSchema, namespace: namespaceSchema, organization: orgSchema, repository: repositorySchema, license: licenseSchema, homepage: homepageSchema, docs: docsSchema, portal: portalSchema, licensing: licensingSchema, contact: contactSchema, support: supportSchema, branch: branchSchema, preid: preidSchema, owner: ownerSchema, bot: workspaceBotSchema, release: workspaceReleaseSchema, socials: workspaceSocialsSchema, error: errorSchema, mode: modeSchema, workspaceRoot: workspaceRootSchema, skipCache: skipCacheSchema, directories: workspaceDirectorySchema, packageManager: packageManagerSchema, timezone: timezoneSchema, locale: localeSchema, logLevel: logLevelSchema, skipConfigLogging: skipConfigLoggingSchema, registry: registrySchema, configFile: configFileSchema, colors: z.union([colorsSchema, themeColorsSchema]), extensions: extensionsSchema }); schemaRegistry.add(extensionsSchema, { description: "Storm Workspace config values used during various dev-ops processes. This type is a combination of the StormPackageConfig and StormProject types. It represents the config of the entire monorepo." }); // ../config/src/types.ts var COLOR_KEYS = [ "dark", "light", "base", "brand", "alternate", "accent", "link", "success", "help", "info", "warning", "danger", "fatal", "positive", "negative" ]; async function getPackageJsonConfig(root) { let license = STORM_DEFAULT_LICENSE; let homepage = void 0; let support = void 0; let name = void 0; let namespace = void 0; let repository = void 0; const workspaceRoot = findWorkspaceRoot(root); if (existsSync(join(workspaceRoot, "package.json"))) { const file = await readFile( joinPaths(workspaceRoot, "package.json"), "utf8" ); if (file) { const packageJson = JSON.parse(file); if (packageJson.name) { name = packageJson.name; } if (packageJson.namespace) { namespace = packageJson.namespace; } if (packageJson.repository) { if (typeof packageJson.repository === "string") { repository = packageJson.repository; } else if (packageJson.repository.url) { repository = packageJson.repository.url; } } if (packageJson.license) { license = packageJson.license; } if (packageJson.homepage) { homepage = packageJson.homepage; } if (packageJson.bugs) { if (typeof packageJson.bugs === "string") { support = packageJson.bugs; } else if (packageJson.bugs.url) { support = packageJson.bugs.url; } } } } return { workspaceRoot, name, namespace, repository, license, homepage, support }; } function applyDefaultConfig(config) { if (!config.support && config.contact) { config.support = config.contact; } if (!config.contact && config.support) { config.contact = config.support; } if (config.homepage) { if (!config.docs) { config.docs = `${config.homepage}/docs`; } if (!config.license) { config.license = `${config.homepage}/license`; } if (!config.support) { config.support = `${config.homepage}/support`; } if (!config.contact) { config.contact = `${config.homepage}/contact`; } if (!config.error?.codesFile || !config?.error?.url) { config.error ??= { codesFile: STORM_DEFAULT_ERROR_CODES_FILE }; if (config.homepage) { config.error.url ??= `${config.homepage}/errors`; } } } return config; } // ../config-tools/src/config-file/get-config-file.ts var getConfigFileByName = async (fileName, filePath, options = {}) => { const workspacePath = filePath || findWorkspaceRoot(filePath); const configs = await Promise.all([ loadConfig({ cwd: workspacePath, packageJson: true, name: fileName, envName: fileName?.toUpperCase(), jitiOptions: { debug: false, fsCache: process.env.STORM_SKIP_CACHE === "true" ? false : joinPaths( process.env.STORM_CACHE_DIR || "node_modules/.cache/storm", "jiti" ) }, ...options }), loadConfig({ cwd: workspacePath, packageJson: true, name: fileName, envName: fileName?.toUpperCase(), jitiOptions: { debug: false, fsCache: process.env.STORM_SKIP_CACHE === "true" ? false : joinPaths( process.env.STORM_CACHE_DIR || "node_modules/.cache/storm", "jiti" ) }, configFile: fileName, ...options }) ]); return defu(configs[0] ?? {}, configs[1] ?? {}); }; var getConfigFile = async (filePath, additionalFileNames = []) => { const workspacePath = filePath ? filePath : findWorkspaceRoot(filePath); const result = await getConfigFileByName("storm-workspace", workspacePath); let config = result.config; const configFile = result.configFile; if (config && configFile && Object.keys(config).length > 0 && !config.skipConfigLogging) { writeTrace( `Found Storm configuration file "${configFile.includes(`${workspacePath}/`) ? configFile.replace(`${workspacePath}/`, "") : configFile}" at "${workspacePath}"`, { logLevel: "all" } ); } if (additionalFileNames && additionalFileNames.length > 0) { const results = await Promise.all( additionalFileNames.map( (fileName) => getConfigFileByName(fileName, workspacePath) ) ); for (const result2 of results) { if (result2?.config && result2?.configFile && Object.keys(result2.config).length > 0) { if (!config.skipConfigLogging && !result2.config.skipConfigLogging) { writeTrace( `Found alternative configuration file "${result2.configFile.includes(`${workspacePath}/`) ? result2.configFile.replace(`${workspacePath}/`, "") : result2.configFile}" at "${workspacePath}"`, { logLevel: "all" } ); } config = defu(result2.config ?? {}, config ?? {}); } } } if (!config || Object.keys(config).length === 0) { return void 0; } config.configFile = configFile; return config; }; var getConfigEnv = () => { const prefix = "STORM_"; let config = { extends: process.env[`${prefix}EXTENDS`] || void 0, name: process.env[`${prefix}NAME`] || void 0, variant: process.env[`${prefix}VARIANT`] || void 0, namespace: process.env[`${prefix}NAMESPACE`] || void 0, owner: process.env[`${prefix}OWNER`] || void 0, bot: { name: process.env[`${prefix}BOT_NAME`] || void 0, email: process.env[`${prefix}BOT_EMAIL`] || void 0 }, release: { banner: { url: process.env[`${prefix}RELEASE_BANNER_URL`] || void 0, alt: process.env[`${prefix}RELEASE_BANNER_ALT`] || void 0 }, header: process.env[`${prefix}RELEASE_HEADER`] || void 0, footer: process.env[`${prefix}RELEASE_FOOTER`] || void 0 }, error: { codesFile: process.env[`${prefix}ERROR_CODES_FILE`] || void 0, url: process.env[`${prefix}ERROR_URL`] || void 0 }, socials: { twitter: process.env[`${prefix}SOCIAL_TWITTER`] || void 0, discord: process.env[`${prefix}SOCIAL_DISCORD`] || void 0, telegram: process.env[`${prefix}SOCIAL_TELEGRAM`] || void 0, slack: process.env[`${prefix}SOCIAL_SLACK`] || void 0, medium: process.env[`${prefix}SOCIAL_MEDIUM`] || void 0, github: process.env[`${prefix}SOCIAL_GITHUB`] || void 0 }, organization: process.env[`${prefix}ORG`] || process.env[`${prefix}ORGANIZATION`] || process.env[`${prefix}ORG_NAME`] || process.env[`${prefix}ORGANIZATION_NAME`] ? process.env[`${prefix}ORG_DESCRIPTION`] || process.env[`${prefix}ORGANIZATION_DESCRIPTION`] || process.env[`${prefix}ORG_URL`] || process.env[`${prefix}ORGANIZATION_URL`] || process.env[`${prefix}ORG_LOGO`] || process.env[`${prefix}ORGANIZATION_LOGO`] ? { name: process.env[`${prefix}ORG`] || process.env[`${prefix}ORGANIZATION`] || process.env[`${prefix}ORG_NAME`] || process.env[`${prefix}ORGANIZATION_NAME`], description: process.env[`${prefix}ORG_DESCRIPTION`] || process.env[`${prefix}ORGANIZATION_DESCRIPTION`] || void 0, url: process.env[`${prefix}ORG_URL`] || process.env[`${prefix}ORGANIZATION_URL`] || void 0, logo: process.env[`${prefix}ORG_LOGO`] || process.env[`${prefix}ORGANIZATION_LOGO`] || void 0, icon: process.env[`${prefix}ORG_ICON`] || process.env[`${prefix}ORGANIZATION_ICON`] || void 0 } : process.env[`${prefix}ORG`] || process.env[`${prefix}ORGANIZATION`] || process.env[`${prefix}ORG_NAME`] || process.env[`${prefix}ORGANIZATION_NAME`] : void 0, packageManager: process.env[`${prefix}PACKAGE_MANAGER`] || void 0, license: process.env[`${prefix}LICENSE`] || void 0, homepage: process.env[`${prefix}HOMEPAGE`] || void 0, docs: process.env[`${prefix}DOCS`] || void 0, portal: process.env[`${prefix}PORTAL`] || void 0, licensing: process.env[`${prefix}LICENSING`] || void 0, contact: process.env[`${prefix}CONTACT`] || void 0, support: process.env[`${prefix}SUPPORT`] || void 0, timezone: process.env[`${prefix}TIMEZONE`] || process.env.TZ || void 0, locale: process.env[`${prefix}LOCALE`] || process.env.LOCALE || void 0, configFile: process.env[`${prefix}WORKSPACE_CONFIG_FILE`] ? correctPaths(process.env[`${prefix}WORKSPACE_CONFIG_FILE`]) : void 0, workspaceRoot: process.env[`${prefix}WORKSPACE_ROOT`] ? correctPaths(process.env[`${prefix}WORKSPACE_ROOT`]) : void 0, directories: { cache: process.env[`${prefix}CACHE_DIR`] ? correctPaths(process.env[`${prefix}CACHE_DIR`]) : process.env[`${prefix}CACHE_DIRECTORY`] ? correctPaths(process.env[`${prefix}CACHE_DIRECTORY`]) : void 0, data: process.env[`${prefix}DATA_DIR`] ? correctPaths(process.env[`${prefix}DATA_DIR`]) : process.env[`${prefix}DATA_DIRECTORY`] ? correctPaths(process.env[`${prefix}DATA_DIRECTORY`]) : void 0, config: process.env[`${prefix}CONFIG_DIR`] ? correctPaths(process.env[`${prefix}CONFIG_DIR`]) : process.env[`${prefix}CONFIG_DIRECTORY`] ? correctPaths(process.env[`${prefix}CONFIG_DIRECTORY`]) : void 0, temp: process.env[`${prefix}TEMP_DIR`] ? correctPaths(process.env[`${prefix}TEMP_DIR`]) : process.env[`${prefix}TEMP_DIRECTORY`] ? correctPaths(process.env[`${prefix}TEMP_DIRECTORY`]) : void 0, log: process.env[`${prefix}LOG_DIR`] ? correctPaths(process.env[`${prefix}LOG_DIR`]) : process.env[`${prefix}LOG_DIRECTORY`] ? correctPaths(process.env[`${prefix}LOG_DIRECTORY`]) : void 0, build: process.env[`${prefix}BUILD_DIR`] ? correctPaths(process.env[`${prefix}BUILD_DIR`]) : process.env[`${prefix}BUILD_DIRECTORY`] ? correctPaths(process.env[`${prefix}BUILD_DIRECTORY`]) : void 0 }, skipCache: process.env[`${prefix}SKIP_CACHE`] !== void 0 ? Boolean(process.env[`${prefix}SKIP_CACHE`]) : void 0, mode: (process.env[`${prefix}MODE`] ?? process.env.NODE_ENV ?? process.env.ENVIRONMENT) || void 0, // ci: // process.env[`${prefix}CI`] !== undefined // ? Boolean( // process.env[`${prefix}CI`] ?? // process.env.CI ?? // process.env.CONTINUOUS_INTEGRATION // ) // : undefined, repository: process.env[`${prefix}REPOSITORY`] || void 0, branch: process.env[`${prefix}BRANCH`] || void 0, preid: process.env[`${prefix}PRE_ID`] || void 0, registry: { github: process.env[`${prefix}REGISTRY_GITHUB`] || void 0, npm: process.env[`${prefix}REGISTRY_NPM`] || void 0, cargo: process.env[`${prefix}REGISTRY_CARGO`] || void 0, cyclone: process.env[`${prefix}REGISTRY_CYCLONE`] || void 0, container: process.env[`${prefix}REGISTRY_CONTAINER`] || void 0 }, logLevel: process.env[`${prefix}LOG_LEVEL`] !== null && process.env[`${prefix}LOG_LEVEL`] !== void 0 ? process.env[`${prefix}LOG_LEVEL`] && Number.isSafeInteger( Number.parseInt(process.env[`${prefix}LOG_LEVEL`]) ) ? getLogLevelLabel( Number.parseInt(process.env[`${prefix}LOG_LEVEL`]) ) : process.env[`${prefix}LOG_LEVEL`] : void 0, skipConfigLogging: process.env[`${prefix}SKIP_CONFIG_LOGGING`] !== void 0 ? Boolean(process.env[`${prefix}SKIP_CONFIG_LOGGING`]) : void 0 }; const themeNames = Object.keys(process.env).filter( (envKey) => envKey.startsWith(`${prefix}COLOR_`) && COLOR_KEYS.every( (colorKey) => !envKey.startsWith(`${prefix}COLOR_LIGHT_${colorKey}`) && !envKey.startsWith(`${prefix}COLOR_DARK_${colorKey}`) ) ); config.colors = themeNames.length > 0 ? themeNames.reduce( (ret, themeName) => { ret[themeName] = getThemeColorsEnv(prefix, themeName); return ret; }, {} ) : getThemeColorsEnv(prefix); if (config.docs === STORM_DEFAULT_DOCS) { if (config.homepage === STORM_DEFAULT_HOMEPAGE) { config.docs = `${STORM_DEFAULT_HOMEPAGE}/projects/${config.name}/docs`; } else { config.docs = `${config.homepage}/docs`; } } if (config.licensing === STORM_DEFAULT_LICENSING) { if (config.homepage === STORM_DEFAULT_HOMEPAGE) { config.licensing = `${STORM_DEFAULT_HOMEPAGE}/projects/${config.name}/licensing`; } else { config.licensing = `${config.homepage}/docs`; } } const serializedConfig = process.env[`${prefix}WORKSPACE_CONFIG`]; if (serializedConfig) { const parsed = JSON.parse(serializedConfig); config = { ...config, ...parsed, colors: { ...config.colors, ...parsed.colors }, extensions: { ...config.extensions, ...parsed.extensions } }; } return config; }; var getThemeColorsEnv = (prefix, theme) => { const themeName = `COLOR_${theme && theme !== "base" ? `${theme}_` : ""}`.toUpperCase(); return process.env[`${prefix}${themeName}LIGHT_BRAND`] || process.env[`${prefix}${themeName}DARK_BRAND`] ? getMultiThemeColorsEnv(prefix + themeName) : getSingleThemeColorsEnv(prefix + themeName); }; var getSingleThemeColorsEnv = (prefix) => { const gradient = []; if (process.env[`${prefix}GRADIENT_START`] && process.env[`${prefix}GRADIENT_END`]) { gradient.push( process.env[`${prefix}GRADIENT_START`], process.env[`${prefix}GRADIENT_END`] ); } else if (process.env[`${prefix}GRADIENT_0`] || process.env[`${prefix}GRADIENT_1`]) { let index = process.env[`${prefix}GRADIENT_0`] ? 0 : 1; while (process.env[`${prefix}GRADIENT_${index}`]) { gradient.push(process.env[`${prefix}GRADIENT_${index}`]); index++; } } return { dark: process.env[`${prefix}DARK`], light: process.env[`${prefix}LIGHT`], brand: process.env[`${prefix}BRAND`], alternate: process.env[`${prefix}ALTERNATE`], accent: process.env[`${prefix}ACCENT`], link: process.env[`${prefix}LINK`], help: process.env[`${prefix}HELP`], success: process.env[`${prefix}SUCCESS`], info: process.env[`${prefix}INFO`], warning: process.env[`${prefix}WARNING`], danger: process.env[`${prefix}DANGER`], fatal: process.env[`${prefix}FATAL`], positive: process.env[`${prefix}POSITIVE`], negative: process.env[`${prefix}NEGATIVE`], gradient }; }; var getMultiThemeColorsEnv = (prefix) => { return { light: getBaseThemeColorsEnv(`${prefix}_LIGHT_`), dark: getBaseThemeColorsEnv(`${prefix}_DARK_`) }; }; var getBaseThemeColorsEnv = (prefix) => { const gradient = []; if (process.env[`${prefix}GRADIENT_START`] && process.env[`${prefix}GRADIENT_END`]) { gradient.push( process.env[`${prefix}GRADIENT_START`], process.env[`${prefix}GRADIENT_END`] ); } else if (process.env[`