@storm-software/config-tools 1.190.120 → 1.190.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/bin/config.cjs +1272 -105
  2. package/bin/config.mjs +1271 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/config-file/get-config-file.cjs +63 -79
  5. package/dist/config-file/get-config-file.d.cts +5 -5
  6. package/dist/config-file/{get-config-file.d.ts → get-config-file.d.mts} +7 -5
  7. package/dist/config-file/get-config-file.mjs +66 -0
  8. package/dist/config-file/index.cjs +4 -1
  9. package/dist/config-file/index.d.cts +2 -3
  10. package/dist/config-file/index.d.mts +4 -0
  11. package/dist/config-file/index.mjs +5 -0
  12. package/dist/create-storm-config.cjs +105 -136
  13. package/dist/create-storm-config.d.cts +5 -5
  14. package/dist/{create-storm-config.d.ts → create-storm-config.d.mts} +7 -5
  15. package/dist/create-storm-config.mjs +113 -0
  16. package/dist/env/get-env.cjs +190 -214
  17. package/dist/env/get-env.d.cts +5 -5
  18. package/dist/env/{get-env.d.ts → get-env.d.mts} +7 -5
  19. package/dist/env/get-env.mjs +203 -0
  20. package/dist/env/index.cjs +7 -2
  21. package/dist/env/index.d.cts +3 -4
  22. package/dist/env/index.d.mts +5 -0
  23. package/dist/env/index.mjs +6 -0
  24. package/dist/env/set-env.cjs +218 -374
  25. package/dist/env/set-env.d.cts +8 -8
  26. package/dist/env/{set-env.d.ts → set-env.d.mts} +10 -8
  27. package/dist/env/set-env.mjs +231 -0
  28. package/dist/get-config.cjs +40 -29
  29. package/dist/get-config.d.cts +18 -18
  30. package/dist/{get-config.d.ts → get-config.d.mts} +20 -18
  31. package/dist/get-config.mjs +46 -0
  32. package/dist/index.cjs +98 -7
  33. package/dist/index.d.cts +27 -28
  34. package/dist/index.d.mts +29 -0
  35. package/dist/index.mjs +26 -0
  36. package/dist/logger/chalk.cjs +38 -29
  37. package/dist/logger/chalk.d.cts +18 -17
  38. package/dist/logger/chalk.d.mts +37 -0
  39. package/dist/logger/chalk.mjs +43 -0
  40. package/dist/logger/console-icons.cjs +15 -14
  41. package/dist/logger/console-icons.d.cts +5 -8
  42. package/dist/logger/console-icons.d.mts +7 -0
  43. package/dist/logger/console-icons.mjs +20 -0
  44. package/dist/logger/console.cjs +187 -183
  45. package/dist/logger/console.d.cts +25 -25
  46. package/dist/logger/{console.d.ts → console.d.mts} +27 -25
  47. package/dist/logger/console.mjs +185 -0
  48. package/dist/logger/create-logger.cjs +31 -24
  49. package/dist/logger/create-logger.d.cts +5 -6
  50. package/dist/logger/{create-logger.d.ts → create-logger.d.mts} +7 -6
  51. package/dist/logger/create-logger.mjs +34 -0
  52. package/dist/logger/format-timestamp.cjs +12 -4
  53. package/dist/logger/format-timestamp.d.cts +3 -2
  54. package/dist/logger/{format-timestamp.d.ts → format-timestamp.d.mts} +5 -2
  55. package/dist/logger/format-timestamp.mjs +16 -0
  56. package/dist/logger/get-log-level.cjs +50 -60
  57. package/dist/logger/get-log-level.d.cts +4 -5
  58. package/dist/logger/{get-log-level.d.ts → get-log-level.d.mts} +6 -5
  59. package/dist/logger/get-log-level.mjs +54 -0
  60. package/dist/logger/index.cjs +29 -7
  61. package/dist/logger/index.d.cts +8 -10
  62. package/dist/logger/index.d.mts +10 -0
  63. package/dist/logger/index.mjs +11 -0
  64. package/dist/logger/is-unicode-supported.cjs +6 -10
  65. package/dist/logger/is-unicode-supported.d.cts +3 -2
  66. package/dist/logger/is-unicode-supported.d.mts +6 -0
  67. package/dist/logger/is-unicode-supported.mjs +10 -0
  68. package/dist/types.cjs +26 -25
  69. package/dist/types.d.cts +39 -41
  70. package/dist/types.d.mts +53 -0
  71. package/dist/types.mjs +30 -0
  72. package/dist/utilities/apply-workspace-tokens.cjs +31 -70
  73. package/dist/utilities/apply-workspace-tokens.d.cts +4 -5
  74. package/dist/utilities/{apply-workspace-tokens.d.ts → apply-workspace-tokens.d.mts} +6 -5
  75. package/dist/utilities/apply-workspace-tokens.mjs +37 -0
  76. package/dist/utilities/colors.cjs +91 -74
  77. package/dist/utilities/colors.d.cts +4 -4
  78. package/dist/utilities/{colors.d.ts → colors.d.mts} +6 -4
  79. package/dist/utilities/colors.mjs +97 -0
  80. package/dist/utilities/correct-paths.cjs +166 -196
  81. package/dist/utilities/correct-paths.d.cts +4 -4
  82. package/dist/utilities/{correct-paths.d.ts → correct-paths.d.mts} +6 -4
  83. package/dist/utilities/correct-paths.mjs +190 -0
  84. package/dist/utilities/file-path-utils.cjs +42 -27
  85. package/dist/utilities/file-path-utils.d.cts +15 -14
  86. package/dist/utilities/{file-path-utils.d.ts → file-path-utils.d.mts} +17 -14
  87. package/dist/utilities/file-path-utils.mjs +48 -0
  88. package/dist/utilities/find-up.cjs +12 -18
  89. package/dist/utilities/find-up.d.cts +3 -2
  90. package/dist/utilities/{find-up.d.ts → find-up.d.mts} +5 -2
  91. package/dist/utilities/find-up.mjs +19 -0
  92. package/dist/utilities/find-workspace-root.cjs +64 -69
  93. package/dist/utilities/find-workspace-root.d.cts +3 -2
  94. package/dist/utilities/{find-workspace-root.d.ts → find-workspace-root.d.mts} +5 -2
  95. package/dist/utilities/find-workspace-root.mjs +73 -0
  96. package/dist/utilities/get-default-config.cjs +69 -91
  97. package/dist/utilities/get-default-config.d.cts +4 -4
  98. package/dist/utilities/{get-default-config.d.ts → get-default-config.d.mts} +6 -4
  99. package/dist/utilities/get-default-config.mjs +74 -0
  100. package/dist/utilities/index.cjs +49 -9
  101. package/dist/utilities/index.d.cts +10 -14
  102. package/dist/utilities/index.d.mts +12 -0
  103. package/dist/utilities/index.mjs +13 -0
  104. package/dist/utilities/process-handler.cjs +32 -47
  105. package/dist/utilities/process-handler.d.cts +4 -4
  106. package/dist/utilities/process-handler.d.mts +9 -0
  107. package/dist/utilities/process-handler.mjs +38 -0
  108. package/dist/utilities/run.cjs +62 -36
  109. package/dist/utilities/run.d.cts +5 -6
  110. package/dist/utilities/{run.d.ts → run.d.mts} +7 -6
  111. package/dist/utilities/run.mjs +64 -0
  112. package/dist/utilities/toml.cjs +27 -32
  113. package/dist/utilities/toml.d.cts +148 -147
  114. package/dist/utilities/toml.d.mts +192 -0
  115. package/dist/utilities/toml.mjs +33 -0
  116. package/package.json +105 -157
  117. package/bin/config.js +0 -108
  118. package/dist/config-file/get-config-file.js +0 -83
  119. package/dist/config-file/index.d.ts +0 -3
  120. package/dist/config-file/index.js +0 -1
  121. package/dist/create-storm-config.js +0 -147
  122. package/dist/env/get-env.js +0 -226
  123. package/dist/env/index.d.ts +0 -4
  124. package/dist/env/index.js +0 -2
  125. package/dist/env/set-env.js +0 -386
  126. package/dist/get-config.js +0 -35
  127. package/dist/index.d.ts +0 -28
  128. package/dist/index.js +0 -7
  129. package/dist/logger/chalk.d.ts +0 -34
  130. package/dist/logger/chalk.js +0 -34
  131. package/dist/logger/console-icons.d.ts +0 -8
  132. package/dist/logger/console-icons.js +0 -17
  133. package/dist/logger/console.js +0 -191
  134. package/dist/logger/create-logger.js +0 -27
  135. package/dist/logger/format-timestamp.js +0 -6
  136. package/dist/logger/get-log-level.js +0 -64
  137. package/dist/logger/index.d.ts +0 -10
  138. package/dist/logger/index.js +0 -7
  139. package/dist/logger/is-unicode-supported.d.ts +0 -3
  140. package/dist/logger/is-unicode-supported.js +0 -12
  141. package/dist/types.d.ts +0 -53
  142. package/dist/types.js +0 -28
  143. package/dist/utilities/apply-workspace-tokens.js +0 -76
  144. package/dist/utilities/colors.js +0 -81
  145. package/dist/utilities/correct-paths.js +0 -231
  146. package/dist/utilities/file-path-utils.js +0 -33
  147. package/dist/utilities/find-up.js +0 -23
  148. package/dist/utilities/find-workspace-root.js +0 -77
  149. package/dist/utilities/get-default-config.js +0 -95
  150. package/dist/utilities/index.d.ts +0 -14
  151. package/dist/utilities/index.js +0 -9
  152. package/dist/utilities/process-handler.d.ts +0 -7
  153. package/dist/utilities/process-handler.js +0 -53
  154. package/dist/utilities/run.js +0 -38
  155. package/dist/utilities/toml.d.ts +0 -189
  156. package/dist/utilities/toml.js +0 -42
package/bin/config.mjs ADDED
@@ -0,0 +1,1271 @@
1
+ #!/usr/bin/env node
2
+ import chalk from "chalk";
3
+ import { Command } from "commander";
4
+ import { workspaceConfigSchema } from "@storm-software/config/schema";
5
+ import defu from "defu";
6
+ import { existsSync } from "node:fs";
7
+ import { loadConfig } from "c12";
8
+ import "date-fns/formatDistanceToNow";
9
+ import { join } from "node:path";
10
+ import { COLOR_KEYS, STORM_DEFAULT_DOCS, STORM_DEFAULT_ERROR_CODES_FILE, STORM_DEFAULT_HOMEPAGE, STORM_DEFAULT_LICENSE, STORM_DEFAULT_LICENSING } from "@storm-software/config";
11
+ import { readFile } from "node:fs/promises";
12
+ //#region src/types.ts
13
+ const LogLevel = {
14
+ SILENT: 0,
15
+ FATAL: 10,
16
+ ERROR: 20,
17
+ WARN: 30,
18
+ SUCCESS: 35,
19
+ INFO: 40,
20
+ PERFORMANCE: 50,
21
+ DEBUG: 60,
22
+ TRACE: 70,
23
+ ALL: 100
24
+ };
25
+ const LogLevelLabel = {
26
+ SILENT: "silent",
27
+ FATAL: "fatal",
28
+ ERROR: "error",
29
+ WARN: "warn",
30
+ SUCCESS: "success",
31
+ INFO: "info",
32
+ PERFORMANCE: "performance",
33
+ DEBUG: "debug",
34
+ TRACE: "trace",
35
+ ALL: "all"
36
+ };
37
+ //#endregion
38
+ //#region src/utilities/colors.ts
39
+ /**
40
+ * Storm theme config values used for styling various workspace elements
41
+ */
42
+ const DEFAULT_COLOR_CONFIG = {
43
+ light: {
44
+ background: "#fafafa",
45
+ foreground: "#1d1e22",
46
+ brand: "#1fb2a6",
47
+ alternate: "#db2777",
48
+ discovery: "#5C4EE5",
49
+ success: "#087f5b",
50
+ info: "#0550ae",
51
+ debug: "#8afafc",
52
+ warning: "#e3b341",
53
+ danger: "#D8314A",
54
+ fatal: "#51070f",
55
+ performance: "#13c302",
56
+ link: "#3fa6ff",
57
+ positive: "#22c55e",
58
+ negative: "#dc2626",
59
+ gradient: [
60
+ "#1fb2a6",
61
+ "#db2777",
62
+ "#5C4EE5"
63
+ ]
64
+ },
65
+ dark: {
66
+ background: "#1e2124",
67
+ foreground: "#cbd5e1",
68
+ brand: "#2dd4bf",
69
+ alternate: "#db2777",
70
+ discovery: "#818cf8",
71
+ success: "#10b981",
72
+ info: "#58a6ff",
73
+ debug: "#8afafc",
74
+ warning: "#f3d371",
75
+ danger: "#D8314A",
76
+ fatal: "#a40e26",
77
+ performance: "#80fd74",
78
+ link: "#3fa6ff",
79
+ positive: "#22c55e",
80
+ negative: "#dc2626",
81
+ gradient: [
82
+ "#1fb2a6",
83
+ "#db2777",
84
+ "#818cf8"
85
+ ]
86
+ }
87
+ };
88
+ /**
89
+ * Get the color configuration from the Storm workspace configuration.
90
+ *
91
+ * @param config - An optional, partial color configuration for the Storm workspace.
92
+ * @returns The color configuration, or the default color configuration if not defined.
93
+ */
94
+ function getColors(config) {
95
+ if (!config?.colors || typeof config.colors !== "object" || !config.colors["dark"] && (!config.colors["base"] || typeof config.colors !== "object" || !config.colors["base"]?.["dark"])) return DEFAULT_COLOR_CONFIG;
96
+ if (config.colors["base"]) {
97
+ if (typeof config.colors["base"]["dark"] === "object") return config.colors["base"]["dark"];
98
+ else if (config.colors["base"]["dark"] === "string") return config.colors["base"];
99
+ }
100
+ if (typeof config.colors["dark"] === "object") return config.colors["dark"];
101
+ return config.colors ?? DEFAULT_COLOR_CONFIG;
102
+ }
103
+ /**
104
+ * Get a specific color from the Storm workspace configuration.
105
+ *
106
+ * @param key - The key of the color to retrieve.
107
+ * @param config - An optional, partial color configuration for the Storm workspace.
108
+ * @returns The color value for the specified key, or a default value if not defined.
109
+ */
110
+ function getColor(key, config) {
111
+ const colors = getColors(config);
112
+ const result = (typeof colors["dark"] === "object" ? colors["dark"][key] : colors[key]) || DEFAULT_COLOR_CONFIG["dark"][key] || DEFAULT_COLOR_CONFIG[key];
113
+ if (result) return result;
114
+ if (key === "link" || key === "debug") return getColor("info", config);
115
+ else if (key === "fatal") return getColor("danger", config);
116
+ return getColor("brand", config);
117
+ }
118
+ //#endregion
119
+ //#region src/logger/chalk.ts
120
+ const chalkDefault = {
121
+ hex: (_) => (message) => message,
122
+ bgHex: (_) => ({
123
+ whiteBright: (message) => message,
124
+ white: (message) => message
125
+ }),
126
+ white: (message) => message,
127
+ whiteBright: (message) => message,
128
+ gray: (message) => message,
129
+ bold: {
130
+ hex: (_) => (message) => message,
131
+ bgHex: (_) => ({
132
+ whiteBright: (message) => message,
133
+ white: (message) => message
134
+ }),
135
+ whiteBright: (message) => message,
136
+ white: (message) => message
137
+ },
138
+ dim: {
139
+ hex: (_) => (message) => message,
140
+ gray: (message) => message
141
+ }
142
+ };
143
+ /**
144
+ * Get the chalk instance
145
+ *
146
+ * @remarks
147
+ * Annoying polyfill to temporarily fix the issue with the `chalk` import
148
+ *
149
+ * @returns The chalk instance
150
+ */
151
+ const getChalk = () => {
152
+ let _chalk = chalk;
153
+ if (!_chalk?.hex || !_chalk?.bold?.hex || !_chalk?.bgHex || !_chalk?.whiteBright || !_chalk?.white) _chalk = chalkDefault;
154
+ return _chalk;
155
+ };
156
+ //#endregion
157
+ //#region src/logger/is-unicode-supported.ts
158
+ function isUnicodeSupported() {
159
+ if (process.platform !== "win32") return process.env.TERM !== "linux";
160
+ return Boolean(process.env.WT_SESSION) || Boolean(process.env.TERMINUS_SUBLIME) || process.env.ConEmuTask === "{cmd::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";
161
+ }
162
+ //#endregion
163
+ //#region src/logger/console-icons.ts
164
+ const useIcon = (c, fallback) => isUnicodeSupported() ? c : fallback;
165
+ const CONSOLE_ICONS = {
166
+ [LogLevelLabel.ERROR]: useIcon("✘", "×"),
167
+ [LogLevelLabel.FATAL]: useIcon("🕱", "×"),
168
+ [LogLevelLabel.WARN]: useIcon("⚠", "‼"),
169
+ [LogLevelLabel.INFO]: useIcon("ℹ", "i"),
170
+ [LogLevelLabel.PERFORMANCE]: useIcon("⏱", "⏱"),
171
+ [LogLevelLabel.SUCCESS]: useIcon("✔", "√"),
172
+ [LogLevelLabel.DEBUG]: useIcon("🛠", "D"),
173
+ [LogLevelLabel.TRACE]: useIcon("⚙", "T"),
174
+ [LogLevelLabel.ALL]: useIcon("✉", "→")
175
+ };
176
+ //#endregion
177
+ //#region src/logger/format-timestamp.ts
178
+ /**
179
+ * Format a timestamp to a human-readable string.
180
+ *
181
+ * @param fullDateTime Whether to include the full date and time in the formatted string (defaults to `false`, which only includes the time)
182
+ * @param date The date to format.
183
+ * @returns The formatted timestamp.
184
+ */
185
+ const formatTimestamp = (fullDateTime = false, date = /* @__PURE__ */ new Date()) => {
186
+ return fullDateTime ? `${date.toLocaleDateString()} ${date.toLocaleTimeString()}` : `${date.toLocaleTimeString()}`;
187
+ };
188
+ //#endregion
189
+ //#region src/logger/get-log-level.ts
190
+ /**
191
+ * Convert the log level label to a log level
192
+ *
193
+ * @param label - The log level label to convert
194
+ * @returns The log level
195
+ */
196
+ const getLogLevel = (label) => {
197
+ switch (label) {
198
+ case "all": return LogLevel.ALL;
199
+ case "trace": return LogLevel.TRACE;
200
+ case "debug": return LogLevel.DEBUG;
201
+ case "performance": return LogLevel.PERFORMANCE;
202
+ case "info": return LogLevel.INFO;
203
+ case "warn": return LogLevel.WARN;
204
+ case "error": return LogLevel.ERROR;
205
+ case "fatal": return LogLevel.FATAL;
206
+ case "silent": return LogLevel.SILENT;
207
+ default: return LogLevel.INFO;
208
+ }
209
+ };
210
+ /**
211
+ * Convert the log level to a log level label
212
+ *
213
+ * @param logLevel - The log level to convert
214
+ * @returns The log level label
215
+ */
216
+ const getLogLevelLabel = (logLevel = LogLevel.INFO) => {
217
+ if (logLevel >= LogLevel.ALL) return LogLevelLabel.ALL;
218
+ if (logLevel >= LogLevel.TRACE) return LogLevelLabel.TRACE;
219
+ if (logLevel >= LogLevel.DEBUG) return LogLevelLabel.DEBUG;
220
+ if (logLevel >= LogLevel.PERFORMANCE) return LogLevelLabel.PERFORMANCE;
221
+ if (logLevel >= LogLevel.INFO) return LogLevelLabel.INFO;
222
+ if (logLevel >= LogLevel.WARN) return LogLevelLabel.WARN;
223
+ if (logLevel >= LogLevel.ERROR) return LogLevelLabel.ERROR;
224
+ if (logLevel >= LogLevel.FATAL) return LogLevelLabel.FATAL;
225
+ if (logLevel <= LogLevel.SILENT) return LogLevelLabel.SILENT;
226
+ return LogLevelLabel.INFO;
227
+ };
228
+ //#endregion
229
+ //#region src/logger/console.ts
230
+ /**
231
+ * Get the log function for a log level
232
+ *
233
+ * @param logLevel - The log level
234
+ * @param config - The Storm configuration
235
+ * @returns The log function
236
+ */
237
+ const getLogFn = (logLevel = LogLevel.INFO, config = {}, options = {}) => {
238
+ const { chalk: _chalk = getChalk(), fullDateTime = false, hideDateTime = false } = options;
239
+ 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;
240
+ const configLogLevel = config.logLevel || process.env.STORM_LOG_LEVEL || LogLevelLabel.INFO;
241
+ if (logLevel > getLogLevel(configLogLevel) || logLevel <= LogLevel.SILENT || getLogLevel(configLogLevel) <= LogLevel.SILENT) return (_) => {};
242
+ if (typeof logLevel === "number" && LogLevel.FATAL >= logLevel) return (message) => {
243
+ console.error(`
244
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.fatal ?? DEFAULT_COLOR_CONFIG.dark.fatal)(`[${CONSOLE_ICONS[LogLevelLabel.FATAL]} Fatal] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
245
+ `);
246
+ };
247
+ if (typeof logLevel === "number" && LogLevel.ERROR >= logLevel) return (message) => {
248
+ console.error(`
249
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.danger ?? DEFAULT_COLOR_CONFIG.dark.danger)(`[${CONSOLE_ICONS[LogLevelLabel.ERROR]} Error] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
250
+ `);
251
+ };
252
+ if (typeof logLevel === "number" && LogLevel.WARN >= logLevel) return (message) => {
253
+ console.warn(`
254
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.warning ?? DEFAULT_COLOR_CONFIG.dark.warning)(`[${CONSOLE_ICONS[LogLevelLabel.WARN]} Warn] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
255
+ `);
256
+ };
257
+ if (typeof logLevel === "number" && LogLevel.SUCCESS >= logLevel) return (message) => {
258
+ console.info(`
259
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.success ?? DEFAULT_COLOR_CONFIG.dark.success)(`[${CONSOLE_ICONS[LogLevelLabel.SUCCESS]} Success] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
260
+ `);
261
+ };
262
+ if (typeof logLevel === "number" && LogLevel.INFO >= logLevel) return (message) => {
263
+ console.info(`
264
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.info ?? DEFAULT_COLOR_CONFIG.dark.info)(`[${CONSOLE_ICONS[LogLevelLabel.INFO]} Info] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
265
+ `);
266
+ };
267
+ if (typeof logLevel === "number" && LogLevel.PERFORMANCE >= logLevel) return (message) => {
268
+ console.debug(`
269
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.performance ?? DEFAULT_COLOR_CONFIG.dark.performance)(`[${CONSOLE_ICONS[LogLevelLabel.PERFORMANCE]} Performance] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
270
+ `);
271
+ };
272
+ if (typeof logLevel === "number" && LogLevel.DEBUG >= logLevel) return (message) => {
273
+ console.debug(`
274
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.debug ?? DEFAULT_COLOR_CONFIG.dark.debug)(`[${CONSOLE_ICONS[LogLevelLabel.DEBUG]} Debug] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
275
+ `);
276
+ };
277
+ if (typeof logLevel === "number" && LogLevel.TRACE >= logLevel) return (message) => {
278
+ console.debug(`
279
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex("#bbbbbb")(`[${CONSOLE_ICONS[LogLevelLabel.TRACE]} Trace] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
280
+ `);
281
+ };
282
+ return (message) => {
283
+ console.log(`
284
+ ${hideDateTime ? "" : `${_chalk.gray(formatTimestamp(fullDateTime))} `}${_chalk.hex(colors.brand ?? DEFAULT_COLOR_CONFIG.dark.brand)(`[${CONSOLE_ICONS[LogLevelLabel.ALL]} System] `)}${_chalk.bold.whiteBright(formatLogMessage(message))}
285
+ `);
286
+ };
287
+ };
288
+ /**
289
+ * Write a message to the console at the `fatal` log level
290
+ *
291
+ * @param message - The message to write
292
+ * @param config - The Storm configuration
293
+ */
294
+ const writeFatal = (message, config) => getLogFn(LogLevel.FATAL, config)(message);
295
+ /**
296
+ * Write a message to the console at the `error` log level
297
+ *
298
+ * @param message - The message to write
299
+ * @param config - The Storm configuration
300
+ */
301
+ const writeError = (message, config) => getLogFn(LogLevel.ERROR, config)(message);
302
+ /**
303
+ * Write a message to the console at the `warning` log level
304
+ *
305
+ * @param message - The message to write
306
+ * @param config - The Storm configuration
307
+ */
308
+ const writeWarning = (message, config) => getLogFn(LogLevel.WARN, config)(message);
309
+ /**
310
+ * Write a message to the console at the `info` log level
311
+ *
312
+ * @param message - The message to write
313
+ * @param config - The Storm configuration
314
+ */
315
+ const writeInfo = (message, config) => getLogFn(LogLevel.INFO, config)(message);
316
+ /**
317
+ * Write a message to the console at the `success` log level
318
+ *
319
+ * @param message - The message to write
320
+ * @param config - The Storm configuration
321
+ */
322
+ const writeSuccess = (message, config) => getLogFn(LogLevel.SUCCESS, config)(message);
323
+ /**
324
+ * Write a message to the console at the `trace` log level
325
+ *
326
+ * @param message - The message to write
327
+ * @param config - The Storm configuration
328
+ */
329
+ const writeTrace = (message, config) => getLogFn(LogLevel.TRACE, config)(message);
330
+ const MAX_DEPTH = 10;
331
+ /**
332
+ * Format a log message for output to the console, handling different types of messages (e.g. strings, objects, arrays) and applying formatting options such as prefixing and skipping certain keys in objects.
333
+ *
334
+ * @param message - The message to format
335
+ * @param options - Formatting options
336
+ * @param depth - The current depth of recursion
337
+ * @returns The formatted log message
338
+ */
339
+ const formatLogMessage = (message, options = {}, depth = 0) => {
340
+ if (depth > MAX_DEPTH) return "<max depth>";
341
+ const prefix = options.prefix ?? "";
342
+ const skip = options.skip ?? [];
343
+ const sort = options.sort ?? true;
344
+ return typeof message === "undefined" || message === null ? "<empty>" : typeof message === "string" ? !message ? "<empty string>" : message : Array.isArray(message) ? `\n${message.sort(sort ? (a, b) => !a && !b ? 0 : !a ? 1 : !b ? -1 : String(a).localeCompare(String(b)) : void 0).map((item, index) => ` ${prefix}> #${index} = ${formatLogMessage(item, {
345
+ prefix: `${prefix}--`,
346
+ skip,
347
+ sort
348
+ }, depth + 1)}`).join("\n")}` : typeof message === "object" && message ? `\n${Object.keys(message).filter((key) => typeof key !== "string" || !skip.map((k) => k.toLowerCase().trim()).includes(key.toLowerCase().trim())).sort(sort ? (a, b) => !a && !b ? 0 : !a ? 1 : !b ? -1 : String(a).localeCompare(String(b)) : void 0).map((key) => ` ${prefix}> ${key} = ${_isFunction(message[key]) ? "<function>" : typeof message[key] === "object" && message[key] ? Object.keys(message[key]).filter((key) => typeof key !== "string" || !skip.map((k) => k.toLowerCase().trim()).includes(key.toLowerCase().trim())).length === 0 ? "{}" : formatLogMessage(message[key], {
349
+ prefix: `${prefix}--`,
350
+ skip,
351
+ sort
352
+ }, depth + 1) : message[key]}`).join("\n")}` : String(message);
353
+ };
354
+ const _isFunction = (value) => {
355
+ try {
356
+ return value instanceof Function || typeof value === "function" || !!(value?.constructor && value?.call && value?.apply);
357
+ } catch {
358
+ return false;
359
+ }
360
+ };
361
+ /**
362
+ * Get the brand icon for the console
363
+ *
364
+ * @param config - The Storm configuration
365
+ * @param _chalk - The chalk instance
366
+ * @returns The brand icon
367
+ */
368
+ const brandIcon = (config = {}, _chalk = getChalk()) => _chalk.hex(getColor("brand", config))("🗲");
369
+ //#endregion
370
+ //#region src/utilities/correct-paths.ts
371
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
372
+ function normalizeWindowsPath(input = "") {
373
+ if (!input) return input;
374
+ return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
375
+ }
376
+ const _UNC_REGEX = /^[/\\]{2}/;
377
+ const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
378
+ const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
379
+ const correctPaths = function(path) {
380
+ if (!path || path.length === 0) return ".";
381
+ path = normalizeWindowsPath(path);
382
+ const isUNCPath = path?.match(_UNC_REGEX);
383
+ const isPathAbsolute = isAbsolute(path);
384
+ const trailingSeparator = path[path.length - 1] === "/";
385
+ path = normalizeString(path, !isPathAbsolute);
386
+ if (path.length === 0) {
387
+ if (isPathAbsolute) return "/";
388
+ return trailingSeparator ? "./" : ".";
389
+ }
390
+ if (trailingSeparator) path += "/";
391
+ if (_DRIVE_LETTER_RE.test(path)) path += "/";
392
+ if (isUNCPath) {
393
+ if (!isPathAbsolute) return `//./${path}`;
394
+ return `//${path}`;
395
+ }
396
+ return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
397
+ };
398
+ const joinPaths = function(...segments) {
399
+ let path = "";
400
+ for (const seg of segments) {
401
+ if (!seg) continue;
402
+ if (path.length > 0) {
403
+ const pathTrailing = path[path.length - 1] === "/";
404
+ const segLeading = seg[0] === "/";
405
+ if (pathTrailing && segLeading) path += seg.slice(1);
406
+ else path += pathTrailing || segLeading ? seg : `/${seg}`;
407
+ } else path += seg;
408
+ }
409
+ return correctPaths(path);
410
+ };
411
+ /**
412
+ * Resolves a string path, resolving '.' and '.' segments and allowing paths above the root.
413
+ *
414
+ * @param path - The path to normalise.
415
+ * @param allowAboveRoot - Whether to allow the resulting path to be above the root directory.
416
+ * @returns the normalised path string.
417
+ */
418
+ function normalizeString(path, allowAboveRoot) {
419
+ let res = "";
420
+ let lastSegmentLength = 0;
421
+ let lastSlash = -1;
422
+ let dots = 0;
423
+ let char = null;
424
+ for (let index = 0; index <= path.length; ++index) {
425
+ if (index < path.length) char = path[index];
426
+ else if (char === "/") break;
427
+ else char = "/";
428
+ if (char === "/") {
429
+ if (lastSlash === index - 1 || dots === 1) {} else if (dots === 2) {
430
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
431
+ if (res.length > 2) {
432
+ const lastSlashIndex = res.lastIndexOf("/");
433
+ if (lastSlashIndex === -1) {
434
+ res = "";
435
+ lastSegmentLength = 0;
436
+ } else {
437
+ res = res.slice(0, lastSlashIndex);
438
+ lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
439
+ }
440
+ lastSlash = index;
441
+ dots = 0;
442
+ continue;
443
+ } else if (res.length > 0) {
444
+ res = "";
445
+ lastSegmentLength = 0;
446
+ lastSlash = index;
447
+ dots = 0;
448
+ continue;
449
+ }
450
+ }
451
+ if (allowAboveRoot) {
452
+ res += res.length > 0 ? "/.." : "..";
453
+ lastSegmentLength = 2;
454
+ }
455
+ } else {
456
+ if (res.length > 0) res += `/${path.slice(lastSlash + 1, index)}`;
457
+ else res = path.slice(lastSlash + 1, index);
458
+ lastSegmentLength = index - lastSlash - 1;
459
+ }
460
+ lastSlash = index;
461
+ dots = 0;
462
+ } else if (char === "." && dots !== -1) ++dots;
463
+ else dots = -1;
464
+ }
465
+ return res;
466
+ }
467
+ const isAbsolute = function(p) {
468
+ return _IS_ABSOLUTE_RE.test(p);
469
+ };
470
+ //#endregion
471
+ //#region src/utilities/find-up.ts
472
+ const MAX_PATH_SEARCH_DEPTH = 30;
473
+ let depth = 0;
474
+ /**
475
+ * Gets the nearest "node_modules" folder by walking up from start path.
476
+ */
477
+ function findFolderUp(startPath, endFileNames = [], endDirectoryNames = []) {
478
+ const _startPath = startPath ?? process.cwd();
479
+ if (endDirectoryNames.some((endDirName) => existsSync(join(_startPath, endDirName)))) return _startPath;
480
+ if (endFileNames.some((endFileName) => existsSync(join(_startPath, endFileName)))) return _startPath;
481
+ if (_startPath !== "/" && depth++ < MAX_PATH_SEARCH_DEPTH) return findFolderUp(join(_startPath, ".."), endFileNames, endDirectoryNames);
482
+ }
483
+ //#endregion
484
+ //#region src/utilities/find-workspace-root.ts
485
+ const rootFiles = [
486
+ "storm-workspace.json",
487
+ "storm-workspace.yaml",
488
+ "storm-workspace.yml",
489
+ "storm-workspace.js",
490
+ "storm-workspace.ts",
491
+ ".storm-workspace.json",
492
+ ".storm-workspace.yaml",
493
+ ".storm-workspace.yml",
494
+ ".storm-workspace.js",
495
+ ".storm-workspace.ts",
496
+ "lerna.json",
497
+ "nx.json",
498
+ "turbo.json",
499
+ "npm-workspace.json",
500
+ "yarn-workspace.json",
501
+ "pnpm-workspace.json",
502
+ "npm-workspace.yaml",
503
+ "yarn-workspace.yaml",
504
+ "pnpm-workspace.yaml",
505
+ "npm-workspace.yml",
506
+ "yarn-workspace.yml",
507
+ "pnpm-workspace.yml",
508
+ "npm-lock.json",
509
+ "yarn-lock.json",
510
+ "pnpm-lock.json",
511
+ "npm-lock.yaml",
512
+ "yarn-lock.yaml",
513
+ "pnpm-lock.yaml",
514
+ "npm-lock.yml",
515
+ "yarn-lock.yml",
516
+ "pnpm-lock.yml",
517
+ "bun.lockb",
518
+ "bun.lock",
519
+ "bunfig.toml"
520
+ ];
521
+ const rootDirectories = [
522
+ ".storm-workspace",
523
+ ".nx",
524
+ ".git",
525
+ ".github",
526
+ ".vscode",
527
+ ".verdaccio"
528
+ ];
529
+ /**
530
+ * Find the monorepo root directory, searching upwards from `path`.
531
+ *
532
+ * @param pathInsideMonorepo - The path inside the monorepo to start searching from
533
+ * @returns The monorepo root directory
534
+ */
535
+ function findWorkspaceRootSafe(pathInsideMonorepo) {
536
+ 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);
537
+ return correctPaths(findFolderUp(pathInsideMonorepo ?? process.cwd(), rootFiles, rootDirectories));
538
+ }
539
+ /**
540
+ * Find the monorepo root directory, searching upwards from `path`.
541
+ *
542
+ * @param pathInsideMonorepo - The path inside the monorepo to start searching from
543
+ * @returns The monorepo root directory
544
+ */
545
+ function findWorkspaceRoot(pathInsideMonorepo) {
546
+ const result = findWorkspaceRootSafe(pathInsideMonorepo);
547
+ if (!result) throw new Error(`Cannot find workspace root upwards from known path. Files search list includes: \n${rootFiles.join("\n")}\nPath: ${pathInsideMonorepo ? pathInsideMonorepo : process.cwd()}`);
548
+ return result;
549
+ }
550
+ //#endregion
551
+ //#region src/utilities/get-default-config.ts
552
+ /**
553
+ * Get the default Storm config values used during various dev-ops processes
554
+ *
555
+ * @returns The default Storm config values
556
+ */
557
+ async function getPackageJsonConfig(root) {
558
+ let license = STORM_DEFAULT_LICENSE;
559
+ let homepage = void 0;
560
+ let support = void 0;
561
+ let name = void 0;
562
+ let namespace = void 0;
563
+ let repository = void 0;
564
+ const workspaceRoot = findWorkspaceRoot(root);
565
+ if (existsSync(join(workspaceRoot, "package.json"))) {
566
+ const file = await readFile(joinPaths(workspaceRoot, "package.json"), "utf8");
567
+ if (file) {
568
+ const packageJson = JSON.parse(file);
569
+ if (packageJson.name) name = packageJson.name;
570
+ if (packageJson.namespace) namespace = packageJson.namespace;
571
+ if (packageJson.repository) {
572
+ if (typeof packageJson.repository === "string") repository = packageJson.repository;
573
+ else if (packageJson.repository.url) repository = packageJson.repository.url;
574
+ }
575
+ if (packageJson.license) license = packageJson.license;
576
+ if (packageJson.homepage) homepage = packageJson.homepage;
577
+ if (packageJson.bugs) {
578
+ if (typeof packageJson.bugs === "string") support = packageJson.bugs;
579
+ else if (packageJson.bugs.url) support = packageJson.bugs.url;
580
+ }
581
+ }
582
+ }
583
+ return {
584
+ workspaceRoot,
585
+ name,
586
+ namespace,
587
+ repository,
588
+ license,
589
+ homepage,
590
+ support
591
+ };
592
+ }
593
+ /**
594
+ * Apply default config values to the given config object
595
+ *
596
+ * @param config - The config object to apply defaults to
597
+ * @returns The config object with defaults applied
598
+ */
599
+ function applyDefaultConfig(config) {
600
+ if (!config.support && config.contact) config.support = config.contact;
601
+ if (!config.contact && config.support) config.contact = config.support;
602
+ if (config.homepage) {
603
+ if (!config.docs) config.docs = `${config.homepage}/docs`;
604
+ if (!config.license) config.license = `${config.homepage}/license`;
605
+ if (!config.support) config.support = `${config.homepage}/support`;
606
+ if (!config.contact) config.contact = `${config.homepage}/contact`;
607
+ if (!config.error?.codesFile || !config?.error?.url) {
608
+ config.error ??= { codesFile: STORM_DEFAULT_ERROR_CODES_FILE };
609
+ if (config.homepage) config.error.url ??= `${config.homepage}/errors`;
610
+ }
611
+ }
612
+ return config;
613
+ }
614
+ //#endregion
615
+ //#region src/utilities/process-handler.ts
616
+ const exitWithError = (config) => {
617
+ writeFatal("Exiting script with an error status...", config);
618
+ process.exit(1);
619
+ };
620
+ const exitWithSuccess = (config) => {
621
+ writeSuccess("Script completed successfully. Exiting...", config);
622
+ process.exit(0);
623
+ };
624
+ const handleProcess = (config) => {
625
+ writeTrace(`Using the following arguments to process the script: ${process.argv.join(", ")}`, config);
626
+ process.on("unhandledRejection", (error) => {
627
+ writeError(`An Unhandled Rejection occurred while running the program: ${error && typeof error === "object" && "message" in error && error?.message ? error.message : typeof error === "string" ? error : "Unknown error"} \nStacktrace: ${error && typeof error === "object" && "stack" in error && error?.stack ? error.stack : ""}`, config);
628
+ exitWithError(config);
629
+ });
630
+ process.on("uncaughtException", (error) => {
631
+ writeError(`An Uncaught Exception occurred while running the program: ${error && typeof error === "object" && "message" in error && error?.message ? error.message : typeof error === "string" ? error : "Unknown error"} \nStacktrace: ${error && typeof error === "object" && "stack" in error && error?.stack ? error.stack : ""}`, config);
632
+ exitWithError(config);
633
+ });
634
+ process.on("SIGTERM", (signal) => {
635
+ writeError(`The program terminated with signal code: ${signal}`, config);
636
+ exitWithError(config);
637
+ });
638
+ process.on("SIGINT", (signal) => {
639
+ writeError(`The program terminated with signal code: ${signal}`, config);
640
+ exitWithError(config);
641
+ });
642
+ process.on("SIGHUP", (signal) => {
643
+ writeError(`The program terminated with signal code: ${signal}`, config);
644
+ exitWithError(config);
645
+ });
646
+ };
647
+ //#endregion
648
+ //#region src/config-file/get-config-file.ts
649
+ /**
650
+ * Get the config file for the current Storm workspace
651
+ *
652
+ * @param fileName - The name of the config file to search for
653
+ * @param filePath - The path to search for the config file in
654
+ * @returns The config file for the current Storm workspace
655
+ */
656
+ const getConfigFileByName = async (fileName, filePath, options = {}) => {
657
+ const workspacePath = filePath || findWorkspaceRoot(filePath);
658
+ const configs = await Promise.all([loadConfig({
659
+ cwd: workspacePath,
660
+ packageJson: true,
661
+ name: fileName,
662
+ envName: fileName?.toUpperCase(),
663
+ jitiOptions: {
664
+ debug: false,
665
+ fsCache: process.env.STORM_SKIP_CACHE === "true" ? false : joinPaths(process.env.STORM_CACHE_DIR || "node_modules/.cache/storm", "jiti")
666
+ },
667
+ ...options
668
+ }), loadConfig({
669
+ cwd: workspacePath,
670
+ packageJson: true,
671
+ name: fileName,
672
+ envName: fileName?.toUpperCase(),
673
+ jitiOptions: {
674
+ debug: false,
675
+ fsCache: process.env.STORM_SKIP_CACHE === "true" ? false : joinPaths(process.env.STORM_CACHE_DIR || "node_modules/.cache/storm", "jiti")
676
+ },
677
+ configFile: fileName,
678
+ ...options
679
+ })]);
680
+ return defu(configs[0] ?? {}, configs[1] ?? {});
681
+ };
682
+ /**
683
+ * Get the config file for the current Storm workspace
684
+ *
685
+ * @returns The config file for the current Storm workspace
686
+ */
687
+ const getConfigFile = async (filePath, additionalFileNames = []) => {
688
+ const workspacePath = filePath ? filePath : findWorkspaceRoot(filePath);
689
+ const result = await getConfigFileByName("storm-workspace", workspacePath);
690
+ let config = result.config;
691
+ const configFile = result.configFile;
692
+ 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" });
693
+ if (additionalFileNames && additionalFileNames.length > 0) {
694
+ const results = await Promise.all(additionalFileNames.map((fileName) => getConfigFileByName(fileName, workspacePath)));
695
+ for (const result of results) if (result?.config && result?.configFile && Object.keys(result.config).length > 0) {
696
+ if (!config.skipConfigLogging && !result.config.skipConfigLogging) writeTrace(`Found alternative configuration file "${result.configFile.includes(`${workspacePath}/`) ? result.configFile.replace(`${workspacePath}/`, "") : result.configFile}" at "${workspacePath}"`, { logLevel: "all" });
697
+ config = defu(result.config ?? {}, config ?? {});
698
+ }
699
+ }
700
+ if (!config || Object.keys(config).length === 0) return;
701
+ config.configFile = configFile;
702
+ return config;
703
+ };
704
+ //#endregion
705
+ //#region src/env/get-env.ts
706
+ /**
707
+ * Get the config for an extension module of Storm workspace from environment variables
708
+ *
709
+ * @param extensionName - The name of the extension module
710
+ * @returns The config for the specified Storm extension module. If the module does not exist, `undefined` is returned.
711
+ */
712
+ const getExtensionEnv = (extensionName) => {
713
+ const prefix = `STORM_EXTENSION_${extensionName.toUpperCase()}_`;
714
+ return Object.keys(process.env).filter((key) => key.startsWith(prefix)).reduce((ret, key) => {
715
+ const name = key.replace(prefix, "").split("_").map((i) => i.length > 0 ? i.trim().charAt(0).toUpperCase() + i.trim().slice(1) : "").join("");
716
+ if (name) ret[name] = process.env[key];
717
+ return ret;
718
+ }, {});
719
+ };
720
+ /**
721
+ * Get the config for the current Storm workspace
722
+ *
723
+ * @returns The config for the current Storm workspace from environment variables
724
+ */
725
+ const getConfigEnv = () => {
726
+ const prefix = "STORM_";
727
+ let config = {
728
+ extends: process.env[`${prefix}EXTENDS`] || void 0,
729
+ name: process.env[`${prefix}NAME`] || void 0,
730
+ variant: process.env[`${prefix}VARIANT`] || void 0,
731
+ namespace: process.env[`${prefix}NAMESPACE`] || void 0,
732
+ owner: process.env[`${prefix}OWNER`] || void 0,
733
+ bot: {
734
+ name: process.env[`${prefix}BOT_NAME`] || void 0,
735
+ email: process.env[`${prefix}BOT_EMAIL`] || void 0
736
+ },
737
+ release: {
738
+ banner: {
739
+ url: process.env[`${prefix}RELEASE_BANNER_URL`] || void 0,
740
+ alt: process.env[`${prefix}RELEASE_BANNER_ALT`] || void 0
741
+ },
742
+ header: process.env[`${prefix}RELEASE_HEADER`] || void 0,
743
+ footer: process.env[`${prefix}RELEASE_FOOTER`] || void 0
744
+ },
745
+ error: {
746
+ codesFile: process.env[`${prefix}ERROR_CODES_FILE`] || void 0,
747
+ url: process.env[`${prefix}ERROR_URL`] || void 0
748
+ },
749
+ socials: {
750
+ twitter: process.env[`${prefix}SOCIAL_TWITTER`] || void 0,
751
+ discord: process.env[`${prefix}SOCIAL_DISCORD`] || void 0,
752
+ telegram: process.env[`${prefix}SOCIAL_TELEGRAM`] || void 0,
753
+ slack: process.env[`${prefix}SOCIAL_SLACK`] || void 0,
754
+ medium: process.env[`${prefix}SOCIAL_MEDIUM`] || void 0,
755
+ github: process.env[`${prefix}SOCIAL_GITHUB`] || void 0
756
+ },
757
+ 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`] ? {
758
+ name: process.env[`${prefix}ORG`] || process.env[`${prefix}ORGANIZATION`] || process.env[`${prefix}ORG_NAME`] || process.env[`${prefix}ORGANIZATION_NAME`],
759
+ description: process.env[`${prefix}ORG_DESCRIPTION`] || process.env[`${prefix}ORGANIZATION_DESCRIPTION`] || void 0,
760
+ url: process.env[`${prefix}ORG_URL`] || process.env[`${prefix}ORGANIZATION_URL`] || void 0,
761
+ logo: process.env[`${prefix}ORG_LOGO`] || process.env[`${prefix}ORGANIZATION_LOGO`] || void 0,
762
+ icon: process.env[`${prefix}ORG_ICON`] || process.env[`${prefix}ORGANIZATION_ICON`] || void 0
763
+ } : process.env[`${prefix}ORG`] || process.env[`${prefix}ORGANIZATION`] || process.env[`${prefix}ORG_NAME`] || process.env[`${prefix}ORGANIZATION_NAME`] : void 0,
764
+ packageManager: process.env[`${prefix}PACKAGE_MANAGER`] || void 0,
765
+ license: process.env[`${prefix}LICENSE`] || void 0,
766
+ homepage: process.env[`${prefix}HOMEPAGE`] || void 0,
767
+ docs: process.env[`${prefix}DOCS`] || void 0,
768
+ portal: process.env[`${prefix}PORTAL`] || void 0,
769
+ licensing: process.env[`${prefix}LICENSING`] || void 0,
770
+ contact: process.env[`${prefix}CONTACT`] || void 0,
771
+ support: process.env[`${prefix}SUPPORT`] || void 0,
772
+ timezone: process.env[`${prefix}TIMEZONE`] || process.env.TZ || void 0,
773
+ locale: process.env[`${prefix}LOCALE`] || process.env.LOCALE || void 0,
774
+ configFile: process.env[`${prefix}WORKSPACE_CONFIG_FILE`] ? correctPaths(process.env[`${prefix}WORKSPACE_CONFIG_FILE`]) : void 0,
775
+ workspaceRoot: process.env[`${prefix}WORKSPACE_ROOT`] ? correctPaths(process.env[`${prefix}WORKSPACE_ROOT`]) : void 0,
776
+ directories: {
777
+ 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,
778
+ 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,
779
+ 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,
780
+ 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,
781
+ 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,
782
+ 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
783
+ },
784
+ skipCache: process.env[`${prefix}SKIP_CACHE`] !== void 0 ? Boolean(process.env[`${prefix}SKIP_CACHE`]) : void 0,
785
+ mode: (process.env[`${prefix}MODE`] ?? process.env.NODE_ENV ?? process.env.ENVIRONMENT) || void 0,
786
+ repository: process.env[`${prefix}REPOSITORY`] || void 0,
787
+ branch: process.env[`${prefix}BRANCH`] || void 0,
788
+ preid: process.env[`${prefix}PRE_ID`] || void 0,
789
+ registry: {
790
+ github: process.env[`${prefix}REGISTRY_GITHUB`] || void 0,
791
+ npm: process.env[`${prefix}REGISTRY_NPM`] || void 0,
792
+ cargo: process.env[`${prefix}REGISTRY_CARGO`] || void 0,
793
+ cyclone: process.env[`${prefix}REGISTRY_CYCLONE`] || void 0,
794
+ container: process.env[`${prefix}REGISTRY_CONTAINER`] || void 0
795
+ },
796
+ 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,
797
+ skipConfigLogging: process.env[`${prefix}SKIP_CONFIG_LOGGING`] !== void 0 ? Boolean(process.env[`${prefix}SKIP_CONFIG_LOGGING`]) : void 0
798
+ };
799
+ 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}`)));
800
+ config.colors = themeNames.length > 0 ? themeNames.reduce((ret, themeName) => {
801
+ ret[themeName] = getThemeColorsEnv(prefix, themeName);
802
+ return ret;
803
+ }, {}) : getThemeColorsEnv(prefix);
804
+ if (config.docs === STORM_DEFAULT_DOCS) {
805
+ if (config.homepage === STORM_DEFAULT_HOMEPAGE) config.docs = `${STORM_DEFAULT_HOMEPAGE}/projects/${config.name}/docs`;
806
+ else config.docs = `${config.homepage}/docs`;
807
+ }
808
+ if (config.licensing === STORM_DEFAULT_LICENSING) {
809
+ if (config.homepage === STORM_DEFAULT_HOMEPAGE) config.licensing = `${STORM_DEFAULT_HOMEPAGE}/projects/${config.name}/licensing`;
810
+ else config.licensing = `${config.homepage}/docs`;
811
+ }
812
+ const serializedConfig = process.env[`${prefix}WORKSPACE_CONFIG`];
813
+ if (serializedConfig) {
814
+ const parsed = JSON.parse(serializedConfig);
815
+ config = {
816
+ ...config,
817
+ ...parsed,
818
+ colors: {
819
+ ...config.colors,
820
+ ...parsed.colors
821
+ },
822
+ extensions: {
823
+ ...config.extensions,
824
+ ...parsed.extensions
825
+ }
826
+ };
827
+ }
828
+ return config;
829
+ };
830
+ const getThemeColorsEnv = (prefix, theme) => {
831
+ const themeName = `COLOR_${theme && theme !== "base" ? `${theme}_` : ""}`.toUpperCase();
832
+ return process.env[`${prefix}${themeName}LIGHT_BRAND`] || process.env[`${prefix}${themeName}DARK_BRAND`] ? getMultiThemeColorsEnv(prefix + themeName) : getSingleThemeColorsEnv(prefix + themeName);
833
+ };
834
+ const getSingleThemeColorsEnv = (prefix) => {
835
+ const gradient = [];
836
+ if (process.env[`${prefix}GRADIENT_START`] && process.env[`${prefix}GRADIENT_END`]) gradient.push(process.env[`${prefix}GRADIENT_START`], process.env[`${prefix}GRADIENT_END`]);
837
+ else if (process.env[`${prefix}GRADIENT_0`] || process.env[`${prefix}GRADIENT_1`]) {
838
+ let index = process.env[`${prefix}GRADIENT_0`] ? 0 : 1;
839
+ while (process.env[`${prefix}GRADIENT_${index}`]) {
840
+ gradient.push(process.env[`${prefix}GRADIENT_${index}`]);
841
+ index++;
842
+ }
843
+ }
844
+ return {
845
+ dark: process.env[`${prefix}DARK`],
846
+ light: process.env[`${prefix}LIGHT`],
847
+ brand: process.env[`${prefix}BRAND`],
848
+ alternate: process.env[`${prefix}ALTERNATE`],
849
+ accent: process.env[`${prefix}ACCENT`],
850
+ link: process.env[`${prefix}LINK`],
851
+ discovery: process.env[`${prefix}DISCOVERY`],
852
+ success: process.env[`${prefix}SUCCESS`],
853
+ info: process.env[`${prefix}INFO`],
854
+ debug: process.env[`${prefix}DEBUG`],
855
+ warning: process.env[`${prefix}WARNING`],
856
+ danger: process.env[`${prefix}DANGER`],
857
+ fatal: process.env[`${prefix}FATAL`],
858
+ performance: process.env[`${prefix}PERFORMANCE`],
859
+ positive: process.env[`${prefix}POSITIVE`],
860
+ negative: process.env[`${prefix}NEGATIVE`],
861
+ gradient
862
+ };
863
+ };
864
+ const getMultiThemeColorsEnv = (prefix) => {
865
+ return {
866
+ light: getBaseThemeColorsEnv(`${prefix}_LIGHT_`),
867
+ dark: getBaseThemeColorsEnv(`${prefix}_DARK_`)
868
+ };
869
+ };
870
+ const getBaseThemeColorsEnv = (prefix) => {
871
+ const gradient = [];
872
+ if (process.env[`${prefix}GRADIENT_START`] && process.env[`${prefix}GRADIENT_END`]) gradient.push(process.env[`${prefix}GRADIENT_START`], process.env[`${prefix}GRADIENT_END`]);
873
+ else if (process.env[`${prefix}GRADIENT_0`] || process.env[`${prefix}GRADIENT_1`]) {
874
+ let index = process.env[`${prefix}GRADIENT_0`] ? 0 : 1;
875
+ while (process.env[`${prefix}GRADIENT_${index}`]) {
876
+ gradient.push(process.env[`${prefix}GRADIENT_${index}`]);
877
+ index++;
878
+ }
879
+ }
880
+ return {
881
+ foreground: process.env[`${prefix}FOREGROUND`],
882
+ background: process.env[`${prefix}BACKGROUND`],
883
+ brand: process.env[`${prefix}BRAND`],
884
+ alternate: process.env[`${prefix}ALTERNATE`],
885
+ accent: process.env[`${prefix}ACCENT`],
886
+ link: process.env[`${prefix}LINK`],
887
+ discovery: process.env[`${prefix}DISCOVERY`],
888
+ success: process.env[`${prefix}SUCCESS`],
889
+ info: process.env[`${prefix}INFO`],
890
+ debug: process.env[`${prefix}DEBUG`],
891
+ warning: process.env[`${prefix}WARNING`],
892
+ danger: process.env[`${prefix}DANGER`],
893
+ fatal: process.env[`${prefix}FATAL`],
894
+ performance: process.env[`${prefix}PERFORMANCE`],
895
+ positive: process.env[`${prefix}POSITIVE`],
896
+ negative: process.env[`${prefix}NEGATIVE`],
897
+ gradient
898
+ };
899
+ };
900
+ //#endregion
901
+ //#region src/env/set-env.ts
902
+ /**
903
+ * Get the config for an extension module of Storm workspace from environment variables
904
+ *
905
+ * @param extensionName - The name of the extension module
906
+ * @returns The config for the specified Storm extension module. If the module does not exist, `undefined` is returned.
907
+ */
908
+ const setExtensionEnv = (extensionName, extension) => {
909
+ for (const key of Object.keys(extension ?? {})) if (extension[key]) {
910
+ const result = key?.replace(/([A-Z])+/g, (input) => input ? input[0]?.toUpperCase() + input.slice(1) : "").split(/(?=[A-Z])|[.\-\s_]/).map((x) => x.toLowerCase()) ?? [];
911
+ let extensionKey;
912
+ if (result.length === 0) return;
913
+ if (result.length === 1) extensionKey = result[0]?.toUpperCase() ?? "";
914
+ else extensionKey = result.reduce((ret, part) => {
915
+ return `${ret}_${part.toLowerCase()}`;
916
+ });
917
+ process.env[`STORM_EXTENSION_${extensionName.toUpperCase()}_${extensionKey.toUpperCase()}`] = extension[key];
918
+ }
919
+ };
920
+ /**
921
+ * Get the config for the current Storm workspace
922
+ *
923
+ * @returns The config for the current Storm workspace from environment variables
924
+ */
925
+ const setConfigEnv = (config) => {
926
+ const prefix = "STORM_";
927
+ if (config.extends) process.env[`${prefix}EXTENDS`] = Array.isArray(config.extends) ? JSON.stringify(config.extends) : config.extends;
928
+ if (config.name) process.env[`${prefix}NAME`] = config.name;
929
+ if (config.variant) process.env[`${prefix}VARIANT`] = config.variant;
930
+ if (config.namespace) process.env[`${prefix}NAMESPACE`] = config.namespace;
931
+ if (config.owner) process.env[`${prefix}OWNER`] = config.owner;
932
+ if (config.bot) {
933
+ process.env[`${prefix}BOT_NAME`] = config.bot.name;
934
+ process.env[`${prefix}BOT_EMAIL`] = config.bot.email;
935
+ }
936
+ if (config.error) {
937
+ process.env[`${prefix}ERROR_CODES_FILE`] = config.error.codesFile;
938
+ process.env[`${prefix}ERROR_URL`] = config.error.url;
939
+ }
940
+ if (config.release) {
941
+ if (config.release.banner) {
942
+ if (typeof config.release.banner === "string") {
943
+ process.env[`${prefix}RELEASE_BANNER`] = config.release.banner;
944
+ process.env[`${prefix}RELEASE_BANNER_URL`] = config.release.banner;
945
+ } else {
946
+ process.env[`${prefix}RELEASE_BANNER`] = config.release.banner.url;
947
+ process.env[`${prefix}RELEASE_BANNER_URL`] = config.release.banner.url;
948
+ process.env[`${prefix}RELEASE_BANNER_ALT`] = config.release.banner.alt;
949
+ }
950
+ }
951
+ process.env[`${prefix}RELEASE_HEADER`] = config.release.header;
952
+ process.env[`${prefix}RELEASE_FOOTER`] = config.release.footer;
953
+ }
954
+ if (config.socials) {
955
+ if (config.socials.twitter) process.env[`${prefix}SOCIAL_TWITTER`] = config.socials.twitter;
956
+ if (config.socials.discord) process.env[`${prefix}SOCIAL_DISCORD`] = config.socials.discord;
957
+ if (config.socials.telegram) process.env[`${prefix}SOCIAL_TELEGRAM`] = config.socials.telegram;
958
+ if (config.socials.slack) process.env[`${prefix}SOCIAL_SLACK`] = config.socials.slack;
959
+ if (config.socials.medium) process.env[`${prefix}SOCIAL_MEDIUM`] = config.socials.medium;
960
+ if (config.socials.github) process.env[`${prefix}SOCIAL_GITHUB`] = config.socials.github;
961
+ }
962
+ if (config.organization) {
963
+ if (typeof config.organization === "string") {
964
+ process.env[`${prefix}ORG`] = config.organization;
965
+ process.env[`${prefix}ORG_NAME`] = config.organization;
966
+ process.env[`${prefix}ORGANIZATION`] = config.organization;
967
+ process.env[`${prefix}ORGANIZATION_NAME`] = config.organization;
968
+ } else {
969
+ process.env[`${prefix}ORG`] = config.organization.name;
970
+ process.env[`${prefix}ORG_NAME`] = config.organization.name;
971
+ process.env[`${prefix}ORGANIZATION`] = config.organization.name;
972
+ process.env[`${prefix}ORGANIZATION_NAME`] = config.organization.name;
973
+ if (config.organization.url) {
974
+ process.env[`${prefix}ORG_URL`] = config.organization.url;
975
+ process.env[`${prefix}ORGANIZATION_URL`] = config.organization.url;
976
+ }
977
+ if (config.organization.description) {
978
+ process.env[`${prefix}ORG_DESCRIPTION`] = config.organization.description;
979
+ process.env[`${prefix}ORGANIZATION_DESCRIPTION`] = config.organization.description;
980
+ }
981
+ if (config.organization.logo) {
982
+ process.env[`${prefix}ORG_LOGO`] = config.organization.logo;
983
+ process.env[`${prefix}ORGANIZATION_LOGO`] = config.organization.logo;
984
+ }
985
+ if (config.organization.icon) {
986
+ process.env[`${prefix}ORG_ICON`] = config.organization.icon;
987
+ process.env[`${prefix}ORGANIZATION_ICON`] = config.organization.icon;
988
+ }
989
+ }
990
+ }
991
+ if (config.packageManager) process.env[`${prefix}PACKAGE_MANAGER`] = config.packageManager;
992
+ if (config.license) process.env[`${prefix}LICENSE`] = config.license;
993
+ if (config.homepage) process.env[`${prefix}HOMEPAGE`] = config.homepage;
994
+ if (config.docs) process.env[`${prefix}DOCS`] = config.docs;
995
+ if (config.portal) process.env[`${prefix}PORTAL`] = config.portal;
996
+ if (config.licensing) process.env[`${prefix}LICENSING`] = config.licensing;
997
+ if (config.contact) process.env[`${prefix}CONTACT`] = config.contact;
998
+ if (config.support) process.env[`${prefix}SUPPORT`] = config.support;
999
+ if (config.timezone) {
1000
+ process.env[`${prefix}TIMEZONE`] = config.timezone;
1001
+ process.env.TZ = config.timezone;
1002
+ process.env.DEFAULT_TIMEZONE = config.timezone;
1003
+ process.env.TIMEZONE = config.timezone;
1004
+ }
1005
+ if (config.locale) {
1006
+ process.env[`${prefix}LOCALE`] = config.locale;
1007
+ process.env.DEFAULT_LOCALE = config.locale;
1008
+ process.env.LOCALE = config.locale;
1009
+ process.env.LANG = config.locale ? `${config.locale.replaceAll("-", "_")}.UTF-8` : "en_US.UTF-8";
1010
+ }
1011
+ if (config.configFile) process.env[`${prefix}WORKSPACE_CONFIG_FILE`] = correctPaths(config.configFile);
1012
+ if (config.workspaceRoot) {
1013
+ process.env[`${prefix}WORKSPACE_ROOT`] = correctPaths(config.workspaceRoot);
1014
+ process.env.NX_WORKSPACE_ROOT = correctPaths(config.workspaceRoot);
1015
+ process.env.NX_WORKSPACE_ROOT_PATH = correctPaths(config.workspaceRoot);
1016
+ }
1017
+ if (config.directories) {
1018
+ if (!config.skipCache && config.directories.cache) {
1019
+ process.env[`${prefix}CACHE_DIR`] = correctPaths(config.directories.cache);
1020
+ process.env[`${prefix}CACHE_DIRECTORY`] = process.env[`${prefix}CACHE_DIR`];
1021
+ }
1022
+ if (config.directories.data) {
1023
+ process.env[`${prefix}DATA_DIR`] = correctPaths(config.directories.data);
1024
+ process.env[`${prefix}DATA_DIRECTORY`] = process.env[`${prefix}DATA_DIR`];
1025
+ }
1026
+ if (config.directories.config) {
1027
+ process.env[`${prefix}CONFIG_DIR`] = correctPaths(config.directories.config);
1028
+ process.env[`${prefix}CONFIG_DIRECTORY`] = process.env[`${prefix}CONFIG_DIR`];
1029
+ }
1030
+ if (config.directories.temp) {
1031
+ process.env[`${prefix}TEMP_DIR`] = correctPaths(config.directories.temp);
1032
+ process.env[`${prefix}TEMP_DIRECTORY`] = process.env[`${prefix}TEMP_DIR`];
1033
+ }
1034
+ if (config.directories.log) {
1035
+ process.env[`${prefix}LOG_DIR`] = correctPaths(config.directories.log);
1036
+ process.env[`${prefix}LOG_DIRECTORY`] = process.env[`${prefix}LOG_DIR`];
1037
+ }
1038
+ if (config.directories.build) {
1039
+ process.env[`${prefix}BUILD_DIR`] = correctPaths(config.directories.build);
1040
+ process.env[`${prefix}BUILD_DIRECTORY`] = process.env[`${prefix}BUILD_DIR`];
1041
+ }
1042
+ }
1043
+ if (config.skipCache !== void 0) {
1044
+ process.env[`${prefix}SKIP_CACHE`] = String(config.skipCache);
1045
+ if (config.skipCache) {
1046
+ process.env.NX_SKIP_NX_CACHE ??= String(config.skipCache);
1047
+ process.env.NX_CACHE_PROJECT_GRAPH ??= String(config.skipCache);
1048
+ }
1049
+ }
1050
+ if (config.mode) {
1051
+ process.env[`${prefix}MODE`] = config.mode;
1052
+ process.env.NODE_ENV = config.mode;
1053
+ process.env.ENVIRONMENT = config.mode;
1054
+ }
1055
+ if (config.colors?.base?.light || config.colors?.base?.dark) for (const key of Object.keys(config.colors)) setThemeColorsEnv(`${prefix}COLOR_${key}_`, config.colors[key]);
1056
+ else setThemeColorsEnv(`${prefix}COLOR_`, config.colors);
1057
+ if (config.repository) process.env[`${prefix}REPOSITORY`] = config.repository;
1058
+ if (config.branch) process.env[`${prefix}BRANCH`] = config.branch;
1059
+ if (config.preid) process.env[`${prefix}PRE_ID`] = String(config.preid);
1060
+ if (config.registry) {
1061
+ if (config.registry.github) process.env[`${prefix}REGISTRY_GITHUB`] = String(config.registry.github);
1062
+ if (config.registry.npm) process.env[`${prefix}REGISTRY_NPM`] = String(config.registry.npm);
1063
+ if (config.registry.cargo) process.env[`${prefix}REGISTRY_CARGO`] = String(config.registry.cargo);
1064
+ if (config.registry.cyclone) process.env[`${prefix}REGISTRY_CYCLONE`] = String(config.registry.cyclone);
1065
+ if (config.registry.container) process.env[`${prefix}REGISTRY_CONTAINER`] = String(config.registry.container);
1066
+ }
1067
+ if (config.logLevel) {
1068
+ process.env[`${prefix}LOG_LEVEL`] = String(config.logLevel);
1069
+ process.env.LOG_LEVEL = String(config.logLevel);
1070
+ process.env.NX_VERBOSE_LOGGING = String(getLogLevel(config.logLevel) >= LogLevel.DEBUG ? true : false);
1071
+ process.env.RUST_BACKTRACE = getLogLevel(config.logLevel) >= LogLevel.DEBUG ? "full" : "none";
1072
+ }
1073
+ if (config.skipConfigLogging !== void 0) process.env[`${prefix}SKIP_CONFIG_LOGGING`] = String(config.skipConfigLogging);
1074
+ process.env[`${prefix}WORKSPACE_CONFIG`] = JSON.stringify(config);
1075
+ for (const key of Object.keys(config.extensions ?? {})) if (config.extensions[key] && Object.keys(config.extensions[key])) setExtensionEnv(key, config.extensions[key]);
1076
+ };
1077
+ const setThemeColorsEnv = (prefix, config) => {
1078
+ return config?.light?.brand || config?.dark?.brand ? setMultiThemeColorsEnv(prefix, config) : setSingleThemeColorsEnv(prefix, config);
1079
+ };
1080
+ const setSingleThemeColorsEnv = (prefix, config) => {
1081
+ if (config.dark) process.env[`${prefix}DARK`] = config.dark;
1082
+ if (config.light) process.env[`${prefix}LIGHT`] = config.light;
1083
+ if (config.brand) process.env[`${prefix}BRAND`] = config.brand;
1084
+ if (config.alternate) process.env[`${prefix}ALTERNATE`] = config.alternate;
1085
+ if (config.accent) process.env[`${prefix}ACCENT`] = config.accent;
1086
+ if (config.link) process.env[`${prefix}LINK`] = config.link;
1087
+ if (config.discovery) process.env[`${prefix}DISCOVERY`] = config.discovery;
1088
+ if (config.success) process.env[`${prefix}SUCCESS`] = config.success;
1089
+ if (config.info) process.env[`${prefix}INFO`] = config.info;
1090
+ if (config.debug) process.env[`${prefix}DEBUG`] = config.debug;
1091
+ if (config.warning) process.env[`${prefix}WARNING`] = config.warning;
1092
+ if (config.danger) process.env[`${prefix}DANGER`] = config.danger;
1093
+ if (config.fatal) process.env[`${prefix}FATAL`] = config.fatal;
1094
+ if (config.performance) process.env[`${prefix}PERFORMANCE`] = config.performance;
1095
+ if (config.positive) process.env[`${prefix}POSITIVE`] = config.positive;
1096
+ if (config.negative) process.env[`${prefix}NEGATIVE`] = config.negative;
1097
+ if (config.gradient) for (let i = 0; i < config.gradient.length; i++) process.env[`${prefix}GRADIENT_${i}`] = config.gradient[i];
1098
+ };
1099
+ const setMultiThemeColorsEnv = (prefix, config) => {
1100
+ return {
1101
+ light: setBaseThemeColorsEnv(`${prefix}LIGHT_`, config.light),
1102
+ dark: setBaseThemeColorsEnv(`${prefix}DARK_`, config.dark)
1103
+ };
1104
+ };
1105
+ const setBaseThemeColorsEnv = (prefix, config) => {
1106
+ if (config.foreground) process.env[`${prefix}FOREGROUND`] = config.foreground;
1107
+ if (config.background) process.env[`${prefix}BACKGROUND`] = config.background;
1108
+ if (config.brand) process.env[`${prefix}BRAND`] = config.brand;
1109
+ if (config.alternate) process.env[`${prefix}ALTERNATE`] = config.alternate;
1110
+ if (config.accent) process.env[`${prefix}ACCENT`] = config.accent;
1111
+ if (config.link) process.env[`${prefix}LINK`] = config.link;
1112
+ if (config.discovery) process.env[`${prefix}DISCOVERY`] = config.discovery;
1113
+ if (config.success) process.env[`${prefix}SUCCESS`] = config.success;
1114
+ if (config.info) process.env[`${prefix}INFO`] = config.info;
1115
+ if (config.debug) process.env[`${prefix}DEBUG`] = config.debug;
1116
+ if (config.warning) process.env[`${prefix}WARNING`] = config.warning;
1117
+ if (config.danger) process.env[`${prefix}DANGER`] = config.danger;
1118
+ if (config.fatal) process.env[`${prefix}FATAL`] = config.fatal;
1119
+ if (config.performance) process.env[`${prefix}PERFORMANCE`] = config.performance;
1120
+ if (config.positive) process.env[`${prefix}POSITIVE`] = config.positive;
1121
+ if (config.negative) process.env[`${prefix}NEGATIVE`] = config.negative;
1122
+ if (config.gradient) for (let i = 0; i < config.gradient.length; i++) process.env[`${prefix}GRADIENT_${i}`] = config.gradient[i];
1123
+ };
1124
+ //#endregion
1125
+ //#region src/create-storm-config.ts
1126
+ const _extension_cache = /* @__PURE__ */ new WeakMap();
1127
+ let _static_cache = void 0;
1128
+ /**
1129
+ * Get the config for the current Storm workspace
1130
+ *
1131
+ * @param extensionName - The name of the config extension
1132
+ * @param schema - The schema for the config extension
1133
+ * @param workspaceRoot - The root directory of the workspace
1134
+ * @param skipLogs - Skip writing logs to the console
1135
+ * @param useDefault - Whether to use the default config if no config file is found
1136
+ * @returns The config for the current Storm workspace
1137
+ */
1138
+ const createStormWorkspaceConfig = async (extensionName, schema, workspaceRoot, skipLogs = false, useDefault = true) => {
1139
+ let result;
1140
+ if (!_static_cache?.data || !_static_cache?.timestamp || _static_cache.timestamp < Date.now() - 8e3) {
1141
+ let _workspaceRoot = workspaceRoot;
1142
+ if (!_workspaceRoot) _workspaceRoot = findWorkspaceRoot();
1143
+ const configEnv = getConfigEnv();
1144
+ const configFile = await getConfigFile(_workspaceRoot);
1145
+ if (!configFile) {
1146
+ if (!skipLogs) writeWarning("No Storm Workspace configuration file found in the current repository. Please ensure this is the expected behavior - you can add a `storm-workspace.json` file to the root of your workspace if it is not.\n", { logLevel: "all" });
1147
+ if (useDefault === false) return;
1148
+ }
1149
+ const defaultConfig = await getPackageJsonConfig(_workspaceRoot);
1150
+ const configInput = defu(configEnv, configFile, defaultConfig);
1151
+ if (!configInput.variant) configInput.variant = existsSync(joinPaths(_workspaceRoot, "nx.json")) || existsSync(joinPaths(_workspaceRoot, ".nx")) || existsSync(joinPaths(_workspaceRoot, "lerna.json")) || existsSync(joinPaths(_workspaceRoot, "turbo.json")) ? "monorepo" : "minimal";
1152
+ try {
1153
+ result = applyDefaultConfig((await Promise.resolve(workspaceConfigSchema._zod.parse({
1154
+ value: configInput,
1155
+ issues: []
1156
+ }, { async: true }))).value);
1157
+ result.workspaceRoot ??= _workspaceRoot;
1158
+ } catch (error) {
1159
+ throw new Error(`Failed to parse Storm Workspace configuration${error?.message ? `: ${error.message}` : ""}
1160
+
1161
+ Please ensure your configuration file is valid JSON and matches the expected schema. The current workspace configuration input is: ${formatLogMessage(configInput)}`, { cause: error });
1162
+ }
1163
+ } else result = _static_cache.data;
1164
+ if (schema && extensionName) result.extensions = {
1165
+ ...result.extensions,
1166
+ [extensionName]: createConfigExtension(extensionName, schema)
1167
+ };
1168
+ _static_cache = {
1169
+ timestamp: Date.now(),
1170
+ data: result
1171
+ };
1172
+ return result;
1173
+ };
1174
+ /**
1175
+ * Get the config for a specific Storm config Extension
1176
+ *
1177
+ * @param extensionName - The name of the config extension
1178
+ * @param options - The options for the config extension
1179
+ * @returns The config for the specified Storm config extension. If the extension does not exist, `undefined` is returned.
1180
+ */
1181
+ const createConfigExtension = (extensionName, schema) => {
1182
+ const extension_cache_key = { extensionName };
1183
+ if (_extension_cache.has(extension_cache_key)) return _extension_cache.get(extension_cache_key);
1184
+ let extension = getExtensionEnv(extensionName);
1185
+ if (schema) extension = schema.parse(extension);
1186
+ _extension_cache.set(extension_cache_key, extension);
1187
+ return extension;
1188
+ };
1189
+ /**
1190
+ * Load the config file values for the current Storm workspace into environment variables
1191
+ *
1192
+ * @param workspaceRoot - The root directory of the workspace
1193
+ * @param skipLogs - Skip writing logs to the console
1194
+ * @returns The config for the current Storm workspace, throws an error if the config file could not be loaded
1195
+ */
1196
+ const loadStormWorkspaceConfig = async (workspaceRoot, skipLogs = false) => {
1197
+ const config = await createStormWorkspaceConfig(void 0, void 0, workspaceRoot, skipLogs, true);
1198
+ setConfigEnv(config);
1199
+ if (!skipLogs && !config.skipConfigLogging) writeTrace(`⚙️ Using Storm Workspace configuration: \n${formatLogMessage(config)}`, config);
1200
+ return config;
1201
+ };
1202
+ //#endregion
1203
+ //#region src/get-config.ts
1204
+ /**
1205
+ * Get the config for the current Storm workspace
1206
+ *
1207
+ * @param workspaceRoot - The root directory of the workspace
1208
+ * @param skipLogs - Skip writing logs to the console
1209
+ * @returns The config for the current Storm workspace
1210
+ */
1211
+ function getConfig(workspaceRoot, skipLogs = false) {
1212
+ return loadStormWorkspaceConfig(workspaceRoot, skipLogs);
1213
+ }
1214
+ //#endregion
1215
+ //#region bin/config.ts
1216
+ function createProgram() {
1217
+ writeInfo(`${brandIcon()} Running Storm Configuration Tools`, { logLevel: "all" });
1218
+ const root = findWorkspaceRootSafe(process.cwd());
1219
+ process.env.STORM_WORKSPACE_ROOT ??= root;
1220
+ process.env.NX_WORKSPACE_ROOT_PATH ??= root;
1221
+ if (root) process.chdir(root);
1222
+ const program = new Command("storm-config");
1223
+ program.version("1.0.0", "-v --version", "display CLI version");
1224
+ program.command("view", { isDefault: true }).description("View the current Storm configuration for the workspace.").option("-d --dir <path>", "A directory that exists inside the workspace root", process.cwd()).action(viewAction);
1225
+ return program;
1226
+ }
1227
+ async function viewAction({ dir }) {
1228
+ writeInfo(`🔍 Searching for Storm configuration for the workspace at "${dir}"...`, { logLevel: "all" });
1229
+ const config = await getConfig(findWorkspaceRootSafe(dir), true);
1230
+ if (config) writeSuccess(`The following Storm configuration values have been found for this repository:
1231
+
1232
+ ${formatLogMessage({
1233
+ ...config,
1234
+ colors: void 0
1235
+ })}
1236
+
1237
+ ${typeof config.colors.light === "string" ? formatSingleThemeColors(config.colors) : formatMultiThemeColors(config.colors)}
1238
+ `, {
1239
+ ...config,
1240
+ logLevel: "all"
1241
+ });
1242
+ else writeError("No Storm config file found in the current workspace. Please ensure this is the expected behavior - you can add a `storm.json` file to the root of your workspace if it is not.\n", { logLevel: "all" });
1243
+ }
1244
+ (async () => {
1245
+ try {
1246
+ handleProcess();
1247
+ await createProgram().parseAsync(process.argv);
1248
+ exitWithSuccess();
1249
+ } catch (error) {
1250
+ writeFatal(`A fatal error occurred while running the Storm Git tool:
1251
+ ${error?.message ? error.message : JSON.stringify(error)}${error?.stack ? `
1252
+ Stack Trace: ${error.stack}` : ""}`, { logLevel: "all" });
1253
+ exitWithError();
1254
+ process.exit(1);
1255
+ }
1256
+ })();
1257
+ const formatSingleThemeColors = (config) => {
1258
+ return `---- Theme Colors ----
1259
+ ${Object.entries(config).filter(([key, value]) => key !== "gradient" && typeof value === "string" && value.length > 0).map(([key, value]) => chalk.hex(String(value))(`${key}: ${chalk.bold(value)}`)).join(" \n")}
1260
+ `;
1261
+ };
1262
+ const formatMultiThemeColors = (config) => {
1263
+ return ` ---- Light Theme Colors ----
1264
+ ${Object.entries(config.light).filter(([key, value]) => key !== "gradient" && typeof value === "string" && value.length > 0).map(([key, value]) => chalk.hex(String(value))(`${key}: ${chalk.bold(value)}`)).join(" \n")}
1265
+
1266
+ ---- Dark Theme Colors ----
1267
+ ${Object.entries(config.dark).filter(([key, value]) => key !== "gradient" && typeof value === "string" && value.length > 0).map(([key, value]) => chalk.hex(String(value))(`${key}: ${chalk.bold(value)}`)).join(" \n")}
1268
+ `;
1269
+ };
1270
+ //#endregion
1271
+ export { createProgram, viewAction };