hanzio 1.0.6 → 1.0.8

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.
package/dist/src/index.js CHANGED
@@ -1042,9 +1042,117 @@ function viteSecretSetPlugin(secretSet) {
1042
1042
  // src/secrets/index.ts
1043
1043
  import { InfisicalSDK } from "@infisical/sdk";
1044
1044
  import { networkInterfaces } from "node:os";
1045
+
1046
+ // src/cool-console-log/index.ts
1047
+ var terminalColors = {
1048
+ reset: "\x1B[0m",
1049
+ bold: "\x1B[1m",
1050
+ dim: "\x1B[2m",
1051
+ italic: "\x1B[3m",
1052
+ underline: "\x1B[4m",
1053
+ black: "\x1B[30m",
1054
+ red: "\x1B[31m",
1055
+ green: "\x1B[32m",
1056
+ yellow: "\x1B[33m",
1057
+ blue: "\x1B[34m",
1058
+ magenta: "\x1B[35m",
1059
+ cyan: "\x1B[36m",
1060
+ white: "\x1B[37m",
1061
+ gray: "\x1B[90m",
1062
+ brightRed: "\x1B[91m",
1063
+ brightGreen: "\x1B[92m",
1064
+ brightYellow: "\x1B[93m",
1065
+ brightBlue: "\x1B[94m",
1066
+ brightMagenta: "\x1B[95m",
1067
+ brightCyan: "\x1B[96m",
1068
+ brightWhite: "\x1B[97m",
1069
+ bgBlack: "\x1B[40m",
1070
+ bgRed: "\x1B[41m",
1071
+ bgGreen: "\x1B[42m",
1072
+ bgYellow: "\x1B[43m",
1073
+ bgBlue: "\x1B[44m",
1074
+ bgMagenta: "\x1B[45m",
1075
+ bgCyan: "\x1B[46m",
1076
+ bgWhite: "\x1B[47m"
1077
+ };
1078
+ var levelColors = {
1079
+ debug: { badge: terminalColors.gray, text: terminalColors.dim },
1080
+ info: { badge: terminalColors.cyan, text: terminalColors.reset },
1081
+ warn: { badge: terminalColors.yellow, text: terminalColors.yellow },
1082
+ error: { badge: terminalColors.red, text: terminalColors.brightRed }
1083
+ };
1084
+ function formatAttributes(attrs) {
1085
+ if (!attrs || Object.keys(attrs).length === 0)
1086
+ return "";
1087
+ const formatted = Object.entries(attrs).map(([k, v]) => `${terminalColors.dim}${k}=${terminalColors.reset}${v}`).join(" ");
1088
+ return ` ${formatted}`;
1089
+ }
1090
+ function createCoolLogger(options = {}) {
1091
+ const { colorsInDevOnly = true, onLog } = options;
1092
+ const isDev = true;
1093
+ const useColors = colorsInDevOnly ? isDev : true;
1094
+ const createLogMethod = (level) => (message, attributes) => {
1095
+ onLog?.(level, message, attributes);
1096
+ if (level === "debug" && !isDev)
1097
+ return;
1098
+ if (useColors) {
1099
+ const { badge, text } = levelColors[level];
1100
+ const label = level.toUpperCase().padEnd(5);
1101
+ const attrStr = formatAttributes(attributes);
1102
+ console.log(`${badge}[${label}]${terminalColors.reset} ${text}${message}${terminalColors.reset}${attrStr}`);
1103
+ } else {
1104
+ console[level](`[${level.toUpperCase()}]`, message, attributes ?? "");
1105
+ }
1106
+ };
1107
+ return {
1108
+ debug: createLogMethod("debug"),
1109
+ info: createLogMethod("info"),
1110
+ warn: createLogMethod("warn"),
1111
+ error: createLogMethod("error")
1112
+ };
1113
+ }
1114
+ function logOperationSummary(operationName, durationMs, success, options = {}) {
1115
+ const { devOnly = true, error } = options;
1116
+ const isDev = true;
1117
+ if (devOnly && !isDev)
1118
+ return;
1119
+ const c = terminalColors;
1120
+ const statusIcon = success ? `${c.brightGreen}✓${c.reset}` : `${c.brightRed}✗${c.reset}`;
1121
+ const statusColor = success ? c.green : c.red;
1122
+ const durationStr = `${c.dim}${durationMs.toFixed(1)}ms${c.reset}`;
1123
+ const errorMessage = error ? ` ${c.dim}·${c.reset} ${c.red}${error instanceof Error ? error.message : String(error)}${c.reset}` : "";
1124
+ console.log(`${statusColor}${c.bold}${operationName}${c.reset} ${statusIcon} ${c.dim}·${c.reset} ${durationStr}${errorMessage}`);
1125
+ }
1126
+ function colorize(text, color, ...modifiers) {
1127
+ const isDev = true;
1128
+ if (!isDev)
1129
+ return text;
1130
+ const colorCodes = [
1131
+ terminalColors[color],
1132
+ ...modifiers.map((m) => terminalColors[m])
1133
+ ].join("");
1134
+ return `${colorCodes}${text}${terminalColors.reset}`;
1135
+ }
1136
+ function logBanner(text, color = "cyan", options = {}) {
1137
+ const { devOnly = true } = options;
1138
+ const isDev = true;
1139
+ if (devOnly && !isDev) {
1140
+ console.log(`=== ${text} ===`);
1141
+ return;
1142
+ }
1143
+ const c = terminalColors;
1144
+ const padding = 2;
1145
+ const line = "═".repeat(text.length + padding * 2);
1146
+ console.log(`${c[color]}╔${line}╗${c.reset}`);
1147
+ console.log(`${c[color]}║${" ".repeat(padding)}${c.bold}${text}${c.reset}${c[color]}${" ".repeat(padding)}║${c.reset}`);
1148
+ console.log(`${c[color]}╚${line}╝${c.reset}`);
1149
+ }
1150
+
1151
+ // src/secrets/index.ts
1045
1152
  var DEFAULT_INFISICAL_SITE_URL = "https://eu.infisical.com";
1046
1153
  var LOCAL_IP_VALUE = "LOCAL_IP";
1047
1154
  var VPN_INTERFACE_RE = /^(utun|tun|tailscale|wg|ipsec|ppp)/i;
1155
+ var logger = createCoolLogger();
1048
1156
  function getSecretEnvironment() {
1049
1157
  const env = process.env.SECRETS_ENV || "development";
1050
1158
  if (env === "production" || env === "prod")
@@ -1066,10 +1174,12 @@ async function defineSecretSet(keys, options) {
1066
1174
  const loadSecrets = async (force = false) => {
1067
1175
  const envSecrets = readEnvSecrets(keySet, force ? cachedSecrets : null);
1068
1176
  const keysMissingFromEnv = keySet.filter((key) => !envSecrets[key]);
1177
+ const environment = resolveEnvironment(options.environment);
1178
+ logSecretEnvironment(environment, keySet.length);
1069
1179
  const loadedSecrets = keysMissingFromEnv.length === 0 && !force ? {} : await loader({
1070
1180
  keys: keySet,
1071
1181
  projectId: options.projectId,
1072
- environment: resolveEnvironment(options.environment),
1182
+ environment,
1073
1183
  siteUrl: options.siteUrl ?? DEFAULT_INFISICAL_SITE_URL,
1074
1184
  clientIdEnvKey: options.clientIdEnvKey ?? "INFISICAL_CLIENT_ID",
1075
1185
  clientSecretEnvKey: options.clientSecretEnvKey ?? "INFISICAL_CLIENT_SECRET"
@@ -1140,6 +1250,12 @@ function resolveEnvironment(environment) {
1140
1250
  return environment();
1141
1251
  return environment ?? getSecretEnvironment();
1142
1252
  }
1253
+ function logSecretEnvironment(environment, secretCount) {
1254
+ logger.info(colorize("Loading secrets", "cyan", "bold"), {
1255
+ environment: colorize(environment, "brightCyan", "bold"),
1256
+ count: secretCount
1257
+ });
1258
+ }
1143
1259
  function readEnvSecrets(keys, previousSecrets = null) {
1144
1260
  return Object.fromEntries(keys.filter((key) => {
1145
1261
  const value = process.env[key];
@@ -1798,110 +1914,6 @@ function formatPeriodLabel(start, end, includeDay = false) {
1798
1914
  function getDomainFaviconUrl(domain, size = 128) {
1799
1915
  return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=${size}`;
1800
1916
  }
1801
- // src/cool-console-log/index.ts
1802
- var terminalColors = {
1803
- reset: "\x1B[0m",
1804
- bold: "\x1B[1m",
1805
- dim: "\x1B[2m",
1806
- italic: "\x1B[3m",
1807
- underline: "\x1B[4m",
1808
- black: "\x1B[30m",
1809
- red: "\x1B[31m",
1810
- green: "\x1B[32m",
1811
- yellow: "\x1B[33m",
1812
- blue: "\x1B[34m",
1813
- magenta: "\x1B[35m",
1814
- cyan: "\x1B[36m",
1815
- white: "\x1B[37m",
1816
- gray: "\x1B[90m",
1817
- brightRed: "\x1B[91m",
1818
- brightGreen: "\x1B[92m",
1819
- brightYellow: "\x1B[93m",
1820
- brightBlue: "\x1B[94m",
1821
- brightMagenta: "\x1B[95m",
1822
- brightCyan: "\x1B[96m",
1823
- brightWhite: "\x1B[97m",
1824
- bgBlack: "\x1B[40m",
1825
- bgRed: "\x1B[41m",
1826
- bgGreen: "\x1B[42m",
1827
- bgYellow: "\x1B[43m",
1828
- bgBlue: "\x1B[44m",
1829
- bgMagenta: "\x1B[45m",
1830
- bgCyan: "\x1B[46m",
1831
- bgWhite: "\x1B[47m"
1832
- };
1833
- var levelColors = {
1834
- debug: { badge: terminalColors.gray, text: terminalColors.dim },
1835
- info: { badge: terminalColors.cyan, text: terminalColors.reset },
1836
- warn: { badge: terminalColors.yellow, text: terminalColors.yellow },
1837
- error: { badge: terminalColors.red, text: terminalColors.brightRed }
1838
- };
1839
- function formatAttributes(attrs) {
1840
- if (!attrs || Object.keys(attrs).length === 0)
1841
- return "";
1842
- const formatted = Object.entries(attrs).map(([k, v]) => `${terminalColors.dim}${k}=${terminalColors.reset}${v}`).join(" ");
1843
- return ` ${formatted}`;
1844
- }
1845
- function createCoolLogger(options = {}) {
1846
- const { colorsInDevOnly = true, onLog } = options;
1847
- const isDev = true;
1848
- const useColors = colorsInDevOnly ? isDev : true;
1849
- const createLogMethod = (level) => (message, attributes) => {
1850
- onLog?.(level, message, attributes);
1851
- if (level === "debug" && !isDev)
1852
- return;
1853
- if (useColors) {
1854
- const { badge, text } = levelColors[level];
1855
- const label = level.toUpperCase().padEnd(5);
1856
- const attrStr = formatAttributes(attributes);
1857
- console.log(`${badge}[${label}]${terminalColors.reset} ${text}${message}${terminalColors.reset}${attrStr}`);
1858
- } else {
1859
- console[level](`[${level.toUpperCase()}]`, message, attributes ?? "");
1860
- }
1861
- };
1862
- return {
1863
- debug: createLogMethod("debug"),
1864
- info: createLogMethod("info"),
1865
- warn: createLogMethod("warn"),
1866
- error: createLogMethod("error")
1867
- };
1868
- }
1869
- function logOperationSummary(operationName, durationMs, success, options = {}) {
1870
- const { devOnly = true, error } = options;
1871
- const isDev = true;
1872
- if (devOnly && !isDev)
1873
- return;
1874
- const c = terminalColors;
1875
- const statusIcon = success ? `${c.brightGreen}✓${c.reset}` : `${c.brightRed}✗${c.reset}`;
1876
- const statusColor = success ? c.green : c.red;
1877
- const durationStr = `${c.dim}${durationMs.toFixed(1)}ms${c.reset}`;
1878
- const errorMessage = error ? ` ${c.dim}·${c.reset} ${c.red}${error instanceof Error ? error.message : String(error)}${c.reset}` : "";
1879
- console.log(`${statusColor}${c.bold}${operationName}${c.reset} ${statusIcon} ${c.dim}·${c.reset} ${durationStr}${errorMessage}`);
1880
- }
1881
- function colorize(text, color, ...modifiers) {
1882
- const isDev = true;
1883
- if (!isDev)
1884
- return text;
1885
- const colorCodes = [
1886
- terminalColors[color],
1887
- ...modifiers.map((m) => terminalColors[m])
1888
- ].join("");
1889
- return `${colorCodes}${text}${terminalColors.reset}`;
1890
- }
1891
- function logBanner(text, color = "cyan", options = {}) {
1892
- const { devOnly = true } = options;
1893
- const isDev = true;
1894
- if (devOnly && !isDev) {
1895
- console.log(`=== ${text} ===`);
1896
- return;
1897
- }
1898
- const c = terminalColors;
1899
- const padding = 2;
1900
- const line = "═".repeat(text.length + padding * 2);
1901
- console.log(`${c[color]}╔${line}╗${c.reset}`);
1902
- console.log(`${c[color]}║${" ".repeat(padding)}${c.bold}${text}${c.reset}${c[color]}${" ".repeat(padding)}║${c.reset}`);
1903
- console.log(`${c[color]}╚${line}╝${c.reset}`);
1904
- }
1905
1917
  export {
1906
1918
  zodToTypeString,
1907
1919
  zodToExample,
@@ -17,9 +17,117 @@ function viteSecretSetPlugin(secretSet) {
17
17
  // src/secrets/index.ts
18
18
  import { InfisicalSDK } from "@infisical/sdk";
19
19
  import { networkInterfaces } from "node:os";
20
+
21
+ // src/cool-console-log/index.ts
22
+ var terminalColors = {
23
+ reset: "\x1B[0m",
24
+ bold: "\x1B[1m",
25
+ dim: "\x1B[2m",
26
+ italic: "\x1B[3m",
27
+ underline: "\x1B[4m",
28
+ black: "\x1B[30m",
29
+ red: "\x1B[31m",
30
+ green: "\x1B[32m",
31
+ yellow: "\x1B[33m",
32
+ blue: "\x1B[34m",
33
+ magenta: "\x1B[35m",
34
+ cyan: "\x1B[36m",
35
+ white: "\x1B[37m",
36
+ gray: "\x1B[90m",
37
+ brightRed: "\x1B[91m",
38
+ brightGreen: "\x1B[92m",
39
+ brightYellow: "\x1B[93m",
40
+ brightBlue: "\x1B[94m",
41
+ brightMagenta: "\x1B[95m",
42
+ brightCyan: "\x1B[96m",
43
+ brightWhite: "\x1B[97m",
44
+ bgBlack: "\x1B[40m",
45
+ bgRed: "\x1B[41m",
46
+ bgGreen: "\x1B[42m",
47
+ bgYellow: "\x1B[43m",
48
+ bgBlue: "\x1B[44m",
49
+ bgMagenta: "\x1B[45m",
50
+ bgCyan: "\x1B[46m",
51
+ bgWhite: "\x1B[47m"
52
+ };
53
+ var levelColors = {
54
+ debug: { badge: terminalColors.gray, text: terminalColors.dim },
55
+ info: { badge: terminalColors.cyan, text: terminalColors.reset },
56
+ warn: { badge: terminalColors.yellow, text: terminalColors.yellow },
57
+ error: { badge: terminalColors.red, text: terminalColors.brightRed }
58
+ };
59
+ function formatAttributes(attrs) {
60
+ if (!attrs || Object.keys(attrs).length === 0)
61
+ return "";
62
+ const formatted = Object.entries(attrs).map(([k, v]) => `${terminalColors.dim}${k}=${terminalColors.reset}${v}`).join(" ");
63
+ return ` ${formatted}`;
64
+ }
65
+ function createCoolLogger(options = {}) {
66
+ const { colorsInDevOnly = true, onLog } = options;
67
+ const isDev = true;
68
+ const useColors = colorsInDevOnly ? isDev : true;
69
+ const createLogMethod = (level) => (message, attributes) => {
70
+ onLog?.(level, message, attributes);
71
+ if (level === "debug" && !isDev)
72
+ return;
73
+ if (useColors) {
74
+ const { badge, text } = levelColors[level];
75
+ const label = level.toUpperCase().padEnd(5);
76
+ const attrStr = formatAttributes(attributes);
77
+ console.log(`${badge}[${label}]${terminalColors.reset} ${text}${message}${terminalColors.reset}${attrStr}`);
78
+ } else {
79
+ console[level](`[${level.toUpperCase()}]`, message, attributes ?? "");
80
+ }
81
+ };
82
+ return {
83
+ debug: createLogMethod("debug"),
84
+ info: createLogMethod("info"),
85
+ warn: createLogMethod("warn"),
86
+ error: createLogMethod("error")
87
+ };
88
+ }
89
+ function logOperationSummary(operationName, durationMs, success, options = {}) {
90
+ const { devOnly = true, error } = options;
91
+ const isDev = true;
92
+ if (devOnly && !isDev)
93
+ return;
94
+ const c = terminalColors;
95
+ const statusIcon = success ? `${c.brightGreen}✓${c.reset}` : `${c.brightRed}✗${c.reset}`;
96
+ const statusColor = success ? c.green : c.red;
97
+ const durationStr = `${c.dim}${durationMs.toFixed(1)}ms${c.reset}`;
98
+ const errorMessage = error ? ` ${c.dim}·${c.reset} ${c.red}${error instanceof Error ? error.message : String(error)}${c.reset}` : "";
99
+ console.log(`${statusColor}${c.bold}${operationName}${c.reset} ${statusIcon} ${c.dim}·${c.reset} ${durationStr}${errorMessage}`);
100
+ }
101
+ function colorize(text, color, ...modifiers) {
102
+ const isDev = true;
103
+ if (!isDev)
104
+ return text;
105
+ const colorCodes = [
106
+ terminalColors[color],
107
+ ...modifiers.map((m) => terminalColors[m])
108
+ ].join("");
109
+ return `${colorCodes}${text}${terminalColors.reset}`;
110
+ }
111
+ function logBanner(text, color = "cyan", options = {}) {
112
+ const { devOnly = true } = options;
113
+ const isDev = true;
114
+ if (devOnly && !isDev) {
115
+ console.log(`=== ${text} ===`);
116
+ return;
117
+ }
118
+ const c = terminalColors;
119
+ const padding = 2;
120
+ const line = "═".repeat(text.length + padding * 2);
121
+ console.log(`${c[color]}╔${line}╗${c.reset}`);
122
+ console.log(`${c[color]}║${" ".repeat(padding)}${c.bold}${text}${c.reset}${c[color]}${" ".repeat(padding)}║${c.reset}`);
123
+ console.log(`${c[color]}╚${line}╝${c.reset}`);
124
+ }
125
+
126
+ // src/secrets/index.ts
20
127
  var DEFAULT_INFISICAL_SITE_URL = "https://eu.infisical.com";
21
128
  var LOCAL_IP_VALUE = "LOCAL_IP";
22
129
  var VPN_INTERFACE_RE = /^(utun|tun|tailscale|wg|ipsec|ppp)/i;
130
+ var logger = createCoolLogger();
23
131
  function getSecretEnvironment() {
24
132
  const env = process.env.SECRETS_ENV || "development";
25
133
  if (env === "production" || env === "prod")
@@ -41,10 +149,12 @@ async function defineSecretSet(keys, options) {
41
149
  const loadSecrets = async (force = false) => {
42
150
  const envSecrets = readEnvSecrets(keySet, force ? cachedSecrets : null);
43
151
  const keysMissingFromEnv = keySet.filter((key) => !envSecrets[key]);
152
+ const environment = resolveEnvironment(options.environment);
153
+ logSecretEnvironment(environment, keySet.length);
44
154
  const loadedSecrets = keysMissingFromEnv.length === 0 && !force ? {} : await loader({
45
155
  keys: keySet,
46
156
  projectId: options.projectId,
47
- environment: resolveEnvironment(options.environment),
157
+ environment,
48
158
  siteUrl: options.siteUrl ?? DEFAULT_INFISICAL_SITE_URL,
49
159
  clientIdEnvKey: options.clientIdEnvKey ?? "INFISICAL_CLIENT_ID",
50
160
  clientSecretEnvKey: options.clientSecretEnvKey ?? "INFISICAL_CLIENT_SECRET"
@@ -115,6 +225,12 @@ function resolveEnvironment(environment) {
115
225
  return environment();
116
226
  return environment ?? getSecretEnvironment();
117
227
  }
228
+ function logSecretEnvironment(environment, secretCount) {
229
+ logger.info(colorize("Loading secrets", "cyan", "bold"), {
230
+ environment: colorize(environment, "brightCyan", "bold"),
231
+ count: secretCount
232
+ });
233
+ }
118
234
  function readEnvSecrets(keys, previousSecrets = null) {
119
235
  return Object.fromEntries(keys.filter((key) => {
120
236
  const value = process.env[key];
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "hanzio",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "A set of utility functions for TypeScript",
5
5
  "type": "module",
6
- "module": "./dist/index.js",
7
- "main": "./dist/index.js",
6
+ "module": "./dist/src/index.js",
7
+ "main": "./dist/src/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "license": "MIT",
10
10
  "repository": {
@@ -32,8 +32,20 @@
32
32
  ".": {
33
33
  "types": "./dist/index.d.ts",
34
34
  "bun": "./src/index.ts",
35
- "import": "./dist/index.js",
36
- "default": "./dist/index.js"
35
+ "import": "./dist/src/index.js",
36
+ "default": "./dist/src/index.js"
37
+ },
38
+ "./secrets": {
39
+ "types": "./dist/secrets/index.d.ts",
40
+ "bun": "./src/secrets/index.ts",
41
+ "import": "./dist/src/secrets/index.js",
42
+ "default": "./dist/src/secrets/index.js"
43
+ },
44
+ "./secrets/vite": {
45
+ "types": "./dist/secrets/vite.d.ts",
46
+ "bun": "./src/secrets/vite.ts",
47
+ "import": "./dist/src/secrets/vite.js",
48
+ "default": "./dist/src/secrets/vite.js"
37
49
  }
38
50
  },
39
51
  "scripts": {
@@ -1,9 +1,11 @@
1
1
  import { InfisicalSDK } from '@infisical/sdk'
2
2
  import { networkInterfaces } from 'node:os'
3
+ import { colorize, createCoolLogger } from '../cool-console-log'
3
4
 
4
5
  const DEFAULT_INFISICAL_SITE_URL = 'https://eu.infisical.com'
5
6
  const LOCAL_IP_VALUE = 'LOCAL_IP'
6
7
  const VPN_INTERFACE_RE = /^(utun|tun|tailscale|wg|ipsec|ppp)/i
8
+ const logger = createCoolLogger()
7
9
 
8
10
  export type SecretEnvironment = 'dev' | 'staging' | 'prod'
9
11
 
@@ -71,13 +73,17 @@ export async function defineSecretSet<
71
73
  const loadSecrets = async (force = false) => {
72
74
  const envSecrets = readEnvSecrets(keySet, force ? cachedSecrets : null)
73
75
  const keysMissingFromEnv = keySet.filter((key) => !envSecrets[key])
76
+ const environment = resolveEnvironment(options.environment)
77
+
78
+ logSecretEnvironment(environment, keySet.length)
79
+
74
80
  const loadedSecrets: Partial<Record<SecretKey, string>> =
75
81
  keysMissingFromEnv.length === 0 && !force
76
82
  ? {}
77
83
  : await loader({
78
84
  keys: keySet,
79
85
  projectId: options.projectId,
80
- environment: resolveEnvironment(options.environment),
86
+ environment,
81
87
  siteUrl: options.siteUrl ?? DEFAULT_INFISICAL_SITE_URL,
82
88
  clientIdEnvKey: options.clientIdEnvKey ?? 'INFISICAL_CLIENT_ID',
83
89
  clientSecretEnvKey:
@@ -173,6 +179,16 @@ function resolveEnvironment(
173
179
  return environment ?? getSecretEnvironment()
174
180
  }
175
181
 
182
+ function logSecretEnvironment(
183
+ environment: SecretEnvironment,
184
+ secretCount: number
185
+ ): void {
186
+ logger.info(colorize('Loading secrets', 'cyan', 'bold'), {
187
+ environment: colorize(environment, 'brightCyan', 'bold'),
188
+ count: secretCount
189
+ })
190
+ }
191
+
176
192
  function readEnvSecrets<SecretKey extends string>(
177
193
  keys: readonly SecretKey[],
178
194
  previousSecrets: Record<SecretKey, string> | null = null