meridianjs 0.2.5 → 0.2.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 (93) hide show
  1. package/dist/capabilities/registry.d.ts.map +1 -1
  2. package/dist/capabilities/registry.js +7 -0
  3. package/dist/capabilities/registry.js.map +1 -1
  4. package/dist/core/types.d.ts +1 -1
  5. package/dist/core/types.js +1 -1
  6. package/dist/generator/index.d.ts +2 -0
  7. package/dist/generator/index.d.ts.map +1 -1
  8. package/dist/generator/index.js +2 -1
  9. package/dist/generator/index.js.map +1 -1
  10. package/dist/generator/openapi-export.d.ts +51 -0
  11. package/dist/generator/openapi-export.d.ts.map +1 -0
  12. package/dist/generator/openapi-export.js +95 -0
  13. package/dist/generator/openapi-export.js.map +1 -0
  14. package/dist/generator/templates.d.ts.map +1 -1
  15. package/dist/generator/templates.js +86 -17
  16. package/dist/generator/templates.js.map +1 -1
  17. package/dist/index.d.ts +5 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +10 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/providers/billdesk/adapter.d.ts +36 -0
  22. package/dist/providers/billdesk/adapter.d.ts.map +1 -0
  23. package/dist/providers/billdesk/adapter.js +212 -0
  24. package/dist/providers/billdesk/adapter.js.map +1 -0
  25. package/dist/providers/billdesk/index.d.ts +3 -0
  26. package/dist/providers/billdesk/index.d.ts.map +1 -0
  27. package/dist/providers/billdesk/index.js +3 -0
  28. package/dist/providers/billdesk/index.js.map +1 -0
  29. package/dist/providers/billdesk/pagination.d.ts +15 -0
  30. package/dist/providers/billdesk/pagination.d.ts.map +1 -0
  31. package/dist/providers/billdesk/pagination.js +51 -0
  32. package/dist/providers/billdesk/pagination.js.map +1 -0
  33. package/dist/providers/ccavenue/adapter.d.ts +38 -0
  34. package/dist/providers/ccavenue/adapter.d.ts.map +1 -0
  35. package/dist/providers/ccavenue/adapter.js +181 -0
  36. package/dist/providers/ccavenue/adapter.js.map +1 -0
  37. package/dist/providers/ccavenue/index.d.ts +3 -0
  38. package/dist/providers/ccavenue/index.d.ts.map +1 -0
  39. package/dist/providers/ccavenue/index.js +3 -0
  40. package/dist/providers/ccavenue/index.js.map +1 -0
  41. package/dist/providers/ccavenue/pagination.d.ts +16 -0
  42. package/dist/providers/ccavenue/pagination.d.ts.map +1 -0
  43. package/dist/providers/ccavenue/pagination.js +20 -0
  44. package/dist/providers/ccavenue/pagination.js.map +1 -0
  45. package/dist/providers/datadog/adapter.d.ts +30 -0
  46. package/dist/providers/datadog/adapter.d.ts.map +1 -0
  47. package/dist/providers/datadog/adapter.js +163 -0
  48. package/dist/providers/datadog/adapter.js.map +1 -0
  49. package/dist/providers/datadog/index.d.ts +3 -0
  50. package/dist/providers/datadog/index.d.ts.map +1 -0
  51. package/dist/providers/datadog/index.js +3 -0
  52. package/dist/providers/datadog/index.js.map +1 -0
  53. package/dist/providers/datadog/pagination.d.ts +16 -0
  54. package/dist/providers/datadog/pagination.d.ts.map +1 -0
  55. package/dist/providers/datadog/pagination.js +41 -0
  56. package/dist/providers/datadog/pagination.js.map +1 -0
  57. package/dist/providers/s3/adapter.d.ts +37 -0
  58. package/dist/providers/s3/adapter.d.ts.map +1 -0
  59. package/dist/providers/s3/adapter.js +206 -0
  60. package/dist/providers/s3/adapter.js.map +1 -0
  61. package/dist/providers/s3/index.d.ts +4 -0
  62. package/dist/providers/s3/index.d.ts.map +1 -0
  63. package/dist/providers/s3/index.js +4 -0
  64. package/dist/providers/s3/index.js.map +1 -0
  65. package/dist/providers/s3/pagination.d.ts +18 -0
  66. package/dist/providers/s3/pagination.d.ts.map +1 -0
  67. package/dist/providers/s3/pagination.js +58 -0
  68. package/dist/providers/s3/pagination.js.map +1 -0
  69. package/dist/providers/s3/sigv4.d.ts +29 -0
  70. package/dist/providers/s3/sigv4.d.ts.map +1 -0
  71. package/dist/providers/s3/sigv4.js +101 -0
  72. package/dist/providers/s3/sigv4.js.map +1 -0
  73. package/dist/providers/sentry/adapter.d.ts +29 -0
  74. package/dist/providers/sentry/adapter.d.ts.map +1 -0
  75. package/dist/providers/sentry/adapter.js +154 -0
  76. package/dist/providers/sentry/adapter.js.map +1 -0
  77. package/dist/providers/sentry/index.d.ts +3 -0
  78. package/dist/providers/sentry/index.d.ts.map +1 -0
  79. package/dist/providers/sentry/index.js +3 -0
  80. package/dist/providers/sentry/index.js.map +1 -0
  81. package/dist/providers/sentry/pagination.d.ts +17 -0
  82. package/dist/providers/sentry/pagination.d.ts.map +1 -0
  83. package/dist/providers/sentry/pagination.js +54 -0
  84. package/dist/providers/sentry/pagination.js.map +1 -0
  85. package/dist/public.d.ts +11 -1
  86. package/dist/public.d.ts.map +1 -1
  87. package/dist/public.js +9 -1
  88. package/dist/public.js.map +1 -1
  89. package/dist/upi/index.d.ts +43 -0
  90. package/dist/upi/index.d.ts.map +1 -0
  91. package/dist/upi/index.js +57 -0
  92. package/dist/upi/index.js.map +1 -0
  93. package/package.json +6 -2
@@ -0,0 +1,206 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { ResponseNormalizer } from "../../core/normalizer.js";
3
+ import { IdempotencyLevel, MeridianError, SDK_VERSION } from "../../core/types.js";
4
+ import { S3PaginationStrategy } from "./pagination.js";
5
+ import { signSigV4 } from "./sigv4.js";
6
+ function extractXmlField(xml, tag) {
7
+ const match = xml.match(new RegExp(`<${tag}>([^<]*)</${tag}>`));
8
+ return match?.[1] ?? null;
9
+ }
10
+ /**
11
+ * The auth token carries SigV4 credentials JSON-encoded (see `authStrategy`).
12
+ * Falls back to treating an opaque token string as the access key ID — this
13
+ * keeps `buildRequest` resilient to non-JSON tokens (e.g. generic contract
14
+ * tests that pass a placeholder string) without producing a usable signature.
15
+ */
16
+ function parseSigV4Credentials(token) {
17
+ try {
18
+ return JSON.parse(token);
19
+ }
20
+ catch {
21
+ return { accessKeyId: token, secretAccessKey: "", region: "us-east-1", service: "s3" };
22
+ }
23
+ }
24
+ /** Parses S3/R2's XML error body into a plain object, when present. */
25
+ function parseS3ErrorXml(body) {
26
+ if (typeof body !== "string" || !body.includes("<Error>")) {
27
+ return typeof body === "object" && body !== null ? body : undefined;
28
+ }
29
+ const result = {};
30
+ const code = extractXmlField(body, "Code");
31
+ const message = extractXmlField(body, "Message");
32
+ const requestId = extractXmlField(body, "RequestId");
33
+ const resource = extractXmlField(body, "Resource");
34
+ if (code !== null)
35
+ result.Code = code;
36
+ if (message !== null)
37
+ result.Message = message;
38
+ if (requestId !== null)
39
+ result.RequestId = requestId;
40
+ if (resource !== null)
41
+ result.Resource = resource;
42
+ return result;
43
+ }
44
+ /**
45
+ * S3-compatible object storage (AWS S3, Cloudflare R2, and other S3-API stores)
46
+ * authenticates every request with AWS Signature Version 4 — there's no bearer
47
+ * token or static API key header. Each call is signed in `buildRequest` using
48
+ * the access key / secret key (and, for R2, region `"auto"`) supplied via
49
+ * `auth.custom`. Responses are XML, not JSON; pagination and error parsing
50
+ * extract the handful of fields they need from that XML directly.
51
+ *
52
+ * Configure with `auth.username`/`auth.password` (access key / secret key) and
53
+ * `auth.custom = { region, endpoint?, sessionToken? }`. For R2, set
54
+ * `auth.custom.region = "auto"` and `auth.custom.endpoint` to your account's
55
+ * `https://<account_id>.r2.cloudflarestorage.com` URL (or pass it as `baseUrl`
56
+ * in the provider config).
57
+ */
58
+ export class S3Adapter {
59
+ baseUrl;
60
+ constructor(baseUrl = "https://s3.amazonaws.com/") {
61
+ this.baseUrl = baseUrl;
62
+ }
63
+ buildRequest(input) {
64
+ const { endpoint, options, authToken, baseUrl } = input;
65
+ const effectiveBaseUrl = baseUrl ?? this.baseUrl;
66
+ const url = new URL(endpoint.replace(/^\//, ""), effectiveBaseUrl);
67
+ if (options.query) {
68
+ for (const [key, value] of Object.entries(options.query)) {
69
+ url.searchParams.set(key, String(value));
70
+ }
71
+ }
72
+ const credentials = parseSigV4Credentials(authToken.token);
73
+ const method = options.method ?? "GET";
74
+ let body;
75
+ const baseHeaders = {
76
+ "User-Agent": `Meridian-SDK/${SDK_VERSION}`,
77
+ ...options.headers,
78
+ };
79
+ if (options.body && method !== "GET" && method !== "HEAD") {
80
+ body = typeof options.body === "string" ? options.body : JSON.stringify(options.body);
81
+ baseHeaders["Content-Type"] ??= "application/octet-stream";
82
+ }
83
+ const signed = signSigV4(body !== undefined
84
+ ? { method, url, headers: baseHeaders, body, credentials }
85
+ : { method, url, headers: baseHeaders, credentials });
86
+ const built = { url: url.toString(), method, headers: signed.headers };
87
+ if (body !== undefined) {
88
+ built.body = body;
89
+ }
90
+ return built;
91
+ }
92
+ parseResponse(raw) {
93
+ const rateLimitInfo = this.rateLimitPolicy(raw.headers);
94
+ const paginationStrategy = this.paginationStrategy();
95
+ const paginationInfo = ResponseNormalizer.extractPaginationInfo(raw, paginationStrategy);
96
+ return ResponseNormalizer.normalize(raw, "s3", rateLimitInfo, paginationInfo, [], "1.0.0");
97
+ }
98
+ parseError(raw) {
99
+ if (raw instanceof Error) {
100
+ const msg = raw.message.toLowerCase();
101
+ if (msg.includes("fetch") ||
102
+ msg.includes("network") ||
103
+ msg.includes("econnreset") ||
104
+ msg.includes("etimedout") ||
105
+ msg.includes("enotfound") ||
106
+ msg.includes("timeout")) {
107
+ return this.createMeridianError("network", true, "Network request failed. Check your connection and try again.", { originalError: raw.message });
108
+ }
109
+ }
110
+ if (typeof raw === "object" &&
111
+ raw !== null &&
112
+ "status" in raw &&
113
+ typeof raw.status === "number") {
114
+ return this.parseHttpError(raw);
115
+ }
116
+ return this.createMeridianError("provider", false, "An unexpected error occurred", { raw });
117
+ }
118
+ parseHttpError(error) {
119
+ const { status } = error;
120
+ const errorBody = parseS3ErrorXml(error.body);
121
+ const errorMessage = errorBody?.Message;
122
+ const metadata = { code: errorBody?.Code, requestId: errorBody?.RequestId };
123
+ if (status === 401 || status === 403) {
124
+ return this.createMeridianError("auth", false, errorMessage ??
125
+ "Authentication failed. Check your access key ID, secret access key, and signing region.", metadata, undefined, status);
126
+ }
127
+ if (status === 404) {
128
+ return this.createMeridianError("validation", false, errorMessage ?? "Bucket or object not found.", metadata, undefined, 404);
129
+ }
130
+ if (status === 409 || status === 412 || status === 422) {
131
+ return this.createMeridianError("validation", false, errorMessage ?? "Request validation failed.", metadata, undefined, status);
132
+ }
133
+ if (status === 429 || (status === 503 && errorBody?.Code === "SlowDown")) {
134
+ return this.createMeridianError("rate_limit", true, errorMessage ?? "Request rate exceeded. Please slow down and retry.", metadata, undefined, status);
135
+ }
136
+ if (status === 400) {
137
+ return this.createMeridianError("validation", false, errorMessage ?? "Request validation failed.", metadata, undefined, 400);
138
+ }
139
+ if (status >= 500) {
140
+ return this.createMeridianError("provider", true, errorMessage ?? `S3 API returned error ${status}. This may be temporary.`, metadata, undefined, status);
141
+ }
142
+ if (status >= 400) {
143
+ return this.createMeridianError("validation", false, errorMessage ?? `Request failed with status ${status}.`, metadata, undefined, status);
144
+ }
145
+ return this.createMeridianError("provider", false, `Unexpected response status ${status}.`, metadata, undefined, status);
146
+ }
147
+ async authStrategy(config) {
148
+ const accessKeyId = config.username ?? config.apiKey ?? config.clientId;
149
+ const secretAccessKey = config.password ?? config.apiSecret ?? config.clientSecret;
150
+ const region = config.custom?.region ?? "us-east-1";
151
+ const sessionToken = config.custom?.sessionToken ?? config.refreshToken;
152
+ if (!accessKeyId || !secretAccessKey) {
153
+ throw this.createMeridianError("auth", false, "S3 authentication requires an access key ID and secret access key. " +
154
+ "Set auth.username (access key ID) + auth.password (secret access key), " +
155
+ 'and optionally auth.custom = { region, sessionToken } (use region: "auto" for R2).', {}, undefined, 401);
156
+ }
157
+ const credentials = {
158
+ accessKeyId,
159
+ secretAccessKey,
160
+ region,
161
+ service: "s3",
162
+ ...(sessionToken ? { sessionToken } : {}),
163
+ };
164
+ return { token: JSON.stringify(credentials) };
165
+ }
166
+ rateLimitPolicy(_headers) {
167
+ // S3 does not publish rate-limit headers; it signals throttling via 503 SlowDown.
168
+ return {
169
+ limit: 100,
170
+ remaining: 100,
171
+ reset: new Date(Date.now() + 60_000),
172
+ };
173
+ }
174
+ paginationStrategy() {
175
+ return new S3PaginationStrategy();
176
+ }
177
+ getIdempotencyConfig() {
178
+ return {
179
+ defaultSafeOperations: new Set(["GET", "HEAD", "OPTIONS"]),
180
+ operationOverrides: new Map([["PUT", IdempotencyLevel.IDEMPOTENT]]),
181
+ };
182
+ }
183
+ /**
184
+ * Verifies an S3 Event Notification delivered via SNS/EventBridge webhook —
185
+ * an HMAC-SHA256 digest of the raw request body, hex-encoded, keyed by a
186
+ * shared secret configured on the destination (S3 itself does not sign
187
+ * notifications; this supports the common "shared secret" relay pattern).
188
+ */
189
+ verifyWebhook(payload, signature, secret) {
190
+ const expected = createHmac("sha256", secret).update(payload).digest("hex");
191
+ try {
192
+ const a = Buffer.from(expected);
193
+ const b = Buffer.from(signature);
194
+ if (a.length !== b.length)
195
+ return false;
196
+ return timingSafeEqual(a, b);
197
+ }
198
+ catch {
199
+ return false;
200
+ }
201
+ }
202
+ createMeridianError(category, retryable, message, metadata, retryAfter, status) {
203
+ return new MeridianError(message, category, "s3", retryable, "", metadata, retryAfter, status);
204
+ }
205
+ }
206
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/s3/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAa9D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAyB,SAAS,EAAE,MAAM,YAAY,CAAC;AAS9D,SAAS,eAAe,CAAC,GAAW,EAAE,GAAW;IAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAqB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACzF,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,SAAS,eAAe,CAAC,IAAa;IACpC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAE,IAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,CAAC;IACD,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACnD,IAAI,IAAI,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;IACtC,IAAI,OAAO,KAAK,IAAI;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAC/C,IAAI,SAAS,KAAK,IAAI;QAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;IACrD,IAAI,QAAQ,KAAK,IAAI;QAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAClD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,SAAS;IACZ,OAAO,CAAS;IAExB,YAAY,OAAO,GAAG,2BAA2B;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,YAAY,CAAC,KAAmB;QAC9B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QACxD,MAAM,gBAAgB,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAEnE,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,MAAM,WAAW,GAAG,qBAAqB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;QAEvC,IAAI,IAAwB,CAAC;QAC7B,MAAM,WAAW,GAA2B;YAC1C,YAAY,EAAE,gBAAgB,WAAW,EAAE;YAC3C,GAAG,OAAO,CAAC,OAAO;SACnB,CAAC;QACF,IAAI,OAAO,CAAC,IAAI,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1D,IAAI,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACtF,WAAW,CAAC,cAAc,CAAC,KAAK,0BAA0B,CAAC;QAC7D,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CACtB,IAAI,KAAK,SAAS;YAChB,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE;YAC1D,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CACvD,CAAC;QAEF,MAAM,KAAK,GAAiB,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QACrF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,aAAa,CAAC,GAAgB;QAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACrD,MAAM,cAAc,GAAG,kBAAkB,CAAC,qBAAqB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACzF,OAAO,kBAAkB,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC7F,CAAC;IAED,UAAU,CAAC,GAAY;QACrB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACtC,IACE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACrB,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACvB,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAC1B,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;gBACzB,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;gBACzB,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EACvB,CAAC;gBACD,OAAO,IAAI,CAAC,mBAAmB,CAC7B,SAAS,EACT,IAAI,EACJ,8DAA8D,EAC9D,EAAE,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,CAC/B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IACE,OAAO,GAAG,KAAK,QAAQ;YACvB,GAAG,KAAK,IAAI;YACZ,QAAQ,IAAI,GAAG;YACf,OAAQ,GAA+B,CAAC,MAAM,KAAK,QAAQ,EAC3D,CAAC;YACD,OAAO,IAAI,CAAC,cAAc,CACxB,GAAqF,CACtF,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9F,CAAC;IAEO,cAAc,CAAC,KAItB;QACC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QACzB,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,SAAS,EAAE,OAAO,CAAC;QACxC,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;QAE5E,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,mBAAmB,CAC7B,MAAM,EACN,KAAK,EACL,YAAY;gBACV,yFAAyF,EAC3F,QAAQ,EACR,SAAS,EACT,MAAM,CACP,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,mBAAmB,CAC7B,YAAY,EACZ,KAAK,EACL,YAAY,IAAI,6BAA6B,EAC7C,QAAQ,EACR,SAAS,EACT,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC,mBAAmB,CAC7B,YAAY,EACZ,KAAK,EACL,YAAY,IAAI,4BAA4B,EAC5C,QAAQ,EACR,SAAS,EACT,MAAM,CACP,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,SAAS,EAAE,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC;YACzE,OAAO,IAAI,CAAC,mBAAmB,CAC7B,YAAY,EACZ,IAAI,EACJ,YAAY,IAAI,oDAAoD,EACpE,QAAQ,EACR,SAAS,EACT,MAAM,CACP,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC,mBAAmB,CAC7B,YAAY,EACZ,KAAK,EACL,YAAY,IAAI,4BAA4B,EAC5C,QAAQ,EACR,SAAS,EACT,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,mBAAmB,CAC7B,UAAU,EACV,IAAI,EACJ,YAAY,IAAI,yBAAyB,MAAM,0BAA0B,EACzE,QAAQ,EACR,SAAS,EACT,MAAM,CACP,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,mBAAmB,CAC7B,YAAY,EACZ,KAAK,EACL,YAAY,IAAI,8BAA8B,MAAM,GAAG,EACvD,QAAQ,EACR,SAAS,EACT,MAAM,CACP,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,mBAAmB,CAC7B,UAAU,EACV,KAAK,EACL,8BAA8B,MAAM,GAAG,EACvC,QAAQ,EACR,SAAS,EACT,MAAM,CACP,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAkB;QACnC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC;QACxE,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC;QACnF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,WAAW,CAAC;QACpD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC;QAExE,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,mBAAmB,CAC5B,MAAM,EACN,KAAK,EACL,qEAAqE;gBACnE,yEAAyE;gBACzE,oFAAoF,EACtF,EAAE,EACF,SAAS,EACT,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAqB;YACpC,WAAW;YACX,eAAe;YACf,MAAM;YACN,OAAO,EAAE,IAAI;YACb,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC;QAEF,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;IAChD,CAAC;IAED,eAAe,CAAC,QAAiB;QAC/B,kFAAkF;QAClF,OAAO;YACL,KAAK,EAAE,GAAG;YACV,SAAS,EAAE,GAAG;YACd,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;SACrC,CAAC;IACJ,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,oBAAoB,EAAE,CAAC;IACpC,CAAC;IAED,oBAAoB;QAClB,OAAO;YACL,qBAAqB,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YAC1D,kBAAkB,EAAE,IAAI,GAAG,CAA2B,CAAC,CAAC,KAAK,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;SAC9F,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,OAAwB,EAAE,SAAiB,EAAE,MAAc;QACvE,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACjC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC;YACxC,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,mBAAmB,CACzB,QAAmC,EACnC,SAAkB,EAClB,OAAe,EACf,QAAkC,EAClC,UAAiB,EACjB,MAAe;QAEf,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACjG,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export * from "./adapter.js";
2
+ export * from "./pagination.js";
3
+ export * from "./sigv4.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/s3/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./adapter.js";
2
+ export * from "./pagination.js";
3
+ export * from "./sigv4.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/s3/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { PaginationStrategy, RawResponse, RequestOptions } from "../../core/types.js";
2
+ /**
3
+ * S3 / R2's `ListObjectsV2` returns XML with `IsTruncated` and, when there are
4
+ * more results, a `NextContinuationToken` — fed back as the `continuation-token`
5
+ * query parameter. The SDK's HTTP layer hands us the raw XML string as the body
6
+ * for non-JSON responses.
7
+ */
8
+ export declare class S3PaginationStrategy implements PaginationStrategy {
9
+ extractCursor(response: RawResponse): string | null;
10
+ extractTotal(response: RawResponse): number | null;
11
+ hasNext(response: RawResponse): boolean;
12
+ buildNextRequest(endpoint: string, options: RequestOptions, cursor: string): {
13
+ endpoint: string;
14
+ options: RequestOptions;
15
+ };
16
+ private bodyAsXml;
17
+ }
18
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/providers/s3/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAY3F;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAMnD,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IASlD,OAAO,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO;IAMvC,gBAAgB,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,GACb;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE;IAahD,OAAO,CAAC,SAAS;CAMlB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Extracts a top-level XML element's text content via a narrow regex match.
3
+ * S3's ListObjectsV2 response is flat enough (no nested elements share these
4
+ * tag names) that a full XML parser isn't warranted here.
5
+ */
6
+ function extractXmlField(xml, tag) {
7
+ const match = xml.match(new RegExp(`<${tag}>([^<]*)</${tag}>`));
8
+ return match?.[1] ?? null;
9
+ }
10
+ /**
11
+ * S3 / R2's `ListObjectsV2` returns XML with `IsTruncated` and, when there are
12
+ * more results, a `NextContinuationToken` — fed back as the `continuation-token`
13
+ * query parameter. The SDK's HTTP layer hands us the raw XML string as the body
14
+ * for non-JSON responses.
15
+ */
16
+ export class S3PaginationStrategy {
17
+ extractCursor(response) {
18
+ const xml = this.bodyAsXml(response);
19
+ if (!xml)
20
+ return null;
21
+ return extractXmlField(xml, "NextContinuationToken");
22
+ }
23
+ extractTotal(response) {
24
+ const xml = this.bodyAsXml(response);
25
+ if (!xml)
26
+ return null;
27
+ const keyCount = extractXmlField(xml, "KeyCount");
28
+ if (keyCount === null)
29
+ return null;
30
+ const parsed = Number.parseInt(keyCount, 10);
31
+ return Number.isNaN(parsed) ? null : parsed;
32
+ }
33
+ hasNext(response) {
34
+ const xml = this.bodyAsXml(response);
35
+ if (!xml)
36
+ return false;
37
+ return extractXmlField(xml, "IsTruncated") === "true";
38
+ }
39
+ buildNextRequest(endpoint, options, cursor) {
40
+ return {
41
+ endpoint,
42
+ options: {
43
+ ...options,
44
+ query: {
45
+ ...options.query,
46
+ "continuation-token": cursor,
47
+ },
48
+ },
49
+ };
50
+ }
51
+ bodyAsXml(response) {
52
+ if (typeof response.body === "string" && response.body.includes("<ListBucketResult")) {
53
+ return response.body;
54
+ }
55
+ return null;
56
+ }
57
+ }
58
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/providers/s3/pagination.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAW,EAAE,GAAW;IAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAC/B,aAAa,CAAC,QAAqB;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,eAAe,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;IACvD,CAAC;IAED,YAAY,CAAC,QAAqB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAClD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9C,CAAC;IAED,OAAO,CAAC,QAAqB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QACvB,OAAO,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,MAAM,CAAC;IACxD,CAAC;IAED,gBAAgB,CACd,QAAgB,EAChB,OAAuB,EACvB,MAAc;QAEd,OAAO;YACL,QAAQ;YACR,OAAO,EAAE;gBACP,GAAG,OAAO;gBACV,KAAK,EAAE;oBACL,GAAG,OAAO,CAAC,KAAK;oBAChB,oBAAoB,EAAE,MAAM;iBAC7B;aACF;SACF,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,QAAqB;QACrC,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACrF,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ export interface SigV4Credentials {
2
+ accessKeyId: string;
3
+ secretAccessKey: string;
4
+ region: string;
5
+ service?: string;
6
+ sessionToken?: string;
7
+ }
8
+ export interface SigV4SignInput {
9
+ method: string;
10
+ url: URL;
11
+ headers: Record<string, string>;
12
+ body?: string;
13
+ credentials: SigV4Credentials;
14
+ /** Override the signing instant — primarily for deterministic tests. */
15
+ date?: Date;
16
+ }
17
+ export interface SigV4SignedRequest {
18
+ headers: Record<string, string>;
19
+ }
20
+ /**
21
+ * Signs a request per AWS Signature Version 4 (the scheme used by S3, R2, and
22
+ * other S3-compatible object stores). Returns the headers to attach — including
23
+ * `Authorization`, `x-amz-date`, `x-amz-content-sha256`, and `host` — that make
24
+ * the request authenticate as the given credentials.
25
+ *
26
+ * Reference: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
27
+ */
28
+ export declare function signSigV4(input: SigV4SignInput): SigV4SignedRequest;
29
+ //# sourceMappingURL=sigv4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sigv4.d.ts","sourceRoot":"","sources":["../../../src/providers/s3/sigv4.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,GAAG,CAAC;IACT,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,gBAAgB,CAAC;IAC9B,wEAAwE;IACxE,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AA4DD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,kBAAkB,CAuDnE"}
@@ -0,0 +1,101 @@
1
+ import { createHash, createHmac } from "node:crypto";
2
+ const UNRESERVED = /^[A-Za-z0-9\-_.~]$/;
3
+ /** AWS's "URI encode" — percent-encodes everything outside the unreserved set. */
4
+ function uriEncode(value, encodeSlash = true) {
5
+ let out = "";
6
+ for (const ch of Buffer.from(value, "utf-8")) {
7
+ const c = String.fromCharCode(ch);
8
+ if (UNRESERVED.test(c) || (c === "/" && !encodeSlash)) {
9
+ out += c;
10
+ }
11
+ else {
12
+ out += `%${ch.toString(16).toUpperCase().padStart(2, "0")}`;
13
+ }
14
+ }
15
+ return out;
16
+ }
17
+ function canonicalUri(pathname) {
18
+ if (!pathname || pathname === "")
19
+ return "/";
20
+ return pathname
21
+ .split("/")
22
+ .map((segment) => uriEncode(segment, false))
23
+ .join("/");
24
+ }
25
+ function canonicalQueryString(url) {
26
+ const params = [];
27
+ url.searchParams.forEach((value, key) => params.push([key, value]));
28
+ params.sort(([ak, av], [bk, bv]) => ak === bk ? (av < bv ? -1 : av > bv ? 1 : 0) : ak < bk ? -1 : 1);
29
+ return params.map(([k, v]) => `${uriEncode(k)}=${uriEncode(v)}`).join("&");
30
+ }
31
+ function sha256Hex(data) {
32
+ return createHash("sha256").update(data, "utf-8").digest("hex");
33
+ }
34
+ function hmac(key, data) {
35
+ return createHmac("sha256", key).update(data, "utf-8").digest();
36
+ }
37
+ function signingKey(secretAccessKey, dateStamp, region, service) {
38
+ const kDate = hmac(`AWS4${secretAccessKey}`, dateStamp);
39
+ const kRegion = hmac(kDate, region);
40
+ const kService = hmac(kRegion, service);
41
+ return hmac(kService, "aws4_request");
42
+ }
43
+ function amzDate(date) {
44
+ const iso = date.toISOString().replace(/[:-]|\.\d{3}/g, "");
45
+ return { amzDate: iso, dateStamp: iso.slice(0, 8) };
46
+ }
47
+ /**
48
+ * Signs a request per AWS Signature Version 4 (the scheme used by S3, R2, and
49
+ * other S3-compatible object stores). Returns the headers to attach — including
50
+ * `Authorization`, `x-amz-date`, `x-amz-content-sha256`, and `host` — that make
51
+ * the request authenticate as the given credentials.
52
+ *
53
+ * Reference: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
54
+ */
55
+ export function signSigV4(input) {
56
+ const { method, url, body, credentials } = input;
57
+ const service = credentials.service ?? "s3";
58
+ const date = input.date ?? new Date();
59
+ const { amzDate: amzDateStr, dateStamp } = amzDate(date);
60
+ const payloadHash = sha256Hex(body ?? "");
61
+ const headers = {
62
+ ...input.headers,
63
+ host: url.host,
64
+ "x-amz-date": amzDateStr,
65
+ "x-amz-content-sha256": payloadHash,
66
+ };
67
+ if (credentials.sessionToken) {
68
+ headers["x-amz-security-token"] = credentials.sessionToken;
69
+ }
70
+ const headerEntries = Object.entries(headers)
71
+ .map(([k, v]) => [k.toLowerCase(), v.trim().replace(/\s+/g, " ")])
72
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
73
+ const canonicalHeaders = headerEntries.map(([k, v]) => `${k}:${v}\n`).join("");
74
+ const signedHeaders = headerEntries.map(([k]) => k).join(";");
75
+ const canonicalRequest = [
76
+ method.toUpperCase(),
77
+ canonicalUri(url.pathname),
78
+ canonicalQueryString(url),
79
+ canonicalHeaders,
80
+ signedHeaders,
81
+ payloadHash,
82
+ ].join("\n");
83
+ const credentialScope = `${dateStamp}/${credentials.region}/${service}/aws4_request`;
84
+ const stringToSign = [
85
+ "AWS4-HMAC-SHA256",
86
+ amzDateStr,
87
+ credentialScope,
88
+ sha256Hex(canonicalRequest),
89
+ ].join("\n");
90
+ const key = signingKey(credentials.secretAccessKey, dateStamp, credentials.region, service);
91
+ const signature = createHmac("sha256", key).update(stringToSign, "utf-8").digest("hex");
92
+ const authorization = `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${credentialScope}, ` +
93
+ `SignedHeaders=${signedHeaders}, Signature=${signature}`;
94
+ return {
95
+ headers: {
96
+ ...headers,
97
+ Authorization: authorization,
98
+ },
99
+ };
100
+ }
101
+ //# sourceMappingURL=sigv4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sigv4.js","sourceRoot":"","sources":["../../../src/providers/s3/sigv4.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { AdapterInput, AuthConfig, AuthToken, BuiltRequest, IdempotencyConfig, NormalizedResponse, PaginationStrategy, ProviderAdapter, RateLimitInfo, RawResponse } from "../../core/types.js";
2
+ import { MeridianError } from "../../core/types.js";
3
+ /**
4
+ * Sentry's REST API (`/api/0/`) authenticates with a bearer auth token
5
+ * (internal integration token or personal API token) and uses RFC 5988
6
+ * `Link`-header cursor pagination. Rate limiting is communicated via 429s
7
+ * with a `Retry-After` header (and, on the SaaS product, `X-Sentry-Rate-Limit-*`).
8
+ */
9
+ export declare class SentryAdapter implements ProviderAdapter {
10
+ private baseUrl;
11
+ constructor(baseUrl?: string);
12
+ buildRequest(input: AdapterInput): BuiltRequest;
13
+ parseResponse(raw: RawResponse): NormalizedResponse;
14
+ parseError(raw: unknown): MeridianError;
15
+ private parseHttpError;
16
+ authStrategy(config: AuthConfig): Promise<AuthToken>;
17
+ rateLimitPolicy(headers: Headers): RateLimitInfo;
18
+ paginationStrategy(): PaginationStrategy;
19
+ getIdempotencyConfig(): IdempotencyConfig;
20
+ /**
21
+ * Verifies a Sentry integration-platform webhook using the `Sentry-Hook-Signature`
22
+ * header — an HMAC-SHA256 digest of the raw request body keyed by the
23
+ * integration's client secret.
24
+ */
25
+ verifyWebhook(payload: string | Buffer, signature: string, secret: string): boolean;
26
+ private createMeridianError;
27
+ private extractRetryAfter;
28
+ }
29
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/sentry/adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAyB,aAAa,EAAe,MAAM,qBAAqB,CAAC;AASxF;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,SAA6B;IAIhD,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY;IA+B/C,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,kBAAkB;IAOnD,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa;IAkCvC,OAAO,CAAC,cAAc;IAiGhB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAkB1D,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa;IAYhD,kBAAkB,IAAI,kBAAkB;IAIxC,oBAAoB,IAAI,iBAAiB;IAOzC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAYnF,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,iBAAiB;CAY1B"}