@stacksjs/ts-cloud 0.9.2 → 0.9.4

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 (191) hide show
  1. package/dist/aws/index.js +1 -269
  2. package/dist/bin/chunk-00kg80qg.js +1 -0
  3. package/dist/bin/chunk-09nwf2gy.js +34 -0
  4. package/dist/bin/chunk-1k5kszjp.js +111 -0
  5. package/dist/bin/chunk-21e0mavm.js +1 -0
  6. package/dist/bin/chunk-271gk1n2.js +6 -0
  7. package/dist/bin/chunk-2empps47.js +2 -0
  8. package/dist/bin/chunk-38pq971s.js +2 -0
  9. package/dist/bin/chunk-3gykfyq4.js +37 -0
  10. package/dist/bin/chunk-3vqfexc4.js +70 -0
  11. package/dist/bin/chunk-4vrqm9h0.js +2 -0
  12. package/dist/bin/chunk-598yf4bs.js +1 -0
  13. package/dist/bin/chunk-5ectjq0b.js +1 -0
  14. package/dist/bin/chunk-5erkxpt7.js +512 -0
  15. package/dist/bin/chunk-5mrtzemj.js +1 -0
  16. package/dist/bin/chunk-5n9fmabb.js +1 -0
  17. package/dist/bin/chunk-9knpg30y.js +1 -0
  18. package/dist/bin/chunk-9pvsff8g.js +1 -0
  19. package/dist/bin/chunk-ax9mr6wm.js +44 -0
  20. package/dist/bin/chunk-axhnkn5g.js +2 -0
  21. package/dist/bin/chunk-c1vcdgvr.js +1 -0
  22. package/dist/bin/chunk-ctd2vg9w.js +2 -0
  23. package/dist/bin/chunk-dbgffky8.js +1 -0
  24. package/dist/bin/chunk-ddk4rt4j.js +6 -0
  25. package/dist/bin/chunk-dwr30vbv.js +1 -0
  26. package/dist/bin/chunk-e0rkrq70.js +1 -0
  27. package/dist/bin/chunk-e3xrwh9z.js +1 -0
  28. package/dist/bin/chunk-etrb03mt.js +1507 -0
  29. package/dist/bin/chunk-fhc6ntvd.js +2 -0
  30. package/dist/bin/chunk-fpm59y25.js +6 -0
  31. package/dist/bin/chunk-fvbxvq6b.js +1 -0
  32. package/dist/bin/chunk-fy8j3y8p.js +92 -0
  33. package/dist/bin/chunk-fz21b57w.js +1 -0
  34. package/dist/bin/chunk-gavvf0pg.js +141 -0
  35. package/dist/bin/chunk-ggn7ax8p.js +4 -0
  36. package/dist/bin/chunk-gpe2prkm.js +1 -0
  37. package/dist/bin/chunk-h5pa5men.js +2 -0
  38. package/dist/bin/chunk-hm08xdxf.js +2 -0
  39. package/dist/bin/chunk-hzgz13nf.js +1 -0
  40. package/dist/bin/chunk-j703btc5.js +50 -0
  41. package/dist/bin/chunk-k9t9wvms.js +1 -0
  42. package/dist/bin/chunk-m669wtgr.js +1 -0
  43. package/dist/bin/chunk-m7dgskt1.js +1 -0
  44. package/dist/bin/chunk-mh0kdzqp.js +2 -0
  45. package/dist/bin/chunk-mr0atd2s.js +2 -0
  46. package/dist/bin/chunk-mz0wbbsj.js +3 -0
  47. package/dist/bin/chunk-ngcyftm2.js +1 -0
  48. package/dist/bin/chunk-p66ptpmr.js +2 -0
  49. package/dist/bin/chunk-qk9qgepa.js +1 -0
  50. package/dist/bin/chunk-rxcvf10f.js +7364 -0
  51. package/dist/bin/chunk-rytk89az.js +60 -0
  52. package/dist/bin/chunk-tga3hhwk.js +6 -0
  53. package/dist/bin/chunk-tx0tqq2k.js +8 -0
  54. package/dist/bin/chunk-vek8a0w6.js +1 -0
  55. package/dist/bin/chunk-vm3q5gf2.js +3 -0
  56. package/dist/bin/chunk-y7s5r8y6.js +3 -0
  57. package/dist/bin/chunk-yv9sth30.js +1 -0
  58. package/dist/bin/chunk-zmegvjp8.js +581 -0
  59. package/dist/bin/cli.js +417 -10597
  60. package/dist/bin/dashboard-server.js +1 -6998
  61. package/dist/chunk-0ccta6z6.js +6 -0
  62. package/dist/chunk-0k1cs6pp.js +1 -0
  63. package/dist/chunk-1egjn203.js +704 -0
  64. package/dist/chunk-2wx29qga.js +5 -0
  65. package/dist/chunk-5m5rqmv7.js +1 -0
  66. package/dist/chunk-8ea5022g.js +114 -0
  67. package/dist/chunk-8xqn3c0w.js +2 -0
  68. package/dist/chunk-b4esxhmw.js +2 -0
  69. package/dist/chunk-b8e5wzwn.js +44 -0
  70. package/dist/chunk-bggt4n6e.js +2 -0
  71. package/dist/chunk-cwkg37rs.js +37 -0
  72. package/dist/chunk-dskvqt67.js +7355 -0
  73. package/dist/chunk-gahsdmxf.js +1617 -0
  74. package/dist/chunk-gnv3r2jg.js +1 -0
  75. package/dist/chunk-hg3c48cp.js +34 -0
  76. package/dist/chunk-m5azeva3.js +2 -0
  77. package/dist/chunk-r3qf56b3.js +92 -0
  78. package/dist/chunk-sdqa9ghv.js +141 -0
  79. package/dist/chunk-svrvvcm7.js +1 -0
  80. package/dist/chunk-v0p3hpc3.js +60 -0
  81. package/dist/chunk-wdzjbecg.js +50 -0
  82. package/dist/chunk-ww8k3g7j.js +1 -0
  83. package/dist/chunk-xmqfc62w.js +1 -0
  84. package/dist/chunk-xrebj679.js +435 -0
  85. package/dist/chunk-xt3s24vr.js +2 -0
  86. package/dist/chunk-y21zk0pn.js +4 -0
  87. package/dist/deploy/attach-credentials.d.ts +57 -0
  88. package/dist/deploy/index.js +1 -168
  89. package/dist/deploy/site-ports.d.ts +151 -0
  90. package/dist/deploy/site-target.d.ts +24 -1
  91. package/dist/dns/index.js +1 -41
  92. package/dist/drivers/index.js +1 -154
  93. package/dist/index.js +100 -6129
  94. package/dist/protection/index.js +1 -89
  95. package/dist/push/index.js +1 -509
  96. package/dist/spend/index.js +1 -173
  97. package/dist/ui/404.html +16 -548
  98. package/dist/ui/_stx/chunk.5ddb5087.js +90 -0
  99. package/dist/ui/_stx/chunk.9fd39d5b.js +86 -0
  100. package/dist/ui/_stx/chunk.d5301f79.js +119 -0
  101. package/dist/ui/_stx/crosswind.222ed683.css +1 -0
  102. package/dist/ui/_stx/crosswind.616c25f3.css +1 -0
  103. package/dist/ui/_stx/crosswind.80baa894.css +320 -0
  104. package/dist/ui/_stx/crosswind.906ee17c.css +1 -0
  105. package/dist/ui/_stx/crosswind.996ed49e.css +1 -0
  106. package/dist/ui/_stx/crosswind.b7a99a5c.css +1 -0
  107. package/dist/ui/_stx/router.fa5bc4dc.js +4 -0
  108. package/dist/ui/_stx/runtime.c696d17a.js +1 -0
  109. package/dist/ui/_stx/style.448ab192.css +1 -0
  110. package/dist/ui/accept-invitation.html +2 -1133
  111. package/dist/ui/access-denied.html +7 -1130
  112. package/dist/ui/account/automation.html +12 -1134
  113. package/dist/ui/account/security.html +13 -1136
  114. package/dist/ui/applications/compose.html +12 -1134
  115. package/dist/ui/applications/new.html +13 -1137
  116. package/dist/ui/data/backups.html +91 -1136
  117. package/dist/ui/data/services.html +89 -1136
  118. package/dist/ui/data/volumes.html +61 -1136
  119. package/dist/ui/index.html +60 -1136
  120. package/dist/ui/infrastructure/topology.html +128 -1135
  121. package/dist/ui/integrations.html +13 -1138
  122. package/dist/ui/operations/alerts.html +59 -1136
  123. package/dist/ui/operations/configuration.html +13 -1135
  124. package/dist/ui/operations/jobs.html +87 -1136
  125. package/dist/ui/operations/maintenance.html +12 -1134
  126. package/dist/ui/operations/observability.html +93 -1136
  127. package/dist/ui/operations/previews.html +12 -1134
  128. package/dist/ui/operations/queue.html +12 -1134
  129. package/dist/ui/operations/regions.html +12 -1134
  130. package/dist/ui/operations/releases.html +12 -1134
  131. package/dist/ui/operations/spend.html +65 -1136
  132. package/dist/ui/operations/workloads.html +115 -1136
  133. package/dist/ui/robots.txt +2 -0
  134. package/dist/ui/security.html +24 -1136
  135. package/dist/ui/server/actions.html +67 -1138
  136. package/dist/ui/server/activity.html +7 -1130
  137. package/dist/ui/server/capacity.html +12 -1134
  138. package/dist/ui/server/database.html +166 -1135
  139. package/dist/ui/server/deployments.html +60 -1136
  140. package/dist/ui/server/diagnostics.html +7 -1130
  141. package/dist/ui/server/firewall.html +286 -1212
  142. package/dist/ui/server/fleet.html +45 -1136
  143. package/dist/ui/server/logs.html +34 -1135
  144. package/dist/ui/server/metrics.html +124 -1140
  145. package/dist/ui/server/security.html +7 -1130
  146. package/dist/ui/server/services.html +46 -1133
  147. package/dist/ui/server/sites.html +287 -1137
  148. package/dist/ui/server/ssh-keys.html +62 -1135
  149. package/dist/ui/server/team.html +155 -1136
  150. package/dist/ui/server/terminal.html +97 -1183
  151. package/dist/ui/serverless/alarms.html +62 -1135
  152. package/dist/ui/serverless/assets.html +47 -1132
  153. package/dist/ui/serverless/cost.html +7 -1130
  154. package/dist/ui/serverless/data.html +46 -1135
  155. package/dist/ui/serverless/deployments.html +47 -1132
  156. package/dist/ui/serverless/firewall.html +7 -1130
  157. package/dist/ui/serverless/functions.html +50 -1136
  158. package/dist/ui/serverless/logs.html +34 -1135
  159. package/dist/ui/serverless/metrics.html +7 -1130
  160. package/dist/ui/serverless/queues.html +58 -1135
  161. package/dist/ui/serverless/secrets.html +62 -1136
  162. package/dist/ui/serverless/traces.html +12 -1134
  163. package/dist/ui/serverless.html +64 -1137
  164. package/dist/ui-src/pages/server/firewall.stx +14 -14
  165. package/package.json +3 -3
  166. package/dist/chunk-01d86gt1.js +0 -1324
  167. package/dist/chunk-050r7ycy.js +0 -46516
  168. package/dist/chunk-29rse4p1.js +0 -12203
  169. package/dist/chunk-32e7ya18.js +0 -642
  170. package/dist/chunk-4cjrg98a.js +0 -597
  171. package/dist/chunk-50jpda9q.js +0 -371
  172. package/dist/chunk-6a1t7fnq.js +0 -12121
  173. package/dist/chunk-728jvrr0.js +0 -1701
  174. package/dist/chunk-7m60qnc8.js +0 -1762
  175. package/dist/chunk-aa2dkn7b.js +0 -205
  176. package/dist/chunk-d48vtdj4.js +0 -433
  177. package/dist/chunk-f55nkpvb.js +0 -8
  178. package/dist/chunk-fgk8cqew.js +0 -152
  179. package/dist/chunk-he9a874b.js +0 -769
  180. package/dist/chunk-hg7rhrgd.js +0 -7274
  181. package/dist/chunk-k2yyatfw.js +0 -10
  182. package/dist/chunk-k4px0bnv.js +0 -23
  183. package/dist/chunk-nsgqsmrh.js +0 -1779
  184. package/dist/chunk-qr803fye.js +0 -2122
  185. package/dist/chunk-rds0sy87.js +0 -1771
  186. package/dist/chunk-rxgchb08.js +0 -42033
  187. package/dist/chunk-ttz2ra5j.js +0 -12
  188. package/dist/chunk-v0bahtg2.js +0 -4
  189. package/dist/chunk-va2yd85b.js +0 -200
  190. package/dist/chunk-x9s0cqfx.js +0 -13
  191. package/dist/chunk-zqtpg06c.js +0 -1752
@@ -1,1752 +0,0 @@
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 rawEndpoint = options.endpoint || `s3.${options.region}.amazonaws.com`;
1177
- const parsed = new URL(/^https?:\/\//i.test(rawEndpoint) ? rawEndpoint : `https://${rawEndpoint}`);
1178
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.pathname !== "/" && parsed.pathname !== "" || parsed.search || parsed.hash || parsed.username || parsed.password) {
1179
- throw new Error("S3 endpoint must be an HTTP(S) origin without a path");
1180
- }
1181
- const protocol = parsed.protocol.slice(0, -1);
1182
- const base = parsed.host;
1183
- if (!options.bucket) {
1184
- return { protocol, host: base, path: options.path };
1185
- }
1186
- if (options.forcePathStyle) {
1187
- const path = options.path === "/" ? `/${options.bucket}` : `/${options.bucket}${options.path}`;
1188
- return { protocol, host: base, path };
1189
- }
1190
- return { protocol, host: `${options.bucket}.${base}`, path: options.path };
1191
- }
1192
-
1193
- class AWSClient {
1194
- credentials;
1195
- config;
1196
- cache;
1197
- xmlParser;
1198
- constructor(credentials, config) {
1199
- this.config = {
1200
- maxRetries: 3,
1201
- retryDelay: 1000,
1202
- cacheEnabled: true,
1203
- defaultCacheTTL: 60000,
1204
- ...config
1205
- };
1206
- this.credentials = credentials || this.loadCredentials();
1207
- this.cache = new Map;
1208
- this.xmlParser = new XMLParser({
1209
- ignoreAttributes: false,
1210
- attributeNamePrefix: "@_",
1211
- textNodeName: "#text",
1212
- parseAttributeValue: true,
1213
- trimValues: true
1214
- });
1215
- }
1216
- loadCredentials() {
1217
- const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
1218
- const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
1219
- const sessionToken = process.env.AWS_SESSION_TOKEN;
1220
- if (accessKeyId && secretAccessKey) {
1221
- return {
1222
- accessKeyId,
1223
- secretAccessKey,
1224
- sessionToken
1225
- };
1226
- }
1227
- const fileCredentials = this.loadCredentialsFromFile();
1228
- if (fileCredentials) {
1229
- return fileCredentials;
1230
- }
1231
- return {
1232
- accessKeyId: "",
1233
- secretAccessKey: ""
1234
- };
1235
- }
1236
- loadCredentialsFromFile() {
1237
- const profile = this.config?.profile || process.env.AWS_PROFILE || "default";
1238
- const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE || join(homedir(), ".aws", "credentials");
1239
- if (!existsSync(credentialsPath)) {
1240
- return null;
1241
- }
1242
- try {
1243
- const content = readFileSync(credentialsPath, "utf-8");
1244
- const credentials = this.parseCredentialsFile(content, profile);
1245
- if (credentials.accessKeyId && credentials.secretAccessKey) {
1246
- return credentials;
1247
- }
1248
- } catch {}
1249
- return null;
1250
- }
1251
- parseCredentialsFile(content, profile) {
1252
- const lines = content.split(`
1253
- `);
1254
- let currentProfile = "";
1255
- let accessKeyId = "";
1256
- let secretAccessKey = "";
1257
- let sessionToken;
1258
- for (const line of lines) {
1259
- const trimmed = line.trim();
1260
- if (!trimmed || trimmed.startsWith("#")) {
1261
- continue;
1262
- }
1263
- const profileMatch = trimmed.match(/^\[([^\]]+)\]$/);
1264
- if (profileMatch) {
1265
- currentProfile = profileMatch[1];
1266
- continue;
1267
- }
1268
- if (currentProfile === profile) {
1269
- const [key, ...valueParts] = trimmed.split("=");
1270
- const value = valueParts.join("=").trim();
1271
- if (key.trim() === "aws_access_key_id") {
1272
- accessKeyId = value;
1273
- } else if (key.trim() === "aws_secret_access_key") {
1274
- secretAccessKey = value;
1275
- } else if (key.trim() === "aws_session_token") {
1276
- sessionToken = value;
1277
- }
1278
- }
1279
- }
1280
- return { accessKeyId, secretAccessKey, sessionToken };
1281
- }
1282
- ec2CredentialsCache;
1283
- async getCredentials() {
1284
- const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
1285
- const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
1286
- if (accessKeyId && secretAccessKey) {
1287
- return {
1288
- accessKeyId,
1289
- secretAccessKey,
1290
- sessionToken: process.env.AWS_SESSION_TOKEN
1291
- };
1292
- }
1293
- const fileCredentials = this.loadCredentialsFromFile();
1294
- if (fileCredentials) {
1295
- return fileCredentials;
1296
- }
1297
- if (this.ec2CredentialsCache) {
1298
- const now = Date.now();
1299
- if (this.ec2CredentialsCache.expiration > now + 5 * 60 * 1000) {
1300
- return this.ec2CredentialsCache.credentials;
1301
- }
1302
- }
1303
- try {
1304
- const tokenResponse = await fetch("http://169.254.169.254/latest/api/token", {
1305
- method: "PUT",
1306
- headers: {
1307
- "X-aws-ec2-metadata-token-ttl-seconds": "21600"
1308
- }
1309
- });
1310
- const token = await tokenResponse.text();
1311
- const roleResponse = await fetch("http://169.254.169.254/latest/meta-data/iam/security-credentials/", {
1312
- headers: { "X-aws-ec2-metadata-token": token }
1313
- });
1314
- const roleName = await roleResponse.text();
1315
- const credsResponse = await fetch(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${roleName}`, {
1316
- headers: { "X-aws-ec2-metadata-token": token }
1317
- });
1318
- const credsData = await credsResponse.json();
1319
- const credentials = {
1320
- accessKeyId: credsData.AccessKeyId,
1321
- secretAccessKey: credsData.SecretAccessKey,
1322
- sessionToken: credsData.Token
1323
- };
1324
- this.ec2CredentialsCache = {
1325
- credentials,
1326
- expiration: new Date(credsData.Expiration).getTime()
1327
- };
1328
- return credentials;
1329
- } catch (error) {
1330
- 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.");
1331
- }
1332
- }
1333
- async request(options) {
1334
- if (options.method === "GET" && this.config.cacheEnabled && options.cacheKey) {
1335
- const cached = this.getFromCache(options.cacheKey);
1336
- if (cached !== null) {
1337
- return cached;
1338
- }
1339
- }
1340
- const maxRetries = options.retries ?? this.config.maxRetries ?? 3;
1341
- let lastError = null;
1342
- for (let attempt = 0;attempt <= maxRetries; attempt++) {
1343
- try {
1344
- const result = await this.makeRequest(options);
1345
- if (options.method === "GET" && this.config.cacheEnabled && options.cacheKey) {
1346
- this.setInCache(options.cacheKey, result, options.cacheTTL ?? this.config.defaultCacheTTL ?? 60000);
1347
- }
1348
- return result;
1349
- } catch (error) {
1350
- lastError = error;
1351
- const isRetryable = this.shouldRetry(error);
1352
- if (!isRetryable) {
1353
- throw error;
1354
- }
1355
- if (attempt === maxRetries) {
1356
- throw error;
1357
- }
1358
- const delay = this.calculateRetryDelay(attempt);
1359
- await this.sleep(delay);
1360
- }
1361
- }
1362
- throw lastError || new Error("Request failed after retries");
1363
- }
1364
- async makeRequest(options) {
1365
- const credentials = options.credentials || (this.credentials?.accessKeyId ? this.credentials : await this.getCredentials());
1366
- if (!credentials || !credentials.accessKeyId || !credentials.secretAccessKey) {
1367
- throw new Error("AWS credentials not provided");
1368
- }
1369
- const url = this.buildUrl(options);
1370
- const headers = this.signRequest(options, credentials);
1371
- const response = await fetch(url, {
1372
- method: options.method,
1373
- headers,
1374
- body: options.body
1375
- });
1376
- const responseText = await response.text();
1377
- if (!response.ok) {
1378
- throw this.parseError(responseText, response.status, response.headers);
1379
- }
1380
- if (!responseText || responseText.trim() === "") {
1381
- if (options.returnHeaders) {
1382
- return { body: null, headers: this.headersToObject(response.headers) };
1383
- }
1384
- return null;
1385
- }
1386
- if (options.rawResponse) {
1387
- if (options.returnHeaders) {
1388
- return { body: responseText, headers: this.headersToObject(response.headers) };
1389
- }
1390
- return responseText;
1391
- }
1392
- let body;
1393
- if (responseText.startsWith("<")) {
1394
- body = this.parseXmlResponse(responseText);
1395
- } else {
1396
- try {
1397
- body = JSON.parse(responseText);
1398
- } catch {
1399
- body = responseText;
1400
- }
1401
- }
1402
- if (options.returnHeaders) {
1403
- return { body, headers: this.headersToObject(response.headers) };
1404
- }
1405
- return body;
1406
- }
1407
- headersToObject(headers) {
1408
- const result = {};
1409
- headers.forEach((value, key) => {
1410
- result[key] = value;
1411
- });
1412
- return result;
1413
- }
1414
- buildUrl(options) {
1415
- const { service, region, queryParams } = options;
1416
- let { path } = options;
1417
- let host;
1418
- let protocol = "https";
1419
- if (service === "s3") {
1420
- const resolved = resolveS3Endpoint({
1421
- region,
1422
- path,
1423
- bucket: options.bucket,
1424
- endpoint: this.config.endpoint,
1425
- forcePathStyle: this.config.forcePathStyle
1426
- });
1427
- protocol = resolved.protocol;
1428
- host = resolved.host;
1429
- path = resolved.path;
1430
- } else if (service === "cloudfront") {
1431
- host = "cloudfront.amazonaws.com";
1432
- } else if (service === "iam") {
1433
- host = "iam.amazonaws.com";
1434
- } else if (service === "route53") {
1435
- host = "route53.amazonaws.com";
1436
- } else if (service === "route53domains") {
1437
- host = "route53domains.us-east-1.amazonaws.com";
1438
- } else if (service === "ecr") {
1439
- host = `api.ecr.${region}.amazonaws.com`;
1440
- } else if (service === "ses") {
1441
- host = `email.${region}.amazonaws.com`;
1442
- } else {
1443
- host = `${service}.${region}.amazonaws.com`;
1444
- }
1445
- let url = `${protocol}://${host}${path}`;
1446
- if (queryParams && Object.keys(queryParams).length > 0) {
1447
- const queryString = Object.keys(queryParams).map((k) => `${this.uriEncode(k)}=${this.uriEncode(queryParams[k])}`).join("&");
1448
- url += `?${queryString}`;
1449
- }
1450
- return url;
1451
- }
1452
- signRequest(options, credentials) {
1453
- const { service, region, method, queryParams, body } = options;
1454
- let { path } = options;
1455
- const now = new Date;
1456
- const amzDate = this.getAmzDate(now);
1457
- const dateStamp = this.getDateStamp(now);
1458
- let host;
1459
- if (service === "s3") {
1460
- const resolved = resolveS3Endpoint({
1461
- region,
1462
- path,
1463
- bucket: options.bucket,
1464
- endpoint: this.config.endpoint,
1465
- forcePathStyle: this.config.forcePathStyle
1466
- });
1467
- host = resolved.host;
1468
- path = resolved.path;
1469
- } else if (service === "cloudfront") {
1470
- host = "cloudfront.amazonaws.com";
1471
- } else if (service === "iam") {
1472
- host = "iam.amazonaws.com";
1473
- } else if (service === "route53") {
1474
- host = "route53.amazonaws.com";
1475
- } else if (service === "route53domains") {
1476
- host = "route53domains.us-east-1.amazonaws.com";
1477
- } else if (service === "ecr") {
1478
- host = `api.ecr.${region}.amazonaws.com`;
1479
- } else if (service === "ses") {
1480
- host = `email.${region}.amazonaws.com`;
1481
- } else {
1482
- host = `${service}.${region}.amazonaws.com`;
1483
- }
1484
- const headers = {
1485
- host,
1486
- "x-amz-date": amzDate,
1487
- ...options.headers || {}
1488
- };
1489
- if (credentials.sessionToken) {
1490
- headers["x-amz-security-token"] = credentials.sessionToken;
1491
- }
1492
- if (body) {
1493
- const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
1494
- if (!hasContentType) {
1495
- headers["content-type"] = "application/x-www-form-urlencoded";
1496
- }
1497
- headers["content-length"] = Buffer.byteLength(body).toString();
1498
- }
1499
- const payloadHash = this.sha256(body || "");
1500
- headers["x-amz-content-sha256"] = payloadHash;
1501
- const canonicalUri = path;
1502
- const canonicalQueryString = queryParams ? Object.keys(queryParams).sort().map((k) => `${this.uriEncode(k)}=${this.uriEncode(queryParams[k])}`).join("&") : "";
1503
- const sortedHeaderKeys = Object.keys(headers).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
1504
- const canonicalHeaders = sortedHeaderKeys.map((key) => `${key.toLowerCase()}:${headers[key].trim()}
1505
- `).join("");
1506
- const signedHeaders = sortedHeaderKeys.map((key) => key.toLowerCase()).join(";");
1507
- const canonicalRequest = [
1508
- method,
1509
- canonicalUri,
1510
- canonicalQueryString,
1511
- canonicalHeaders,
1512
- signedHeaders,
1513
- payloadHash
1514
- ].join(`
1515
- `);
1516
- const algorithm = "AWS4-HMAC-SHA256";
1517
- let signingService = service;
1518
- if (service === "email")
1519
- signingService = "ses";
1520
- const credentialScope = `${dateStamp}/${region}/${signingService}/aws4_request`;
1521
- const stringToSign = [algorithm, amzDate, credentialScope, this.sha256(canonicalRequest)].join(`
1522
- `);
1523
- const signingKey = this.getSignatureKey(credentials.secretAccessKey, dateStamp, region, signingService);
1524
- const signature = this.hmac(signingKey, stringToSign);
1525
- const authorizationHeader = `${algorithm} Credential=${credentials.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
1526
- return {
1527
- ...headers,
1528
- Authorization: authorizationHeader
1529
- };
1530
- }
1531
- getAmzDate(date) {
1532
- return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
1533
- }
1534
- getDateStamp(date) {
1535
- return date.toISOString().slice(0, 10).replace(/-/g, "");
1536
- }
1537
- uriEncode(str) {
1538
- return encodeURIComponent(str).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
1539
- }
1540
- sha256(data) {
1541
- return crypto.createHash("sha256").update(data, "utf8").digest("hex");
1542
- }
1543
- hmac(key, data) {
1544
- return crypto.createHmac("sha256", key).update(data, "utf8").digest("hex");
1545
- }
1546
- getSignatureKey(key, dateStamp, region, service) {
1547
- const kDate = crypto.createHmac("sha256", `AWS4${key}`).update(dateStamp).digest();
1548
- const kRegion = crypto.createHmac("sha256", kDate).update(region).digest();
1549
- const kService = crypto.createHmac("sha256", kRegion).update(service).digest();
1550
- const kSigning = crypto.createHmac("sha256", kService).update("aws4_request").digest();
1551
- return kSigning;
1552
- }
1553
- parseXmlResponse(xml) {
1554
- try {
1555
- const parsed = this.xmlParser.parse(xml);
1556
- if (parsed.ErrorResponse) {
1557
- throw this.createErrorFromXml(parsed.ErrorResponse.Error);
1558
- }
1559
- const keys = Object.keys(parsed);
1560
- if (keys.length === 1) {
1561
- return parsed[keys[0]];
1562
- }
1563
- return parsed;
1564
- } catch (error) {
1565
- if (error.code || error.statusCode) {
1566
- throw error;
1567
- }
1568
- return {};
1569
- }
1570
- }
1571
- parseError(responseText, statusCode, headers) {
1572
- const error = new Error;
1573
- error.statusCode = statusCode;
1574
- error.requestId = headers.get("x-amzn-requestid") || headers.get("x-amz-request-id") || undefined;
1575
- if (responseText.startsWith("<")) {
1576
- try {
1577
- const parsed = this.xmlParser.parse(responseText);
1578
- if (parsed.ErrorResponse?.Error) {
1579
- const awsError = parsed.ErrorResponse.Error;
1580
- error.code = awsError.Code;
1581
- error.message = `AWS Error [${awsError.Code}]: ${awsError.Message || "Unknown error"}`;
1582
- error.type = awsError.Type;
1583
- return error;
1584
- }
1585
- if (parsed.Error) {
1586
- error.code = parsed.Error.Code;
1587
- error.message = `AWS Error [${parsed.Error.Code}]: ${parsed.Error.Message || "Unknown error"}`;
1588
- return error;
1589
- }
1590
- } catch {}
1591
- }
1592
- try {
1593
- const json = JSON.parse(responseText);
1594
- if (json.__type || json.code) {
1595
- error.code = json.__type || json.code;
1596
- error.message = `AWS Error [${error.code}]: ${json.message || json.Message || "Unknown error"}`;
1597
- return error;
1598
- }
1599
- } catch {}
1600
- error.message = `AWS API Error (${statusCode}): ${responseText}`;
1601
- return error;
1602
- }
1603
- createErrorFromXml(errorData) {
1604
- const error = new Error;
1605
- error.code = errorData.Code;
1606
- error.message = `AWS Error [${errorData.Code}]: ${errorData.Message || "Unknown error"}`;
1607
- error.type = errorData.Type;
1608
- return error;
1609
- }
1610
- isRetryableError(code) {
1611
- const retryableCodes = [
1612
- "RequestTimeout",
1613
- "RequestTimeoutException",
1614
- "PriorRequestNotComplete",
1615
- "ConnectionError",
1616
- "ThrottlingException",
1617
- "Throttling",
1618
- "TooManyRequestsException",
1619
- "ProvisionedThroughputExceededException",
1620
- "RequestLimitExceeded",
1621
- "BandwidthLimitExceeded",
1622
- "SlowDown",
1623
- "ServiceUnavailable",
1624
- "ServiceUnavailableException",
1625
- "InternalError",
1626
- "InternalFailure",
1627
- "InternalServerError",
1628
- "InternalServiceException",
1629
- "TransientError",
1630
- "TransientFailure",
1631
- "IDPCommunicationErrorException",
1632
- "NetworkError",
1633
- "ConnectionRefusedException",
1634
- "EC2ThrottledException",
1635
- "503 Slow Down",
1636
- "500 InternalError"
1637
- ];
1638
- return retryableCodes.includes(code);
1639
- }
1640
- isRetryableStatusCode(statusCode) {
1641
- return statusCode >= 500 || statusCode === 429;
1642
- }
1643
- shouldRetry(error) {
1644
- if (error.name === "FetchError" || error.name === "TypeError" || error.code === "ECONNRESET") {
1645
- return true;
1646
- }
1647
- if (error.code && this.isRetryableError(error.code)) {
1648
- return true;
1649
- }
1650
- if (error.statusCode && this.isRetryableStatusCode(error.statusCode)) {
1651
- return true;
1652
- }
1653
- if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
1654
- return false;
1655
- }
1656
- if (error.statusCode) {
1657
- return false;
1658
- }
1659
- return true;
1660
- }
1661
- calculateRetryDelay(attempt) {
1662
- const baseDelay = this.config.retryDelay ?? 1000;
1663
- const maxDelay = 30000;
1664
- const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
1665
- const jitter = Math.random() * 0.3 * delay;
1666
- return delay + jitter;
1667
- }
1668
- sleep(ms) {
1669
- return new Promise((resolve) => setTimeout(resolve, ms));
1670
- }
1671
- getFromCache(key) {
1672
- const entry = this.cache.get(key);
1673
- if (!entry) {
1674
- return null;
1675
- }
1676
- if (Date.now() > entry.expires) {
1677
- this.cache.delete(key);
1678
- return null;
1679
- }
1680
- return entry.data;
1681
- }
1682
- setInCache(key, data, ttl) {
1683
- this.cache.set(key, {
1684
- data,
1685
- expires: Date.now() + ttl
1686
- });
1687
- }
1688
- clearCache() {
1689
- this.cache.clear();
1690
- }
1691
- clearExpiredCache() {
1692
- const now = Date.now();
1693
- for (const [key, entry] of this.cache.entries()) {
1694
- if (now > entry.expires) {
1695
- this.cache.delete(key);
1696
- }
1697
- }
1698
- }
1699
- }
1700
- function buildQueryParams(params) {
1701
- const result = {};
1702
- for (const [key, value] of Object.entries(params)) {
1703
- if (value === undefined || value === null) {
1704
- continue;
1705
- }
1706
- if (Array.isArray(value)) {
1707
- value.forEach((item, index) => {
1708
- result[`${key}.${index + 1}`] = String(item);
1709
- });
1710
- } else if (typeof value === "object") {
1711
- for (const [subKey, subValue] of Object.entries(value)) {
1712
- result[`${key}.${subKey}`] = String(subValue);
1713
- }
1714
- } else {
1715
- result[key] = String(value);
1716
- }
1717
- }
1718
- return result;
1719
- }
1720
- function detectCredentialSource() {
1721
- const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
1722
- const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
1723
- const emptyEnvKey = accessKeyId === "";
1724
- const emptyEnvSecret = secretAccessKey === "";
1725
- if (accessKeyId && secretAccessKey) {
1726
- return {
1727
- source: "env",
1728
- emptyEnvKey,
1729
- emptyEnvSecret,
1730
- description: "environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)"
1731
- };
1732
- }
1733
- const profile = process.env.AWS_PROFILE || "default";
1734
- const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE || join(homedir(), ".aws", "credentials");
1735
- if (existsSync(credentialsPath)) {
1736
- return {
1737
- source: "file",
1738
- profile,
1739
- emptyEnvKey,
1740
- emptyEnvSecret,
1741
- description: `~/.aws/credentials (profile: ${profile})`
1742
- };
1743
- }
1744
- return {
1745
- source: "ec2",
1746
- emptyEnvKey,
1747
- emptyEnvSecret,
1748
- description: "EC2 instance metadata service (IMDSv2)"
1749
- };
1750
- }
1751
-
1752
- export { resolveS3Endpoint, AWSClient, buildQueryParams, detectCredentialSource };