@varlock/hashicorp-vault-plugin 0.0.0 → 0.0.2
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/README.md +341 -0
- package/dist/plugin.cjs +1267 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +2 -0
- package/package.json +50 -6
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,1267 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var promises = require('fs/promises');
|
|
4
|
+
var os = require('os');
|
|
5
|
+
var path = require('path');
|
|
6
|
+
|
|
7
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/errors/HTTPError.js
|
|
8
|
+
var HTTPError = class extends Error {
|
|
9
|
+
response;
|
|
10
|
+
request;
|
|
11
|
+
options;
|
|
12
|
+
constructor(response, request, options) {
|
|
13
|
+
const code = response.status || response.status === 0 ? response.status : "";
|
|
14
|
+
const title = response.statusText ?? "";
|
|
15
|
+
const status = `${code} ${title}`.trim();
|
|
16
|
+
const reason = status ? `status code ${status}` : "an unknown error";
|
|
17
|
+
super(`Request failed with ${reason}: ${request.method} ${request.url}`);
|
|
18
|
+
this.name = "HTTPError";
|
|
19
|
+
this.response = response;
|
|
20
|
+
this.request = request;
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/errors/NonError.js
|
|
26
|
+
var NonError = class extends Error {
|
|
27
|
+
name = "NonError";
|
|
28
|
+
value;
|
|
29
|
+
constructor(value) {
|
|
30
|
+
let message = "Non-error value was thrown";
|
|
31
|
+
try {
|
|
32
|
+
if (typeof value === "string") {
|
|
33
|
+
message = value;
|
|
34
|
+
} else if (value && typeof value === "object" && "message" in value && typeof value.message === "string") {
|
|
35
|
+
message = value.message;
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
super(message);
|
|
40
|
+
this.value = value;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/errors/ForceRetryError.js
|
|
45
|
+
var ForceRetryError = class extends Error {
|
|
46
|
+
name = "ForceRetryError";
|
|
47
|
+
customDelay;
|
|
48
|
+
code;
|
|
49
|
+
customRequest;
|
|
50
|
+
constructor(options) {
|
|
51
|
+
const cause = options?.cause ? options.cause instanceof Error ? options.cause : new NonError(options.cause) : void 0;
|
|
52
|
+
super(options?.code ? `Forced retry: ${options.code}` : "Forced retry", cause ? { cause } : void 0);
|
|
53
|
+
this.customDelay = options?.delay;
|
|
54
|
+
this.code = options?.code;
|
|
55
|
+
this.customRequest = options?.request;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/core/constants.js
|
|
60
|
+
var supportsRequestStreams = (() => {
|
|
61
|
+
let duplexAccessed = false;
|
|
62
|
+
let hasContentType = false;
|
|
63
|
+
const supportsReadableStream = typeof globalThis.ReadableStream === "function";
|
|
64
|
+
const supportsRequest = typeof globalThis.Request === "function";
|
|
65
|
+
if (supportsReadableStream && supportsRequest) {
|
|
66
|
+
try {
|
|
67
|
+
hasContentType = new globalThis.Request("https://empty.invalid", {
|
|
68
|
+
body: new globalThis.ReadableStream(),
|
|
69
|
+
method: "POST",
|
|
70
|
+
// @ts-expect-error - Types are outdated.
|
|
71
|
+
get duplex() {
|
|
72
|
+
duplexAccessed = true;
|
|
73
|
+
return "half";
|
|
74
|
+
}
|
|
75
|
+
}).headers.has("Content-Type");
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error instanceof Error && error.message === "unsupported BodyInit type") {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return duplexAccessed && !hasContentType;
|
|
84
|
+
})();
|
|
85
|
+
var supportsAbortController = typeof globalThis.AbortController === "function";
|
|
86
|
+
var supportsAbortSignal = typeof globalThis.AbortSignal === "function" && typeof globalThis.AbortSignal.any === "function";
|
|
87
|
+
var supportsResponseStreams = typeof globalThis.ReadableStream === "function";
|
|
88
|
+
var supportsFormData = typeof globalThis.FormData === "function";
|
|
89
|
+
var requestMethods = ["get", "post", "put", "patch", "head", "delete"];
|
|
90
|
+
var responseTypes = {
|
|
91
|
+
json: "application/json",
|
|
92
|
+
text: "text/*",
|
|
93
|
+
formData: "multipart/form-data",
|
|
94
|
+
arrayBuffer: "*/*",
|
|
95
|
+
blob: "*/*",
|
|
96
|
+
// Supported in modern Fetch implementations (for example, browsers and recent Node.js/undici).
|
|
97
|
+
// We still feature-check at runtime before exposing the shortcut.
|
|
98
|
+
bytes: "*/*"
|
|
99
|
+
};
|
|
100
|
+
var maxSafeTimeout = 2147483647;
|
|
101
|
+
var usualFormBoundarySize = new TextEncoder().encode("------WebKitFormBoundaryaxpyiPgbbPti10Rw").length;
|
|
102
|
+
var stop = /* @__PURE__ */ Symbol("stop");
|
|
103
|
+
var RetryMarker = class {
|
|
104
|
+
options;
|
|
105
|
+
constructor(options) {
|
|
106
|
+
this.options = options;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var retry = (options) => new RetryMarker(options);
|
|
110
|
+
var kyOptionKeys = {
|
|
111
|
+
json: true,
|
|
112
|
+
parseJson: true,
|
|
113
|
+
stringifyJson: true,
|
|
114
|
+
searchParams: true,
|
|
115
|
+
prefixUrl: true,
|
|
116
|
+
retry: true,
|
|
117
|
+
timeout: true,
|
|
118
|
+
hooks: true,
|
|
119
|
+
throwHttpErrors: true,
|
|
120
|
+
onDownloadProgress: true,
|
|
121
|
+
onUploadProgress: true,
|
|
122
|
+
fetch: true,
|
|
123
|
+
context: true
|
|
124
|
+
};
|
|
125
|
+
var vendorSpecificOptions = {
|
|
126
|
+
next: true
|
|
127
|
+
// Next.js cache revalidation (revalidate, tags)
|
|
128
|
+
};
|
|
129
|
+
var requestOptionsRegistry = {
|
|
130
|
+
method: true,
|
|
131
|
+
headers: true,
|
|
132
|
+
body: true,
|
|
133
|
+
mode: true,
|
|
134
|
+
credentials: true,
|
|
135
|
+
cache: true,
|
|
136
|
+
redirect: true,
|
|
137
|
+
referrer: true,
|
|
138
|
+
referrerPolicy: true,
|
|
139
|
+
integrity: true,
|
|
140
|
+
keepalive: true,
|
|
141
|
+
signal: true,
|
|
142
|
+
window: true,
|
|
143
|
+
duplex: true
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/body.js
|
|
147
|
+
var getBodySize = (body) => {
|
|
148
|
+
if (!body) {
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
if (body instanceof FormData) {
|
|
152
|
+
let size = 0;
|
|
153
|
+
for (const [key, value] of body) {
|
|
154
|
+
size += usualFormBoundarySize;
|
|
155
|
+
size += new TextEncoder().encode(`Content-Disposition: form-data; name="${key}"`).length;
|
|
156
|
+
size += typeof value === "string" ? new TextEncoder().encode(value).length : value.size;
|
|
157
|
+
}
|
|
158
|
+
return size;
|
|
159
|
+
}
|
|
160
|
+
if (body instanceof Blob) {
|
|
161
|
+
return body.size;
|
|
162
|
+
}
|
|
163
|
+
if (body instanceof ArrayBuffer) {
|
|
164
|
+
return body.byteLength;
|
|
165
|
+
}
|
|
166
|
+
if (typeof body === "string") {
|
|
167
|
+
return new TextEncoder().encode(body).length;
|
|
168
|
+
}
|
|
169
|
+
if (body instanceof URLSearchParams) {
|
|
170
|
+
return new TextEncoder().encode(body.toString()).length;
|
|
171
|
+
}
|
|
172
|
+
if ("byteLength" in body) {
|
|
173
|
+
return body.byteLength;
|
|
174
|
+
}
|
|
175
|
+
if (typeof body === "object" && body !== null) {
|
|
176
|
+
try {
|
|
177
|
+
const jsonString = JSON.stringify(body);
|
|
178
|
+
return new TextEncoder().encode(jsonString).length;
|
|
179
|
+
} catch {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return 0;
|
|
184
|
+
};
|
|
185
|
+
var withProgress = (stream, totalBytes, onProgress) => {
|
|
186
|
+
let previousChunk;
|
|
187
|
+
let transferredBytes = 0;
|
|
188
|
+
return stream.pipeThrough(new TransformStream({
|
|
189
|
+
transform(currentChunk, controller) {
|
|
190
|
+
controller.enqueue(currentChunk);
|
|
191
|
+
if (previousChunk) {
|
|
192
|
+
transferredBytes += previousChunk.byteLength;
|
|
193
|
+
let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
|
|
194
|
+
if (percent >= 1) {
|
|
195
|
+
percent = 1 - Number.EPSILON;
|
|
196
|
+
}
|
|
197
|
+
onProgress?.({ percent, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);
|
|
198
|
+
}
|
|
199
|
+
previousChunk = currentChunk;
|
|
200
|
+
},
|
|
201
|
+
flush() {
|
|
202
|
+
if (previousChunk) {
|
|
203
|
+
transferredBytes += previousChunk.byteLength;
|
|
204
|
+
onProgress?.({ percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes }, previousChunk);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}));
|
|
208
|
+
};
|
|
209
|
+
var streamResponse = (response, onDownloadProgress) => {
|
|
210
|
+
if (!response.body) {
|
|
211
|
+
return response;
|
|
212
|
+
}
|
|
213
|
+
if (response.status === 204) {
|
|
214
|
+
return new Response(null, {
|
|
215
|
+
status: response.status,
|
|
216
|
+
statusText: response.statusText,
|
|
217
|
+
headers: response.headers
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
const totalBytes = Math.max(0, Number(response.headers.get("content-length")) || 0);
|
|
221
|
+
return new Response(withProgress(response.body, totalBytes, onDownloadProgress), {
|
|
222
|
+
status: response.status,
|
|
223
|
+
statusText: response.statusText,
|
|
224
|
+
headers: response.headers
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
var streamRequest = (request, onUploadProgress, originalBody) => {
|
|
228
|
+
if (!request.body) {
|
|
229
|
+
return request;
|
|
230
|
+
}
|
|
231
|
+
const totalBytes = getBodySize(originalBody ?? request.body);
|
|
232
|
+
return new Request(request, {
|
|
233
|
+
// @ts-expect-error - Types are outdated.
|
|
234
|
+
duplex: "half",
|
|
235
|
+
body: withProgress(request.body, totalBytes, onUploadProgress)
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/is.js
|
|
240
|
+
var isObject = (value) => value !== null && typeof value === "object";
|
|
241
|
+
|
|
242
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/merge.js
|
|
243
|
+
var validateAndMerge = (...sources) => {
|
|
244
|
+
for (const source of sources) {
|
|
245
|
+
if ((!isObject(source) || Array.isArray(source)) && source !== void 0) {
|
|
246
|
+
throw new TypeError("The `options` argument must be an object");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return deepMerge({}, ...sources);
|
|
250
|
+
};
|
|
251
|
+
var mergeHeaders = (source1 = {}, source2 = {}) => {
|
|
252
|
+
const result = new globalThis.Headers(source1);
|
|
253
|
+
const isHeadersInstance = source2 instanceof globalThis.Headers;
|
|
254
|
+
const source = new globalThis.Headers(source2);
|
|
255
|
+
for (const [key, value] of source.entries()) {
|
|
256
|
+
if (isHeadersInstance && value === "undefined" || value === void 0) {
|
|
257
|
+
result.delete(key);
|
|
258
|
+
} else {
|
|
259
|
+
result.set(key, value);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return result;
|
|
263
|
+
};
|
|
264
|
+
function newHookValue(original, incoming, property) {
|
|
265
|
+
return Object.hasOwn(incoming, property) && incoming[property] === void 0 ? [] : deepMerge(original[property] ?? [], incoming[property] ?? []);
|
|
266
|
+
}
|
|
267
|
+
var mergeHooks = (original = {}, incoming = {}) => ({
|
|
268
|
+
beforeRequest: newHookValue(original, incoming, "beforeRequest"),
|
|
269
|
+
beforeRetry: newHookValue(original, incoming, "beforeRetry"),
|
|
270
|
+
afterResponse: newHookValue(original, incoming, "afterResponse"),
|
|
271
|
+
beforeError: newHookValue(original, incoming, "beforeError")
|
|
272
|
+
});
|
|
273
|
+
var appendSearchParameters = (target, source) => {
|
|
274
|
+
const result = new URLSearchParams();
|
|
275
|
+
for (const input of [target, source]) {
|
|
276
|
+
if (input === void 0) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (input instanceof URLSearchParams) {
|
|
280
|
+
for (const [key, value] of input.entries()) {
|
|
281
|
+
result.append(key, value);
|
|
282
|
+
}
|
|
283
|
+
} else if (Array.isArray(input)) {
|
|
284
|
+
for (const pair of input) {
|
|
285
|
+
if (!Array.isArray(pair) || pair.length !== 2) {
|
|
286
|
+
throw new TypeError("Array search parameters must be provided in [[key, value], ...] format");
|
|
287
|
+
}
|
|
288
|
+
result.append(String(pair[0]), String(pair[1]));
|
|
289
|
+
}
|
|
290
|
+
} else if (isObject(input)) {
|
|
291
|
+
for (const [key, value] of Object.entries(input)) {
|
|
292
|
+
if (value !== void 0) {
|
|
293
|
+
result.append(key, String(value));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
const parameters = new URLSearchParams(input);
|
|
298
|
+
for (const [key, value] of parameters.entries()) {
|
|
299
|
+
result.append(key, value);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
304
|
+
};
|
|
305
|
+
var deepMerge = (...sources) => {
|
|
306
|
+
let returnValue = {};
|
|
307
|
+
let headers = {};
|
|
308
|
+
let hooks = {};
|
|
309
|
+
let searchParameters;
|
|
310
|
+
const signals = [];
|
|
311
|
+
for (const source of sources) {
|
|
312
|
+
if (Array.isArray(source)) {
|
|
313
|
+
if (!Array.isArray(returnValue)) {
|
|
314
|
+
returnValue = [];
|
|
315
|
+
}
|
|
316
|
+
returnValue = [...returnValue, ...source];
|
|
317
|
+
} else if (isObject(source)) {
|
|
318
|
+
for (let [key, value] of Object.entries(source)) {
|
|
319
|
+
if (key === "signal" && value instanceof globalThis.AbortSignal) {
|
|
320
|
+
signals.push(value);
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
if (key === "context") {
|
|
324
|
+
if (value !== void 0 && value !== null && (!isObject(value) || Array.isArray(value))) {
|
|
325
|
+
throw new TypeError("The `context` option must be an object");
|
|
326
|
+
}
|
|
327
|
+
returnValue = {
|
|
328
|
+
...returnValue,
|
|
329
|
+
context: value === void 0 || value === null ? {} : { ...returnValue.context, ...value }
|
|
330
|
+
};
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
if (key === "searchParams") {
|
|
334
|
+
if (value === void 0 || value === null) {
|
|
335
|
+
searchParameters = void 0;
|
|
336
|
+
} else {
|
|
337
|
+
searchParameters = searchParameters === void 0 ? value : appendSearchParameters(searchParameters, value);
|
|
338
|
+
}
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (isObject(value) && key in returnValue) {
|
|
342
|
+
value = deepMerge(returnValue[key], value);
|
|
343
|
+
}
|
|
344
|
+
returnValue = { ...returnValue, [key]: value };
|
|
345
|
+
}
|
|
346
|
+
if (isObject(source.hooks)) {
|
|
347
|
+
hooks = mergeHooks(hooks, source.hooks);
|
|
348
|
+
returnValue.hooks = hooks;
|
|
349
|
+
}
|
|
350
|
+
if (isObject(source.headers)) {
|
|
351
|
+
headers = mergeHeaders(headers, source.headers);
|
|
352
|
+
returnValue.headers = headers;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (searchParameters !== void 0) {
|
|
357
|
+
returnValue.searchParams = searchParameters;
|
|
358
|
+
}
|
|
359
|
+
if (signals.length > 0) {
|
|
360
|
+
if (signals.length === 1) {
|
|
361
|
+
returnValue.signal = signals[0];
|
|
362
|
+
} else if (supportsAbortSignal) {
|
|
363
|
+
returnValue.signal = AbortSignal.any(signals);
|
|
364
|
+
} else {
|
|
365
|
+
returnValue.signal = signals.at(-1);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return returnValue;
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/normalize.js
|
|
372
|
+
var normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
|
|
373
|
+
var retryMethods = ["get", "put", "head", "delete", "options", "trace"];
|
|
374
|
+
var retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];
|
|
375
|
+
var retryAfterStatusCodes = [413, 429, 503];
|
|
376
|
+
var defaultRetryOptions = {
|
|
377
|
+
limit: 2,
|
|
378
|
+
methods: retryMethods,
|
|
379
|
+
statusCodes: retryStatusCodes,
|
|
380
|
+
afterStatusCodes: retryAfterStatusCodes,
|
|
381
|
+
maxRetryAfter: Number.POSITIVE_INFINITY,
|
|
382
|
+
backoffLimit: Number.POSITIVE_INFINITY,
|
|
383
|
+
delay: (attemptCount) => 0.3 * 2 ** (attemptCount - 1) * 1e3,
|
|
384
|
+
jitter: void 0,
|
|
385
|
+
retryOnTimeout: false
|
|
386
|
+
};
|
|
387
|
+
var normalizeRetryOptions = (retry2 = {}) => {
|
|
388
|
+
if (typeof retry2 === "number") {
|
|
389
|
+
return {
|
|
390
|
+
...defaultRetryOptions,
|
|
391
|
+
limit: retry2
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
if (retry2.methods && !Array.isArray(retry2.methods)) {
|
|
395
|
+
throw new Error("retry.methods must be an array");
|
|
396
|
+
}
|
|
397
|
+
retry2.methods &&= retry2.methods.map((method) => method.toLowerCase());
|
|
398
|
+
if (retry2.statusCodes && !Array.isArray(retry2.statusCodes)) {
|
|
399
|
+
throw new Error("retry.statusCodes must be an array");
|
|
400
|
+
}
|
|
401
|
+
const normalizedRetry = Object.fromEntries(Object.entries(retry2).filter(([, value]) => value !== void 0));
|
|
402
|
+
return {
|
|
403
|
+
...defaultRetryOptions,
|
|
404
|
+
...normalizedRetry
|
|
405
|
+
};
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/errors/TimeoutError.js
|
|
409
|
+
var TimeoutError = class extends Error {
|
|
410
|
+
request;
|
|
411
|
+
constructor(request) {
|
|
412
|
+
super(`Request timed out: ${request.method} ${request.url}`);
|
|
413
|
+
this.name = "TimeoutError";
|
|
414
|
+
this.request = request;
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
|
|
419
|
+
async function timeout(request, init, abortController, options) {
|
|
420
|
+
return new Promise((resolve, reject) => {
|
|
421
|
+
const timeoutId = setTimeout(() => {
|
|
422
|
+
if (abortController) {
|
|
423
|
+
abortController.abort();
|
|
424
|
+
}
|
|
425
|
+
reject(new TimeoutError(request));
|
|
426
|
+
}, options.timeout);
|
|
427
|
+
void options.fetch(request, init).then(resolve).catch(reject).then(() => {
|
|
428
|
+
clearTimeout(timeoutId);
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
|
|
434
|
+
async function delay(ms, { signal }) {
|
|
435
|
+
return new Promise((resolve, reject) => {
|
|
436
|
+
if (signal) {
|
|
437
|
+
signal.throwIfAborted();
|
|
438
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
439
|
+
}
|
|
440
|
+
function abortHandler() {
|
|
441
|
+
clearTimeout(timeoutId);
|
|
442
|
+
reject(signal.reason);
|
|
443
|
+
}
|
|
444
|
+
const timeoutId = setTimeout(() => {
|
|
445
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
446
|
+
resolve();
|
|
447
|
+
}, ms);
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/options.js
|
|
452
|
+
var findUnknownOptions = (request, options) => {
|
|
453
|
+
const unknownOptions = {};
|
|
454
|
+
for (const key in options) {
|
|
455
|
+
if (!Object.hasOwn(options, key)) {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && (!(key in request) || key in vendorSpecificOptions)) {
|
|
459
|
+
unknownOptions[key] = options[key];
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return unknownOptions;
|
|
463
|
+
};
|
|
464
|
+
var hasSearchParameters = (search) => {
|
|
465
|
+
if (search === void 0) {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
if (Array.isArray(search)) {
|
|
469
|
+
return search.length > 0;
|
|
470
|
+
}
|
|
471
|
+
if (search instanceof URLSearchParams) {
|
|
472
|
+
return search.size > 0;
|
|
473
|
+
}
|
|
474
|
+
if (typeof search === "object") {
|
|
475
|
+
return Object.keys(search).length > 0;
|
|
476
|
+
}
|
|
477
|
+
if (typeof search === "string") {
|
|
478
|
+
return search.trim().length > 0;
|
|
479
|
+
}
|
|
480
|
+
return Boolean(search);
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/utils/type-guards.js
|
|
484
|
+
function isHTTPError(error) {
|
|
485
|
+
return error instanceof HTTPError || error?.name === HTTPError.name;
|
|
486
|
+
}
|
|
487
|
+
function isTimeoutError(error) {
|
|
488
|
+
return error instanceof TimeoutError || error?.name === TimeoutError.name;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/core/Ky.js
|
|
492
|
+
var Ky = class _Ky {
|
|
493
|
+
static create(input, options) {
|
|
494
|
+
const ky2 = new _Ky(input, options);
|
|
495
|
+
const function_ = async () => {
|
|
496
|
+
if (typeof ky2.#options.timeout === "number" && ky2.#options.timeout > maxSafeTimeout) {
|
|
497
|
+
throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
|
|
498
|
+
}
|
|
499
|
+
await Promise.resolve();
|
|
500
|
+
let response = await ky2.#fetch();
|
|
501
|
+
for (const hook of ky2.#options.hooks.afterResponse) {
|
|
502
|
+
const clonedResponse = ky2.#decorateResponse(response.clone());
|
|
503
|
+
let modifiedResponse;
|
|
504
|
+
try {
|
|
505
|
+
modifiedResponse = await hook(ky2.request, ky2.#getNormalizedOptions(), clonedResponse, { retryCount: ky2.#retryCount });
|
|
506
|
+
} catch (error) {
|
|
507
|
+
ky2.#cancelResponseBody(clonedResponse);
|
|
508
|
+
ky2.#cancelResponseBody(response);
|
|
509
|
+
throw error;
|
|
510
|
+
}
|
|
511
|
+
if (modifiedResponse instanceof RetryMarker) {
|
|
512
|
+
ky2.#cancelResponseBody(clonedResponse);
|
|
513
|
+
ky2.#cancelResponseBody(response);
|
|
514
|
+
throw new ForceRetryError(modifiedResponse.options);
|
|
515
|
+
}
|
|
516
|
+
const nextResponse = modifiedResponse instanceof globalThis.Response ? modifiedResponse : response;
|
|
517
|
+
if (clonedResponse !== nextResponse) {
|
|
518
|
+
ky2.#cancelResponseBody(clonedResponse);
|
|
519
|
+
}
|
|
520
|
+
if (response !== nextResponse) {
|
|
521
|
+
ky2.#cancelResponseBody(response);
|
|
522
|
+
}
|
|
523
|
+
response = nextResponse;
|
|
524
|
+
}
|
|
525
|
+
ky2.#decorateResponse(response);
|
|
526
|
+
if (!response.ok && (typeof ky2.#options.throwHttpErrors === "function" ? ky2.#options.throwHttpErrors(response.status) : ky2.#options.throwHttpErrors)) {
|
|
527
|
+
let error = new HTTPError(response, ky2.request, ky2.#getNormalizedOptions());
|
|
528
|
+
for (const hook of ky2.#options.hooks.beforeError) {
|
|
529
|
+
error = await hook(error, { retryCount: ky2.#retryCount });
|
|
530
|
+
}
|
|
531
|
+
throw error;
|
|
532
|
+
}
|
|
533
|
+
if (ky2.#options.onDownloadProgress) {
|
|
534
|
+
if (typeof ky2.#options.onDownloadProgress !== "function") {
|
|
535
|
+
throw new TypeError("The `onDownloadProgress` option must be a function");
|
|
536
|
+
}
|
|
537
|
+
if (!supportsResponseStreams) {
|
|
538
|
+
throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");
|
|
539
|
+
}
|
|
540
|
+
const progressResponse = response.clone();
|
|
541
|
+
ky2.#cancelResponseBody(response);
|
|
542
|
+
return streamResponse(progressResponse, ky2.#options.onDownloadProgress);
|
|
543
|
+
}
|
|
544
|
+
return response;
|
|
545
|
+
};
|
|
546
|
+
const result = ky2.#retry(function_).finally(() => {
|
|
547
|
+
const originalRequest = ky2.#originalRequest;
|
|
548
|
+
ky2.#cancelBody(originalRequest?.body ?? void 0);
|
|
549
|
+
ky2.#cancelBody(ky2.request.body ?? void 0);
|
|
550
|
+
});
|
|
551
|
+
for (const [type, mimeType] of Object.entries(responseTypes)) {
|
|
552
|
+
if (type === "bytes" && typeof globalThis.Response?.prototype?.bytes !== "function") {
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
result[type] = async () => {
|
|
556
|
+
ky2.request.headers.set("accept", ky2.request.headers.get("accept") || mimeType);
|
|
557
|
+
const response = await result;
|
|
558
|
+
if (type === "json") {
|
|
559
|
+
if (response.status === 204) {
|
|
560
|
+
return "";
|
|
561
|
+
}
|
|
562
|
+
const text = await response.text();
|
|
563
|
+
if (text === "") {
|
|
564
|
+
return "";
|
|
565
|
+
}
|
|
566
|
+
if (options.parseJson) {
|
|
567
|
+
return options.parseJson(text);
|
|
568
|
+
}
|
|
569
|
+
return JSON.parse(text);
|
|
570
|
+
}
|
|
571
|
+
return response[type]();
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
return result;
|
|
575
|
+
}
|
|
576
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
577
|
+
static #normalizeSearchParams(searchParams) {
|
|
578
|
+
if (searchParams && typeof searchParams === "object" && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) {
|
|
579
|
+
return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => value !== void 0));
|
|
580
|
+
}
|
|
581
|
+
return searchParams;
|
|
582
|
+
}
|
|
583
|
+
request;
|
|
584
|
+
#abortController;
|
|
585
|
+
#retryCount = 0;
|
|
586
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly -- False positive: #input is reassigned on line 202
|
|
587
|
+
#input;
|
|
588
|
+
#options;
|
|
589
|
+
#originalRequest;
|
|
590
|
+
#userProvidedAbortSignal;
|
|
591
|
+
#cachedNormalizedOptions;
|
|
592
|
+
// eslint-disable-next-line complexity
|
|
593
|
+
constructor(input, options = {}) {
|
|
594
|
+
this.#input = input;
|
|
595
|
+
this.#options = {
|
|
596
|
+
...options,
|
|
597
|
+
headers: mergeHeaders(this.#input.headers, options.headers),
|
|
598
|
+
hooks: mergeHooks({
|
|
599
|
+
beforeRequest: [],
|
|
600
|
+
beforeRetry: [],
|
|
601
|
+
beforeError: [],
|
|
602
|
+
afterResponse: []
|
|
603
|
+
}, options.hooks),
|
|
604
|
+
method: normalizeRequestMethod(options.method ?? this.#input.method ?? "GET"),
|
|
605
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
606
|
+
prefixUrl: String(options.prefixUrl || ""),
|
|
607
|
+
retry: normalizeRetryOptions(options.retry),
|
|
608
|
+
throwHttpErrors: options.throwHttpErrors ?? true,
|
|
609
|
+
timeout: options.timeout ?? 1e4,
|
|
610
|
+
fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
|
|
611
|
+
context: options.context ?? {}
|
|
612
|
+
};
|
|
613
|
+
if (typeof this.#input !== "string" && !(this.#input instanceof URL || this.#input instanceof globalThis.Request)) {
|
|
614
|
+
throw new TypeError("`input` must be a string, URL, or Request");
|
|
615
|
+
}
|
|
616
|
+
if (this.#options.prefixUrl && typeof this.#input === "string") {
|
|
617
|
+
if (this.#input.startsWith("/")) {
|
|
618
|
+
throw new Error("`input` must not begin with a slash when using `prefixUrl`");
|
|
619
|
+
}
|
|
620
|
+
if (!this.#options.prefixUrl.endsWith("/")) {
|
|
621
|
+
this.#options.prefixUrl += "/";
|
|
622
|
+
}
|
|
623
|
+
this.#input = this.#options.prefixUrl + this.#input;
|
|
624
|
+
}
|
|
625
|
+
if (supportsAbortController && supportsAbortSignal) {
|
|
626
|
+
this.#userProvidedAbortSignal = this.#options.signal ?? this.#input.signal;
|
|
627
|
+
this.#abortController = new globalThis.AbortController();
|
|
628
|
+
this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;
|
|
629
|
+
}
|
|
630
|
+
if (supportsRequestStreams) {
|
|
631
|
+
this.#options.duplex = "half";
|
|
632
|
+
}
|
|
633
|
+
if (this.#options.json !== void 0) {
|
|
634
|
+
this.#options.body = this.#options.stringifyJson?.(this.#options.json) ?? JSON.stringify(this.#options.json);
|
|
635
|
+
this.#options.headers.set("content-type", this.#options.headers.get("content-type") ?? "application/json");
|
|
636
|
+
}
|
|
637
|
+
const userProvidedContentType = options.headers && new globalThis.Headers(options.headers).has("content-type");
|
|
638
|
+
if (this.#input instanceof globalThis.Request && (supportsFormData && this.#options.body instanceof globalThis.FormData || this.#options.body instanceof URLSearchParams) && !userProvidedContentType) {
|
|
639
|
+
this.#options.headers.delete("content-type");
|
|
640
|
+
}
|
|
641
|
+
this.request = new globalThis.Request(this.#input, this.#options);
|
|
642
|
+
if (hasSearchParameters(this.#options.searchParams)) {
|
|
643
|
+
const textSearchParams = typeof this.#options.searchParams === "string" ? this.#options.searchParams.replace(/^\?/, "") : new URLSearchParams(_Ky.#normalizeSearchParams(this.#options.searchParams)).toString();
|
|
644
|
+
const searchParams = "?" + textSearchParams;
|
|
645
|
+
const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
|
|
646
|
+
this.request = new globalThis.Request(url, this.#options);
|
|
647
|
+
}
|
|
648
|
+
if (this.#options.onUploadProgress) {
|
|
649
|
+
if (typeof this.#options.onUploadProgress !== "function") {
|
|
650
|
+
throw new TypeError("The `onUploadProgress` option must be a function");
|
|
651
|
+
}
|
|
652
|
+
if (!supportsRequestStreams) {
|
|
653
|
+
throw new Error("Request streams are not supported in your environment. The `duplex` option for `Request` is not available.");
|
|
654
|
+
}
|
|
655
|
+
this.request = this.#wrapRequestWithUploadProgress(this.request, this.#options.body ?? void 0);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
#calculateDelay() {
|
|
659
|
+
const retryDelay = this.#options.retry.delay(this.#retryCount);
|
|
660
|
+
let jitteredDelay = retryDelay;
|
|
661
|
+
if (this.#options.retry.jitter === true) {
|
|
662
|
+
jitteredDelay = Math.random() * retryDelay;
|
|
663
|
+
} else if (typeof this.#options.retry.jitter === "function") {
|
|
664
|
+
jitteredDelay = this.#options.retry.jitter(retryDelay);
|
|
665
|
+
if (!Number.isFinite(jitteredDelay) || jitteredDelay < 0) {
|
|
666
|
+
jitteredDelay = retryDelay;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
const backoffLimit = this.#options.retry.backoffLimit ?? Number.POSITIVE_INFINITY;
|
|
670
|
+
return Math.min(backoffLimit, jitteredDelay);
|
|
671
|
+
}
|
|
672
|
+
async #calculateRetryDelay(error) {
|
|
673
|
+
this.#retryCount++;
|
|
674
|
+
if (this.#retryCount > this.#options.retry.limit) {
|
|
675
|
+
throw error;
|
|
676
|
+
}
|
|
677
|
+
const errorObject = error instanceof Error ? error : new NonError(error);
|
|
678
|
+
if (errorObject instanceof ForceRetryError) {
|
|
679
|
+
return errorObject.customDelay ?? this.#calculateDelay();
|
|
680
|
+
}
|
|
681
|
+
if (!this.#options.retry.methods.includes(this.request.method.toLowerCase())) {
|
|
682
|
+
throw error;
|
|
683
|
+
}
|
|
684
|
+
if (this.#options.retry.shouldRetry !== void 0) {
|
|
685
|
+
const result = await this.#options.retry.shouldRetry({ error: errorObject, retryCount: this.#retryCount });
|
|
686
|
+
if (result === false) {
|
|
687
|
+
throw error;
|
|
688
|
+
}
|
|
689
|
+
if (result === true) {
|
|
690
|
+
return this.#calculateDelay();
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (isTimeoutError(error) && !this.#options.retry.retryOnTimeout) {
|
|
694
|
+
throw error;
|
|
695
|
+
}
|
|
696
|
+
if (isHTTPError(error)) {
|
|
697
|
+
if (!this.#options.retry.statusCodes.includes(error.response.status)) {
|
|
698
|
+
throw error;
|
|
699
|
+
}
|
|
700
|
+
const retryAfter = error.response.headers.get("Retry-After") ?? error.response.headers.get("RateLimit-Reset") ?? error.response.headers.get("X-RateLimit-Retry-After") ?? error.response.headers.get("X-RateLimit-Reset") ?? error.response.headers.get("X-Rate-Limit-Reset");
|
|
701
|
+
if (retryAfter && this.#options.retry.afterStatusCodes.includes(error.response.status)) {
|
|
702
|
+
let after = Number(retryAfter) * 1e3;
|
|
703
|
+
if (Number.isNaN(after)) {
|
|
704
|
+
after = Date.parse(retryAfter) - Date.now();
|
|
705
|
+
} else if (after >= Date.parse("2024-01-01")) {
|
|
706
|
+
after -= Date.now();
|
|
707
|
+
}
|
|
708
|
+
const max = this.#options.retry.maxRetryAfter ?? after;
|
|
709
|
+
return after < max ? after : max;
|
|
710
|
+
}
|
|
711
|
+
if (error.response.status === 413) {
|
|
712
|
+
throw error;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return this.#calculateDelay();
|
|
716
|
+
}
|
|
717
|
+
#decorateResponse(response) {
|
|
718
|
+
if (this.#options.parseJson) {
|
|
719
|
+
response.json = async () => this.#options.parseJson(await response.text());
|
|
720
|
+
}
|
|
721
|
+
return response;
|
|
722
|
+
}
|
|
723
|
+
#cancelBody(body) {
|
|
724
|
+
if (!body) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
void body.cancel().catch(() => void 0);
|
|
728
|
+
}
|
|
729
|
+
#cancelResponseBody(response) {
|
|
730
|
+
this.#cancelBody(response.body ?? void 0);
|
|
731
|
+
}
|
|
732
|
+
async #retry(function_) {
|
|
733
|
+
try {
|
|
734
|
+
return await function_();
|
|
735
|
+
} catch (error) {
|
|
736
|
+
const ms = Math.min(await this.#calculateRetryDelay(error), maxSafeTimeout);
|
|
737
|
+
if (this.#retryCount < 1) {
|
|
738
|
+
throw error;
|
|
739
|
+
}
|
|
740
|
+
await delay(ms, this.#userProvidedAbortSignal ? { signal: this.#userProvidedAbortSignal } : {});
|
|
741
|
+
if (error instanceof ForceRetryError && error.customRequest) {
|
|
742
|
+
const managedRequest = this.#options.signal ? new globalThis.Request(error.customRequest, { signal: this.#options.signal }) : new globalThis.Request(error.customRequest);
|
|
743
|
+
this.#assignRequest(managedRequest);
|
|
744
|
+
}
|
|
745
|
+
for (const hook of this.#options.hooks.beforeRetry) {
|
|
746
|
+
const hookResult = await hook({
|
|
747
|
+
request: this.request,
|
|
748
|
+
options: this.#getNormalizedOptions(),
|
|
749
|
+
error,
|
|
750
|
+
retryCount: this.#retryCount
|
|
751
|
+
});
|
|
752
|
+
if (hookResult instanceof globalThis.Request) {
|
|
753
|
+
this.#assignRequest(hookResult);
|
|
754
|
+
break;
|
|
755
|
+
}
|
|
756
|
+
if (hookResult instanceof globalThis.Response) {
|
|
757
|
+
return hookResult;
|
|
758
|
+
}
|
|
759
|
+
if (hookResult === stop) {
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return this.#retry(function_);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
async #fetch() {
|
|
767
|
+
if (this.#abortController?.signal.aborted) {
|
|
768
|
+
this.#abortController = new globalThis.AbortController();
|
|
769
|
+
this.#options.signal = this.#userProvidedAbortSignal ? AbortSignal.any([this.#userProvidedAbortSignal, this.#abortController.signal]) : this.#abortController.signal;
|
|
770
|
+
this.request = new globalThis.Request(this.request, { signal: this.#options.signal });
|
|
771
|
+
}
|
|
772
|
+
for (const hook of this.#options.hooks.beforeRequest) {
|
|
773
|
+
const result = await hook(this.request, this.#getNormalizedOptions(), { retryCount: this.#retryCount });
|
|
774
|
+
if (result instanceof Response) {
|
|
775
|
+
return result;
|
|
776
|
+
}
|
|
777
|
+
if (result instanceof globalThis.Request) {
|
|
778
|
+
this.#assignRequest(result);
|
|
779
|
+
break;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
const nonRequestOptions = findUnknownOptions(this.request, this.#options);
|
|
783
|
+
this.#originalRequest = this.request;
|
|
784
|
+
this.request = this.#originalRequest.clone();
|
|
785
|
+
if (this.#options.timeout === false) {
|
|
786
|
+
return this.#options.fetch(this.#originalRequest, nonRequestOptions);
|
|
787
|
+
}
|
|
788
|
+
return timeout(this.#originalRequest, nonRequestOptions, this.#abortController, this.#options);
|
|
789
|
+
}
|
|
790
|
+
#getNormalizedOptions() {
|
|
791
|
+
if (!this.#cachedNormalizedOptions) {
|
|
792
|
+
const { hooks, ...normalizedOptions } = this.#options;
|
|
793
|
+
this.#cachedNormalizedOptions = Object.freeze(normalizedOptions);
|
|
794
|
+
}
|
|
795
|
+
return this.#cachedNormalizedOptions;
|
|
796
|
+
}
|
|
797
|
+
#assignRequest(request) {
|
|
798
|
+
this.#cachedNormalizedOptions = void 0;
|
|
799
|
+
this.request = this.#wrapRequestWithUploadProgress(request);
|
|
800
|
+
}
|
|
801
|
+
#wrapRequestWithUploadProgress(request, originalBody) {
|
|
802
|
+
if (!this.#options.onUploadProgress || !request.body) {
|
|
803
|
+
return request;
|
|
804
|
+
}
|
|
805
|
+
return streamRequest(request, this.#options.onUploadProgress, originalBody ?? this.#options.body ?? void 0);
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
// ../../../node_modules/.bun/ky@1.14.3/node_modules/ky/distribution/index.js
|
|
810
|
+
var createInstance = (defaults) => {
|
|
811
|
+
const ky2 = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
|
|
812
|
+
for (const method of requestMethods) {
|
|
813
|
+
ky2[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));
|
|
814
|
+
}
|
|
815
|
+
ky2.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
|
|
816
|
+
ky2.extend = (newDefaults) => {
|
|
817
|
+
if (typeof newDefaults === "function") {
|
|
818
|
+
newDefaults = newDefaults(defaults ?? {});
|
|
819
|
+
}
|
|
820
|
+
return createInstance(validateAndMerge(defaults, newDefaults));
|
|
821
|
+
};
|
|
822
|
+
ky2.stop = stop;
|
|
823
|
+
ky2.retry = retry;
|
|
824
|
+
return ky2;
|
|
825
|
+
};
|
|
826
|
+
var ky = createInstance();
|
|
827
|
+
var distribution_default = ky;
|
|
828
|
+
var { SchemaError, ResolutionError } = plugin.ERRORS;
|
|
829
|
+
var VAULT_ICON = "simple-icons:vault";
|
|
830
|
+
plugin.name = "vault";
|
|
831
|
+
var { debug } = plugin;
|
|
832
|
+
debug("init - version =", plugin.version);
|
|
833
|
+
plugin.icon = VAULT_ICON;
|
|
834
|
+
plugin.standardVars = {
|
|
835
|
+
initDecorator: "@initHcpVault",
|
|
836
|
+
params: {
|
|
837
|
+
url: { key: "VAULT_ADDR" },
|
|
838
|
+
token: { key: "VAULT_TOKEN", dataType: "vaultToken" },
|
|
839
|
+
namespace: { key: "VAULT_NAMESPACE" }
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
var FIX_AUTH_TIP = [
|
|
843
|
+
"Verify your Vault credentials are configured correctly. Use one of the following options:",
|
|
844
|
+
" 1. Provide a token explicitly via @initHcpVault(token=$VAULT_TOKEN)",
|
|
845
|
+
" 2. Use AppRole auth via @initHcpVault(roleId=..., secretId=...)",
|
|
846
|
+
" 3. Login via the vault CLI (vault login) - the ~/.vault-token file will be used automatically"
|
|
847
|
+
].join("\n");
|
|
848
|
+
var VaultPluginInstance = class {
|
|
849
|
+
constructor(id) {
|
|
850
|
+
this.id = id;
|
|
851
|
+
this.secretCache = /* @__PURE__ */ new Map();
|
|
852
|
+
}
|
|
853
|
+
setAuth(url, namespace, token, roleId, secretId, defaultPath, pathPrefix) {
|
|
854
|
+
this.url = url ? String(url).replace(/\/+$/, "") : void 0;
|
|
855
|
+
this.namespace = namespace ? String(namespace) : void 0;
|
|
856
|
+
this.token = token ? String(token) : void 0;
|
|
857
|
+
this.roleId = roleId ? String(roleId) : void 0;
|
|
858
|
+
this.secretId = secretId ? String(secretId) : void 0;
|
|
859
|
+
this.defaultPath = defaultPath ? String(defaultPath) : void 0;
|
|
860
|
+
this.pathPrefix = pathPrefix ? String(pathPrefix) : void 0;
|
|
861
|
+
debug(
|
|
862
|
+
"vault instance",
|
|
863
|
+
this.id,
|
|
864
|
+
"set auth - url:",
|
|
865
|
+
this.url,
|
|
866
|
+
"hasToken:",
|
|
867
|
+
!!this.token,
|
|
868
|
+
"hasRoleId:",
|
|
869
|
+
!!this.roleId,
|
|
870
|
+
"namespace:",
|
|
871
|
+
this.namespace,
|
|
872
|
+
"defaultPath:",
|
|
873
|
+
this.defaultPath,
|
|
874
|
+
"pathPrefix:",
|
|
875
|
+
this.pathPrefix
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
async getVaultToken() {
|
|
879
|
+
if (this.cachedToken && this.cachedToken.expiresAt > Date.now() + 3e4) {
|
|
880
|
+
debug("Using cached Vault token");
|
|
881
|
+
return this.cachedToken.token;
|
|
882
|
+
}
|
|
883
|
+
if (this.token) {
|
|
884
|
+
debug("Using explicitly provided Vault token");
|
|
885
|
+
return this.token;
|
|
886
|
+
}
|
|
887
|
+
if (this.roleId && this.secretId) {
|
|
888
|
+
return this.loginWithAppRole();
|
|
889
|
+
}
|
|
890
|
+
for (const tokenFile of [".vault-token", ".bao-token"]) {
|
|
891
|
+
try {
|
|
892
|
+
const tokenPath = path.join(os.homedir(), tokenFile);
|
|
893
|
+
const fileToken = (await promises.readFile(tokenPath, "utf-8")).trim();
|
|
894
|
+
if (fileToken) {
|
|
895
|
+
debug(`Using token from ~/${tokenFile}`);
|
|
896
|
+
return fileToken;
|
|
897
|
+
}
|
|
898
|
+
} catch {
|
|
899
|
+
debug(`Could not read ~/${tokenFile}`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
throw new SchemaError("No Vault authentication found", {
|
|
903
|
+
tip: FIX_AUTH_TIP
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
async loginWithAppRole() {
|
|
907
|
+
if (!this.url) throw new SchemaError("Vault URL is required for AppRole auth");
|
|
908
|
+
try {
|
|
909
|
+
const headers = {};
|
|
910
|
+
if (this.namespace) headers["X-Vault-Namespace"] = this.namespace;
|
|
911
|
+
const response = await distribution_default.post(`${this.url}/v1/auth/approle/login`, {
|
|
912
|
+
json: { role_id: this.roleId, secret_id: this.secretId },
|
|
913
|
+
headers
|
|
914
|
+
}).json();
|
|
915
|
+
const clientToken = response.auth.client_token;
|
|
916
|
+
const leaseDuration = response.auth.lease_duration;
|
|
917
|
+
this.cachedToken = {
|
|
918
|
+
token: clientToken,
|
|
919
|
+
expiresAt: Date.now() + leaseDuration * 1e3
|
|
920
|
+
};
|
|
921
|
+
debug("Successfully authenticated with AppRole");
|
|
922
|
+
return clientToken;
|
|
923
|
+
} catch (err) {
|
|
924
|
+
let errorMessage = "AppRole authentication failed";
|
|
925
|
+
let errorTip;
|
|
926
|
+
if (err.response) {
|
|
927
|
+
const status = err.response.status;
|
|
928
|
+
if (status === 400) {
|
|
929
|
+
errorMessage = "AppRole login failed - invalid role_id or secret_id";
|
|
930
|
+
errorTip = [
|
|
931
|
+
"Verify your AppRole credentials:",
|
|
932
|
+
" - role_id: The UUID of the AppRole role",
|
|
933
|
+
" - secret_id: A valid secret ID for the role",
|
|
934
|
+
"Generate a new secret_id: vault write -f auth/approle/role/<role>/secret-id"
|
|
935
|
+
].join("\n");
|
|
936
|
+
} else if (status === 403) {
|
|
937
|
+
errorMessage = "AppRole login denied - insufficient permissions";
|
|
938
|
+
errorTip = "Ensure the AppRole auth method is enabled and the role exists";
|
|
939
|
+
} else {
|
|
940
|
+
errorMessage = `AppRole login failed (HTTP ${status})`;
|
|
941
|
+
}
|
|
942
|
+
} else if (err.message) {
|
|
943
|
+
errorMessage = `AppRole login error: ${err.message}`;
|
|
944
|
+
}
|
|
945
|
+
throw new SchemaError(errorMessage, { tip: errorTip });
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
buildPath(explicitPath) {
|
|
949
|
+
let basePath;
|
|
950
|
+
if (explicitPath) {
|
|
951
|
+
basePath = explicitPath;
|
|
952
|
+
} else if (this.defaultPath) {
|
|
953
|
+
basePath = this.defaultPath;
|
|
954
|
+
} else {
|
|
955
|
+
throw new ResolutionError("No path specified and no defaultPath configured", {
|
|
956
|
+
tip: "Either provide a path argument to vaultSecret() or set defaultPath in @initHcpVault()"
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
if (this.pathPrefix) {
|
|
960
|
+
const prefix = this.pathPrefix.replace(/\/+$/, "");
|
|
961
|
+
const path = basePath.replace(/^\/+/, "");
|
|
962
|
+
return `${prefix}/${path}`;
|
|
963
|
+
}
|
|
964
|
+
return basePath;
|
|
965
|
+
}
|
|
966
|
+
fetchSecretData(secretPath) {
|
|
967
|
+
const cached = this.secretCache.get(secretPath);
|
|
968
|
+
if (cached) {
|
|
969
|
+
debug(`Using cached fetch for: ${secretPath}`);
|
|
970
|
+
return cached;
|
|
971
|
+
}
|
|
972
|
+
const promise = this._fetchSecretData(secretPath);
|
|
973
|
+
this.secretCache.set(secretPath, promise);
|
|
974
|
+
promise.catch(() => this.secretCache.delete(secretPath));
|
|
975
|
+
return promise;
|
|
976
|
+
}
|
|
977
|
+
async _fetchSecretData(secretPath) {
|
|
978
|
+
if (!this.url) {
|
|
979
|
+
throw new SchemaError("Vault URL is required");
|
|
980
|
+
}
|
|
981
|
+
const token = await this.getVaultToken();
|
|
982
|
+
const slashIdx = secretPath.indexOf("/");
|
|
983
|
+
let mount;
|
|
984
|
+
let kvPath;
|
|
985
|
+
if (slashIdx === -1) {
|
|
986
|
+
mount = secretPath;
|
|
987
|
+
kvPath = "";
|
|
988
|
+
} else {
|
|
989
|
+
mount = secretPath.substring(0, slashIdx);
|
|
990
|
+
kvPath = secretPath.substring(slashIdx + 1);
|
|
991
|
+
}
|
|
992
|
+
const apiUrl = kvPath ? `${this.url}/v1/${mount}/data/${kvPath}` : `${this.url}/v1/${mount}/data`;
|
|
993
|
+
const headers = { "X-Vault-Token": token };
|
|
994
|
+
if (this.namespace) headers["X-Vault-Namespace"] = this.namespace;
|
|
995
|
+
try {
|
|
996
|
+
debug(`Fetching secret: ${secretPath}`);
|
|
997
|
+
const response = await distribution_default.get(apiUrl, { headers }).json();
|
|
998
|
+
const secretData = response.data?.data;
|
|
999
|
+
if (!secretData) {
|
|
1000
|
+
throw new ResolutionError("Secret data is empty");
|
|
1001
|
+
}
|
|
1002
|
+
return secretData;
|
|
1003
|
+
} catch (err) {
|
|
1004
|
+
if (err instanceof ResolutionError) throw err;
|
|
1005
|
+
let errorMessage = "Failed to fetch secret";
|
|
1006
|
+
let errorTip;
|
|
1007
|
+
if (err.response) {
|
|
1008
|
+
const status = err.response.status;
|
|
1009
|
+
if (status === 404) {
|
|
1010
|
+
errorMessage = `Secret at path "${secretPath}" not found`;
|
|
1011
|
+
errorTip = [
|
|
1012
|
+
"Verify the secret exists in Vault:",
|
|
1013
|
+
` vault kv get ${secretPath}`,
|
|
1014
|
+
"",
|
|
1015
|
+
"Common issues:",
|
|
1016
|
+
" - The mount point may be wrong (first path segment)",
|
|
1017
|
+
" - The secret path may not exist",
|
|
1018
|
+
" - KV v1 secrets use a different API format"
|
|
1019
|
+
].join("\n");
|
|
1020
|
+
} else if (status === 403) {
|
|
1021
|
+
errorMessage = `Permission denied for path "${secretPath}"`;
|
|
1022
|
+
errorTip = [
|
|
1023
|
+
"Ensure your token has the correct policy. Required capability: read",
|
|
1024
|
+
"Example policy:",
|
|
1025
|
+
` path "${mount}/data/${kvPath || "*"}" {`,
|
|
1026
|
+
' capabilities = ["read"]',
|
|
1027
|
+
" }"
|
|
1028
|
+
].join("\n");
|
|
1029
|
+
} else if (status === 401) {
|
|
1030
|
+
errorMessage = "Vault authentication failed";
|
|
1031
|
+
errorTip = [
|
|
1032
|
+
"Your token may be expired or invalid",
|
|
1033
|
+
FIX_AUTH_TIP
|
|
1034
|
+
].join("\n");
|
|
1035
|
+
} else if (status === 503) {
|
|
1036
|
+
errorMessage = "Vault server is sealed or unavailable";
|
|
1037
|
+
errorTip = "Check that the Vault server is running and unsealed";
|
|
1038
|
+
} else {
|
|
1039
|
+
try {
|
|
1040
|
+
const errorBody = await err.response.json();
|
|
1041
|
+
const errors = errorBody.errors?.join("; ") || "";
|
|
1042
|
+
errorMessage = `Vault error (HTTP ${status}): ${errors || err.message}`;
|
|
1043
|
+
} catch {
|
|
1044
|
+
errorMessage = `Vault error (HTTP ${status})`;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
} else if (err.message) {
|
|
1048
|
+
errorMessage = `Network error: ${err.message}`;
|
|
1049
|
+
errorTip = "Verify the Vault URL is correct and the server is reachable";
|
|
1050
|
+
}
|
|
1051
|
+
throw new ResolutionError(errorMessage, {
|
|
1052
|
+
tip: errorTip
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
async getSecret(secretPath, jsonKey) {
|
|
1057
|
+
const secretData = await this.fetchSecretData(secretPath);
|
|
1058
|
+
if (jsonKey) {
|
|
1059
|
+
if (!(jsonKey in secretData)) {
|
|
1060
|
+
throw new ResolutionError(`Key "${jsonKey}" not found in secret`, {
|
|
1061
|
+
tip: `Available keys: ${Object.keys(secretData).join(", ")}`
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
return String(secretData[jsonKey]);
|
|
1065
|
+
}
|
|
1066
|
+
const keys = Object.keys(secretData);
|
|
1067
|
+
if (keys.length === 1) {
|
|
1068
|
+
return String(secretData[keys[0]]);
|
|
1069
|
+
}
|
|
1070
|
+
return JSON.stringify(secretData);
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
var pluginInstances = {};
|
|
1074
|
+
plugin.registerRootDecorator({
|
|
1075
|
+
name: "initHcpVault",
|
|
1076
|
+
description: "Initialize a HashiCorp Vault plugin instance for vaultSecret() resolver",
|
|
1077
|
+
isFunction: true,
|
|
1078
|
+
async process(argsVal) {
|
|
1079
|
+
const objArgs = argsVal.objArgs;
|
|
1080
|
+
if (!objArgs) throw new SchemaError("Expected some args");
|
|
1081
|
+
if (objArgs.id && !objArgs.id.isStatic) {
|
|
1082
|
+
throw new SchemaError("Expected id to be static");
|
|
1083
|
+
}
|
|
1084
|
+
const id = String(objArgs?.id?.staticValue || "_default");
|
|
1085
|
+
if (pluginInstances[id]) {
|
|
1086
|
+
throw new SchemaError(`Instance with id "${id}" already initialized`);
|
|
1087
|
+
}
|
|
1088
|
+
if (!objArgs.url) {
|
|
1089
|
+
throw new SchemaError("url parameter is required", {
|
|
1090
|
+
tip: 'Provide your Vault server URL: @initHcpVault(url="https://vault.example.com:8200")'
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
pluginInstances[id] = new VaultPluginInstance(id);
|
|
1094
|
+
return {
|
|
1095
|
+
id,
|
|
1096
|
+
urlResolver: objArgs.url,
|
|
1097
|
+
namespaceResolver: objArgs.namespace,
|
|
1098
|
+
tokenResolver: objArgs.token,
|
|
1099
|
+
roleIdResolver: objArgs.roleId,
|
|
1100
|
+
secretIdResolver: objArgs.secretId,
|
|
1101
|
+
defaultPathResolver: objArgs.defaultPath,
|
|
1102
|
+
pathPrefixResolver: objArgs.pathPrefix
|
|
1103
|
+
};
|
|
1104
|
+
},
|
|
1105
|
+
async execute({
|
|
1106
|
+
id,
|
|
1107
|
+
urlResolver,
|
|
1108
|
+
namespaceResolver,
|
|
1109
|
+
tokenResolver,
|
|
1110
|
+
roleIdResolver,
|
|
1111
|
+
secretIdResolver,
|
|
1112
|
+
defaultPathResolver,
|
|
1113
|
+
pathPrefixResolver
|
|
1114
|
+
}) {
|
|
1115
|
+
const url = await urlResolver.resolve();
|
|
1116
|
+
const namespace = await namespaceResolver?.resolve();
|
|
1117
|
+
const token = await tokenResolver?.resolve();
|
|
1118
|
+
const roleId = await roleIdResolver?.resolve();
|
|
1119
|
+
const secretId = await secretIdResolver?.resolve();
|
|
1120
|
+
const defaultPath = await defaultPathResolver?.resolve();
|
|
1121
|
+
const pathPrefix = await pathPrefixResolver?.resolve();
|
|
1122
|
+
pluginInstances[id].setAuth(url, namespace, token, roleId, secretId, defaultPath, pathPrefix);
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
plugin.registerDataType({
|
|
1126
|
+
name: "vaultToken",
|
|
1127
|
+
sensitive: true,
|
|
1128
|
+
typeDescription: "HashiCorp Vault authentication token",
|
|
1129
|
+
icon: VAULT_ICON,
|
|
1130
|
+
docs: [
|
|
1131
|
+
{
|
|
1132
|
+
description: "Vault Tokens",
|
|
1133
|
+
url: "https://developer.hashicorp.com/vault/docs/concepts/tokens"
|
|
1134
|
+
}
|
|
1135
|
+
]
|
|
1136
|
+
});
|
|
1137
|
+
plugin.registerResolverFunction({
|
|
1138
|
+
name: "vaultSecret",
|
|
1139
|
+
label: "Fetch secret from HashiCorp Vault KV v2",
|
|
1140
|
+
icon: VAULT_ICON,
|
|
1141
|
+
argsSchema: {
|
|
1142
|
+
type: "mixed",
|
|
1143
|
+
arrayMinLength: 0,
|
|
1144
|
+
arrayMaxLength: 2
|
|
1145
|
+
},
|
|
1146
|
+
process() {
|
|
1147
|
+
let instanceId;
|
|
1148
|
+
let secretRefResolver;
|
|
1149
|
+
let keyResolver;
|
|
1150
|
+
let returnJson = false;
|
|
1151
|
+
if (this.objArgs?.key) {
|
|
1152
|
+
keyResolver = this.objArgs.key;
|
|
1153
|
+
}
|
|
1154
|
+
if (this.objArgs?.raw) {
|
|
1155
|
+
if (!this.objArgs.raw.isStatic || this.objArgs.raw.staticValue !== true) {
|
|
1156
|
+
throw new SchemaError("Expected raw=true");
|
|
1157
|
+
}
|
|
1158
|
+
if (keyResolver) {
|
|
1159
|
+
throw new SchemaError("Cannot use raw=true with key= parameter", {
|
|
1160
|
+
tip: "Remove the key= parameter, or remove raw=true"
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
returnJson = true;
|
|
1164
|
+
}
|
|
1165
|
+
const parent = this.parent;
|
|
1166
|
+
const itemKey = parent?.key || "";
|
|
1167
|
+
if (!this.arrArgs || this.arrArgs.length === 0) {
|
|
1168
|
+
instanceId = "_default";
|
|
1169
|
+
} else if (this.arrArgs.length === 1) {
|
|
1170
|
+
instanceId = "_default";
|
|
1171
|
+
secretRefResolver = this.arrArgs[0];
|
|
1172
|
+
} else if (this.arrArgs.length === 2) {
|
|
1173
|
+
if (!this.arrArgs[0].isStatic) {
|
|
1174
|
+
throw new SchemaError("Expected instance id to be a static value");
|
|
1175
|
+
} else {
|
|
1176
|
+
instanceId = String(this.arrArgs[0].staticValue);
|
|
1177
|
+
}
|
|
1178
|
+
secretRefResolver = this.arrArgs[1];
|
|
1179
|
+
} else {
|
|
1180
|
+
throw new SchemaError("Expected 0, 1, or 2 args");
|
|
1181
|
+
}
|
|
1182
|
+
if (!Object.values(pluginInstances).length) {
|
|
1183
|
+
throw new SchemaError("No Vault plugin instances found", {
|
|
1184
|
+
tip: "Initialize at least one Vault instance using the @initHcpVault() root decorator"
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
const selectedInstance = pluginInstances[instanceId];
|
|
1188
|
+
if (!selectedInstance) {
|
|
1189
|
+
if (instanceId === "_default") {
|
|
1190
|
+
throw new SchemaError("Vault plugin instance (without id) not found", {
|
|
1191
|
+
tip: [
|
|
1192
|
+
"Either remove the `id` param from your @initHcpVault call",
|
|
1193
|
+
"or use `vaultSecret(id, secretRef)` to select an instance by id.",
|
|
1194
|
+
`Possible ids are: ${Object.keys(pluginInstances).join(", ")}`
|
|
1195
|
+
].join("\n")
|
|
1196
|
+
});
|
|
1197
|
+
} else {
|
|
1198
|
+
throw new SchemaError(`Vault plugin instance id "${instanceId}" not found`, {
|
|
1199
|
+
tip: [`Valid ids are: ${Object.keys(pluginInstances).join(", ")}`].join("\n")
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return {
|
|
1204
|
+
instanceId,
|
|
1205
|
+
secretRefResolver,
|
|
1206
|
+
keyResolver,
|
|
1207
|
+
itemKey,
|
|
1208
|
+
returnJson
|
|
1209
|
+
};
|
|
1210
|
+
},
|
|
1211
|
+
async resolve({
|
|
1212
|
+
instanceId,
|
|
1213
|
+
secretRefResolver,
|
|
1214
|
+
keyResolver,
|
|
1215
|
+
itemKey,
|
|
1216
|
+
returnJson
|
|
1217
|
+
}) {
|
|
1218
|
+
const selectedInstance = pluginInstances[instanceId];
|
|
1219
|
+
let secretRef;
|
|
1220
|
+
if (secretRefResolver) {
|
|
1221
|
+
const resolved = await secretRefResolver.resolve();
|
|
1222
|
+
if (typeof resolved !== "string") {
|
|
1223
|
+
throw new SchemaError("Expected secret reference to resolve to a string");
|
|
1224
|
+
}
|
|
1225
|
+
secretRef = resolved;
|
|
1226
|
+
}
|
|
1227
|
+
let secretPath;
|
|
1228
|
+
let explicitKey;
|
|
1229
|
+
if (secretRef) {
|
|
1230
|
+
const hashIndex = secretRef.indexOf("#");
|
|
1231
|
+
if (hashIndex !== -1) {
|
|
1232
|
+
secretPath = secretRef.substring(0, hashIndex);
|
|
1233
|
+
explicitKey = secretRef.substring(hashIndex + 1);
|
|
1234
|
+
} else {
|
|
1235
|
+
secretPath = secretRef;
|
|
1236
|
+
}
|
|
1237
|
+
} else {
|
|
1238
|
+
secretPath = "";
|
|
1239
|
+
}
|
|
1240
|
+
if (returnJson && explicitKey) {
|
|
1241
|
+
throw new SchemaError("Cannot use raw=true with #KEY syntax", {
|
|
1242
|
+
tip: "Remove the #KEY from the path, or remove raw=true"
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
let jsonKey;
|
|
1246
|
+
if (keyResolver) {
|
|
1247
|
+
const keyValue = await keyResolver.resolve();
|
|
1248
|
+
if (typeof keyValue !== "string") {
|
|
1249
|
+
throw new SchemaError("Expected key parameter to resolve to a string");
|
|
1250
|
+
}
|
|
1251
|
+
jsonKey = keyValue;
|
|
1252
|
+
} else if (explicitKey) {
|
|
1253
|
+
jsonKey = explicitKey;
|
|
1254
|
+
} else if (!returnJson) {
|
|
1255
|
+
jsonKey = itemKey || void 0;
|
|
1256
|
+
}
|
|
1257
|
+
const fullPath = selectedInstance.buildPath(secretPath || void 0);
|
|
1258
|
+
return await selectedInstance.getSecret(fullPath, jsonKey);
|
|
1259
|
+
}
|
|
1260
|
+
});
|
|
1261
|
+
/*! Bundled license information:
|
|
1262
|
+
|
|
1263
|
+
ky/distribution/index.js:
|
|
1264
|
+
(*! MIT License © Sindre Sorhus *)
|
|
1265
|
+
*/
|
|
1266
|
+
//# sourceMappingURL=plugin.cjs.map
|
|
1267
|
+
//# sourceMappingURL=plugin.cjs.map
|