@stacksjs/ts-cloud 0.7.5 → 0.7.7

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 (57) hide show
  1. package/dist/aws/index.js +259 -0
  2. package/dist/bin/cli.js +231 -231
  3. package/dist/chunk-0wxyppza.js +146 -0
  4. package/dist/chunk-3knnr7wh.js +601 -0
  5. package/dist/chunk-3rsfns7x.js +10427 -0
  6. package/dist/chunk-93hjhs78.js +1752 -0
  7. package/dist/chunk-arsh1g5h.js +1749 -0
  8. package/dist/chunk-b82pbxyp.js +1572 -0
  9. package/dist/chunk-c6rgvg1j.js +46124 -0
  10. package/dist/chunk-d2p5n2aq.js +23 -0
  11. package/dist/chunk-d7p84vz5.js +1699 -0
  12. package/dist/chunk-eq08r166.js +8 -0
  13. package/dist/chunk-hsk6fe6x.js +371 -0
  14. package/dist/chunk-mj1tmhte.js +13 -0
  15. package/dist/chunk-pegd7rmf.js +10 -0
  16. package/dist/chunk-pqfzdg68.js +12 -0
  17. package/dist/chunk-qpj3edwz.js +601 -0
  18. package/dist/chunk-tjjgajbh.js +1032 -0
  19. package/dist/chunk-tnztxpcb.js +630 -0
  20. package/dist/chunk-tt4kxske.js +1788 -0
  21. package/dist/chunk-v0bahtg2.js +4 -0
  22. package/dist/chunk-vd87cpvn.js +1754 -0
  23. package/dist/chunk-x07dz3sd.js +12828 -0
  24. package/dist/chunk-xzn0ntr0.js +4616 -0
  25. package/dist/chunk-zn0nxxa8.js +1779 -0
  26. package/dist/deploy/index.js +87 -0
  27. package/dist/dns/index.js +31 -0
  28. package/dist/drivers/index.d.ts +2 -0
  29. package/dist/drivers/index.js +108 -0
  30. package/dist/drivers/shared/box-provision.d.ts +102 -0
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +4383 -91358
  33. package/dist/push/index.js +509 -0
  34. package/dist/ui/index.html +3 -3
  35. package/dist/ui/server/actions.html +3 -3
  36. package/dist/ui/server/backups.html +3 -3
  37. package/dist/ui/server/database.html +3 -3
  38. package/dist/ui/server/deployments.html +3 -3
  39. package/dist/ui/server/firewall.html +3 -3
  40. package/dist/ui/server/logs.html +3 -3
  41. package/dist/ui/server/services.html +3 -3
  42. package/dist/ui/server/sites.html +3 -3
  43. package/dist/ui/server/ssh-keys.html +3 -3
  44. package/dist/ui/server/terminal.html +3 -3
  45. package/dist/ui/server/workers.html +3 -3
  46. package/dist/ui/serverless/alarms.html +3 -3
  47. package/dist/ui/serverless/assets.html +3 -3
  48. package/dist/ui/serverless/data.html +3 -3
  49. package/dist/ui/serverless/deployments.html +3 -3
  50. package/dist/ui/serverless/functions.html +3 -3
  51. package/dist/ui/serverless/logs.html +3 -3
  52. package/dist/ui/serverless/queues.html +3 -3
  53. package/dist/ui/serverless/scheduler.html +3 -3
  54. package/dist/ui/serverless/secrets.html +3 -3
  55. package/dist/ui/serverless/traces.html +3 -3
  56. package/dist/ui/serverless.html +3 -3
  57. package/package.json +3 -3
@@ -0,0 +1,1749 @@
1
+ // src/aws/client.ts
2
+ import * as crypto from "node:crypto";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+
7
+ // ../../node_modules/@stacksjs/ts-xml/dist/index.js
8
+ var xmlEntities = {
9
+ amp: "&",
10
+ lt: "<",
11
+ gt: ">",
12
+ quot: '"',
13
+ apos: "'"
14
+ };
15
+ var htmlEntities = {
16
+ nbsp: " ",
17
+ copy: "©",
18
+ reg: "®",
19
+ trade: "™",
20
+ euro: "€",
21
+ pound: "£",
22
+ yen: "¥",
23
+ cent: "¢",
24
+ deg: "°",
25
+ micro: "µ",
26
+ middot: "·",
27
+ bull: "•",
28
+ hellip: "…",
29
+ prime: "′",
30
+ Prime: "″",
31
+ laquo: "«",
32
+ raquo: "»",
33
+ lsquo: "‘",
34
+ rsquo: "’",
35
+ ldquo: "“",
36
+ rdquo: "”",
37
+ ndash: "–",
38
+ mdash: "—",
39
+ iexcl: "¡",
40
+ iquest: "¿",
41
+ sect: "§",
42
+ para: "¶",
43
+ dagger: "†",
44
+ Dagger: "‡",
45
+ lsaquo: "‹",
46
+ rsaquo: "›",
47
+ oline: "‾",
48
+ frasl: "⁄",
49
+ ensp: " ",
50
+ emsp: " ",
51
+ thinsp: " ",
52
+ zwnj: "‌",
53
+ zwj: "‍",
54
+ lrm: "‎",
55
+ rlm: "‏",
56
+ times: "×",
57
+ divide: "÷",
58
+ plusmn: "±",
59
+ ne: "≠",
60
+ le: "≤",
61
+ ge: "≥",
62
+ infin: "∞",
63
+ fnof: "ƒ",
64
+ Alpha: "Α",
65
+ Beta: "Β",
66
+ Gamma: "Γ",
67
+ Delta: "Δ",
68
+ Epsilon: "Ε",
69
+ Zeta: "Ζ",
70
+ Eta: "Η",
71
+ Theta: "Θ",
72
+ Iota: "Ι",
73
+ Kappa: "Κ",
74
+ Lambda: "Λ",
75
+ Mu: "Μ",
76
+ Nu: "Ν",
77
+ Xi: "Ξ",
78
+ Omicron: "Ο",
79
+ Pi: "Π",
80
+ Rho: "Ρ",
81
+ Sigma: "Σ",
82
+ Tau: "Τ",
83
+ Upsilon: "Υ",
84
+ Phi: "Φ",
85
+ Chi: "Χ",
86
+ Psi: "Ψ",
87
+ Omega: "Ω",
88
+ alpha: "α",
89
+ beta: "β",
90
+ gamma: "γ",
91
+ delta: "δ",
92
+ epsilon: "ε",
93
+ zeta: "ζ",
94
+ eta: "η",
95
+ theta: "θ",
96
+ iota: "ι",
97
+ kappa: "κ",
98
+ lambda: "λ",
99
+ mu: "μ",
100
+ nu: "ν",
101
+ xi: "ξ",
102
+ omicron: "ο",
103
+ pi: "π",
104
+ rho: "ρ",
105
+ sigmaf: "ς",
106
+ sigma: "σ",
107
+ tau: "τ",
108
+ upsilon: "υ",
109
+ phi: "φ",
110
+ chi: "χ",
111
+ psi: "ψ",
112
+ omega: "ω",
113
+ thetasym: "ϑ",
114
+ upsih: "ϒ",
115
+ piv: "ϖ",
116
+ larr: "←",
117
+ uarr: "↑",
118
+ rarr: "→",
119
+ darr: "↓",
120
+ harr: "↔",
121
+ crarr: "↵",
122
+ lArr: "⇐",
123
+ uArr: "⇑",
124
+ rArr: "⇒",
125
+ dArr: "⇓",
126
+ hArr: "⇔",
127
+ forall: "∀",
128
+ part: "∂",
129
+ exist: "∃",
130
+ empty: "∅",
131
+ nabla: "∇",
132
+ isin: "∈",
133
+ notin: "∉",
134
+ ni: "∋",
135
+ prod: "∏",
136
+ sum: "∑",
137
+ minus: "−",
138
+ lowast: "∗",
139
+ radic: "√",
140
+ prop: "∝",
141
+ ang: "∠",
142
+ and: "∧",
143
+ or: "∨",
144
+ cap: "∩",
145
+ cup: "∪",
146
+ int: "∫",
147
+ there4: "∴",
148
+ sim: "∼",
149
+ cong: "≅",
150
+ asymp: "≈",
151
+ equiv: "≡",
152
+ sub: "⊂",
153
+ sup: "⊃",
154
+ nsub: "⊄",
155
+ sube: "⊆",
156
+ supe: "⊇",
157
+ oplus: "⊕",
158
+ otimes: "⊗",
159
+ perp: "⊥",
160
+ sdot: "⋅",
161
+ lceil: "⌈",
162
+ rceil: "⌉",
163
+ lfloor: "⌊",
164
+ rfloor: "⌋",
165
+ lang: "〈",
166
+ rang: "〉",
167
+ loz: "◊",
168
+ spades: "♠",
169
+ clubs: "♣",
170
+ hearts: "♥",
171
+ diams: "♦",
172
+ Agrave: "À",
173
+ Aacute: "Á",
174
+ Acirc: "Â",
175
+ Atilde: "Ã",
176
+ Auml: "Ä",
177
+ Aring: "Å",
178
+ AElig: "Æ",
179
+ Ccedil: "Ç",
180
+ Egrave: "È",
181
+ Eacute: "É",
182
+ Ecirc: "Ê",
183
+ Euml: "Ë",
184
+ Igrave: "Ì",
185
+ Iacute: "Í",
186
+ Icirc: "Î",
187
+ Iuml: "Ï",
188
+ ETH: "Ð",
189
+ Ntilde: "Ñ",
190
+ Ograve: "Ò",
191
+ Oacute: "Ó",
192
+ Ocirc: "Ô",
193
+ Otilde: "Õ",
194
+ Ouml: "Ö",
195
+ Oslash: "Ø",
196
+ Ugrave: "Ù",
197
+ Uacute: "Ú",
198
+ Ucirc: "Û",
199
+ Uuml: "Ü",
200
+ Yacute: "Ý",
201
+ THORN: "Þ",
202
+ szlig: "ß",
203
+ agrave: "à",
204
+ aacute: "á",
205
+ acirc: "â",
206
+ atilde: "ã",
207
+ auml: "ä",
208
+ aring: "å",
209
+ aelig: "æ",
210
+ ccedil: "ç",
211
+ egrave: "è",
212
+ eacute: "é",
213
+ ecirc: "ê",
214
+ euml: "ë",
215
+ igrave: "ì",
216
+ iacute: "í",
217
+ icirc: "î",
218
+ iuml: "ï",
219
+ eth: "ð",
220
+ ntilde: "ñ",
221
+ ograve: "ò",
222
+ oacute: "ó",
223
+ ocirc: "ô",
224
+ otilde: "õ",
225
+ ouml: "ö",
226
+ oslash: "ø",
227
+ ugrave: "ù",
228
+ uacute: "ú",
229
+ ucirc: "û",
230
+ uuml: "ü",
231
+ yacute: "ý",
232
+ thorn: "þ",
233
+ yuml: "ÿ",
234
+ OElig: "Œ",
235
+ oelig: "œ",
236
+ Scaron: "Š",
237
+ scaron: "š",
238
+ Yuml: "Ÿ",
239
+ circ: "ˆ",
240
+ tilde: "˜"
241
+ };
242
+
243
+ class EntityDecoder {
244
+ customEntities = {};
245
+ useHtmlEntities;
246
+ constructor(useHtmlEntities = false) {
247
+ this.useHtmlEntities = useHtmlEntities;
248
+ }
249
+ addEntity(name, value) {
250
+ this.customEntities[name] = value;
251
+ }
252
+ decodeEntities(text) {
253
+ let ampIdx = text.indexOf("&");
254
+ if (ampIdx === -1)
255
+ return text;
256
+ const len = text.length;
257
+ let result = "";
258
+ let lastPos = 0;
259
+ while (ampIdx !== -1 && ampIdx < len) {
260
+ if (ampIdx > lastPos)
261
+ result += text.substring(lastPos, ampIdx);
262
+ const semiIdx = text.indexOf(";", ampIdx + 1);
263
+ if (semiIdx === -1 || semiIdx - ampIdx > 32) {
264
+ result += "&";
265
+ lastPos = ampIdx + 1;
266
+ ampIdx = text.indexOf("&", lastPos);
267
+ continue;
268
+ }
269
+ const entity = text.substring(ampIdx + 1, semiIdx);
270
+ if (entity.charCodeAt(0) === 35) {
271
+ const elen = entity.length;
272
+ let code = 0;
273
+ let valid = false;
274
+ if (elen > 2 && (entity.charCodeAt(1) === 120 || entity.charCodeAt(1) === 88)) {
275
+ valid = true;
276
+ for (let k = 2;k < elen; k++) {
277
+ const d = entity.charCodeAt(k);
278
+ if (d >= 48 && d <= 57)
279
+ code = code << 4 | d - 48;
280
+ else if (d >= 65 && d <= 70)
281
+ code = code << 4 | d - 55;
282
+ else if (d >= 97 && d <= 102)
283
+ code = code << 4 | d - 87;
284
+ else {
285
+ valid = false;
286
+ break;
287
+ }
288
+ }
289
+ } else if (elen > 1) {
290
+ valid = true;
291
+ for (let k = 1;k < elen; k++) {
292
+ const d = entity.charCodeAt(k);
293
+ if (d >= 48 && d <= 57)
294
+ code = code * 10 + (d - 48);
295
+ else {
296
+ valid = false;
297
+ break;
298
+ }
299
+ }
300
+ }
301
+ if (valid) {
302
+ result += String.fromCodePoint(code);
303
+ } else {
304
+ result += text.substring(ampIdx, semiIdx + 1);
305
+ }
306
+ } else {
307
+ let replacement = this.customEntities[entity];
308
+ if (replacement === undefined) {
309
+ const elen = entity.length;
310
+ if (elen >= 2 && elen <= 4) {
311
+ const e0 = entity.charCodeAt(0);
312
+ if (e0 === 108 && elen === 2 && entity.charCodeAt(1) === 116)
313
+ replacement = "<";
314
+ else if (e0 === 103 && elen === 2 && entity.charCodeAt(1) === 116)
315
+ replacement = ">";
316
+ else if (e0 === 97 && elen === 3 && entity.charCodeAt(1) === 109 && entity.charCodeAt(2) === 112)
317
+ replacement = "&";
318
+ else if (e0 === 113 && elen === 4)
319
+ replacement = entity === "quot" ? '"' : undefined;
320
+ else if (e0 === 97 && elen === 4)
321
+ replacement = entity === "apos" ? "'" : undefined;
322
+ }
323
+ if (replacement === undefined)
324
+ replacement = xmlEntities[entity] ?? (this.useHtmlEntities ? htmlEntities[entity] : undefined);
325
+ }
326
+ if (replacement !== undefined) {
327
+ result += replacement;
328
+ } else {
329
+ result += text.substring(ampIdx, semiIdx + 1);
330
+ }
331
+ }
332
+ lastPos = semiIdx + 1;
333
+ ampIdx = text.indexOf("&", lastPos);
334
+ }
335
+ if (lastPos < len)
336
+ result += text.substring(lastPos);
337
+ return result;
338
+ }
339
+ }
340
+ var _encodeMap = [];
341
+ _encodeMap[38] = "&amp;";
342
+ _encodeMap[60] = "&lt;";
343
+ _encodeMap[62] = "&gt;";
344
+ _encodeMap[34] = "&quot;";
345
+ _encodeMap[39] = "&apos;";
346
+ var defaultParserOptions = {
347
+ attributeNamePrefix: "@_",
348
+ attributesGroupName: false,
349
+ textNodeName: "#text",
350
+ ignoreAttributes: true,
351
+ removeNSPrefix: false,
352
+ allowBooleanAttributes: false,
353
+ alwaysCreateTextNode: false,
354
+ trimValues: true,
355
+ parseTagValue: true,
356
+ parseAttributeValue: false,
357
+ processEntities: true,
358
+ htmlEntities: false,
359
+ commentPropName: false,
360
+ cdataPropName: false,
361
+ piPropName: false,
362
+ preserveOrder: false,
363
+ stopNodes: [],
364
+ unpairedTags: [],
365
+ isArray: undefined,
366
+ tagValueProcessor: undefined,
367
+ attributeValueProcessor: undefined,
368
+ updateTag: undefined,
369
+ numberParseOptions: {
370
+ hex: true,
371
+ leadingZeros: true,
372
+ scientific: true
373
+ },
374
+ ignorePiTags: false,
375
+ transformAttributeName: undefined,
376
+ transformTagName: undefined,
377
+ ignoreDeclaration: false
378
+ };
379
+ function isWhitespace(ch) {
380
+ return ch === 32 || ch === 9 || ch === 10 || ch === 13;
381
+ }
382
+ function isNameStartChar(ch) {
383
+ return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 95 || ch === 58 || ch >= 192 && ch <= 214 || ch >= 216 && ch <= 246 || ch >= 248 && ch <= 767 || ch >= 880 && ch <= 893 || ch >= 895 && ch <= 8191 || ch >= 8204 && ch <= 8205 || ch >= 8304 && ch <= 8591 || ch >= 11264 && ch <= 12271 || ch >= 12289 && ch <= 55295 || ch >= 63744 && ch <= 64975 || ch >= 65008 && ch <= 65533;
384
+ }
385
+ function isNameChar(ch) {
386
+ return isNameStartChar(ch) || ch === 45 || ch === 46 || ch >= 48 && ch <= 57 || ch === 183 || ch >= 768 && ch <= 879 || ch >= 8255 && ch <= 8256;
387
+ }
388
+ var RE_HEX = /^0x[\da-fA-F]+$/;
389
+ var RE_SCIENTIFIC = /^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/;
390
+ var RE_NUMBER = /^[+-]?(\d+\.?\d*|\.\d+)$/;
391
+ function isCDATA(xml, pos) {
392
+ return xml.charCodeAt(pos) === 91 && xml.charCodeAt(pos + 1) === 67 && xml.charCodeAt(pos + 2) === 68 && xml.charCodeAt(pos + 3) === 65 && xml.charCodeAt(pos + 4) === 84 && xml.charCodeAt(pos + 5) === 65 && xml.charCodeAt(pos + 6) === 91;
393
+ }
394
+ function isDOCTYPE(xml, pos) {
395
+ const c0 = xml.charCodeAt(pos);
396
+ const c1 = xml.charCodeAt(pos + 1);
397
+ const c2 = xml.charCodeAt(pos + 2);
398
+ const c3 = xml.charCodeAt(pos + 3);
399
+ const c4 = xml.charCodeAt(pos + 4);
400
+ const c5 = xml.charCodeAt(pos + 5);
401
+ const c6 = xml.charCodeAt(pos + 6);
402
+ return (c0 === 68 || c0 === 100) && (c1 === 79 || c1 === 111) && (c2 === 67 || c2 === 99) && (c3 === 84 || c3 === 116) && (c4 === 89 || c4 === 121) && (c5 === 80 || c5 === 112) && (c6 === 69 || c6 === 101);
403
+ }
404
+ function readNameEnd(xml, pos, len) {
405
+ if (pos >= len || !isNameStartChar(xml.charCodeAt(pos)))
406
+ return pos;
407
+ pos++;
408
+ while (pos < len && isNameChar(xml.charCodeAt(pos)))
409
+ pos++;
410
+ return pos;
411
+ }
412
+
413
+ class XMLParser {
414
+ options;
415
+ entityDecoder;
416
+ unpairedSet;
417
+ exactStopNodes;
418
+ wildcardStopSuffixes;
419
+ needsJPath;
420
+ _ignoreAttributes = true;
421
+ _textNodeName = "#text";
422
+ _commentPropName = false;
423
+ _cdataPropName = false;
424
+ _piPropName = false;
425
+ _alwaysCreateTextNode = false;
426
+ _trimValues = true;
427
+ _processEntities = true;
428
+ _parseTagValue = true;
429
+ _parseAttributeValue = false;
430
+ _removeNSPrefix = false;
431
+ _attrPrefix = "@_";
432
+ _attrsGroupName = false;
433
+ _ignorePiTags = false;
434
+ _ignoreDeclaration = false;
435
+ constructor(options) {
436
+ this.options = { ...defaultParserOptions, ...options };
437
+ this.entityDecoder = new EntityDecoder(this.options.htmlEntities);
438
+ this.unpairedSet = new Set(this.options.unpairedTags);
439
+ this.exactStopNodes = new Set;
440
+ this.wildcardStopSuffixes = [];
441
+ for (const stopNode of this.options.stopNodes) {
442
+ if (stopNode.startsWith("*.")) {
443
+ this.wildcardStopSuffixes.push(stopNode.substring(2));
444
+ } else {
445
+ this.exactStopNodes.add(stopNode);
446
+ }
447
+ }
448
+ this._ignoreAttributes = this.options.ignoreAttributes;
449
+ this._textNodeName = this.options.textNodeName;
450
+ this._commentPropName = this.options.commentPropName;
451
+ this._cdataPropName = this.options.cdataPropName;
452
+ this._piPropName = this.options.piPropName;
453
+ this._alwaysCreateTextNode = this.options.alwaysCreateTextNode;
454
+ this._trimValues = this.options.trimValues;
455
+ this._processEntities = this.options.processEntities;
456
+ this._parseTagValue = this.options.parseTagValue;
457
+ this._parseAttributeValue = this.options.parseAttributeValue;
458
+ this._removeNSPrefix = this.options.removeNSPrefix;
459
+ this._attrPrefix = this.options.attributeNamePrefix;
460
+ this._attrsGroupName = this.options.attributesGroupName;
461
+ this._ignorePiTags = this.options.ignorePiTags;
462
+ this._ignoreDeclaration = this.options.ignoreDeclaration;
463
+ this.needsJPath = this.options.stopNodes.length > 0 || this.options.isArray !== undefined || this.options.updateTag !== undefined || this.options.tagValueProcessor !== undefined || this.options.attributeValueProcessor !== undefined;
464
+ }
465
+ addEntity(name, value) {
466
+ this.entityDecoder.addEntity(name, value);
467
+ }
468
+ parse(xmlData) {
469
+ if (xmlData instanceof Uint8Array) {
470
+ xmlData = new TextDecoder().decode(xmlData);
471
+ }
472
+ const xml = xmlData;
473
+ if (this.options.preserveOrder) {
474
+ return this.parseOrdered(xml);
475
+ }
476
+ return this.parseUnordered(xml);
477
+ }
478
+ parseUnordered(xml) {
479
+ const result = {};
480
+ const len = xml.length;
481
+ let i = 0;
482
+ if (len > 0 && xml.charCodeAt(0) === 65279)
483
+ i = 1;
484
+ i = this.parseChildren(xml, i, len, result, "", []);
485
+ return result;
486
+ }
487
+ parseOrdered(xml) {
488
+ const len = xml.length;
489
+ let i = 0;
490
+ if (len > 0 && xml.charCodeAt(0) === 65279)
491
+ i = 1;
492
+ const result = [];
493
+ this.parseChildrenOrdered(xml, i, len, result, "");
494
+ return result;
495
+ }
496
+ readTagName(xml, pos, len) {
497
+ const end = readNameEnd(xml, pos, len);
498
+ return end;
499
+ }
500
+ extractTagName(xml, start, end) {
501
+ let name = xml.substring(start, end);
502
+ if (this._removeNSPrefix) {
503
+ const colonIdx = name.indexOf(":");
504
+ if (colonIdx !== -1)
505
+ name = name.substring(colonIdx + 1);
506
+ }
507
+ if (this.options.transformTagName)
508
+ name = this.options.transformTagName(name);
509
+ return name;
510
+ }
511
+ parseAttributes(xml, pos, len, jPath, outAttrs) {
512
+ let count = 0;
513
+ const removeNS = this._removeNSPrefix;
514
+ const transformAttr = this.options.transformAttributeName;
515
+ const trimVals = this._trimValues;
516
+ const processEnts = this._processEntities;
517
+ const attrProcessor = this.options.attributeValueProcessor;
518
+ while (pos < len) {
519
+ let ch = xml.charCodeAt(pos);
520
+ while (ch === 32 || ch === 9 || ch === 10 || ch === 13) {
521
+ pos++;
522
+ if (pos >= len)
523
+ break;
524
+ ch = xml.charCodeAt(pos);
525
+ }
526
+ if (pos >= len)
527
+ break;
528
+ if (ch === 62 || ch === 47)
529
+ break;
530
+ const attrStart = pos;
531
+ if (!isNameStartChar(ch))
532
+ break;
533
+ pos++;
534
+ while (pos < len && isNameChar(xml.charCodeAt(pos)))
535
+ pos++;
536
+ let attrName = xml.substring(attrStart, pos);
537
+ if (removeNS) {
538
+ const colonIdx = attrName.indexOf(":");
539
+ if (colonIdx !== -1)
540
+ attrName = attrName.substring(colonIdx + 1);
541
+ }
542
+ if (transformAttr)
543
+ attrName = transformAttr(attrName);
544
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
545
+ pos++;
546
+ if (pos < len && xml.charCodeAt(pos) === 61) {
547
+ pos++;
548
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
549
+ pos++;
550
+ if (pos >= len)
551
+ break;
552
+ const quoteChar = xml.charCodeAt(pos);
553
+ if (quoteChar === 34 || quoteChar === 39) {
554
+ pos++;
555
+ const valueStart = pos;
556
+ while (pos < len && xml.charCodeAt(pos) !== quoteChar)
557
+ pos++;
558
+ let value = xml.substring(valueStart, pos);
559
+ if (trimVals && value.length > 0) {
560
+ const f = value.charCodeAt(0);
561
+ const l = value.charCodeAt(value.length - 1);
562
+ if (f <= 32 || l <= 32)
563
+ value = value.trim();
564
+ }
565
+ if (processEnts)
566
+ value = this.entityDecoder.decodeEntities(value);
567
+ if (attrProcessor)
568
+ value = attrProcessor(attrName, value, jPath) ?? value;
569
+ outAttrs[attrName] = value;
570
+ count++;
571
+ if (pos < len)
572
+ pos++;
573
+ }
574
+ } else {
575
+ outAttrs[attrName] = "true";
576
+ count++;
577
+ }
578
+ }
579
+ return count > 0 ? -pos - 1 : pos;
580
+ }
581
+ processTagValue(value, tagName, jPath, hasAttributes, isLeaf) {
582
+ if (this._trimValues) {
583
+ const vlen = value.length;
584
+ if (vlen > 0) {
585
+ const first = value.charCodeAt(0);
586
+ const last = value.charCodeAt(vlen - 1);
587
+ if (first <= 32 || last <= 32)
588
+ value = value.trim();
589
+ }
590
+ }
591
+ if (this._processEntities)
592
+ value = this.entityDecoder.decodeEntities(value);
593
+ if (this.options.tagValueProcessor) {
594
+ const processed = this.options.tagValueProcessor(tagName, value, jPath, hasAttributes, isLeaf);
595
+ if (processed !== undefined)
596
+ value = processed;
597
+ }
598
+ if (!value)
599
+ return value;
600
+ if (this._parseTagValue)
601
+ return this.parseValue(value);
602
+ return value;
603
+ }
604
+ parseValue(val) {
605
+ if (val === "true")
606
+ return true;
607
+ if (val === "false")
608
+ return false;
609
+ if (!val)
610
+ return val;
611
+ const firstCh = val.charCodeAt(0);
612
+ const isNumStart = firstCh >= 48 && firstCh <= 57 || firstCh === 43 || firstCh === 45 || firstCh === 46;
613
+ if (!isNumStart)
614
+ return val;
615
+ const opts = this.options.numberParseOptions;
616
+ if (opts.skipLike?.test(val))
617
+ return val;
618
+ if (opts.hex && firstCh === 48 && RE_HEX.test(val))
619
+ return Number.parseInt(val, 16);
620
+ if (val.length > 1 && firstCh === 48 && val.charCodeAt(1) !== 46) {
621
+ if (opts.leadingZeros)
622
+ return val;
623
+ }
624
+ if (opts.scientific && RE_SCIENTIFIC.test(val)) {
625
+ const num = Number(val);
626
+ if (!Number.isNaN(num))
627
+ return num;
628
+ }
629
+ if (RE_NUMBER.test(val)) {
630
+ const num = Number(val);
631
+ if (!Number.isNaN(num))
632
+ return num;
633
+ }
634
+ return val;
635
+ }
636
+ parseAttributeValue(val) {
637
+ if (!this._parseAttributeValue)
638
+ return val;
639
+ return this.parseValue(val);
640
+ }
641
+ isStopNode(jPath) {
642
+ if (this.exactStopNodes.has(jPath))
643
+ return true;
644
+ for (const suffix of this.wildcardStopSuffixes) {
645
+ if (jPath.endsWith(`.${suffix}`) || jPath === suffix)
646
+ return true;
647
+ }
648
+ return false;
649
+ }
650
+ readStopNodeContent(xml, pos, len, tagName) {
651
+ const closingTag = `</${tagName}`;
652
+ const idx = xml.indexOf(closingTag, pos);
653
+ if (idx === -1) {
654
+ return { content: xml.substring(pos), pos: len };
655
+ }
656
+ const content = xml.substring(pos, idx);
657
+ let endPos = idx + closingTag.length;
658
+ while (endPos < len && xml.charCodeAt(endPos) !== 62)
659
+ endPos++;
660
+ if (endPos < len)
661
+ endPos++;
662
+ return { content, pos: endPos };
663
+ }
664
+ addToObj(obj, key, value, jPath, isLeaf, isAttribute) {
665
+ const existing = obj[key];
666
+ if (existing !== undefined) {
667
+ if (!Array.isArray(existing)) {
668
+ obj[key] = [existing, value];
669
+ } else {
670
+ existing.push(value);
671
+ }
672
+ } else if (this.options.isArray?.(key, jPath, isLeaf, isAttribute)) {
673
+ obj[key] = [value];
674
+ } else {
675
+ obj[key] = value;
676
+ }
677
+ }
678
+ flushText(textContent, cdataBuffer, jPath, parent) {
679
+ if (!textContent && !cdataBuffer)
680
+ return;
681
+ const textNodeName = this._textNodeName;
682
+ if (cdataBuffer) {
683
+ let decodedText = textContent;
684
+ if (decodedText && this._processEntities)
685
+ decodedText = this.entityDecoder.decodeEntities(decodedText);
686
+ let value = cdataBuffer + decodedText;
687
+ if (this._trimValues && value.length > 0) {
688
+ const f = value.charCodeAt(0);
689
+ const l = value.charCodeAt(value.length - 1);
690
+ if (f <= 32 || l <= 32)
691
+ value = value.trim();
692
+ }
693
+ if (this.options.tagValueProcessor) {
694
+ const processed = this.options.tagValueProcessor(textNodeName, value, jPath, false, true);
695
+ if (processed !== undefined)
696
+ value = processed;
697
+ }
698
+ if (value) {
699
+ const parsed = this._parseTagValue ? this.parseValue(value) : value;
700
+ if (parsed !== undefined && parsed !== "")
701
+ this.addToObj(parent, textNodeName, parsed, jPath, true, false);
702
+ }
703
+ } else {
704
+ const processed = this.processTagValue(textContent, textNodeName, jPath, false, true);
705
+ if (processed !== undefined && processed !== "")
706
+ this.addToObj(parent, textNodeName, processed, jPath, true, false);
707
+ }
708
+ }
709
+ parseChildren(xml, pos, len, parent, jPath, unpairedStack) {
710
+ let textContent = "";
711
+ let cdataBuffer = "";
712
+ const needsJPath = this.needsJPath;
713
+ while (pos < len) {
714
+ const ch = xml.charCodeAt(pos);
715
+ if (ch !== 60) {
716
+ const textStart = pos;
717
+ pos++;
718
+ while (pos < len && xml.charCodeAt(pos) !== 60)
719
+ pos++;
720
+ if (!textContent)
721
+ textContent = xml.substring(textStart, pos);
722
+ else
723
+ textContent += xml.substring(textStart, pos);
724
+ continue;
725
+ }
726
+ if (pos + 1 >= len)
727
+ break;
728
+ const nextCh = xml.charCodeAt(pos + 1);
729
+ if (nextCh === 33 && pos + 3 < len && xml.charCodeAt(pos + 2) === 45 && xml.charCodeAt(pos + 3) === 45) {
730
+ if (textContent || cdataBuffer) {
731
+ this.flushText(textContent, cdataBuffer, jPath, parent);
732
+ textContent = "";
733
+ cdataBuffer = "";
734
+ }
735
+ pos += 4;
736
+ const endComment = xml.indexOf("-->", pos);
737
+ if (endComment === -1) {
738
+ pos = len;
739
+ break;
740
+ }
741
+ if (this._commentPropName) {
742
+ const comment = xml.substring(pos, endComment);
743
+ this.addToObj(parent, this._commentPropName, comment, jPath, true, false);
744
+ }
745
+ pos = endComment + 3;
746
+ continue;
747
+ }
748
+ if (nextCh === 33 && pos + 8 < len && isCDATA(xml, pos + 2)) {
749
+ pos += 9;
750
+ const endCdata = xml.indexOf("]]>", pos);
751
+ if (endCdata === -1) {
752
+ pos = len;
753
+ break;
754
+ }
755
+ const cdataContent = xml.substring(pos, endCdata);
756
+ if (this._cdataPropName) {
757
+ this.flushText(textContent, cdataBuffer, jPath, parent);
758
+ textContent = "";
759
+ cdataBuffer = "";
760
+ this.addToObj(parent, this._cdataPropName, cdataContent, jPath, true, false);
761
+ } else {
762
+ if (textContent) {
763
+ let decoded = textContent;
764
+ if (this._processEntities)
765
+ decoded = this.entityDecoder.decodeEntities(decoded);
766
+ cdataBuffer += decoded;
767
+ textContent = "";
768
+ }
769
+ cdataBuffer += cdataContent;
770
+ }
771
+ pos = endCdata + 3;
772
+ continue;
773
+ }
774
+ if (nextCh === 33 && pos + 9 < len && isDOCTYPE(xml, pos + 2)) {
775
+ pos += 9;
776
+ let depth = 1;
777
+ while (pos < len && depth > 0) {
778
+ const c = xml.charCodeAt(pos);
779
+ if (c === 60)
780
+ depth++;
781
+ else if (c === 62)
782
+ depth--;
783
+ pos++;
784
+ }
785
+ continue;
786
+ }
787
+ if (nextCh === 63) {
788
+ pos += 2;
789
+ const piNameStart = pos;
790
+ while (pos < len && !isWhitespace(xml.charCodeAt(pos)) && xml.charCodeAt(pos) !== 63)
791
+ pos++;
792
+ const piTarget = xml.substring(piNameStart, pos);
793
+ const endPi = xml.indexOf("?>", pos);
794
+ if (endPi === -1) {
795
+ pos = len;
796
+ break;
797
+ }
798
+ const piContent = xml.substring(pos, endPi).trim();
799
+ if (piTarget === "xml") {
800
+ if (!this._ignoreDeclaration && this._piPropName) {
801
+ const declAttrs = this.parsePiAttributes(piContent);
802
+ this.addToObj(parent, this._piPropName, { [piTarget]: declAttrs }, jPath, true, false);
803
+ }
804
+ } else if (!this._ignorePiTags && this._piPropName) {
805
+ this.addToObj(parent, this._piPropName, { [piTarget]: piContent }, jPath, true, false);
806
+ }
807
+ pos = endPi + 2;
808
+ continue;
809
+ }
810
+ if (nextCh === 47) {
811
+ if (textContent || cdataBuffer) {
812
+ this.flushText(textContent, cdataBuffer, jPath, parent);
813
+ textContent = "";
814
+ cdataBuffer = "";
815
+ }
816
+ pos += 2;
817
+ const nameStart2 = pos;
818
+ const nameEnd2 = this.readTagName(xml, pos, len);
819
+ const closingName = this.extractTagName(xml, nameStart2, nameEnd2);
820
+ pos = nameEnd2;
821
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
822
+ pos++;
823
+ if (pos < len && xml.charCodeAt(pos) === 62)
824
+ pos++;
825
+ if (unpairedStack.length > 0 && unpairedStack[unpairedStack.length - 1] === closingName) {
826
+ unpairedStack.pop();
827
+ continue;
828
+ }
829
+ return pos;
830
+ }
831
+ if (textContent || cdataBuffer) {
832
+ this.flushText(textContent, cdataBuffer, jPath, parent);
833
+ textContent = "";
834
+ cdataBuffer = "";
835
+ }
836
+ pos++;
837
+ const nameStart = pos;
838
+ const nameEnd = this.readTagName(xml, pos, len);
839
+ const tagName = this.extractTagName(xml, nameStart, nameEnd);
840
+ if (!tagName) {
841
+ pos = nameEnd + 1;
842
+ continue;
843
+ }
844
+ pos = nameEnd;
845
+ const childJPath = needsJPath ? jPath ? `${jPath}.${tagName}` : tagName : "";
846
+ let attrs = {};
847
+ let hasAttrs = false;
848
+ if (!this._ignoreAttributes) {
849
+ const attrResult = this.parseAttributes(xml, pos, len, childJPath, attrs);
850
+ if (attrResult < 0) {
851
+ pos = -attrResult - 1;
852
+ hasAttrs = true;
853
+ } else {
854
+ pos = attrResult;
855
+ }
856
+ } else {
857
+ while (pos < len) {
858
+ const c = xml.charCodeAt(pos);
859
+ if (c === 62 || c === 47)
860
+ break;
861
+ if (c === 34 || c === 39) {
862
+ pos++;
863
+ while (pos < len && xml.charCodeAt(pos) !== c)
864
+ pos++;
865
+ }
866
+ pos++;
867
+ }
868
+ }
869
+ if (this.options.updateTag) {
870
+ const newName = this.options.updateTag(tagName, childJPath, attrs);
871
+ if (newName === false) {
872
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
873
+ pos++;
874
+ if (pos < len && xml.charCodeAt(pos) === 47) {
875
+ pos += 2;
876
+ } else if (pos < len && xml.charCodeAt(pos) === 62) {
877
+ pos++;
878
+ const closingTag = `</${tagName}>`;
879
+ const closeIdx = xml.indexOf(closingTag, pos);
880
+ if (closeIdx !== -1)
881
+ pos = closeIdx + closingTag.length;
882
+ }
883
+ continue;
884
+ }
885
+ }
886
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
887
+ pos++;
888
+ if (pos < len && xml.charCodeAt(pos) === 47) {
889
+ pos += 2;
890
+ if (hasAttrs || this._alwaysCreateTextNode) {
891
+ const childObj = {};
892
+ if (hasAttrs)
893
+ this.applyAttributes(childObj, attrs, childJPath);
894
+ if (this._alwaysCreateTextNode)
895
+ childObj[this._textNodeName] = "";
896
+ this.addToObj(parent, tagName, childObj, childJPath, true, false);
897
+ } else {
898
+ this.addToObj(parent, tagName, "", childJPath, true, false);
899
+ }
900
+ continue;
901
+ }
902
+ if (pos < len && xml.charCodeAt(pos) === 62) {
903
+ pos++;
904
+ if (this.unpairedSet.has(tagName)) {
905
+ if (hasAttrs) {
906
+ const childObj2 = {};
907
+ this.applyAttributes(childObj2, attrs, childJPath);
908
+ this.addToObj(parent, tagName, childObj2, childJPath, true, false);
909
+ } else {
910
+ this.addToObj(parent, tagName, "", childJPath, true, false);
911
+ }
912
+ unpairedStack.push(tagName);
913
+ continue;
914
+ }
915
+ if (this.exactStopNodes.size > 0 || this.wildcardStopSuffixes.length > 0) {
916
+ if (this.isStopNode(childJPath)) {
917
+ const stopResult = this.readStopNodeContent(xml, pos, len, tagName);
918
+ const childObj2 = {};
919
+ if (hasAttrs)
920
+ this.applyAttributes(childObj2, attrs, childJPath);
921
+ if (stopResult.content)
922
+ childObj2[this._textNodeName] = stopResult.content;
923
+ this.addToObj(parent, tagName, childObj2, childJPath, true, false);
924
+ pos = stopResult.pos;
925
+ continue;
926
+ }
927
+ }
928
+ const childObj = {};
929
+ if (hasAttrs)
930
+ this.applyAttributes(childObj, attrs, childJPath);
931
+ pos = this.parseChildren(xml, pos, len, childObj, childJPath, unpairedStack);
932
+ const textNodeName = this._textNodeName;
933
+ const textValue = childObj[textNodeName];
934
+ if (!hasAttrs && !this._alwaysCreateTextNode) {
935
+ let isLeaf = true;
936
+ for (const k in childObj) {
937
+ if (k !== textNodeName) {
938
+ isLeaf = false;
939
+ break;
940
+ }
941
+ }
942
+ if (isLeaf) {
943
+ this.addToObj(parent, tagName, textValue !== undefined ? textValue : "", childJPath, true, false);
944
+ continue;
945
+ }
946
+ }
947
+ this.addToObj(parent, tagName, childObj, childJPath, false, false);
948
+ }
949
+ }
950
+ if (textContent || cdataBuffer) {
951
+ this.flushText(textContent, cdataBuffer, jPath, parent);
952
+ }
953
+ return pos;
954
+ }
955
+ parseChildrenOrdered(xml, pos, len, parent, jPath) {
956
+ let textContent = "";
957
+ const needsJPath = this.needsJPath;
958
+ while (pos < len) {
959
+ const ch = xml.charCodeAt(pos);
960
+ if (ch !== 60) {
961
+ const textStart = pos;
962
+ pos++;
963
+ while (pos < len && xml.charCodeAt(pos) !== 60)
964
+ pos++;
965
+ if (!textContent)
966
+ textContent = xml.substring(textStart, pos);
967
+ else
968
+ textContent += xml.substring(textStart, pos);
969
+ continue;
970
+ }
971
+ if (pos + 1 >= len)
972
+ break;
973
+ const nextCh = xml.charCodeAt(pos + 1);
974
+ if (nextCh === 33 && pos + 3 < len && xml.charCodeAt(pos + 2) === 45 && xml.charCodeAt(pos + 3) === 45) {
975
+ if (textContent) {
976
+ const processed = this.processTagValue(textContent, this._textNodeName, jPath, false, true);
977
+ if (processed !== undefined && processed !== "")
978
+ parent.push({ [this._textNodeName]: processed });
979
+ textContent = "";
980
+ }
981
+ pos += 4;
982
+ const endComment = xml.indexOf("-->", pos);
983
+ if (endComment === -1) {
984
+ pos = len;
985
+ break;
986
+ }
987
+ if (this._commentPropName) {
988
+ parent.push({ [this._commentPropName]: [{ [this._textNodeName]: xml.substring(pos, endComment) }] });
989
+ }
990
+ pos = endComment + 3;
991
+ continue;
992
+ }
993
+ if (nextCh === 33 && pos + 8 < len && isCDATA(xml, pos + 2)) {
994
+ pos += 9;
995
+ const endCdata = xml.indexOf("]]>", pos);
996
+ if (endCdata === -1) {
997
+ pos = len;
998
+ break;
999
+ }
1000
+ const cdataContent = xml.substring(pos, endCdata);
1001
+ if (this._cdataPropName) {
1002
+ if (textContent) {
1003
+ const processed = this.processTagValue(textContent, this._textNodeName, jPath, false, true);
1004
+ if (processed !== undefined && processed !== "")
1005
+ parent.push({ [this._textNodeName]: processed });
1006
+ textContent = "";
1007
+ }
1008
+ parent.push({ [this._cdataPropName]: [{ [this._textNodeName]: cdataContent }] });
1009
+ } else {
1010
+ textContent += cdataContent;
1011
+ }
1012
+ pos = endCdata + 3;
1013
+ continue;
1014
+ }
1015
+ if (nextCh === 33 && pos + 9 < len && isDOCTYPE(xml, pos + 2)) {
1016
+ pos += 9;
1017
+ let depth = 1;
1018
+ while (pos < len && depth > 0) {
1019
+ const c = xml.charCodeAt(pos);
1020
+ if (c === 60)
1021
+ depth++;
1022
+ else if (c === 62)
1023
+ depth--;
1024
+ pos++;
1025
+ }
1026
+ continue;
1027
+ }
1028
+ if (nextCh === 63) {
1029
+ pos += 2;
1030
+ const endPi = xml.indexOf("?>", pos);
1031
+ if (endPi === -1) {
1032
+ pos = len;
1033
+ break;
1034
+ }
1035
+ pos = endPi + 2;
1036
+ continue;
1037
+ }
1038
+ if (nextCh === 47) {
1039
+ if (textContent) {
1040
+ const processed = this.processTagValue(textContent, this._textNodeName, jPath, false, true);
1041
+ if (processed !== undefined && processed !== "")
1042
+ parent.push({ [this._textNodeName]: processed });
1043
+ textContent = "";
1044
+ }
1045
+ pos += 2;
1046
+ const nameEnd2 = this.readTagName(xml, pos, len);
1047
+ pos = nameEnd2;
1048
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
1049
+ pos++;
1050
+ if (pos < len && xml.charCodeAt(pos) === 62)
1051
+ pos++;
1052
+ return pos;
1053
+ }
1054
+ if (textContent) {
1055
+ const processed = this.processTagValue(textContent, this._textNodeName, jPath, false, true);
1056
+ if (processed !== undefined && processed !== "")
1057
+ parent.push({ [this._textNodeName]: processed });
1058
+ textContent = "";
1059
+ }
1060
+ pos++;
1061
+ const nameStart = pos;
1062
+ const nameEnd = this.readTagName(xml, pos, len);
1063
+ const tagName = this.extractTagName(xml, nameStart, nameEnd);
1064
+ if (!tagName) {
1065
+ pos = nameEnd + 1;
1066
+ continue;
1067
+ }
1068
+ pos = nameEnd;
1069
+ const childJPath = needsJPath ? jPath ? `${jPath}.${tagName}` : tagName : "";
1070
+ let attrs = {};
1071
+ let hasAttrs = false;
1072
+ if (!this._ignoreAttributes) {
1073
+ const attrResult = this.parseAttributes(xml, pos, len, childJPath, attrs);
1074
+ if (attrResult < 0) {
1075
+ pos = -attrResult - 1;
1076
+ hasAttrs = true;
1077
+ } else {
1078
+ pos = attrResult;
1079
+ }
1080
+ } else {
1081
+ while (pos < len) {
1082
+ const c = xml.charCodeAt(pos);
1083
+ if (c === 62 || c === 47)
1084
+ break;
1085
+ if (c === 34 || c === 39) {
1086
+ pos++;
1087
+ while (pos < len && xml.charCodeAt(pos) !== c)
1088
+ pos++;
1089
+ }
1090
+ pos++;
1091
+ }
1092
+ }
1093
+ while (pos < len && isWhitespace(xml.charCodeAt(pos)))
1094
+ pos++;
1095
+ const orderedNode = { [tagName]: [] };
1096
+ if (hasAttrs) {
1097
+ const attrKey = ":@";
1098
+ orderedNode[attrKey] = {};
1099
+ for (const name in attrs) {
1100
+ orderedNode[attrKey][this._attrPrefix + name] = this.parseAttributeValue(attrs[name]);
1101
+ }
1102
+ }
1103
+ if (pos < len && xml.charCodeAt(pos) === 47) {
1104
+ pos += 2;
1105
+ parent.push(orderedNode);
1106
+ continue;
1107
+ }
1108
+ if (pos < len && xml.charCodeAt(pos) === 62) {
1109
+ pos++;
1110
+ pos = this.parseChildrenOrdered(xml, pos, len, orderedNode[tagName], childJPath);
1111
+ parent.push(orderedNode);
1112
+ }
1113
+ }
1114
+ if (textContent) {
1115
+ const processed = this.processTagValue(textContent, this._textNodeName, jPath, false, true);
1116
+ if (processed !== undefined && processed !== "")
1117
+ parent.push({ [this._textNodeName]: processed });
1118
+ }
1119
+ return pos;
1120
+ }
1121
+ applyAttributes(obj, attrs, jPath) {
1122
+ const prefix = this._attrPrefix;
1123
+ if (this._attrsGroupName) {
1124
+ const group = {};
1125
+ for (const name in attrs) {
1126
+ group[prefix + name] = this.parseAttributeValue(attrs[name]);
1127
+ }
1128
+ obj[this._attrsGroupName] = group;
1129
+ } else {
1130
+ for (const name in attrs) {
1131
+ obj[prefix + name] = this.parseAttributeValue(attrs[name]);
1132
+ }
1133
+ }
1134
+ }
1135
+ parsePiAttributes(content) {
1136
+ const attrs = {};
1137
+ let i = 0;
1138
+ const len = content.length;
1139
+ while (i < len) {
1140
+ while (i < len && isWhitespace(content.charCodeAt(i)))
1141
+ i++;
1142
+ if (i >= len)
1143
+ break;
1144
+ const nameStart = i;
1145
+ while (i < len && !isWhitespace(content.charCodeAt(i)) && content.charCodeAt(i) !== 61)
1146
+ i++;
1147
+ const name = content.substring(nameStart, i);
1148
+ if (!name)
1149
+ break;
1150
+ while (i < len && isWhitespace(content.charCodeAt(i)))
1151
+ i++;
1152
+ if (i < len && content.charCodeAt(i) === 61) {
1153
+ i++;
1154
+ while (i < len && isWhitespace(content.charCodeAt(i)))
1155
+ i++;
1156
+ if (i < len) {
1157
+ const quote = content.charCodeAt(i);
1158
+ if (quote === 34 || quote === 39) {
1159
+ i++;
1160
+ const valueStart = i;
1161
+ while (i < len && content.charCodeAt(i) !== quote)
1162
+ i++;
1163
+ attrs[name] = content.substring(valueStart, i);
1164
+ if (i < len)
1165
+ i++;
1166
+ }
1167
+ }
1168
+ }
1169
+ }
1170
+ return attrs;
1171
+ }
1172
+ }
1173
+
1174
+ // src/aws/client.ts
1175
+ function resolveS3Endpoint(options) {
1176
+ const base = options.endpoint || `s3.${options.region}.amazonaws.com`;
1177
+ if (!options.bucket) {
1178
+ return { host: base, path: options.path };
1179
+ }
1180
+ if (options.forcePathStyle) {
1181
+ const path = options.path === "/" ? `/${options.bucket}` : `/${options.bucket}${options.path}`;
1182
+ return { host: base, path };
1183
+ }
1184
+ return { host: `${options.bucket}.${base}`, path: options.path };
1185
+ }
1186
+
1187
+ class AWSClient {
1188
+ credentials;
1189
+ config;
1190
+ cache;
1191
+ xmlParser;
1192
+ constructor(credentials, config) {
1193
+ this.config = {
1194
+ maxRetries: 3,
1195
+ retryDelay: 1000,
1196
+ cacheEnabled: true,
1197
+ defaultCacheTTL: 60000,
1198
+ ...config
1199
+ };
1200
+ this.credentials = credentials || this.loadCredentials();
1201
+ this.cache = new Map;
1202
+ this.xmlParser = new XMLParser({
1203
+ ignoreAttributes: false,
1204
+ attributeNamePrefix: "@_",
1205
+ textNodeName: "#text",
1206
+ parseAttributeValue: true,
1207
+ trimValues: true
1208
+ });
1209
+ }
1210
+ loadCredentials() {
1211
+ const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
1212
+ const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
1213
+ const sessionToken = process.env.AWS_SESSION_TOKEN;
1214
+ if (accessKeyId && secretAccessKey) {
1215
+ return {
1216
+ accessKeyId,
1217
+ secretAccessKey,
1218
+ sessionToken
1219
+ };
1220
+ }
1221
+ const fileCredentials = this.loadCredentialsFromFile();
1222
+ if (fileCredentials) {
1223
+ return fileCredentials;
1224
+ }
1225
+ return {
1226
+ accessKeyId: "",
1227
+ secretAccessKey: ""
1228
+ };
1229
+ }
1230
+ loadCredentialsFromFile() {
1231
+ const profile = this.config?.profile || process.env.AWS_PROFILE || "default";
1232
+ const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE || join(homedir(), ".aws", "credentials");
1233
+ if (!existsSync(credentialsPath)) {
1234
+ return null;
1235
+ }
1236
+ try {
1237
+ const content = readFileSync(credentialsPath, "utf-8");
1238
+ const credentials = this.parseCredentialsFile(content, profile);
1239
+ if (credentials.accessKeyId && credentials.secretAccessKey) {
1240
+ return credentials;
1241
+ }
1242
+ } catch {}
1243
+ return null;
1244
+ }
1245
+ parseCredentialsFile(content, profile) {
1246
+ const lines = content.split(`
1247
+ `);
1248
+ let currentProfile = "";
1249
+ let accessKeyId = "";
1250
+ let secretAccessKey = "";
1251
+ let sessionToken;
1252
+ for (const line of lines) {
1253
+ const trimmed = line.trim();
1254
+ if (!trimmed || trimmed.startsWith("#")) {
1255
+ continue;
1256
+ }
1257
+ const profileMatch = trimmed.match(/^\[([^\]]+)\]$/);
1258
+ if (profileMatch) {
1259
+ currentProfile = profileMatch[1];
1260
+ continue;
1261
+ }
1262
+ if (currentProfile === profile) {
1263
+ const [key, ...valueParts] = trimmed.split("=");
1264
+ const value = valueParts.join("=").trim();
1265
+ if (key.trim() === "aws_access_key_id") {
1266
+ accessKeyId = value;
1267
+ } else if (key.trim() === "aws_secret_access_key") {
1268
+ secretAccessKey = value;
1269
+ } else if (key.trim() === "aws_session_token") {
1270
+ sessionToken = value;
1271
+ }
1272
+ }
1273
+ }
1274
+ return { accessKeyId, secretAccessKey, sessionToken };
1275
+ }
1276
+ ec2CredentialsCache;
1277
+ async getCredentials() {
1278
+ const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
1279
+ const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
1280
+ if (accessKeyId && secretAccessKey) {
1281
+ return {
1282
+ accessKeyId,
1283
+ secretAccessKey,
1284
+ sessionToken: process.env.AWS_SESSION_TOKEN
1285
+ };
1286
+ }
1287
+ const fileCredentials = this.loadCredentialsFromFile();
1288
+ if (fileCredentials) {
1289
+ return fileCredentials;
1290
+ }
1291
+ if (this.ec2CredentialsCache) {
1292
+ const now = Date.now();
1293
+ if (this.ec2CredentialsCache.expiration > now + 5 * 60 * 1000) {
1294
+ return this.ec2CredentialsCache.credentials;
1295
+ }
1296
+ }
1297
+ try {
1298
+ const tokenResponse = await fetch("http://169.254.169.254/latest/api/token", {
1299
+ method: "PUT",
1300
+ headers: {
1301
+ "X-aws-ec2-metadata-token-ttl-seconds": "21600"
1302
+ }
1303
+ });
1304
+ const token = await tokenResponse.text();
1305
+ const roleResponse = await fetch("http://169.254.169.254/latest/meta-data/iam/security-credentials/", {
1306
+ headers: { "X-aws-ec2-metadata-token": token }
1307
+ });
1308
+ const roleName = await roleResponse.text();
1309
+ const credsResponse = await fetch(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${roleName}`, {
1310
+ headers: { "X-aws-ec2-metadata-token": token }
1311
+ });
1312
+ const credsData = await credsResponse.json();
1313
+ const credentials = {
1314
+ accessKeyId: credsData.AccessKeyId,
1315
+ secretAccessKey: credsData.SecretAccessKey,
1316
+ sessionToken: credsData.Token
1317
+ };
1318
+ this.ec2CredentialsCache = {
1319
+ credentials,
1320
+ expiration: new Date(credsData.Expiration).getTime()
1321
+ };
1322
+ return credentials;
1323
+ } catch (error) {
1324
+ throw new Error("AWS credentials not found. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or run on an EC2 instance with an IAM role.");
1325
+ }
1326
+ }
1327
+ async request(options) {
1328
+ if (options.method === "GET" && this.config.cacheEnabled && options.cacheKey) {
1329
+ const cached = this.getFromCache(options.cacheKey);
1330
+ if (cached !== null) {
1331
+ return cached;
1332
+ }
1333
+ }
1334
+ const maxRetries = options.retries ?? this.config.maxRetries ?? 3;
1335
+ let lastError = null;
1336
+ for (let attempt = 0;attempt <= maxRetries; attempt++) {
1337
+ try {
1338
+ const result = await this.makeRequest(options);
1339
+ if (options.method === "GET" && this.config.cacheEnabled && options.cacheKey) {
1340
+ this.setInCache(options.cacheKey, result, options.cacheTTL ?? this.config.defaultCacheTTL ?? 60000);
1341
+ }
1342
+ return result;
1343
+ } catch (error) {
1344
+ lastError = error;
1345
+ const isRetryable = this.shouldRetry(error);
1346
+ if (!isRetryable) {
1347
+ throw error;
1348
+ }
1349
+ if (attempt === maxRetries) {
1350
+ throw error;
1351
+ }
1352
+ const delay = this.calculateRetryDelay(attempt);
1353
+ await this.sleep(delay);
1354
+ }
1355
+ }
1356
+ throw lastError || new Error("Request failed after retries");
1357
+ }
1358
+ async makeRequest(options) {
1359
+ const credentials = options.credentials || (this.credentials?.accessKeyId ? this.credentials : await this.getCredentials());
1360
+ if (!credentials || !credentials.accessKeyId || !credentials.secretAccessKey) {
1361
+ throw new Error("AWS credentials not provided");
1362
+ }
1363
+ const url = this.buildUrl(options);
1364
+ const headers = this.signRequest(options, credentials);
1365
+ const response = await fetch(url, {
1366
+ method: options.method,
1367
+ headers,
1368
+ body: options.body
1369
+ });
1370
+ const responseText = await response.text();
1371
+ if (!response.ok) {
1372
+ throw this.parseError(responseText, response.status, response.headers);
1373
+ }
1374
+ if (!responseText || responseText.trim() === "") {
1375
+ if (options.returnHeaders) {
1376
+ return { body: null, headers: this.headersToObject(response.headers) };
1377
+ }
1378
+ return null;
1379
+ }
1380
+ if (options.rawResponse) {
1381
+ if (options.returnHeaders) {
1382
+ return { body: responseText, headers: this.headersToObject(response.headers) };
1383
+ }
1384
+ return responseText;
1385
+ }
1386
+ let body;
1387
+ if (responseText.startsWith("<")) {
1388
+ body = this.parseXmlResponse(responseText);
1389
+ } else {
1390
+ try {
1391
+ body = JSON.parse(responseText);
1392
+ } catch {
1393
+ body = responseText;
1394
+ }
1395
+ }
1396
+ if (options.returnHeaders) {
1397
+ return { body, headers: this.headersToObject(response.headers) };
1398
+ }
1399
+ return body;
1400
+ }
1401
+ headersToObject(headers) {
1402
+ const result = {};
1403
+ headers.forEach((value, key) => {
1404
+ result[key] = value;
1405
+ });
1406
+ return result;
1407
+ }
1408
+ buildUrl(options) {
1409
+ const { service, region, queryParams } = options;
1410
+ let { path } = options;
1411
+ let host;
1412
+ if (service === "s3") {
1413
+ const resolved = resolveS3Endpoint({
1414
+ region,
1415
+ path,
1416
+ bucket: options.bucket,
1417
+ endpoint: this.config.endpoint,
1418
+ forcePathStyle: this.config.forcePathStyle
1419
+ });
1420
+ host = resolved.host;
1421
+ path = resolved.path;
1422
+ } else if (service === "cloudfront") {
1423
+ host = "cloudfront.amazonaws.com";
1424
+ } else if (service === "iam") {
1425
+ host = "iam.amazonaws.com";
1426
+ } else if (service === "route53") {
1427
+ host = "route53.amazonaws.com";
1428
+ } else if (service === "route53domains") {
1429
+ host = "route53domains.us-east-1.amazonaws.com";
1430
+ } else if (service === "ecr") {
1431
+ host = `api.ecr.${region}.amazonaws.com`;
1432
+ } else if (service === "ses") {
1433
+ host = `email.${region}.amazonaws.com`;
1434
+ } else {
1435
+ host = `${service}.${region}.amazonaws.com`;
1436
+ }
1437
+ let url = `https://${host}${path}`;
1438
+ if (queryParams && Object.keys(queryParams).length > 0) {
1439
+ const queryString = Object.keys(queryParams).map((k) => `${this.uriEncode(k)}=${this.uriEncode(queryParams[k])}`).join("&");
1440
+ url += `?${queryString}`;
1441
+ }
1442
+ return url;
1443
+ }
1444
+ signRequest(options, credentials) {
1445
+ const { service, region, method, queryParams, body } = options;
1446
+ let { path } = options;
1447
+ const now = new Date;
1448
+ const amzDate = this.getAmzDate(now);
1449
+ const dateStamp = this.getDateStamp(now);
1450
+ let host;
1451
+ if (service === "s3") {
1452
+ const resolved = resolveS3Endpoint({
1453
+ region,
1454
+ path,
1455
+ bucket: options.bucket,
1456
+ endpoint: this.config.endpoint,
1457
+ forcePathStyle: this.config.forcePathStyle
1458
+ });
1459
+ host = resolved.host;
1460
+ path = resolved.path;
1461
+ } else if (service === "cloudfront") {
1462
+ host = "cloudfront.amazonaws.com";
1463
+ } else if (service === "iam") {
1464
+ host = "iam.amazonaws.com";
1465
+ } else if (service === "route53") {
1466
+ host = "route53.amazonaws.com";
1467
+ } else if (service === "route53domains") {
1468
+ host = "route53domains.us-east-1.amazonaws.com";
1469
+ } else if (service === "ecr") {
1470
+ host = `api.ecr.${region}.amazonaws.com`;
1471
+ } else if (service === "ses") {
1472
+ host = `email.${region}.amazonaws.com`;
1473
+ } else {
1474
+ host = `${service}.${region}.amazonaws.com`;
1475
+ }
1476
+ const headers = {
1477
+ host,
1478
+ "x-amz-date": amzDate,
1479
+ ...options.headers || {}
1480
+ };
1481
+ if (credentials.sessionToken) {
1482
+ headers["x-amz-security-token"] = credentials.sessionToken;
1483
+ }
1484
+ if (body) {
1485
+ const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
1486
+ if (!hasContentType) {
1487
+ headers["content-type"] = "application/x-www-form-urlencoded";
1488
+ }
1489
+ headers["content-length"] = Buffer.byteLength(body).toString();
1490
+ }
1491
+ const payloadHash = this.sha256(body || "");
1492
+ headers["x-amz-content-sha256"] = payloadHash;
1493
+ const canonicalUri = path;
1494
+ const canonicalQueryString = queryParams ? Object.keys(queryParams).sort().map((k) => `${this.uriEncode(k)}=${this.uriEncode(queryParams[k])}`).join("&") : "";
1495
+ const sortedHeaderKeys = Object.keys(headers).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
1496
+ const canonicalHeaders = sortedHeaderKeys.map((key) => `${key.toLowerCase()}:${headers[key].trim()}
1497
+ `).join("");
1498
+ const signedHeaders = sortedHeaderKeys.map((key) => key.toLowerCase()).join(";");
1499
+ const canonicalRequest = [
1500
+ method,
1501
+ canonicalUri,
1502
+ canonicalQueryString,
1503
+ canonicalHeaders,
1504
+ signedHeaders,
1505
+ payloadHash
1506
+ ].join(`
1507
+ `);
1508
+ const algorithm = "AWS4-HMAC-SHA256";
1509
+ let signingService = service;
1510
+ if (service === "email")
1511
+ signingService = "ses";
1512
+ const credentialScope = `${dateStamp}/${region}/${signingService}/aws4_request`;
1513
+ const stringToSign = [
1514
+ algorithm,
1515
+ amzDate,
1516
+ credentialScope,
1517
+ this.sha256(canonicalRequest)
1518
+ ].join(`
1519
+ `);
1520
+ const signingKey = this.getSignatureKey(credentials.secretAccessKey, dateStamp, region, signingService);
1521
+ const signature = this.hmac(signingKey, stringToSign);
1522
+ const authorizationHeader = `${algorithm} Credential=${credentials.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
1523
+ return {
1524
+ ...headers,
1525
+ Authorization: authorizationHeader
1526
+ };
1527
+ }
1528
+ getAmzDate(date) {
1529
+ return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
1530
+ }
1531
+ getDateStamp(date) {
1532
+ return date.toISOString().slice(0, 10).replace(/-/g, "");
1533
+ }
1534
+ uriEncode(str) {
1535
+ return encodeURIComponent(str).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
1536
+ }
1537
+ sha256(data) {
1538
+ return crypto.createHash("sha256").update(data, "utf8").digest("hex");
1539
+ }
1540
+ hmac(key, data) {
1541
+ return crypto.createHmac("sha256", key).update(data, "utf8").digest("hex");
1542
+ }
1543
+ getSignatureKey(key, dateStamp, region, service) {
1544
+ const kDate = crypto.createHmac("sha256", `AWS4${key}`).update(dateStamp).digest();
1545
+ const kRegion = crypto.createHmac("sha256", kDate).update(region).digest();
1546
+ const kService = crypto.createHmac("sha256", kRegion).update(service).digest();
1547
+ const kSigning = crypto.createHmac("sha256", kService).update("aws4_request").digest();
1548
+ return kSigning;
1549
+ }
1550
+ parseXmlResponse(xml) {
1551
+ try {
1552
+ const parsed = this.xmlParser.parse(xml);
1553
+ if (parsed.ErrorResponse) {
1554
+ throw this.createErrorFromXml(parsed.ErrorResponse.Error);
1555
+ }
1556
+ const keys = Object.keys(parsed);
1557
+ if (keys.length === 1) {
1558
+ return parsed[keys[0]];
1559
+ }
1560
+ return parsed;
1561
+ } catch (error) {
1562
+ if (error.code || error.statusCode) {
1563
+ throw error;
1564
+ }
1565
+ return {};
1566
+ }
1567
+ }
1568
+ parseError(responseText, statusCode, headers) {
1569
+ const error = new Error;
1570
+ error.statusCode = statusCode;
1571
+ error.requestId = headers.get("x-amzn-requestid") || headers.get("x-amz-request-id") || undefined;
1572
+ if (responseText.startsWith("<")) {
1573
+ try {
1574
+ const parsed = this.xmlParser.parse(responseText);
1575
+ if (parsed.ErrorResponse?.Error) {
1576
+ const awsError = parsed.ErrorResponse.Error;
1577
+ error.code = awsError.Code;
1578
+ error.message = `AWS Error [${awsError.Code}]: ${awsError.Message || "Unknown error"}`;
1579
+ error.type = awsError.Type;
1580
+ return error;
1581
+ }
1582
+ if (parsed.Error) {
1583
+ error.code = parsed.Error.Code;
1584
+ error.message = `AWS Error [${parsed.Error.Code}]: ${parsed.Error.Message || "Unknown error"}`;
1585
+ return error;
1586
+ }
1587
+ } catch {}
1588
+ }
1589
+ try {
1590
+ const json = JSON.parse(responseText);
1591
+ if (json.__type || json.code) {
1592
+ error.code = json.__type || json.code;
1593
+ error.message = `AWS Error [${error.code}]: ${json.message || json.Message || "Unknown error"}`;
1594
+ return error;
1595
+ }
1596
+ } catch {}
1597
+ error.message = `AWS API Error (${statusCode}): ${responseText}`;
1598
+ return error;
1599
+ }
1600
+ createErrorFromXml(errorData) {
1601
+ const error = new Error;
1602
+ error.code = errorData.Code;
1603
+ error.message = `AWS Error [${errorData.Code}]: ${errorData.Message || "Unknown error"}`;
1604
+ error.type = errorData.Type;
1605
+ return error;
1606
+ }
1607
+ isRetryableError(code) {
1608
+ const retryableCodes = [
1609
+ "RequestTimeout",
1610
+ "RequestTimeoutException",
1611
+ "PriorRequestNotComplete",
1612
+ "ConnectionError",
1613
+ "ThrottlingException",
1614
+ "Throttling",
1615
+ "TooManyRequestsException",
1616
+ "ProvisionedThroughputExceededException",
1617
+ "RequestLimitExceeded",
1618
+ "BandwidthLimitExceeded",
1619
+ "SlowDown",
1620
+ "ServiceUnavailable",
1621
+ "ServiceUnavailableException",
1622
+ "InternalError",
1623
+ "InternalFailure",
1624
+ "InternalServerError",
1625
+ "InternalServiceException",
1626
+ "TransientError",
1627
+ "TransientFailure",
1628
+ "IDPCommunicationErrorException",
1629
+ "NetworkError",
1630
+ "ConnectionRefusedException",
1631
+ "EC2ThrottledException",
1632
+ "503 Slow Down",
1633
+ "500 InternalError"
1634
+ ];
1635
+ return retryableCodes.includes(code);
1636
+ }
1637
+ isRetryableStatusCode(statusCode) {
1638
+ return statusCode >= 500 || statusCode === 429;
1639
+ }
1640
+ shouldRetry(error) {
1641
+ if (error.name === "FetchError" || error.name === "TypeError" || error.code === "ECONNRESET") {
1642
+ return true;
1643
+ }
1644
+ if (error.code && this.isRetryableError(error.code)) {
1645
+ return true;
1646
+ }
1647
+ if (error.statusCode && this.isRetryableStatusCode(error.statusCode)) {
1648
+ return true;
1649
+ }
1650
+ if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
1651
+ return false;
1652
+ }
1653
+ if (error.statusCode) {
1654
+ return false;
1655
+ }
1656
+ return true;
1657
+ }
1658
+ calculateRetryDelay(attempt) {
1659
+ const baseDelay = this.config.retryDelay ?? 1000;
1660
+ const maxDelay = 30000;
1661
+ const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
1662
+ const jitter = Math.random() * 0.3 * delay;
1663
+ return delay + jitter;
1664
+ }
1665
+ sleep(ms) {
1666
+ return new Promise((resolve) => setTimeout(resolve, ms));
1667
+ }
1668
+ getFromCache(key) {
1669
+ const entry = this.cache.get(key);
1670
+ if (!entry) {
1671
+ return null;
1672
+ }
1673
+ if (Date.now() > entry.expires) {
1674
+ this.cache.delete(key);
1675
+ return null;
1676
+ }
1677
+ return entry.data;
1678
+ }
1679
+ setInCache(key, data, ttl) {
1680
+ this.cache.set(key, {
1681
+ data,
1682
+ expires: Date.now() + ttl
1683
+ });
1684
+ }
1685
+ clearCache() {
1686
+ this.cache.clear();
1687
+ }
1688
+ clearExpiredCache() {
1689
+ const now = Date.now();
1690
+ for (const [key, entry] of this.cache.entries()) {
1691
+ if (now > entry.expires) {
1692
+ this.cache.delete(key);
1693
+ }
1694
+ }
1695
+ }
1696
+ }
1697
+ function buildQueryParams(params) {
1698
+ const result = {};
1699
+ for (const [key, value] of Object.entries(params)) {
1700
+ if (value === undefined || value === null) {
1701
+ continue;
1702
+ }
1703
+ if (Array.isArray(value)) {
1704
+ value.forEach((item, index) => {
1705
+ result[`${key}.${index + 1}`] = String(item);
1706
+ });
1707
+ } else if (typeof value === "object") {
1708
+ for (const [subKey, subValue] of Object.entries(value)) {
1709
+ result[`${key}.${subKey}`] = String(subValue);
1710
+ }
1711
+ } else {
1712
+ result[key] = String(value);
1713
+ }
1714
+ }
1715
+ return result;
1716
+ }
1717
+ function detectCredentialSource() {
1718
+ const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
1719
+ const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
1720
+ const emptyEnvKey = accessKeyId === "";
1721
+ const emptyEnvSecret = secretAccessKey === "";
1722
+ if (accessKeyId && secretAccessKey) {
1723
+ return {
1724
+ source: "env",
1725
+ emptyEnvKey,
1726
+ emptyEnvSecret,
1727
+ description: "environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)"
1728
+ };
1729
+ }
1730
+ const profile = process.env.AWS_PROFILE || "default";
1731
+ const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE || join(homedir(), ".aws", "credentials");
1732
+ if (existsSync(credentialsPath)) {
1733
+ return {
1734
+ source: "file",
1735
+ profile,
1736
+ emptyEnvKey,
1737
+ emptyEnvSecret,
1738
+ description: `~/.aws/credentials (profile: ${profile})`
1739
+ };
1740
+ }
1741
+ return {
1742
+ source: "ec2",
1743
+ emptyEnvKey,
1744
+ emptyEnvSecret,
1745
+ description: "EC2 instance metadata service (IMDSv2)"
1746
+ };
1747
+ }
1748
+
1749
+ export { resolveS3Endpoint, AWSClient, buildQueryParams, detectCredentialSource };