hanzio 1.1.0 → 2.0.0

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 (172) hide show
  1. package/README.md +832 -219
  2. package/dist/api-wrapper/builders.d.ts +15 -3
  3. package/dist/api-wrapper/create-client.d.ts +1 -1
  4. package/dist/api-wrapper/describe.d.ts +16 -0
  5. package/dist/api-wrapper/endpoint.d.ts +18 -0
  6. package/dist/api-wrapper/errors.d.ts +40 -2
  7. package/dist/api-wrapper/headers.d.ts +2 -1
  8. package/dist/api-wrapper/index.d.ts +5 -0
  9. package/dist/api-wrapper/otel.d.ts +44 -0
  10. package/dist/api-wrapper/paginate.d.ts +12 -0
  11. package/dist/api-wrapper/redaction.d.ts +2 -0
  12. package/dist/api-wrapper/shared.d.ts +16 -2
  13. package/dist/api-wrapper/testing.d.ts +23 -0
  14. package/dist/api-wrapper/transport.d.ts +12 -10
  15. package/dist/api-wrapper/types.d.ts +104 -18
  16. package/dist/array/index.d.ts +50 -4
  17. package/dist/cache/createCache.d.ts +31 -0
  18. package/dist/cache/index.d.ts +45 -2
  19. package/dist/color/contrast.d.ts +40 -0
  20. package/dist/color/index.d.ts +2 -0
  21. package/dist/{math → color}/metricsSeriesColors.d.ts +14 -7
  22. package/dist/cool-console-log/index.d.ts +34 -5
  23. package/dist/crypto/encoding.d.ts +18 -0
  24. package/dist/crypto/hash.d.ts +33 -0
  25. package/dist/crypto/index.d.ts +4 -0
  26. package/dist/crypto/sealer.d.ts +25 -0
  27. package/dist/crypto/webhook.d.ts +20 -0
  28. package/dist/date/index.d.ts +46 -2
  29. package/dist/emitter/index.d.ts +21 -0
  30. package/dist/error/index.d.ts +12 -0
  31. package/dist/format/index.d.ts +102 -0
  32. package/dist/function/index.d.ts +60 -0
  33. package/dist/guard/index.d.ts +20 -0
  34. package/dist/i18n/index.d.ts +37 -0
  35. package/dist/index-0zvtcbzy.js +224 -0
  36. package/dist/index-181e6vfw.js +29 -0
  37. package/dist/index-8r2vdzjg.js +87 -0
  38. package/dist/index-hy7kbb99.js +157 -0
  39. package/dist/{src/secrets/loaders.js → index-j1ybktbr.js} +608 -405
  40. package/dist/index-k9yx6bne.js +89 -0
  41. package/dist/index-kj1phgrx.js +169 -0
  42. package/dist/index-mnkcfyx8.js +78 -0
  43. package/dist/{p-queue/index.js → index-pwt0dz63.js} +7 -11
  44. package/dist/index-rp5pqghz.js +157 -0
  45. package/dist/index-srt06xd2.js +15 -0
  46. package/dist/index-wjyb9bsd.js +263 -0
  47. package/dist/index.d.ts +7 -7
  48. package/dist/jwt/index.d.ts +50 -2
  49. package/dist/math/index.d.ts +2 -2
  50. package/dist/math/linearRegressionTrend.d.ts +14 -1
  51. package/dist/math/scale.d.ts +8 -0
  52. package/dist/object/index.d.ts +19 -0
  53. package/dist/p-queue/index.d.ts +1 -1
  54. package/dist/promise/index.d.ts +97 -2
  55. package/dist/secrets/core.d.ts +47 -0
  56. package/dist/secrets/deadline.d.ts +6 -0
  57. package/dist/secrets/environment.d.ts +9 -0
  58. package/dist/secrets/errors.d.ts +11 -0
  59. package/dist/secrets/index.d.ts +13 -25
  60. package/dist/secrets/infisical-cli.d.ts +6 -0
  61. package/dist/secrets/infisical-config.d.ts +17 -0
  62. package/dist/secrets/infisical-session.d.ts +4 -0
  63. package/dist/secrets/infisical.d.ts +8 -13
  64. package/dist/secrets/loaders.d.ts +5 -12
  65. package/dist/secrets/vite.d.ts +7 -3
  66. package/dist/secrets/worker-loader.d.ts +9 -0
  67. package/dist/secrets/worker.d.ts +3 -0
  68. package/dist/sitemap/index.d.ts +48 -6
  69. package/dist/src/api-wrapper/index.js +60 -1100
  70. package/dist/src/api-wrapper/testing.js +20 -0
  71. package/dist/{cool-console-log → src/cool-console-log}/index.js +80 -33
  72. package/dist/src/crypto/index.js +195 -0
  73. package/dist/src/format/index.js +211 -0
  74. package/dist/src/i18n/index.js +36 -0
  75. package/dist/src/index.js +863 -2809
  76. package/dist/src/jwt/index.js +138 -92
  77. package/dist/src/p-queue/index.js +9 -437
  78. package/dist/src/secrets/index.js +261 -1377
  79. package/dist/src/secrets/vite.js +6 -17
  80. package/dist/src/secrets/worker.js +12 -0
  81. package/dist/src/sitemap/index.js +183 -511
  82. package/dist/src/storage/index.js +119 -0
  83. package/dist/src/zod/index.js +347 -174
  84. package/dist/state/index.d.ts +21 -0
  85. package/dist/storage/index.d.ts +58 -0
  86. package/dist/string/index.d.ts +75 -2
  87. package/dist/typedswitch/index.d.ts +37 -26
  88. package/dist/types/index.d.ts +11 -0
  89. package/dist/url/index.d.ts +50 -1
  90. package/dist/zod/index.d.ts +32 -3
  91. package/dist/zod/introspect.d.ts +19 -0
  92. package/dist/zod/jsonToZodSchemaMapper.d.ts +3 -1
  93. package/dist/zod/zodMinMaxFilter.d.ts +22 -3
  94. package/dist/zod/zodToTypeString.d.ts +8 -3
  95. package/package.json +87 -7
  96. package/src/api-wrapper/actions-impl.ts +11 -72
  97. package/src/api-wrapper/builders.ts +84 -52
  98. package/src/api-wrapper/create-client.ts +246 -96
  99. package/src/api-wrapper/describe.ts +157 -0
  100. package/src/api-wrapper/endpoint.ts +26 -0
  101. package/src/api-wrapper/error-reporting.ts +7 -1
  102. package/src/api-wrapper/errors.ts +117 -2
  103. package/src/api-wrapper/headers.ts +19 -1
  104. package/src/api-wrapper/index.ts +5 -0
  105. package/src/api-wrapper/otel.ts +139 -0
  106. package/src/api-wrapper/paginate.ts +28 -0
  107. package/src/api-wrapper/redaction.ts +43 -0
  108. package/src/api-wrapper/shared.ts +21 -2
  109. package/src/api-wrapper/testing.ts +48 -0
  110. package/src/api-wrapper/transport.ts +68 -74
  111. package/src/api-wrapper/types.ts +186 -18
  112. package/src/array/index.ts +195 -42
  113. package/src/cache/createCache.ts +157 -0
  114. package/src/cache/index.ts +235 -83
  115. package/src/color/contrast.ts +163 -0
  116. package/src/color/index.ts +22 -0
  117. package/src/{math → color}/metricsSeriesColors.ts +47 -49
  118. package/src/cool-console-log/index.ts +128 -41
  119. package/src/crypto/encoding.ts +83 -0
  120. package/src/crypto/hash.ts +170 -0
  121. package/src/crypto/index.ts +26 -0
  122. package/src/crypto/sealer.ts +168 -0
  123. package/src/crypto/webhook.ts +86 -0
  124. package/src/date/index.ts +109 -34
  125. package/src/emitter/index.ts +82 -0
  126. package/src/error/index.ts +63 -0
  127. package/src/format/index.ts +389 -0
  128. package/src/function/index.ts +201 -0
  129. package/src/guard/index.ts +80 -0
  130. package/src/i18n/index.ts +125 -0
  131. package/src/index.ts +11 -7
  132. package/src/jwt/index.ts +199 -125
  133. package/src/math/index.ts +5 -10
  134. package/src/math/linearRegressionTrend.ts +33 -8
  135. package/src/math/scale.ts +17 -0
  136. package/src/object/index.ts +99 -0
  137. package/src/p-queue/index.ts +2 -0
  138. package/src/promise/index.ts +304 -9
  139. package/src/secrets/core.ts +348 -0
  140. package/src/secrets/deadline.ts +69 -0
  141. package/src/secrets/environment.ts +69 -0
  142. package/src/secrets/errors.ts +29 -0
  143. package/src/secrets/index.ts +79 -210
  144. package/src/secrets/infisical-cli.ts +99 -0
  145. package/src/secrets/infisical-config.ts +70 -0
  146. package/src/secrets/infisical-session.ts +42 -0
  147. package/src/secrets/infisical.ts +214 -66
  148. package/src/secrets/loaders.ts +24 -48
  149. package/src/secrets/vite.ts +44 -15
  150. package/src/secrets/worker-loader.ts +56 -0
  151. package/src/secrets/worker.ts +4 -0
  152. package/src/sitemap/index.ts +293 -130
  153. package/src/state/index.ts +133 -81
  154. package/src/storage/index.ts +187 -0
  155. package/src/string/index.ts +261 -23
  156. package/src/typedswitch/index.ts +134 -103
  157. package/src/types/index.ts +14 -0
  158. package/src/url/index.ts +146 -1
  159. package/src/zod/index.ts +105 -9
  160. package/src/zod/introspect.ts +103 -0
  161. package/src/zod/jsonToZodSchemaMapper.ts +44 -21
  162. package/src/zod/zodMinMaxFilter.ts +37 -13
  163. package/src/zod/zodToTypeString.ts +184 -181
  164. package/dist/api-wrapper/index.js +0 -250
  165. package/dist/gzip/index.d.ts +0 -2
  166. package/dist/gzip/index.js +0 -16
  167. package/dist/index.js +0 -1823
  168. package/dist/jwt/index.js +0 -19
  169. package/dist/sitemap/index.js +0 -552
  170. package/dist/src/gzip/index.js +0 -16
  171. package/dist/src/secrets/infisical.js +0 -1194
  172. package/dist/zod/index.js +0 -210
@@ -1,1152 +1,249 @@
1
- // src/api-wrapper/headers.ts
2
- var CANONICAL_HEADER_NAMES = {
3
- "content-type": "Content-Type",
4
- authorization: "Authorization",
5
- accept: "Accept",
6
- "user-agent": "User-Agent",
7
- "x-request-id": "X-Request-Id",
8
- "x-correlation-id": "X-Correlation-Id"
9
- };
10
- function normalizeHeaders(headers) {
11
- const result = {};
12
- const lowerToCanonical = new Map;
13
- for (const [key, value] of Object.entries(headers)) {
14
- const lower = key.toLowerCase();
15
- const canonical = CANONICAL_HEADER_NAMES[lower] ?? key;
16
- const existing = lowerToCanonical.get(lower);
17
- if (existing && existing !== canonical)
18
- delete result[existing];
19
- lowerToCanonical.set(lower, canonical);
20
- result[canonical] = value;
21
- }
22
- return result;
23
- }
24
- function getHeader(headers, name) {
25
- const lower = name.toLowerCase();
26
- const canonical = CANONICAL_HEADER_NAMES[lower];
27
- if (canonical !== undefined) {
28
- if (headers[canonical] !== undefined)
29
- return headers[canonical];
30
- }
31
- for (const [k, v] of Object.entries(headers)) {
32
- if (k.toLowerCase() === lower)
33
- return v;
34
- }
35
- return;
36
- }
37
- function hasJsonContentType(headers) {
38
- const ct = getHeader(headers, "content-type") ?? "";
39
- return ct.includes("application/json");
40
- }
41
- function buildFetchBody(body, headers) {
42
- if (body === undefined || body === null)
43
- return;
44
- if (body instanceof FormData || body instanceof Blob)
45
- return body;
46
- if (hasJsonContentType(headers))
47
- return JSON.stringify(body);
48
- return body;
49
- }
50
- function getHeadersAsObject(headers) {
51
- const result = {};
52
- headers.forEach((value, key) => {
53
- result[key] = value;
54
- });
55
- return result;
56
- }
57
-
58
- // src/api-wrapper/zod-issues.ts
59
- import { ZodError } from "zod";
60
- function formatZodIssues(error, rawData) {
61
- return error.issues.map((issue) => {
62
- const pathArray = [...issue.path];
63
- const path = formatIssuePath(pathArray);
64
- const value = getValueAtPath(rawData, pathArray);
65
- const valuePreview = value === undefined ? undefined : previewValue(value);
66
- const raw = issue;
67
- const expected = typeof raw.expected === "string" ? raw.expected : undefined;
68
- const received = typeof raw.received === "string" ? raw.received : value !== undefined ? typeofVerbose(value) : undefined;
69
- const known = new Set([
70
- "code",
71
- "path",
72
- "message",
73
- "expected",
74
- "received",
75
- "fatal"
76
- ]);
77
- const extra = {};
78
- for (const [k, v] of Object.entries(raw)) {
79
- if (!known.has(k) && v !== undefined)
80
- extra[k] = v;
81
- }
82
- return {
83
- path,
84
- pathArray,
85
- code: issue.code,
86
- message: issue.message,
87
- expected,
88
- received,
89
- value,
90
- valuePreview,
91
- extra: Object.keys(extra).length > 0 ? extra : undefined
92
- };
93
- });
94
- }
95
- function renderIssueSummary(issues) {
96
- if (issues.length === 0)
97
- return "(no issues reported)";
98
- return issues.map((issue, idx) => {
99
- const parts = [];
100
- parts.push(` [${idx + 1}] ${issue.path}: ${issue.message}`);
101
- if (issue.expected || issue.received) {
102
- const exp = issue.expected ? `expected ${issue.expected}` : "";
103
- const rec = issue.received ? `received ${issue.received}` : "";
104
- parts.push(` (${[exp, rec].filter(Boolean).join(", ")})`);
105
- }
106
- if (issue.valuePreview !== undefined) {
107
- parts.push(` value: ${issue.valuePreview}`);
108
- }
109
- if (issue.extra) {
110
- for (const [k, v] of Object.entries(issue.extra)) {
111
- parts.push(` ${k}: ${previewValue(v, 120)}`);
112
- }
113
- }
114
- return parts.join(`
115
- `);
116
- }).join(`
117
- `);
118
- }
119
- function formatIssuePath(pathArray) {
120
- if (pathArray.length === 0)
121
- return "<root>";
122
- let out = "";
123
- for (const segment of pathArray) {
124
- if (typeof segment === "number") {
125
- out += `[${segment}]`;
126
- } else if (/^[A-Za-z_$][\w$]*$/.test(segment)) {
127
- out += out === "" ? segment : `.${segment}`;
128
- } else {
129
- out += `[${JSON.stringify(segment)}]`;
130
- }
131
- }
132
- return out;
133
- }
134
- function getValueAtPath(data, pathArray) {
135
- let current = data;
136
- for (const segment of pathArray) {
137
- if (current === null || current === undefined)
138
- return;
139
- if (typeof current !== "object")
140
- return;
141
- current = current[segment];
142
- }
143
- return current;
144
- }
145
- function typeofVerbose(value) {
146
- if (value === null)
147
- return "null";
148
- if (Array.isArray(value))
149
- return "array";
150
- return typeof value;
151
- }
152
- function previewValue(value, maxLen = 200) {
153
- let str;
154
- try {
155
- if (value === undefined)
156
- str = "undefined";
157
- else if (typeof value === "string")
158
- str = JSON.stringify(value);
159
- else
160
- str = JSON.stringify(value);
161
- } catch {
162
- str = String(value);
163
- }
164
- if (str === undefined)
165
- str = String(value);
166
- if (str.length > maxLen)
167
- str = `${str.slice(0, maxLen)}…`;
168
- return str;
169
- }
170
- function makeJsonParseZodError(error, text) {
171
- const message = error instanceof Error ? `Response body was not valid JSON: ${error.message}` : "Response body was not valid JSON";
172
- const preview = text.length > 200 ? `${text.slice(0, 200)}…` : text;
173
- return new ZodError([
174
- {
175
- code: "custom",
176
- path: [],
177
- message: `${message} (body preview: ${JSON.stringify(preview)})`,
178
- input: text
179
- }
180
- ]);
181
- }
182
- function tryParseJson(body) {
183
- if (!body)
184
- return;
185
- try {
186
- return JSON.parse(body);
187
- } catch {
188
- return;
189
- }
190
- }
191
-
192
- // src/api-wrapper/errors.ts
193
- var MAX_BODY_PREVIEW = 500;
1
+ import {
2
+ HttpResponseError2,
3
+ createApiClient2
4
+ } from "../../index-j1ybktbr.js";
5
+ import {
6
+ getViteDefine2,
7
+ viteSecretSetPlugin2
8
+ } from "../../index-181e6vfw.js";
9
+ import {
10
+ withSecretDeadline,
11
+ getProcessEnvironment,
12
+ resolveSecretEnvironment,
13
+ defineSecretSet2,
14
+ cloudflareWorkerEnvLoader2
15
+ } from "../../index-wjyb9bsd.js";
16
+ import {
17
+ SecretLoadError2
18
+ } from "../../index-srt06xd2.js";
194
19
 
195
- class ApiError extends Error {
196
- context;
197
- cause;
198
- constructor(message, context, options) {
199
- super(message);
200
- this.name = "ApiError";
201
- this.context = context;
202
- this.cause = options?.cause;
203
- }
204
- toJSON() {
205
- return {
206
- name: this.name,
207
- message: this.message,
208
- context: this.context
209
- };
210
- }
211
- }
212
-
213
- class HttpResponseError extends ApiError {
214
- status;
215
- body;
216
- bodyJson;
217
- responseHeaders;
218
- requestId;
219
- constructor(status, body, responseHeaders, context) {
220
- const preview = body.length > MAX_BODY_PREVIEW ? `${body.slice(0, MAX_BODY_PREVIEW)}…` : body;
221
- super(`HTTP ${status} ${context.method} ${context.url} - ${preview}`, context);
222
- this.name = "HttpResponseError";
223
- this.status = status;
224
- this.body = body;
225
- this.responseHeaders = responseHeaders;
226
- this.requestId = getHeader(responseHeaders, "x-request-id") ?? getHeader(responseHeaders, "x-correlation-id");
227
- this.bodyJson = tryParseJson(body);
228
- }
229
- toJSON() {
230
- return {
231
- ...super.toJSON(),
232
- status: this.status,
233
- body: this.body,
234
- bodyJson: this.bodyJson,
235
- requestId: this.requestId,
236
- responseHeaders: this.responseHeaders
237
- };
238
- }
239
- }
240
-
241
- class ResponseValidationError extends ApiError {
242
- zodError;
243
- rawResponse;
244
- issues;
245
- validationIssues;
246
- constructor(zodError, rawResponse, context) {
247
- const issues = formatZodIssues(zodError, rawResponse);
248
- const summary = renderIssueSummary(issues);
249
- super(`Response validation failed (${context.method} ${context.url}):
250
- ${summary}`, context, { cause: zodError });
251
- this.name = "ResponseValidationError";
252
- this.zodError = zodError;
253
- this.rawResponse = rawResponse;
254
- this.issues = issues;
255
- this.validationIssues = issues.map((i) => `${i.path}: ${i.message}`).join("; ");
256
- }
257
- toJSON() {
258
- return {
259
- ...super.toJSON(),
260
- issues: this.issues,
261
- validationIssues: this.validationIssues,
262
- rawResponsePreview: previewValue(this.rawResponse, 1000)
263
- };
264
- }
265
- }
266
-
267
- class RequestValidationError extends ApiError {
268
- zodError;
269
- target;
270
- rawInput;
271
- issues;
272
- validationIssues;
273
- constructor(zodError, target, rawInput, context) {
274
- const issues = formatZodIssues(zodError, rawInput);
275
- const summary = renderIssueSummary(issues);
276
- super(`Request ${target} validation failed (${context.method} ${context.url}):
277
- ${summary}`, context, { cause: zodError });
278
- this.name = "RequestValidationError";
279
- this.zodError = zodError;
280
- this.target = target;
281
- this.rawInput = rawInput;
282
- this.issues = issues;
283
- this.validationIssues = issues.map((i) => `${i.path}: ${i.message}`).join("; ");
284
- }
285
- toJSON() {
286
- return {
287
- ...super.toJSON(),
288
- target: this.target,
289
- issues: this.issues,
290
- validationIssues: this.validationIssues
291
- };
292
- }
293
- }
294
-
295
- class RequestTimeoutError extends ApiError {
296
- timeoutMs;
297
- constructor(timeoutMs, context) {
298
- super(`Request timed out after ${timeoutMs}ms: ${context.method} ${context.url}`, context);
299
- this.name = "RequestTimeoutError";
300
- this.timeoutMs = timeoutMs;
301
- }
302
- }
303
-
304
- class NetworkError extends ApiError {
305
- constructor(message, context, cause) {
306
- super(message, context, { cause });
307
- this.name = "NetworkError";
308
- }
309
- }
310
-
311
- class RequestAbortedError extends ApiError {
312
- constructor(context, cause) {
313
- super(`Request aborted: ${context.method} ${context.url}`, context, {
314
- cause
315
- });
316
- this.name = "RequestAbortedError";
317
- }
318
- }
319
-
320
- class ConfigError extends ApiError {
321
- constructor(message, context) {
322
- super(message, context);
323
- this.name = "ConfigError";
324
- }
325
- }
20
+ // src/secrets/infisical.ts
21
+ import { z as z2 } from "zod";
326
22
 
327
- class ActionError extends ApiError {
328
- constructor(message, context, cause) {
329
- super(message, context, { cause });
330
- this.name = "ActionError";
331
- }
332
- }
333
- var isApiError = (e) => e instanceof ApiError;
334
- var isHttpResponseError = (e) => e instanceof HttpResponseError;
335
- var isResponseValidationError = (e) => e instanceof ResponseValidationError;
336
- var isRequestValidationError = (e) => e instanceof RequestValidationError;
337
- var isRequestTimeoutError = (e) => e instanceof RequestTimeoutError;
338
- var isNetworkError = (e) => e instanceof NetworkError;
339
- var isRequestAbortedError = (e) => e instanceof RequestAbortedError;
340
- var isConfigError = (e) => e instanceof ConfigError;
341
- var isActionError = (e) => e instanceof ActionError;
342
- // src/api-wrapper/builders.ts
343
- import { ZodError as ZodError2 } from "zod";
344
- function buildUrl(endpoint, params, reqQuery, baseApiUrls, defaultBaseApiUrl, url, configError) {
345
- if (url) {
346
- const finalUrl2 = replacePathParams(url, params, configError);
347
- const queryString2 = new URLSearchParams(buildQueryParamsRaw(endpoint, reqQuery)).toString();
348
- return {
349
- finalUrl: finalUrl2,
350
- fullUrl: queryString2 ? `${finalUrl2}?${queryString2}` : finalUrl2
351
- };
352
- }
353
- const defaultBaseUrl = defaultBaseApiUrl ?? Object.keys(baseApiUrls)[0];
354
- if (!defaultBaseUrl) {
355
- throw configError("At least one base API URL is required");
356
- }
357
- const baseUrlKey = endpoint.baseApiUrl ?? defaultBaseUrl;
358
- const configBaseUrl = baseApiUrls[baseUrlKey];
359
- if (!configBaseUrl) {
360
- throw configError(`Unknown base API URL: ${baseUrlKey}`);
361
- }
362
- const baseUrl = typeof configBaseUrl === "function" ? configBaseUrl() : configBaseUrl;
363
- const path = typeof endpoint.path === "function" ? endpoint.path(baseUrl) : endpoint.path;
364
- const finalUrl = replacePathParams(`${baseUrl}${path}`, params, configError);
365
- const queryString = new URLSearchParams(buildQueryParamsRaw(endpoint, reqQuery)).toString();
366
- return {
367
- finalUrl,
368
- fullUrl: queryString ? `${finalUrl}?${queryString}` : finalUrl
23
+ // src/secrets/infisical-cli.ts
24
+ async function readInfisicalCliToken(options) {
25
+ const { execFile } = await import("node:child_process").catch(() => {
26
+ throw new SecretLoadError2("CLI", "Infisical CLI fallback requires a runtime with subprocess support. Provide Infisical client credentials or a custom secret loader.");
27
+ });
28
+ options.signal.throwIfAborted();
29
+ const env = {
30
+ ...getProcessEnvironment(),
31
+ INFISICAL_DISABLE_UPDATE_CHECK: "true"
369
32
  };
370
- }
371
- function buildQueryParamsRaw(endpoint, query) {
372
- const defaultParams = endpoint.reqDefaultQueryParams ?? {};
373
- const merged = { ...defaultParams, ...query ?? {} };
374
- return Object.fromEntries(Object.entries(merged).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)]));
375
- }
376
- function buildQueryParams(endpoint, query, ctx) {
377
- const defaultParams = endpoint.reqDefaultQueryParams ?? {};
378
- let parsedQuery;
379
- if (endpoint.reqQuerySchema) {
380
- try {
381
- parsedQuery = endpoint.reqQuerySchema.parse(query);
382
- } catch (error) {
383
- if (error instanceof ZodError2) {
384
- throw new RequestValidationError(error, "query", query, ctx());
385
- }
386
- throw error;
387
- }
388
- } else {
389
- parsedQuery = query ?? {};
390
- }
391
- const merged = { ...defaultParams, ...parsedQuery };
392
- return Object.fromEntries(Object.entries(merged).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)]));
393
- }
394
- function buildRequestBody(endpoint, body, ctx) {
395
- if (!endpoint.reqBodySchema)
396
- return body;
397
- let parsedBody;
33
+ delete env.INFISICAL_TOKEN;
34
+ delete env.INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN;
35
+ delete env.TOKEN;
398
36
  try {
399
- parsedBody = endpoint.reqBodySchema.parse(body);
37
+ const stdout = await new Promise((resolve, reject) => {
38
+ const child = execFile("infisical", [
39
+ "user",
40
+ "get",
41
+ "token",
42
+ "--plain",
43
+ `--domain=${options.siteUrl}`,
44
+ "--silent"
45
+ ], {
46
+ env,
47
+ encoding: "utf8",
48
+ shell: false,
49
+ timeout: options.timeoutMs ?? 30000,
50
+ signal: options.signal,
51
+ killSignal: "SIGKILL",
52
+ maxBuffer: 10485760,
53
+ windowsHide: true
54
+ }, (error, output) => {
55
+ if (error) {
56
+ reject(error);
57
+ } else {
58
+ resolve(output);
59
+ }
60
+ });
61
+ child.stdin?.end();
62
+ });
63
+ return stdout.trim();
400
64
  } catch (error) {
401
- if (error instanceof ZodError2) {
402
- throw new RequestValidationError(error, "body", body, ctx());
65
+ if (options.signal.aborted) {
66
+ throw options.signal.reason;
403
67
  }
404
- throw error;
405
- }
406
- if (endpoint.reqBodyFormat !== "form-data") {
407
- return parsedBody;
408
- }
409
- const formData = new FormData;
410
- for (const [key, value] of Object.entries(parsedBody)) {
411
- if (value == null)
412
- continue;
413
- formData.set(key, value instanceof Blob ? value : String(value));
414
- }
415
- return formData;
416
- }
417
- function buildHeaders(endpoint, headers, defaultHeaders, ctx) {
418
- const contentType = endpoint.reqBodyFormat === "json" ? "application/json" : undefined;
419
- let parsedHeaders;
420
- if (endpoint.reqHeadersSchema) {
421
- try {
422
- parsedHeaders = endpoint.reqHeadersSchema.parse(headers);
423
- } catch (error) {
424
- if (error instanceof ZodError2) {
425
- throw new RequestValidationError(error, "headers", headers, ctx());
426
- }
427
- throw error;
68
+ const failure = error;
69
+ if (failure?.code === "ENOENT") {
70
+ throw new SecretLoadError2("CLI", "Infisical CLI not found. Install infisical and ensure it is on PATH, or provide Infisical client credentials.");
428
71
  }
429
- } else {
430
- parsedHeaders = headers ?? {};
431
- }
432
- return normalizeHeaders({
433
- ...defaultHeaders,
434
- ...contentType && { "Content-Type": contentType },
435
- ...endpoint.defaultHeaders,
436
- ...parsedHeaders
437
- });
438
- }
439
- function replacePathParams(path, params, configError) {
440
- return path.replace(/:(\w+)/g, (_, key) => {
441
- const value = params?.[key];
442
- if (value === undefined) {
443
- throw configError(`Missing required path parameter: ${key}`);
72
+ if (failure?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
73
+ throw new SecretLoadError2("CLI", "Infisical CLI output exceeded the 10 MiB limit.");
444
74
  }
445
- return encodeURIComponent(String(value));
446
- });
447
- }
448
-
449
- // src/api-wrapper/actions-impl.ts
450
- function createActionCache() {
451
- const store = new Map;
452
- const isExpired = (entry) => entry.expiresAt !== undefined && entry.expiresAt <= Date.now();
453
- const cache = async (key, fn, options) => {
454
- const existing = store.get(key);
455
- if (existing && !isExpired(existing)) {
456
- if (existing.inflight)
457
- return existing.inflight;
458
- if (existing.hasValue)
459
- return existing.value;
460
- }
461
- const promise = (async () => fn())();
462
- const entry = {
463
- hasValue: false,
464
- inflight: promise,
465
- expiresAt: options?.ttlMs !== undefined ? Date.now() + options.ttlMs : undefined
466
- };
467
- store.set(key, entry);
468
- try {
469
- const value = await promise;
470
- entry.value = value;
471
- entry.hasValue = true;
472
- entry.inflight = undefined;
473
- return value;
474
- } catch (error) {
475
- store.delete(key);
476
- throw error;
477
- }
478
- };
479
- cache.get = (key) => {
480
- const entry = store.get(key);
481
- if (!entry || !entry.hasValue)
482
- return;
483
- if (isExpired(entry)) {
484
- store.delete(key);
485
- return;
486
- }
487
- return entry.value;
488
- };
489
- cache.set = (key, value, options) => {
490
- store.set(key, {
491
- value,
492
- hasValue: true,
493
- expiresAt: options?.ttlMs !== undefined ? Date.now() + options.ttlMs : undefined
494
- });
495
- };
496
- cache.invalidate = (key) => {
497
- store.delete(key);
498
- };
499
- cache.clear = () => {
500
- store.clear();
501
- };
502
- return cache;
503
- }
504
- function makeDefineAction() {
505
- function defineAction(...args) {
506
- if (args.length === 0) {
507
- return (def2) => ({
508
- ...def2,
509
- noRuntimeInput: false
510
- });
75
+ if (failure?.killed) {
76
+ throw new SecretLoadError2("TIMEOUT", `Infisical CLI timed out after ${(options.timeoutMs ?? 30000) / 1000} seconds or was terminated.`);
511
77
  }
512
- const def = args[0];
513
- return {
514
- ...def,
515
- noRuntimeInput: true
516
- };
78
+ throw new SecretLoadError2("CLI", `Infisical CLI session token failed. Run infisical login --domain=${options.siteUrl} and verify access to the configured organization, project, and environment.`);
517
79
  }
518
- return defineAction;
519
80
  }
520
- var defineAction = makeDefineAction();
521
81
 
522
- // src/api-wrapper/redaction.ts
523
- var SENSITIVE_HEADER_KEYS = new Set([
524
- "authorization",
525
- "cookie",
526
- "set-cookie",
527
- "x-api-key",
528
- "x-auth-token"
529
- ]);
530
- var SENSITIVE_BODY_KEYS = new Set([
531
- "password",
532
- "token",
533
- "accesstoken",
534
- "access_token",
535
- "refreshtoken",
536
- "refresh_token",
537
- "secret",
538
- "client_secret",
539
- "apikey",
540
- "api_key"
541
- ]);
542
- function redactHeaders(headers) {
543
- if (!headers)
544
- return;
545
- const out = {};
546
- for (const [k, v] of Object.entries(headers)) {
547
- if (SENSITIVE_HEADER_KEYS.has(k.toLowerCase())) {
548
- out[k] = "[REDACTED]";
549
- } else {
550
- out[k] = v;
551
- }
82
+ // src/secrets/infisical-config.ts
83
+ function validateInfisicalScope(options) {
84
+ validateInfisicalOrganizationId(options.organizationId);
85
+ let url;
86
+ try {
87
+ url = new URL(options.siteUrl);
88
+ } catch {
89
+ throw new SecretLoadError2("CONFIGURATION", "Invalid Infisical siteUrl.");
552
90
  }
553
- return out;
554
- }
555
- function redactBody(body) {
556
- if (body === null || body === undefined)
557
- return body;
558
- if (typeof body !== "object" || Array.isArray(body)) {
559
- return body;
91
+ if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
92
+ throw new SecretLoadError2("CONFIGURATION", "Infisical siteUrl must be an HTTP(S) URL without credentials, query, or fragment.");
560
93
  }
561
- const rec = body;
562
- const out = { ...rec };
563
- for (const key of Object.keys(out)) {
564
- if (SENSITIVE_BODY_KEYS.has(key.toLowerCase())) {
565
- out[key] = "[REDACTED]";
566
- }
94
+ if (!options.projectId.trim() || !options.environment.trim() || !(options.secretPath ?? "/").startsWith("/")) {
95
+ throw new SecretLoadError2("CONFIGURATION", "Infisical requires a projectId, environment, and absolute secretPath.");
567
96
  }
568
- return out;
569
97
  }
570
- function defaultRedactContext(ctx) {
571
- return {
572
- ...ctx,
573
- requestHeaders: redactHeaders(ctx.requestHeaders),
574
- requestBody: redactBody(ctx.requestBody),
575
- meta: ctx.meta
576
- };
577
- }
578
-
579
- // src/api-wrapper/error-reporting.ts
580
- function applyErrorContextRedaction(ctx, config) {
581
- const base = defaultRedactContext(ctx);
582
- return config.redact ? config.redact(base) : base;
583
- }
584
- async function reportApiError(err, config) {
585
- err.context = applyErrorContextRedaction(err.context, config);
586
- try {
587
- await config.onError?.(err);
588
- } catch {}
589
- config.logger?.error?.(err);
590
- return err;
591
- }
592
-
593
- // src/api-wrapper/size.ts
594
- function calculateSizeInMb(data) {
595
- let bytes;
596
- if (data === undefined || data === null) {
597
- bytes = 0;
598
- } else if (data instanceof Blob) {
599
- bytes = data.size;
600
- } else if (typeof FormData !== "undefined" && data instanceof FormData) {
601
- bytes = 0;
602
- data.forEach((value) => {
603
- if (value instanceof Blob)
604
- bytes += value.size;
605
- else
606
- bytes += new TextEncoder().encode(String(value)).length;
607
- });
608
- } else if (typeof data === "string") {
609
- bytes = new TextEncoder().encode(data).length;
610
- } else {
611
- bytes = new TextEncoder().encode(JSON.stringify(data) ?? "").length;
98
+ function validateInfisicalOrganizationId(organizationId) {
99
+ if (typeof organizationId !== "string" || !organizationId.trim() || /\s/.test(organizationId)) {
100
+ throw new SecretLoadError2("CONFIGURATION", "Infisical organizationId is required and must be a nonempty ID without whitespace.");
612
101
  }
613
- return bytes / (1024 * 1024);
614
102
  }
615
103
 
616
- // src/api-wrapper/transport.ts
617
- import { ZodError as ZodError3 } from "zod";
618
- async function validateResponse(schema, data, ctx) {
104
+ // src/secrets/infisical-session.ts
105
+ import { z } from "zod";
106
+ var sessionClaimsSchema = z.object({
107
+ organizationId: z.string().optional(),
108
+ subOrganizationId: z.string().optional(),
109
+ exp: z.number().finite().optional()
110
+ });
111
+ function parseInfisicalSessionToken(token) {
112
+ let claims;
619
113
  try {
620
- return await schema.parseAsync(data);
621
- } catch (error) {
622
- if (error instanceof ZodError3) {
623
- throw new ResponseValidationError(error, data, ctx());
114
+ if (!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(token)) {
115
+ throw new Error("Invalid token format");
624
116
  }
625
- throw error;
117
+ const payload = token.split(".")[1];
118
+ const json = atob(payload.replace(/-/g, "+").replace(/_/g, "/"));
119
+ claims = sessionClaimsSchema.parse(JSON.parse(json));
120
+ } catch {
121
+ throw new SecretLoadError2("AUTHENTICATION", "Infisical returned an invalid user session token. Run infisical login for the configured domain.");
626
122
  }
627
- }
628
- async function httpRequest(config, ctx) {
629
- const queryString = config.doNotEncodeQueryParams ? Object.entries(config.queryParams).map(([key, value]) => `${key}=${value}`).join("&") : new URLSearchParams(config.queryParams).toString();
630
- const fullUrl = queryString ? `${config.url}?${queryString}` : config.url;
631
- const timeoutController = new AbortController;
632
- const timeout = config.timeoutMs === undefined ? undefined : setTimeout(() => timeoutController.abort(), config.timeoutMs);
633
- const signal = mergeSignals(timeoutController.signal, config.userSignal);
634
- try {
635
- return await config.fetchFn(fullUrl, {
636
- method: config.method,
637
- headers: config.headers,
638
- body: buildFetchBody(config.body, config.headers),
639
- signal
640
- });
641
- } catch (error) {
642
- if (isDomAbortError(error)) {
643
- if (config.userSignal?.aborted) {
644
- throw new RequestAbortedError(ctx(), error);
645
- }
646
- if (timeoutController.signal.aborted && config.timeoutMs !== undefined) {
647
- throw new RequestTimeoutError(config.timeoutMs, ctx());
648
- }
649
- throw new RequestAbortedError(ctx(), error);
650
- }
651
- throw new NetworkError(error instanceof Error ? error.message : String(error), ctx(), error);
652
- } finally {
653
- if (timeout)
654
- clearTimeout(timeout);
123
+ if (claims.exp !== undefined && claims.exp <= Date.now() / 1000) {
124
+ throw new SecretLoadError2("AUTHENTICATION", "Infisical user session has expired. Run infisical login for the configured domain.");
655
125
  }
126
+ return { organizationId: claims.subOrganizationId ?? claims.organizationId };
656
127
  }
657
- function isDomAbortError(error) {
658
- return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
659
- }
660
- function mergeSignals(a, b) {
661
- if (!b)
662
- return a;
663
- const anyFn = AbortSignal.any;
664
- if (typeof anyFn === "function")
665
- return anyFn([a, b]);
666
- const controller = new AbortController;
667
- const onAbort = () => controller.abort();
668
- if (a.aborted)
669
- controller.abort();
670
- else
671
- a.addEventListener("abort", onAbort, { once: true });
672
- if (b.aborted)
673
- controller.abort();
674
- else
675
- b.addEventListener("abort", onAbort, { once: true });
676
- return controller.signal;
677
- }
678
- async function readErrorResponse(response) {
679
- const body = await response.text();
680
- return {
681
- body,
682
- headers: getHeadersAsObject(response.headers),
683
- status: response.status
684
- };
685
- }
686
- function getRetryDelay(params) {
687
- const { retryDelay, attempt, response } = params;
688
- if (response && (response.status === 429 || response.status === 503)) {
689
- const retryAfter = response.headers.get("retry-after");
690
- if (retryAfter) {
691
- const seconds = Number(retryAfter);
692
- if (Number.isFinite(seconds))
693
- return seconds * 1000;
694
- const dateMs = Date.parse(retryAfter);
695
- if (!Number.isNaN(dateMs)) {
696
- return Math.max(0, dateMs - Date.now());
697
- }
698
- }
699
- }
700
- if (typeof retryDelay === "function")
701
- return retryDelay(attempt);
702
- return retryDelay;
703
- }
704
- function shouldAttemptRetryOnError(error) {
705
- if (error instanceof HttpResponseError)
706
- return false;
707
- if (error instanceof ResponseValidationError)
708
- return false;
709
- if (error instanceof RequestValidationError)
710
- return false;
711
- if (error instanceof ConfigError)
712
- return false;
713
- if (error instanceof RequestAbortedError)
714
- return false;
715
- return true;
716
- }
717
- function shouldAttemptRetryOnHttp(retryCtx) {
718
- const { error, response } = retryCtx;
719
- if (error)
720
- return shouldAttemptRetryOnError(error);
721
- return response ? response.status >= 500 || response.status === 429 : false;
722
- }
723
- async function makeRequestWithRetry(args) {
724
- const {
725
- config,
726
- maxRetries,
727
- retryDelay,
728
- validateFn,
729
- shouldRetry,
730
- logger,
731
- ctx,
732
- endpointName,
733
- method,
734
- fullUrl,
735
- meta,
736
- onResponse,
737
- onRetry
738
- } = args;
739
- let retryCount = 0;
740
- while (true) {
741
- let response;
128
+
129
+ // src/secrets/infisical.ts
130
+ var DEFAULT_INFISICAL_SITE_URL = "https://eu.infisical.com";
131
+ var defaultFetch = globalThis.fetch;
132
+ var infisicalAuthResponseSchema = z2.object({ accessToken: z2.string() });
133
+ var infisicalSecretSchema = z2.object({
134
+ secretKey: z2.string(),
135
+ secretValue: z2.string()
136
+ });
137
+ var infisicalSecretsResponseSchema = z2.object({
138
+ secrets: z2.array(infisicalSecretSchema)
139
+ });
140
+ async function fetchInfisicalSecrets(options) {
141
+ validateInfisicalScope(options);
142
+ return withSecretDeadline(options, async (signal) => {
143
+ let operation = "login";
742
144
  try {
743
- logger?.debug?.("API request", config);
744
- response = await httpRequest(config, (over) => ctx({ attempt: retryCount, ...over }));
745
- await onResponse?.({
746
- endpoint: endpointName,
747
- method,
748
- url: fullUrl,
749
- response: response.clone(),
750
- attempt: retryCount,
751
- meta
752
- });
753
- if (response.status >= 400) {
754
- const retryCtx = {
755
- response,
756
- retryCount,
757
- maxRetries,
758
- endpoint: endpointName,
759
- method,
760
- url: fullUrl
761
- };
762
- if (retryCount < maxRetries && shouldRetry(retryCtx)) {
763
- const delayMs = getRetryDelay({
764
- retryDelay,
765
- attempt: retryCount,
766
- response
767
- });
768
- await onRetry?.({
769
- ...retryCtx,
770
- delayMs,
771
- nextAttempt: retryCount + 1
772
- });
773
- retryCount++;
774
- await delay(delayMs);
775
- continue;
145
+ const infisical = createInfisicalApiClient(options.siteUrl);
146
+ const { data: auth } = await infisical.request("login", {
147
+ signal,
148
+ reqBody: {
149
+ clientId: options.clientId,
150
+ clientSecret: options.clientSecret
776
151
  }
777
- const { body, headers: responseHeaders } = await readErrorResponse(response);
778
- throw new HttpResponseError(response.status, body, responseHeaders, ctx({ attempt: retryCount }));
779
- }
780
- return {
781
- validatedData: await validateFn(response),
782
- retryCount,
783
- httpStatus: response.status
784
- };
785
- } catch (error) {
786
- if (error instanceof HttpResponseError || error instanceof ResponseValidationError || error instanceof RequestValidationError || error instanceof ConfigError || error instanceof RequestAbortedError) {
787
- throw error;
788
- }
789
- const retryCtx = {
790
- error,
791
- retryCount,
792
- maxRetries,
793
- endpoint: endpointName,
794
- method,
795
- url: fullUrl
796
- };
797
- if (retryCount >= maxRetries || !shouldRetry(retryCtx)) {
798
- throw error;
799
- }
800
- const delayMs = getRetryDelay({
801
- retryDelay,
802
- attempt: retryCount,
803
- response: undefined
804
152
  });
805
- await onRetry?.({
806
- ...retryCtx,
807
- delayMs,
808
- nextAttempt: retryCount + 1
153
+ signal.throwIfAborted();
154
+ operation = "listSecrets";
155
+ return await listInfisicalSecrets(infisical, auth.accessToken, {
156
+ ...options,
157
+ signal
809
158
  });
810
- retryCount++;
811
- await delay(delayMs);
812
- }
813
- }
814
- }
815
- async function validateAndTransformResponse(endpoint, response, ctx) {
816
- const responseHeaders = getHeadersAsObject(response.headers);
817
- let responseData;
818
- if (hasJsonContentType(responseHeaders)) {
819
- const text = await response.text();
820
- try {
821
- responseData = text === "" ? undefined : JSON.parse(text);
822
159
  } catch (error) {
823
- throw new ResponseValidationError(makeJsonParseZodError(error, text), text, ctx());
160
+ throwInfisicalHttpError(error, operation, signal);
824
161
  }
825
- } else {
826
- responseData = await response.text();
827
- }
828
- const transformedData = endpoint.resFormatter ? endpoint.resFormatter(responseData, responseHeaders) : responseData;
829
- return validateResponse(endpoint.resSchema, transformedData, ctx);
830
- }
831
- function defaultShouldRetry(ctx) {
832
- if (ctx.error)
833
- return shouldAttemptRetryOnError(ctx.error);
834
- return shouldAttemptRetryOnHttp(ctx);
835
- }
836
- function delay(ms) {
837
- return new Promise((resolve) => setTimeout(resolve, ms));
838
- }
839
-
840
- // src/api-wrapper/create-client.ts
841
- function isActionInvokeOptionsOnly(value) {
842
- if (value === null || value === undefined)
843
- return false;
844
- if (typeof value !== "object" || Array.isArray(value))
845
- return false;
846
- return Object.keys(value).every((k) => k === "signal" || k === "meta");
162
+ });
847
163
  }
848
- function createApiClientImpl(apiConfig) {
849
- let actions = {};
850
- const cache = createActionCache();
851
- const invokeEndpoint = async (endpointKey, input = {}) => {
852
- const endpoint = apiConfig.endpoints[endpointKey];
853
- const rawInput = input;
854
- const endpointName = apiConfig.name ? `${apiConfig.name}.${String(endpointKey)}` : String(endpointKey);
855
- const startedAt = Date.now();
856
- const maxRetries = input.retries ?? apiConfig.retries ?? 3;
857
- const baseContext = {
858
- endpoint: endpointName,
859
- method: endpoint?.method ?? "GET",
860
- url: "",
861
- attempt: 0,
862
- maxRetries,
863
- elapsedMs: 0,
864
- meta: input.meta
865
- };
866
- const elapsed = () => Date.now() - startedAt;
867
- const ctx = (over = {}) => ({
868
- ...baseContext,
869
- elapsedMs: elapsed(),
870
- ...over
871
- });
872
- if (!endpoint) {
873
- throw await reportApiError(new ConfigError(`Unknown API endpoint: ${String(endpointKey)}`, ctx()), apiConfig);
874
- }
875
- baseContext.method = endpoint.method;
876
- let finalUrl;
877
- let fullUrl;
878
- try {
879
- const built = buildUrl(endpoint, rawInput.reqParams, rawInput.reqQuery, apiConfig.baseApiUrls, apiConfig.defaultBaseApiUrl, input.url, (msg) => new ConfigError(msg, ctx()));
880
- finalUrl = built.finalUrl;
881
- fullUrl = built.fullUrl;
882
- } catch (e) {
883
- if (e instanceof ApiError)
884
- throw await reportApiError(e, apiConfig);
885
- throw e;
886
- }
887
- baseContext.url = fullUrl;
888
- let queryParams;
889
- let body;
890
- let headers;
891
- try {
892
- queryParams = buildQueryParams(endpoint, rawInput.reqQuery, ctx);
893
- body = buildRequestBody(endpoint, rawInput.reqBody, ctx);
894
- headers = buildHeaders(endpoint, rawInput.reqHeaders, apiConfig.defaultHeaders ?? {}, ctx);
895
- } catch (e) {
896
- if (e instanceof ApiError)
897
- throw await reportApiError(e, apiConfig);
898
- throw e;
899
- }
900
- baseContext.requestHeaders = headers;
901
- baseContext.requestBody = body;
902
- if (apiConfig.onRequest) {
903
- try {
904
- const result = await apiConfig.onRequest({
905
- endpoint: endpointName,
906
- method: endpoint.method,
907
- url: fullUrl,
908
- headers,
909
- body,
910
- meta: input.meta
911
- });
912
- if (result?.headers)
913
- headers = result.headers;
914
- if (result && "body" in result)
915
- body = result.body;
916
- } catch (e) {
917
- if (e instanceof ApiError)
918
- throw await reportApiError(e, apiConfig);
919
- throw e;
920
- }
921
- }
922
- const config = {
923
- method: endpoint.method,
924
- url: finalUrl,
925
- queryParams,
926
- body,
927
- headers,
928
- doNotEncodeQueryParams: endpoint.doNotEncodeQueryParams,
929
- timeoutMs: input.timeoutMs ?? apiConfig.timeoutMs,
930
- fetchFn: input.fetch ?? apiConfig.fetch ?? fetch,
931
- userSignal: input.signal
932
- };
933
- try {
934
- const result = await makeRequestWithRetry({
935
- config,
936
- maxRetries,
937
- retryDelay: apiConfig.retryDelayMs ?? 300,
938
- validateFn: (response) => validateAndTransformResponse(endpoint, response, ctx),
939
- shouldRetry: apiConfig.shouldRetry ?? defaultShouldRetry,
940
- logger: apiConfig.logger,
941
- ctx,
942
- endpointName,
943
- method: endpoint.method,
944
- fullUrl,
945
- meta: input.meta,
946
- onResponse: apiConfig.onResponse,
947
- onRetry: apiConfig.onRetry
948
- });
949
- const responseTimeMs = elapsed();
950
- const responseSizeMb = calculateSizeInMb(result.validatedData);
951
- const requestBodySizeMb = calculateSizeInMb(config.body);
952
- return {
953
- data: result.validatedData,
954
- requestBodySizeMb,
955
- responseSizeMb,
956
- responseTimeMs,
957
- httpStatus: result.httpStatus,
958
- retryCount: result.retryCount
959
- };
960
- } catch (error) {
961
- if (error instanceof ApiError)
962
- throw await reportApiError(error, apiConfig);
963
- throw error;
964
- }
965
- };
966
- async function invokeAction(name, rawInput, options = {}) {
967
- const action = actions[name];
968
- const inputForHandler = action.noRuntimeInput ? undefined : rawInput;
969
- const actionName = apiConfig.name ? `${apiConfig.name}.${name}` : name;
970
- const startedAt = Date.now();
971
- const baseContext = {
972
- endpoint: actionName,
973
- method: "GET",
974
- url: "",
975
- attempt: 0,
976
- maxRetries: 0,
977
- elapsedMs: 0,
978
- meta: options.meta,
979
- requestBody: action.noRuntimeInput ? undefined : rawInput
980
- };
981
- const ctx = (over = {}) => ({
982
- ...baseContext,
983
- elapsedMs: Date.now() - startedAt,
984
- ...over
985
- });
986
- apiConfig.logger?.debug?.("Action start", { action: actionName });
987
- try {
988
- const result = await action.handler({
989
- input: inputForHandler,
990
- api: proxy,
991
- signal: options.signal,
992
- meta: options.meta,
993
- logger: apiConfig.logger,
994
- cache
995
- });
996
- apiConfig.logger?.debug?.("Action end", {
997
- action: actionName,
998
- elapsedMs: Date.now() - startedAt
164
+ async function loadInfisicalSecrets(options) {
165
+ validateInfisicalScope(options);
166
+ const env = getProcessEnvironment();
167
+ const clientId = env?.[options.clientIdEnvKey];
168
+ const clientSecret = env?.[options.clientSecretEnvKey];
169
+ const mode = options.auth ?? "auto";
170
+ if (!["auto", "http", "cli"].includes(mode)) {
171
+ throw new SecretLoadError2("CONFIGURATION", "Invalid Infisical auth mode.");
172
+ }
173
+ const useHttp = mode === "http" || mode === "auto" && Boolean(clientId && clientSecret);
174
+ if (useHttp) {
175
+ if (!clientId || !clientSecret) {
176
+ throw new SecretLoadError2("AUTHENTICATION", "Infisical HTTP authentication requires both client credentials.");
177
+ }
178
+ options.reportSource?.("Infisical HTTP");
179
+ return fetchInfisicalSecrets({ ...options, clientId, clientSecret });
180
+ }
181
+ options.reportSource?.(`Infisical CLI session (organization=${options.organizationId} project=${options.projectId} environment=${options.environment})`);
182
+ return withSecretDeadline(options, (signal) => fetchInfisicalSessionSecrets({ ...options, signal }));
183
+ }
184
+ async function fetchInfisicalSessionSecrets(options) {
185
+ const { signal } = options;
186
+ let token = await readInfisicalCliToken(options);
187
+ signal.throwIfAborted();
188
+ const session = parseInfisicalSessionToken(token);
189
+ const infisical = createInfisicalApiClient(options.siteUrl);
190
+ let operation = "selectOrganization";
191
+ try {
192
+ if (session.organizationId !== options.organizationId) {
193
+ const { data } = await infisical.request("selectOrganization", {
194
+ signal,
195
+ reqHeaders: {
196
+ Authorization: `Bearer ${token}`,
197
+ "User-Agent": "hanzio/secrets"
198
+ },
199
+ reqBody: { organizationId: options.organizationId }
999
200
  });
1000
- return result;
1001
- } catch (error) {
1002
- if (error instanceof ApiError) {
1003
- throw await reportApiError(error, apiConfig);
201
+ signal.throwIfAborted();
202
+ if (data.isMfaEnabled) {
203
+ throw new SecretLoadError2("AUTHENTICATION", "Infisical requires MFA for this organization. Complete infisical login for the target organization and configured domain before loading secrets.", { operation });
1004
204
  }
1005
- const wrapped = new ActionError(`Action ${actionName} failed: ${error instanceof Error ? error.message : String(error)}`, ctx(), error);
1006
- throw await reportApiError(wrapped, apiConfig);
1007
- }
1008
- }
1009
- const request = async (key, input, options) => {
1010
- if (key in actions) {
1011
- const action = actions[key];
1012
- if (action.noRuntimeInput) {
1013
- if (input === undefined || input === null) {
1014
- return invokeAction(key, undefined, options ?? {});
1015
- }
1016
- if (options !== undefined) {
1017
- return invokeAction(key, undefined, options);
1018
- }
1019
- if (isActionInvokeOptionsOnly(input)) {
1020
- return invokeAction(key, undefined, input);
1021
- }
1022
- return invokeAction(key, undefined, {});
205
+ const scopedSession = parseInfisicalSessionToken(data.token);
206
+ if (scopedSession.organizationId !== options.organizationId) {
207
+ throw new SecretLoadError2("AUTHENTICATION", "Infisical returned a session for a different organization.", { operation });
1023
208
  }
1024
- return invokeAction(key, input, options);
209
+ token = data.token;
1025
210
  }
1026
- return invokeEndpoint(key, input ?? {});
1027
- };
1028
- const client = { request, cache };
1029
- const proxy = new Proxy(client, {
1030
- get(target, prop, receiver) {
1031
- if (prop in target || typeof prop !== "string") {
1032
- return Reflect.get(target, prop, receiver);
1033
- }
1034
- if (prop in apiConfig.endpoints) {
1035
- return (input) => invokeEndpoint(prop, input ?? {});
1036
- }
1037
- if (prop in actions) {
1038
- const action = actions[prop];
1039
- if (action.noRuntimeInput) {
1040
- return (first, second) => {
1041
- if (first === undefined || first === null) {
1042
- return invokeAction(prop, undefined, second ?? {});
1043
- }
1044
- if (second !== undefined) {
1045
- return invokeAction(prop, undefined, second);
1046
- }
1047
- if (isActionInvokeOptionsOnly(first)) {
1048
- return invokeAction(prop, undefined, first);
1049
- }
1050
- return invokeAction(prop, undefined, {});
1051
- };
1052
- }
1053
- return (input, opt) => invokeAction(prop, input, opt);
1054
- }
1055
- return;
1056
- }
1057
- });
1058
- const rawActions = apiConfig.actions;
1059
- if (typeof rawActions === "function") {
1060
- actions = rawActions({
1061
- api: proxy,
1062
- defineAction: makeDefineAction()
1063
- });
1064
- } else if (rawActions) {
1065
- actions = rawActions;
1066
- }
1067
- const collisions = Object.keys(actions).filter((key) => (key in apiConfig.endpoints));
1068
- if (collisions.length > 0) {
1069
- throw new ConfigError(`Action name(s) collide with endpoint name(s): ${collisions.join(", ")}`, {
1070
- endpoint: collisions[0],
1071
- method: "GET",
1072
- url: "",
1073
- attempt: 0,
1074
- maxRetries: 0,
1075
- elapsedMs: 0
1076
- });
211
+ signal.throwIfAborted();
212
+ operation = "listSecrets";
213
+ return await listInfisicalSecrets(infisical, token, options);
214
+ } catch (error) {
215
+ throwInfisicalHttpError(error, operation, signal);
1077
216
  }
1078
- return proxy;
1079
217
  }
1080
- var createApiClient = (apiConfig) => createApiClientImpl(apiConfig);
1081
- // src/secrets/infisical.ts
1082
- import { z } from "zod";
1083
- var DEFAULT_INFISICAL_SITE_URL = "https://eu.infisical.com";
1084
- var defaultFetch = globalThis.fetch;
1085
- var infisicalAuthResponseSchema = z.object({
1086
- accessToken: z.string()
1087
- });
1088
- var infisicalSecretSchema = z.object({
1089
- secretKey: z.string(),
1090
- secretValue: z.string()
1091
- });
1092
- var infisicalSecretsResponseSchema = z.object({
1093
- secrets: z.array(infisicalSecretSchema)
1094
- });
1095
- async function fetchInfisicalSecrets({
1096
- keys,
1097
- projectId,
1098
- environment,
1099
- siteUrl,
1100
- clientId,
1101
- clientSecret
1102
- }) {
1103
- const infisical = createInfisicalApiClient(siteUrl);
1104
- const { data: auth } = await infisical.request("login", {
1105
- reqBody: {
1106
- clientId,
1107
- clientSecret
1108
- }
1109
- });
218
+ async function listInfisicalSecrets(infisical, token, options) {
1110
219
  const { data } = await infisical.request("listSecrets", {
1111
- reqHeaders: {
1112
- Authorization: `Bearer ${auth.accessToken}`
1113
- },
220
+ signal: options.signal,
221
+ reqHeaders: { Authorization: `Bearer ${token}` },
1114
222
  reqQuery: {
1115
- environment,
1116
- projectId,
1117
- secretPath: "/",
223
+ environment: options.environment,
224
+ projectId: options.projectId,
225
+ secretPath: options.secretPath ?? "/",
1118
226
  viewSecretValue: true,
1119
227
  expandSecretReferences: true,
1120
228
  includeImports: true
1121
229
  }
1122
230
  });
1123
- const wantedKeys = new Set(keys);
231
+ const wantedKeys = new Set(options.keys);
1124
232
  return Object.fromEntries(data.secrets.filter((secret) => wantedKeys.has(secret.secretKey)).map((secret) => [secret.secretKey, secret.secretValue]));
1125
233
  }
1126
- async function loadInfisicalSecrets({
1127
- keys,
1128
- projectId,
1129
- environment,
1130
- siteUrl,
1131
- clientIdEnvKey,
1132
- clientSecretEnvKey
1133
- }) {
1134
- const clientId = process.env[clientIdEnvKey];
1135
- const clientSecret = process.env[clientSecretEnvKey];
1136
- if (!clientId || !clientSecret) {
1137
- throw new Error("Missing Infisical credentials");
234
+ function throwInfisicalHttpError(error, operation, signal) {
235
+ if (signal.aborted) {
236
+ throw signal.reason;
1138
237
  }
1139
- return fetchInfisicalSecrets({
1140
- keys,
1141
- projectId,
1142
- environment,
1143
- siteUrl,
1144
- clientId,
1145
- clientSecret
1146
- });
238
+ if (error instanceof SecretLoadError2) {
239
+ throw error;
240
+ }
241
+ const status = error instanceof HttpResponseError2 ? error.status : undefined;
242
+ const guidance = operation === "selectOrganization" && (status === 401 || status === 403) ? " Run infisical login for the target organization and configured domain, then verify your access." : "";
243
+ throw new SecretLoadError2("HTTP", `Infisical HTTP ${operation} failed${status ? ` (status ${status})` : ""}.${guidance}`, { operation, status });
1147
244
  }
1148
245
  function createInfisicalApiClient(siteUrl) {
1149
- return createApiClient({
246
+ return createApiClient2({
1150
247
  name: "infisical",
1151
248
  baseApiUrls: {
1152
249
  infisical: siteUrl
@@ -1155,12 +252,26 @@ function createInfisicalApiClient(siteUrl) {
1155
252
  fetch: getFetch(),
1156
253
  retries: 1,
1157
254
  endpoints: {
255
+ selectOrganization: {
256
+ method: "POST",
257
+ path: "/api/v3/auth/select-organization",
258
+ reqHeadersSchema: z2.object({
259
+ Authorization: z2.string(),
260
+ "User-Agent": z2.string()
261
+ }),
262
+ reqBodySchema: z2.object({ organizationId: z2.string() }),
263
+ resSchema: z2.object({
264
+ token: z2.string().min(1),
265
+ isMfaEnabled: z2.boolean().optional()
266
+ }),
267
+ reqBodyFormat: "json"
268
+ },
1158
269
  login: {
1159
270
  method: "POST",
1160
271
  path: "/api/v1/auth/universal-auth/login",
1161
- reqBodySchema: z.object({
1162
- clientId: z.string(),
1163
- clientSecret: z.string()
272
+ reqBodySchema: z2.object({
273
+ clientId: z2.string(),
274
+ clientSecret: z2.string()
1164
275
  }),
1165
276
  resSchema: infisicalAuthResponseSchema,
1166
277
  reqBodyFormat: "json"
@@ -1168,16 +279,16 @@ function createInfisicalApiClient(siteUrl) {
1168
279
  listSecrets: {
1169
280
  method: "GET",
1170
281
  path: "/api/v4/secrets",
1171
- reqHeadersSchema: z.object({
1172
- Authorization: z.string()
282
+ reqHeadersSchema: z2.object({
283
+ Authorization: z2.string()
1173
284
  }),
1174
- reqQuerySchema: z.object({
1175
- projectId: z.string(),
1176
- environment: z.string(),
1177
- secretPath: z.string(),
1178
- viewSecretValue: z.boolean(),
1179
- expandSecretReferences: z.boolean(),
1180
- includeImports: z.boolean()
285
+ reqQuerySchema: z2.object({
286
+ projectId: z2.string(),
287
+ environment: z2.string(),
288
+ secretPath: z2.string(),
289
+ viewSecretValue: z2.boolean(),
290
+ expandSecretReferences: z2.boolean(),
291
+ includeImports: z2.boolean()
1181
292
  }),
1182
293
  resSchema: infisicalSecretsResponseSchema
1183
294
  }
@@ -1185,297 +296,70 @@ function createInfisicalApiClient(siteUrl) {
1185
296
  });
1186
297
  }
1187
298
  function getFetch() {
1188
- return globalThis.fetch ?? defaultFetch;
1189
- }
1190
-
1191
- // src/secrets/loaders.ts
1192
- function cloudflareWorkerEnvLoader(workerEnv) {
1193
- return async (ctx) => {
1194
- const out = {};
1195
- for (const key of ctx.keys) {
1196
- const str = workerBindingToString(workerEnv[key]);
1197
- if (str !== undefined) {
1198
- out[key] = str;
1199
- }
1200
- }
1201
- return out;
299
+ const fetchFn = globalThis.fetch ?? defaultFetch;
300
+ return (input, init) => {
301
+ init?.signal?.throwIfAborted();
302
+ return fetchFn(input, init);
1202
303
  };
1203
304
  }
1204
- function workerBindingToString(value) {
1205
- if (value === undefined || value === null) {
1206
- return;
1207
- }
1208
- if (typeof value === "string") {
1209
- return value === "" ? undefined : value;
1210
- }
1211
- if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
1212
- return String(value);
1213
- }
1214
- if (typeof value === "object") {
1215
- return JSON.stringify(value);
1216
- }
1217
- return String(value);
1218
- }
305
+ // src/secrets/loaders.ts
1219
306
  function infisicalLoader(config) {
1220
- return async (ctx) => fetchInfisicalSecrets({
307
+ validateInfisicalOrganizationId(config.organizationId);
308
+ const loader = async (ctx) => fetchInfisicalSecrets({
1221
309
  keys: ctx.keys,
1222
310
  projectId: config.projectId,
311
+ organizationId: config.organizationId,
1223
312
  environment: ctx.environment,
1224
313
  siteUrl: config.siteUrl ?? DEFAULT_INFISICAL_SITE_URL,
1225
314
  clientId: config.clientId,
1226
- clientSecret: config.clientSecret
315
+ clientSecret: config.clientSecret,
316
+ secretPath: config.secretPath,
317
+ timeoutMs: config.timeoutMs ?? ctx.timeoutMs,
318
+ signal: ctx.signal
1227
319
  });
320
+ return Object.assign(loader, { source: "Infisical HTTP" });
1228
321
  }
1229
322
  async function processEnvLoader(_ctx) {
1230
323
  return {};
1231
324
  }
1232
-
1233
- // src/secrets/vite.ts
1234
- function getViteDefine(secretSet) {
1235
- return Object.fromEntries(Object.entries(secretSet.secrets()).map(([key, value]) => [
1236
- `import.meta.env.${key}`,
1237
- JSON.stringify(value)
1238
- ]));
1239
- }
1240
- function viteSecretSetPlugin(secretSet) {
1241
- return {
1242
- name: "hanzio-secret-set",
1243
- config: () => ({
1244
- define: getViteDefine(secretSet)
1245
- })
1246
- };
1247
- }
1248
-
1249
- // src/cool-console-log/index.ts
1250
- var terminalColors = {
1251
- reset: "\x1B[0m",
1252
- bold: "\x1B[1m",
1253
- dim: "\x1B[2m",
1254
- italic: "\x1B[3m",
1255
- underline: "\x1B[4m",
1256
- black: "\x1B[30m",
1257
- red: "\x1B[31m",
1258
- green: "\x1B[32m",
1259
- yellow: "\x1B[33m",
1260
- blue: "\x1B[34m",
1261
- magenta: "\x1B[35m",
1262
- cyan: "\x1B[36m",
1263
- white: "\x1B[37m",
1264
- gray: "\x1B[90m",
1265
- brightRed: "\x1B[91m",
1266
- brightGreen: "\x1B[92m",
1267
- brightYellow: "\x1B[93m",
1268
- brightBlue: "\x1B[94m",
1269
- brightMagenta: "\x1B[95m",
1270
- brightCyan: "\x1B[96m",
1271
- brightWhite: "\x1B[97m",
1272
- bgBlack: "\x1B[40m",
1273
- bgRed: "\x1B[41m",
1274
- bgGreen: "\x1B[42m",
1275
- bgYellow: "\x1B[43m",
1276
- bgBlue: "\x1B[44m",
1277
- bgMagenta: "\x1B[45m",
1278
- bgCyan: "\x1B[46m",
1279
- bgWhite: "\x1B[47m"
1280
- };
1281
- var levelColors = {
1282
- debug: { badge: terminalColors.gray, text: terminalColors.dim },
1283
- info: { badge: terminalColors.cyan, text: terminalColors.reset },
1284
- warn: { badge: terminalColors.yellow, text: terminalColors.yellow },
1285
- error: { badge: terminalColors.red, text: terminalColors.brightRed }
1286
- };
1287
- function formatAttributes(attrs) {
1288
- if (!attrs || Object.keys(attrs).length === 0)
1289
- return "";
1290
- const formatted = Object.entries(attrs).map(([k, v]) => `${terminalColors.dim}${k}=${terminalColors.reset}${v}`).join(" ");
1291
- return ` ${formatted}`;
1292
- }
1293
- function createCoolLogger(options = {}) {
1294
- const { colorsInDevOnly = true, onLog } = options;
1295
- const isDev = true;
1296
- const useColors = colorsInDevOnly ? isDev : true;
1297
- const createLogMethod = (level) => (message, attributes) => {
1298
- onLog?.(level, message, attributes);
1299
- if (level === "debug" && !isDev)
1300
- return;
1301
- if (useColors) {
1302
- const { badge, text } = levelColors[level];
1303
- const label = level.toUpperCase().padEnd(5);
1304
- const attrStr = formatAttributes(attributes);
1305
- console.log(`${badge}[${label}]${terminalColors.reset} ${text}${message}${terminalColors.reset}${attrStr}`);
1306
- } else {
1307
- console[level](`[${level.toUpperCase()}]`, message, attributes ?? "");
1308
- }
1309
- };
1310
- return {
1311
- debug: createLogMethod("debug"),
1312
- info: createLogMethod("info"),
1313
- warn: createLogMethod("warn"),
1314
- error: createLogMethod("error")
1315
- };
1316
- }
1317
- function logOperationSummary(operationName, durationMs, success, options = {}) {
1318
- const { devOnly = true, error } = options;
1319
- const isDev = true;
1320
- if (devOnly && !isDev)
1321
- return;
1322
- const c = terminalColors;
1323
- const statusIcon = success ? `${c.brightGreen}✓${c.reset}` : `${c.brightRed}✗${c.reset}`;
1324
- const statusColor = success ? c.green : c.red;
1325
- const durationStr = `${c.dim}${durationMs.toFixed(1)}ms${c.reset}`;
1326
- const errorMessage = error ? ` ${c.dim}·${c.reset} ${c.red}${error instanceof Error ? error.message : String(error)}${c.reset}` : "";
1327
- console.log(`${statusColor}${c.bold}${operationName}${c.reset} ${statusIcon} ${c.dim}·${c.reset} ${durationStr}${errorMessage}`);
1328
- }
1329
- function colorize(text, color, ...modifiers) {
1330
- const isDev = true;
1331
- if (!isDev)
1332
- return text;
1333
- const colorCodes = [
1334
- terminalColors[color],
1335
- ...modifiers.map((m) => terminalColors[m])
1336
- ].join("");
1337
- return `${colorCodes}${text}${terminalColors.reset}`;
1338
- }
1339
- function logBanner(text, color = "cyan", options = {}) {
1340
- const { devOnly = true } = options;
1341
- const isDev = true;
1342
- if (devOnly && !isDev) {
1343
- console.log(`=== ${text} ===`);
1344
- return;
1345
- }
1346
- const c = terminalColors;
1347
- const padding = 2;
1348
- const line = "═".repeat(text.length + padding * 2);
1349
- console.log(`${c[color]}╔${line}╗${c.reset}`);
1350
- console.log(`${c[color]}║${" ".repeat(padding)}${c.bold}${text}${c.reset}${c[color]}${" ".repeat(padding)}║${c.reset}`);
1351
- console.log(`${c[color]}╚${line}╝${c.reset}`);
1352
- }
325
+ Object.assign(processEnvLoader, { source: "process.env" });
1353
326
 
1354
327
  // src/secrets/index.ts
1355
- var logger = createCoolLogger();
1356
328
  function getSecretEnvironment() {
1357
- const env = process.env.SECRETS_ENV || "development";
1358
- if (env === "production" || env === "prod")
1359
- return "prod";
1360
- if (env === "staging")
1361
- return "staging";
1362
- return "dev";
329
+ return resolveSecretEnvironment(undefined, getProcessEnvironment());
1363
330
  }
1364
331
  async function defineSecretSet(keys, options) {
1365
- const keySet = [...new Set(keys)];
1366
- const resolvedOptions = resolveSecretSetOptions(options);
1367
- let cachedSecrets = null;
1368
- const loadSecrets = async (force = false) => {
1369
- const nextSecrets = await loadAndMergeSecrets({
1370
- keySet,
1371
- cachedSecrets,
1372
- force,
1373
- ...resolvedOptions
1374
- });
1375
- cachedSecrets = nextSecrets;
1376
- return nextSecrets;
1377
- };
1378
- const secretSet = createSecretSet({
1379
- getCachedSecrets: () => cachedSecrets,
1380
- reload: loadSecrets
1381
- });
1382
- await loadSecrets();
1383
- return secretSet;
332
+ let loader;
333
+ if (!options.loader) {
334
+ validateInfisicalOrganizationId(options.organizationId);
335
+ loader = createDefaultInfisicalLoader(options);
336
+ } else {
337
+ loader = options.loader;
338
+ }
339
+ return defineSecretSet2(keys, { ...options, loader }, getProcessEnvironment());
1384
340
  }
1385
- function resolveSecretSetOptions(options) {
1386
- const environment = resolveEnvironment(options.environment);
1387
- const loader = options.loader ? options.loader : (context) => loadInfisicalSecrets({
341
+ function createDefaultInfisicalLoader(options) {
342
+ return (context) => loadInfisicalSecrets({
1388
343
  ...context,
1389
344
  projectId: options.projectId,
345
+ organizationId: options.organizationId,
1390
346
  siteUrl: options.siteUrl ?? DEFAULT_INFISICAL_SITE_URL,
347
+ secretPath: options.secretPath,
348
+ auth: options.auth,
1391
349
  clientIdEnvKey: options.clientIdEnvKey ?? "INFISICAL_CLIENT_ID",
1392
350
  clientSecretEnvKey: options.clientSecretEnvKey ?? "INFISICAL_CLIENT_SECRET"
1393
351
  });
1394
- return {
1395
- loader,
1396
- environment
1397
- };
1398
- }
1399
- async function loadAndMergeSecrets({
1400
- keySet,
1401
- cachedSecrets,
1402
- loader,
1403
- environment,
1404
- force
1405
- }) {
1406
- const processEnvSecrets = readProcessEnvSecrets(keySet, force ? cachedSecrets : null);
1407
- const keysMissingFromEnv = keySet.filter((key) => !processEnvSecrets[key]);
1408
- logSecretEnvironment(environment, keySet.length);
1409
- const loaderKeys = force ? keySet : keysMissingFromEnv;
1410
- const loadedSecrets = loaderKeys.length === 0 ? {} : await loader({
1411
- keys: loaderKeys,
1412
- environment
1413
- });
1414
- const missingKeys = keySet.filter((key) => !(processEnvSecrets[key] ?? loadedSecrets[key]));
1415
- if (missingKeys.length > 0) {
1416
- throw new Error(`Missing secrets: ${missingKeys.join(", ")}`);
1417
- }
1418
- const nextSecrets = Object.fromEntries(keySet.map((key) => [
1419
- key,
1420
- processEnvSecrets[key] ?? loadedSecrets[key]
1421
- ]));
1422
- for (const [key, value] of Object.entries(nextSecrets)) {
1423
- process.env[key] = value;
1424
- }
1425
- return nextSecrets;
1426
- }
1427
- function createSecretSet({
1428
- getCachedSecrets,
1429
- reload
1430
- }) {
1431
- const secretSet = {
1432
- secret(key) {
1433
- const value = getCachedSecrets()?.[key] ?? process.env[key];
1434
- if (!value) {
1435
- throw new Error(`Secret ${key} not found`);
1436
- }
1437
- return value;
1438
- },
1439
- secrets() {
1440
- const cachedSecrets = getCachedSecrets();
1441
- if (!cachedSecrets) {
1442
- throw new Error("Secrets not initialized.");
1443
- }
1444
- return { ...cachedSecrets };
1445
- },
1446
- async reload() {
1447
- await reload(true);
1448
- return secretSet;
1449
- }
1450
- };
1451
- return secretSet;
1452
- }
1453
- function resolveEnvironment(environment) {
1454
- if (typeof environment === "function")
1455
- return environment();
1456
- return environment ?? getSecretEnvironment();
1457
- }
1458
- function logSecretEnvironment(environment, secretCount) {
1459
- logger.info(colorize("Loading secrets", "cyan", "bold"), {
1460
- environment: colorize(environment, "brightCyan", "bold"),
1461
- count: secretCount
1462
- });
1463
- }
1464
- function readProcessEnvSecrets(keys, previousSecrets = null) {
1465
- return Object.fromEntries(keys.filter((key) => {
1466
- const value = process.env[key];
1467
- return value && value !== previousSecrets?.[key];
1468
- }).map((key) => [key, process.env[key]]));
1469
352
  }
1470
353
  export {
1471
- viteSecretSetPlugin,
1472
- processEnvLoader,
1473
- loadInfisicalSecrets,
1474
- infisicalLoader,
1475
- getViteDefine,
1476
- getSecretEnvironment,
1477
- fetchInfisicalSecrets,
354
+ DEFAULT_INFISICAL_SITE_URL,
355
+ SecretLoadError2 as SecretLoadError,
356
+ cloudflareWorkerEnvLoader2 as cloudflareWorkerEnvLoader,
1478
357
  defineSecretSet,
1479
- cloudflareWorkerEnvLoader,
1480
- DEFAULT_INFISICAL_SITE_URL
358
+ fetchInfisicalSecrets,
359
+ getSecretEnvironment,
360
+ getViteDefine2 as getViteDefine,
361
+ infisicalLoader,
362
+ loadInfisicalSecrets,
363
+ processEnvLoader,
364
+ viteSecretSetPlugin2 as viteSecretSetPlugin
1481
365
  };