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.
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js +7 -0
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.js +1 -1
- package/dist/generator/index.d.ts +2 -0
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +2 -1
- package/dist/generator/index.js.map +1 -1
- package/dist/generator/openapi-export.d.ts +51 -0
- package/dist/generator/openapi-export.d.ts.map +1 -0
- package/dist/generator/openapi-export.js +95 -0
- package/dist/generator/openapi-export.js.map +1 -0
- package/dist/generator/templates.d.ts.map +1 -1
- package/dist/generator/templates.js +86 -17
- package/dist/generator/templates.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/billdesk/adapter.d.ts +36 -0
- package/dist/providers/billdesk/adapter.d.ts.map +1 -0
- package/dist/providers/billdesk/adapter.js +212 -0
- package/dist/providers/billdesk/adapter.js.map +1 -0
- package/dist/providers/billdesk/index.d.ts +3 -0
- package/dist/providers/billdesk/index.d.ts.map +1 -0
- package/dist/providers/billdesk/index.js +3 -0
- package/dist/providers/billdesk/index.js.map +1 -0
- package/dist/providers/billdesk/pagination.d.ts +15 -0
- package/dist/providers/billdesk/pagination.d.ts.map +1 -0
- package/dist/providers/billdesk/pagination.js +51 -0
- package/dist/providers/billdesk/pagination.js.map +1 -0
- package/dist/providers/ccavenue/adapter.d.ts +38 -0
- package/dist/providers/ccavenue/adapter.d.ts.map +1 -0
- package/dist/providers/ccavenue/adapter.js +181 -0
- package/dist/providers/ccavenue/adapter.js.map +1 -0
- package/dist/providers/ccavenue/index.d.ts +3 -0
- package/dist/providers/ccavenue/index.d.ts.map +1 -0
- package/dist/providers/ccavenue/index.js +3 -0
- package/dist/providers/ccavenue/index.js.map +1 -0
- package/dist/providers/ccavenue/pagination.d.ts +16 -0
- package/dist/providers/ccavenue/pagination.d.ts.map +1 -0
- package/dist/providers/ccavenue/pagination.js +20 -0
- package/dist/providers/ccavenue/pagination.js.map +1 -0
- package/dist/providers/datadog/adapter.d.ts +30 -0
- package/dist/providers/datadog/adapter.d.ts.map +1 -0
- package/dist/providers/datadog/adapter.js +163 -0
- package/dist/providers/datadog/adapter.js.map +1 -0
- package/dist/providers/datadog/index.d.ts +3 -0
- package/dist/providers/datadog/index.d.ts.map +1 -0
- package/dist/providers/datadog/index.js +3 -0
- package/dist/providers/datadog/index.js.map +1 -0
- package/dist/providers/datadog/pagination.d.ts +16 -0
- package/dist/providers/datadog/pagination.d.ts.map +1 -0
- package/dist/providers/datadog/pagination.js +41 -0
- package/dist/providers/datadog/pagination.js.map +1 -0
- package/dist/providers/s3/adapter.d.ts +37 -0
- package/dist/providers/s3/adapter.d.ts.map +1 -0
- package/dist/providers/s3/adapter.js +206 -0
- package/dist/providers/s3/adapter.js.map +1 -0
- package/dist/providers/s3/index.d.ts +4 -0
- package/dist/providers/s3/index.d.ts.map +1 -0
- package/dist/providers/s3/index.js +4 -0
- package/dist/providers/s3/index.js.map +1 -0
- package/dist/providers/s3/pagination.d.ts +18 -0
- package/dist/providers/s3/pagination.d.ts.map +1 -0
- package/dist/providers/s3/pagination.js +58 -0
- package/dist/providers/s3/pagination.js.map +1 -0
- package/dist/providers/s3/sigv4.d.ts +29 -0
- package/dist/providers/s3/sigv4.d.ts.map +1 -0
- package/dist/providers/s3/sigv4.js +101 -0
- package/dist/providers/s3/sigv4.js.map +1 -0
- package/dist/providers/sentry/adapter.d.ts +29 -0
- package/dist/providers/sentry/adapter.d.ts.map +1 -0
- package/dist/providers/sentry/adapter.js +154 -0
- package/dist/providers/sentry/adapter.js.map +1 -0
- package/dist/providers/sentry/index.d.ts +3 -0
- package/dist/providers/sentry/index.d.ts.map +1 -0
- package/dist/providers/sentry/index.js +3 -0
- package/dist/providers/sentry/index.js.map +1 -0
- package/dist/providers/sentry/pagination.d.ts +17 -0
- package/dist/providers/sentry/pagination.d.ts.map +1 -0
- package/dist/providers/sentry/pagination.js +54 -0
- package/dist/providers/sentry/pagination.js.map +1 -0
- package/dist/public.d.ts +11 -1
- package/dist/public.d.ts.map +1 -1
- package/dist/public.js +9 -1
- package/dist/public.js.map +1 -1
- package/dist/upi/index.d.ts +43 -0
- package/dist/upi/index.d.ts.map +1 -0
- package/dist/upi/index.js +57 -0
- package/dist/upi/index.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, createHash, createHmac, timingSafeEqual, } from "node:crypto";
|
|
2
|
+
import { ResponseNormalizer } from "../../core/normalizer.js";
|
|
3
|
+
import { MeridianError, SDK_VERSION } from "../../core/types.js";
|
|
4
|
+
import { CcavenuePaginationStrategy } from "./pagination.js";
|
|
5
|
+
// CCAvenue's published integration kit (Crypto.php / Crypto.java) derives a
|
|
6
|
+
// fixed 16-byte AES-128-CBC key/IV pair from the merchant's "working key":
|
|
7
|
+
// key = MD5(workingKey) (raw 16-byte digest)
|
|
8
|
+
// iv = ASCII bytes "0123456789abcdef" (constant across all merchants)
|
|
9
|
+
const CCAVENUE_IV = Buffer.from("0123456789abcdef", "utf-8");
|
|
10
|
+
/** Encrypts a JSON-serializable payload into the hex `enc_request` CCAvenue expects. */
|
|
11
|
+
export function ccavenueEncrypt(data, workingKey) {
|
|
12
|
+
const key = createHash("md5").update(workingKey, "utf-8").digest();
|
|
13
|
+
const cipher = createCipheriv("aes-128-cbc", key, CCAVENUE_IV);
|
|
14
|
+
const plaintext = typeof data === "string" ? data : JSON.stringify(data);
|
|
15
|
+
return Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]).toString("hex");
|
|
16
|
+
}
|
|
17
|
+
/** Decrypts a hex `enc_response` string back into its plaintext (typically JSON). */
|
|
18
|
+
export function ccavenueDecrypt(encHex, workingKey) {
|
|
19
|
+
const key = createHash("md5").update(workingKey, "utf-8").digest();
|
|
20
|
+
const decipher = createDecipheriv("aes-128-cbc", key, CCAVENUE_IV);
|
|
21
|
+
const ciphertext = Buffer.from(encHex, "hex");
|
|
22
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf-8");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* CCAvenue's REST APIs exchange AES-128-CBC encrypted payloads (`enc_request` /
|
|
26
|
+
* `enc_response`) keyed off a merchant "working key", alongside a plaintext
|
|
27
|
+
* `access_code` that identifies the registered integration. Because
|
|
28
|
+
* `parseResponse` doesn't have access to the working key, this adapter passes
|
|
29
|
+
* `enc_response` through untouched in the normalized data — call the exported
|
|
30
|
+
* `ccavenueDecrypt` helper (or the adapter's `decryptResponse`) with your
|
|
31
|
+
* working key to recover the plaintext payload.
|
|
32
|
+
*/
|
|
33
|
+
export class CcavenueAdapter {
|
|
34
|
+
baseUrl;
|
|
35
|
+
constructor(baseUrl = "https://api.ccavenue.com/") {
|
|
36
|
+
this.baseUrl = baseUrl;
|
|
37
|
+
}
|
|
38
|
+
buildRequest(input) {
|
|
39
|
+
const { endpoint, options, authToken, baseUrl } = input;
|
|
40
|
+
const effectiveBaseUrl = baseUrl ?? this.baseUrl;
|
|
41
|
+
const url = new URL(endpoint, effectiveBaseUrl);
|
|
42
|
+
const [accessCode, workingKey] = authToken.token.split("|CCA|");
|
|
43
|
+
const method = options.method ?? "GET";
|
|
44
|
+
if (options.query) {
|
|
45
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
46
|
+
url.searchParams.set(key, String(value));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (accessCode) {
|
|
50
|
+
url.searchParams.set("access_code", accessCode);
|
|
51
|
+
}
|
|
52
|
+
url.searchParams.set("request_type", "JSON");
|
|
53
|
+
url.searchParams.set("response_type", "JSON");
|
|
54
|
+
if (options.body && workingKey) {
|
|
55
|
+
url.searchParams.set("enc_request", ccavenueEncrypt(options.body, workingKey));
|
|
56
|
+
}
|
|
57
|
+
const headers = {
|
|
58
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
59
|
+
"User-Agent": `Meridian-SDK/${SDK_VERSION}`,
|
|
60
|
+
...options.headers,
|
|
61
|
+
};
|
|
62
|
+
return { url: url.toString(), method, headers };
|
|
63
|
+
}
|
|
64
|
+
/** Decrypts a normalized response's `enc_response` field with the given working key. */
|
|
65
|
+
decryptResponse(response, workingKey) {
|
|
66
|
+
const data = response.data;
|
|
67
|
+
if (!data?.enc_response)
|
|
68
|
+
return response.data;
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(ccavenueDecrypt(data.enc_response, workingKey));
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return ccavenueDecrypt(data.enc_response, workingKey);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
parseResponse(raw) {
|
|
77
|
+
const rateLimitInfo = this.rateLimitPolicy(raw.headers);
|
|
78
|
+
const paginationStrategy = this.paginationStrategy();
|
|
79
|
+
const paginationInfo = ResponseNormalizer.extractPaginationInfo(raw, paginationStrategy);
|
|
80
|
+
const warnings = [];
|
|
81
|
+
if (typeof raw.body === "object" && raw.body !== null && "enc_response" in raw.body) {
|
|
82
|
+
warnings.push("Response payload is AES-encrypted (enc_response). Decrypt it with your working key " +
|
|
83
|
+
"via `ccavenueDecrypt(encHex, workingKey)` or `adapter.decryptResponse(response, workingKey)`.");
|
|
84
|
+
}
|
|
85
|
+
return ResponseNormalizer.normalize(raw, "ccavenue", rateLimitInfo, paginationInfo, warnings, "1.0.0");
|
|
86
|
+
}
|
|
87
|
+
parseError(raw) {
|
|
88
|
+
if (raw instanceof Error) {
|
|
89
|
+
const msg = raw.message.toLowerCase();
|
|
90
|
+
if (msg.includes("fetch") ||
|
|
91
|
+
msg.includes("network") ||
|
|
92
|
+
msg.includes("econnreset") ||
|
|
93
|
+
msg.includes("etimedout") ||
|
|
94
|
+
msg.includes("enotfound") ||
|
|
95
|
+
msg.includes("timeout")) {
|
|
96
|
+
return this.createMeridianError("network", true, "Network request failed. Check your connection and try again.", { originalError: raw.message });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (typeof raw === "object" &&
|
|
100
|
+
raw !== null &&
|
|
101
|
+
"status" in raw &&
|
|
102
|
+
typeof raw.status === "number") {
|
|
103
|
+
return this.parseHttpError(raw);
|
|
104
|
+
}
|
|
105
|
+
return this.createMeridianError("provider", false, "An unexpected error occurred", { raw });
|
|
106
|
+
}
|
|
107
|
+
parseHttpError(error) {
|
|
108
|
+
const { status, body } = error;
|
|
109
|
+
const errorBody = body;
|
|
110
|
+
const errorMessage = errorBody?.error_desc ?? errorBody?.reason;
|
|
111
|
+
if (status === 401 || status === 403) {
|
|
112
|
+
return this.createMeridianError("auth", false, errorMessage ?? "Authentication failed. Check your CCAvenue access code and working key.", { errorCode: errorBody?.error_code }, undefined, status);
|
|
113
|
+
}
|
|
114
|
+
if (status === 404) {
|
|
115
|
+
return this.createMeridianError("validation", false, errorMessage ?? "Resource not found.", { errorCode: errorBody?.error_code }, undefined, 404);
|
|
116
|
+
}
|
|
117
|
+
if (status === 429) {
|
|
118
|
+
return this.createMeridianError("rate_limit", true, errorMessage ?? "Rate limit exceeded. Please wait before retrying.", { errorCode: errorBody?.error_code }, undefined, 429);
|
|
119
|
+
}
|
|
120
|
+
if (status === 400 || status === 422) {
|
|
121
|
+
return this.createMeridianError("validation", false, errorMessage ?? "Request validation failed.", { errorCode: errorBody?.error_code, reason: errorBody?.reason }, undefined, status);
|
|
122
|
+
}
|
|
123
|
+
if (status >= 500) {
|
|
124
|
+
return this.createMeridianError("provider", true, errorMessage ?? `CCAvenue API returned error ${status}. This may be temporary.`, { status }, undefined, status);
|
|
125
|
+
}
|
|
126
|
+
if (status >= 400) {
|
|
127
|
+
return this.createMeridianError("validation", false, errorMessage ?? `Request failed with status ${status}.`, { status }, undefined, status);
|
|
128
|
+
}
|
|
129
|
+
return this.createMeridianError("provider", false, `Unexpected response status ${status}.`, { status }, undefined, status);
|
|
130
|
+
}
|
|
131
|
+
async authStrategy(config) {
|
|
132
|
+
const accessCode = config.apiKey ?? config.username;
|
|
133
|
+
const workingKey = config.apiSecret ?? config.password ?? config.clientSecret;
|
|
134
|
+
if (!accessCode || !workingKey) {
|
|
135
|
+
throw this.createMeridianError("auth", false, "CCAvenue authentication requires an access code and working key. " +
|
|
136
|
+
"Set auth.apiKey (access code) + auth.apiSecret (working key).", {}, undefined, 401);
|
|
137
|
+
}
|
|
138
|
+
return { token: `${accessCode}|CCA|${workingKey}` };
|
|
139
|
+
}
|
|
140
|
+
rateLimitPolicy(_headers) {
|
|
141
|
+
// CCAvenue does not publish rate-limit headers; return conservative defaults.
|
|
142
|
+
return {
|
|
143
|
+
limit: 60,
|
|
144
|
+
remaining: 60,
|
|
145
|
+
reset: new Date(Date.now() + 60_000),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
paginationStrategy() {
|
|
149
|
+
return new CcavenuePaginationStrategy();
|
|
150
|
+
}
|
|
151
|
+
getIdempotencyConfig() {
|
|
152
|
+
return {
|
|
153
|
+
defaultSafeOperations: new Set(["GET", "HEAD", "OPTIONS"]),
|
|
154
|
+
operationOverrides: new Map(),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* CCAvenue server-to-server (S2S) response/webhook payloads carry a plaintext
|
|
159
|
+
* `enc_resp_hash` / signature derived as HMAC-SHA256 of the encrypted response
|
|
160
|
+
* body using the working key. `payload` should be the raw `enc_response` (or
|
|
161
|
+
* full body string) CCAvenue posted, and `secret` the merchant's working key.
|
|
162
|
+
*/
|
|
163
|
+
verifyWebhook(payload, signature, secret) {
|
|
164
|
+
const raw = typeof payload === "string" ? payload : payload.toString("utf-8");
|
|
165
|
+
const expected = createHmac("sha256", secret).update(raw).digest("hex");
|
|
166
|
+
try {
|
|
167
|
+
const a = Buffer.from(expected);
|
|
168
|
+
const b = Buffer.from(signature);
|
|
169
|
+
if (a.length !== b.length)
|
|
170
|
+
return false;
|
|
171
|
+
return timingSafeEqual(a, b);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
createMeridianError(category, retryable, message, metadata, retryAfter, status) {
|
|
178
|
+
return new MeridianError(message, category, "ccavenue", retryable, "", metadata, retryAfter, status);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/ccavenue/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/ccavenue/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/ccavenue/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PaginationStrategy, RawResponse, RequestOptions } from "../../core/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* CCAvenue's transaction/order-status APIs are command-driven, single-record
|
|
4
|
+
* lookups rather than paginated listings — there is no documented cursor or
|
|
5
|
+
* page convention. This strategy reports "no further pages" for every response.
|
|
6
|
+
*/
|
|
7
|
+
export declare class CcavenuePaginationStrategy implements PaginationStrategy {
|
|
8
|
+
extractCursor(_response: RawResponse): string | null;
|
|
9
|
+
extractTotal(_response: RawResponse): number | null;
|
|
10
|
+
hasNext(_response: RawResponse): boolean;
|
|
11
|
+
buildNextRequest(endpoint: string, options: RequestOptions, _cursor: string): {
|
|
12
|
+
endpoint: string;
|
|
13
|
+
options: RequestOptions;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/providers/ccavenue/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3F;;;;GAIG;AACH,qBAAa,0BAA2B,YAAW,kBAAkB;IACnE,aAAa,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAIpD,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAInD,OAAO,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO;IAIxC,gBAAgB,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,GACd;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE;CAGjD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CCAvenue's transaction/order-status APIs are command-driven, single-record
|
|
3
|
+
* lookups rather than paginated listings — there is no documented cursor or
|
|
4
|
+
* page convention. This strategy reports "no further pages" for every response.
|
|
5
|
+
*/
|
|
6
|
+
export class CcavenuePaginationStrategy {
|
|
7
|
+
extractCursor(_response) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
extractTotal(_response) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
hasNext(_response) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
buildNextRequest(endpoint, options, _cursor) {
|
|
17
|
+
return { endpoint, options };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/providers/ccavenue/pagination.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,0BAA0B;IACrC,aAAa,CAAC,SAAsB;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,SAAsB;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,SAAsB;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gBAAgB,CACd,QAAgB,EAChB,OAAuB,EACvB,OAAe;QAEf,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
* Datadog's API authenticates every request with a pair of headers —
|
|
5
|
+
* `DD-API-KEY` (account-level) and `DD-APPLICATION-KEY` (user-level, required
|
|
6
|
+
* for most read endpoints) — rather than a bearer token. Rate limits surface
|
|
7
|
+
* via `X-RateLimit-Limit` / `-Remaining` / `-Reset` / `-Period` headers, and
|
|
8
|
+
* v2 search APIs paginate with a `meta.page.after` cursor.
|
|
9
|
+
*/
|
|
10
|
+
export declare class DatadogAdapter implements ProviderAdapter {
|
|
11
|
+
private baseUrl;
|
|
12
|
+
constructor(baseUrl?: string);
|
|
13
|
+
buildRequest(input: AdapterInput): BuiltRequest;
|
|
14
|
+
parseResponse(raw: RawResponse): NormalizedResponse;
|
|
15
|
+
parseError(raw: unknown): MeridianError;
|
|
16
|
+
private parseHttpError;
|
|
17
|
+
authStrategy(config: AuthConfig): Promise<AuthToken>;
|
|
18
|
+
rateLimitPolicy(headers: Headers): RateLimitInfo;
|
|
19
|
+
paginationStrategy(): PaginationStrategy;
|
|
20
|
+
getIdempotencyConfig(): IdempotencyConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Verifies a Datadog webhook signature: an HMAC-SHA256 digest of the raw
|
|
23
|
+
* request body, hex-encoded, sent in the `X-Datadog-Signature` header and
|
|
24
|
+
* keyed by the webhook's shared secret.
|
|
25
|
+
*/
|
|
26
|
+
verifyWebhook(payload: string | Buffer, signature: string, secret: string): boolean;
|
|
27
|
+
private createMeridianError;
|
|
28
|
+
private extractRetryAfter;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/datadog/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;AAOxF;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,SAAmC;IAItD,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY;IAkC/C,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,kBAAkB;IAOnD,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa;IAkCvC,OAAO,CAAC,cAAc;IAkGhB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAmB1D,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa;IAchD,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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { parseRetryAfter } from "../../core/header-parser.js";
|
|
3
|
+
import { ResponseNormalizer } from "../../core/normalizer.js";
|
|
4
|
+
import { MeridianError, SDK_VERSION } from "../../core/types.js";
|
|
5
|
+
import { DatadogPaginationStrategy } from "./pagination.js";
|
|
6
|
+
/**
|
|
7
|
+
* Datadog's API authenticates every request with a pair of headers —
|
|
8
|
+
* `DD-API-KEY` (account-level) and `DD-APPLICATION-KEY` (user-level, required
|
|
9
|
+
* for most read endpoints) — rather than a bearer token. Rate limits surface
|
|
10
|
+
* via `X-RateLimit-Limit` / `-Remaining` / `-Reset` / `-Period` headers, and
|
|
11
|
+
* v2 search APIs paginate with a `meta.page.after` cursor.
|
|
12
|
+
*/
|
|
13
|
+
export class DatadogAdapter {
|
|
14
|
+
baseUrl;
|
|
15
|
+
constructor(baseUrl = "https://api.datadoghq.com/api/") {
|
|
16
|
+
this.baseUrl = baseUrl;
|
|
17
|
+
}
|
|
18
|
+
buildRequest(input) {
|
|
19
|
+
const { endpoint, options, authToken, baseUrl } = input;
|
|
20
|
+
const effectiveBaseUrl = baseUrl ?? this.baseUrl;
|
|
21
|
+
const url = new URL(endpoint.replace(/^\//, ""), effectiveBaseUrl);
|
|
22
|
+
if (options.query) {
|
|
23
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
24
|
+
url.searchParams.set(key, String(value));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const [apiKey, appKey] = authToken.token.split("|DD|");
|
|
28
|
+
const headers = {
|
|
29
|
+
"User-Agent": `Meridian-SDK/${SDK_VERSION}`,
|
|
30
|
+
...options.headers,
|
|
31
|
+
};
|
|
32
|
+
if (apiKey)
|
|
33
|
+
headers["DD-API-KEY"] = apiKey;
|
|
34
|
+
if (appKey)
|
|
35
|
+
headers["DD-APPLICATION-KEY"] = appKey;
|
|
36
|
+
let body;
|
|
37
|
+
const method = options.method ?? "GET";
|
|
38
|
+
if (options.body && method !== "GET" && method !== "HEAD") {
|
|
39
|
+
body = JSON.stringify(options.body);
|
|
40
|
+
headers["Content-Type"] = "application/json";
|
|
41
|
+
}
|
|
42
|
+
const built = { url: url.toString(), method, headers };
|
|
43
|
+
if (body !== undefined) {
|
|
44
|
+
built.body = body;
|
|
45
|
+
}
|
|
46
|
+
return built;
|
|
47
|
+
}
|
|
48
|
+
parseResponse(raw) {
|
|
49
|
+
const rateLimitInfo = this.rateLimitPolicy(raw.headers);
|
|
50
|
+
const paginationStrategy = this.paginationStrategy();
|
|
51
|
+
const paginationInfo = ResponseNormalizer.extractPaginationInfo(raw, paginationStrategy);
|
|
52
|
+
return ResponseNormalizer.normalize(raw, "datadog", rateLimitInfo, paginationInfo, [], "1.0.0");
|
|
53
|
+
}
|
|
54
|
+
parseError(raw) {
|
|
55
|
+
if (raw instanceof Error) {
|
|
56
|
+
const msg = raw.message.toLowerCase();
|
|
57
|
+
if (msg.includes("fetch") ||
|
|
58
|
+
msg.includes("network") ||
|
|
59
|
+
msg.includes("econnreset") ||
|
|
60
|
+
msg.includes("etimedout") ||
|
|
61
|
+
msg.includes("enotfound") ||
|
|
62
|
+
msg.includes("timeout")) {
|
|
63
|
+
return this.createMeridianError("network", true, "Network request failed. Check your connection and try again.", { originalError: raw.message });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (typeof raw === "object" &&
|
|
67
|
+
raw !== null &&
|
|
68
|
+
"status" in raw &&
|
|
69
|
+
typeof raw.status === "number") {
|
|
70
|
+
return this.parseHttpError(raw);
|
|
71
|
+
}
|
|
72
|
+
return this.createMeridianError("provider", false, "An unexpected error occurred", { raw });
|
|
73
|
+
}
|
|
74
|
+
parseHttpError(error) {
|
|
75
|
+
const { status, body, headers } = error;
|
|
76
|
+
const errorBody = body;
|
|
77
|
+
const errorMessage = errorBody?.errors?.join("; ");
|
|
78
|
+
if (status === 401) {
|
|
79
|
+
return this.createMeridianError("auth", false, errorMessage ?? "Authentication failed. Check your Datadog API key.", { datadogErrors: errorBody?.errors }, undefined, 401);
|
|
80
|
+
}
|
|
81
|
+
if (status === 403) {
|
|
82
|
+
return this.createMeridianError("auth", false, errorMessage ??
|
|
83
|
+
"Permission denied. Check that your Application key has the required scopes.", { datadogErrors: errorBody?.errors }, undefined, 403);
|
|
84
|
+
}
|
|
85
|
+
if (status === 404) {
|
|
86
|
+
return this.createMeridianError("validation", false, errorMessage ?? "Resource not found.", { datadogErrors: errorBody?.errors }, undefined, 404);
|
|
87
|
+
}
|
|
88
|
+
if (status === 429) {
|
|
89
|
+
const retryAfter = this.extractRetryAfter(headers);
|
|
90
|
+
return this.createMeridianError("rate_limit", true, errorMessage ?? "Rate limit exceeded. Please wait before retrying.", { retryAfter: retryAfter?.toISOString() }, retryAfter, 429);
|
|
91
|
+
}
|
|
92
|
+
if (status === 400 || status === 422) {
|
|
93
|
+
return this.createMeridianError("validation", false, errorMessage ?? "Request validation failed.", { datadogErrors: errorBody?.errors }, undefined, status);
|
|
94
|
+
}
|
|
95
|
+
if (status >= 500) {
|
|
96
|
+
return this.createMeridianError("provider", true, errorMessage ?? `Datadog API returned error ${status}. This may be temporary.`, { status }, undefined, status);
|
|
97
|
+
}
|
|
98
|
+
if (status >= 400) {
|
|
99
|
+
return this.createMeridianError("validation", false, errorMessage ?? `Request failed with status ${status}.`, { status }, undefined, status);
|
|
100
|
+
}
|
|
101
|
+
return this.createMeridianError("provider", false, `Unexpected response status ${status}.`, { status }, undefined, status);
|
|
102
|
+
}
|
|
103
|
+
async authStrategy(config) {
|
|
104
|
+
const apiKey = config.apiKey ?? config.username;
|
|
105
|
+
const appKey = config.clientSecret ?? config.apiSecret ?? config.password;
|
|
106
|
+
if (!apiKey) {
|
|
107
|
+
throw this.createMeridianError("auth", false, "Datadog authentication requires an API key. Set auth.apiKey (account API key), " +
|
|
108
|
+
"and optionally auth.apiSecret/auth.clientSecret (Application key) for read endpoints.", {}, undefined, 401);
|
|
109
|
+
}
|
|
110
|
+
return { token: appKey ? `${apiKey}|DD|${appKey}` : apiKey };
|
|
111
|
+
}
|
|
112
|
+
rateLimitPolicy(headers) {
|
|
113
|
+
const limit = headers.get("X-RateLimit-Limit");
|
|
114
|
+
const remaining = headers.get("X-RateLimit-Remaining");
|
|
115
|
+
const reset = headers.get("X-RateLimit-Reset");
|
|
116
|
+
return {
|
|
117
|
+
limit: limit ? Number.parseInt(limit, 10) : 100,
|
|
118
|
+
remaining: remaining ? Number.parseInt(remaining, 10) : 100,
|
|
119
|
+
reset: reset
|
|
120
|
+
? new Date(Date.now() + Number.parseInt(reset, 10) * 1000)
|
|
121
|
+
: new Date(Date.now() + 60_000),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
paginationStrategy() {
|
|
125
|
+
return new DatadogPaginationStrategy();
|
|
126
|
+
}
|
|
127
|
+
getIdempotencyConfig() {
|
|
128
|
+
return {
|
|
129
|
+
defaultSafeOperations: new Set(["GET", "HEAD", "OPTIONS"]),
|
|
130
|
+
operationOverrides: new Map(),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Verifies a Datadog webhook signature: an HMAC-SHA256 digest of the raw
|
|
135
|
+
* request body, hex-encoded, sent in the `X-Datadog-Signature` header and
|
|
136
|
+
* keyed by the webhook's shared secret.
|
|
137
|
+
*/
|
|
138
|
+
verifyWebhook(payload, signature, secret) {
|
|
139
|
+
const expected = createHmac("sha256", secret).update(payload).digest("hex");
|
|
140
|
+
try {
|
|
141
|
+
const a = Buffer.from(expected);
|
|
142
|
+
const b = Buffer.from(signature);
|
|
143
|
+
if (a.length !== b.length)
|
|
144
|
+
return false;
|
|
145
|
+
return timingSafeEqual(a, b);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
createMeridianError(category, retryable, message, metadata, retryAfter, status) {
|
|
152
|
+
return new MeridianError(message, category, "datadog", retryable, "", metadata, retryAfter, status);
|
|
153
|
+
}
|
|
154
|
+
extractRetryAfter(headers) {
|
|
155
|
+
if (!headers)
|
|
156
|
+
return undefined;
|
|
157
|
+
const value = headers instanceof Headers
|
|
158
|
+
? headers.get("retry-after")
|
|
159
|
+
: (Object.entries(headers).find(([k]) => k.toLowerCase() === "retry-after")?.[1] ?? null);
|
|
160
|
+
return parseRetryAfter(value) ?? undefined;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/datadog/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/datadog/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/datadog/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PaginationStrategy, RawResponse, RequestOptions } from "../../core/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Datadog's v2 search APIs (Logs, Events, Spans, ...) return a cursor for the
|
|
4
|
+
* next page at `meta.page.after`, which callers feed back as `page[cursor]`.
|
|
5
|
+
*/
|
|
6
|
+
export declare class DatadogPaginationStrategy implements PaginationStrategy {
|
|
7
|
+
extractCursor(response: RawResponse): string | null;
|
|
8
|
+
extractTotal(_response: RawResponse): number | null;
|
|
9
|
+
hasNext(response: RawResponse): boolean;
|
|
10
|
+
buildNextRequest(endpoint: string, options: RequestOptions, cursor: string): {
|
|
11
|
+
endpoint: string;
|
|
12
|
+
options: RequestOptions;
|
|
13
|
+
};
|
|
14
|
+
private readAfterCursor;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/providers/datadog/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3F;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,kBAAkB;IAClE,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAKnD,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAKnD,OAAO,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO;IAIvC,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,eAAe;CAUxB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog's v2 search APIs (Logs, Events, Spans, ...) return a cursor for the
|
|
3
|
+
* next page at `meta.page.after`, which callers feed back as `page[cursor]`.
|
|
4
|
+
*/
|
|
5
|
+
export class DatadogPaginationStrategy {
|
|
6
|
+
extractCursor(response) {
|
|
7
|
+
const cursor = this.readAfterCursor(response);
|
|
8
|
+
return cursor ?? null;
|
|
9
|
+
}
|
|
10
|
+
extractTotal(_response) {
|
|
11
|
+
// Datadog search APIs do not return a total result count.
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
hasNext(response) {
|
|
15
|
+
return this.readAfterCursor(response) !== null;
|
|
16
|
+
}
|
|
17
|
+
buildNextRequest(endpoint, options, cursor) {
|
|
18
|
+
return {
|
|
19
|
+
endpoint,
|
|
20
|
+
options: {
|
|
21
|
+
...options,
|
|
22
|
+
query: {
|
|
23
|
+
...options.query,
|
|
24
|
+
"page[cursor]": cursor,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
readAfterCursor(response) {
|
|
30
|
+
if (typeof response.body !== "object" || response.body === null)
|
|
31
|
+
return null;
|
|
32
|
+
const body = response.body;
|
|
33
|
+
const meta = body.meta;
|
|
34
|
+
const page = meta?.page;
|
|
35
|
+
if (page && typeof page.after === "string" && page.after.length > 0) {
|
|
36
|
+
return page.after;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/providers/datadog/pagination.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IACpC,aAAa,CAAC,QAAqB;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC9C,OAAO,MAAM,IAAI,IAAI,CAAC;IACxB,CAAC;IAED,YAAY,CAAC,SAAsB;QACjC,0DAA0D;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,QAAqB;QAC3B,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IACjD,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,cAAc,EAAE,MAAM;iBACvB;aACF;SACF,CAAC;IACJ,CAAC;IAEO,eAAe,CAAC,QAAqB;QAC3C,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAA+B,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAA2C,CAAC;QAC9D,MAAM,IAAI,GAAG,IAAI,EAAE,IAA2C,CAAC;QAC/D,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
* S3-compatible object storage (AWS S3, Cloudflare R2, and other S3-API stores)
|
|
5
|
+
* authenticates every request with AWS Signature Version 4 — there's no bearer
|
|
6
|
+
* token or static API key header. Each call is signed in `buildRequest` using
|
|
7
|
+
* the access key / secret key (and, for R2, region `"auto"`) supplied via
|
|
8
|
+
* `auth.custom`. Responses are XML, not JSON; pagination and error parsing
|
|
9
|
+
* extract the handful of fields they need from that XML directly.
|
|
10
|
+
*
|
|
11
|
+
* Configure with `auth.username`/`auth.password` (access key / secret key) and
|
|
12
|
+
* `auth.custom = { region, endpoint?, sessionToken? }`. For R2, set
|
|
13
|
+
* `auth.custom.region = "auto"` and `auth.custom.endpoint` to your account's
|
|
14
|
+
* `https://<account_id>.r2.cloudflarestorage.com` URL (or pass it as `baseUrl`
|
|
15
|
+
* in the provider config).
|
|
16
|
+
*/
|
|
17
|
+
export declare class S3Adapter implements ProviderAdapter {
|
|
18
|
+
private baseUrl;
|
|
19
|
+
constructor(baseUrl?: string);
|
|
20
|
+
buildRequest(input: AdapterInput): BuiltRequest;
|
|
21
|
+
parseResponse(raw: RawResponse): NormalizedResponse;
|
|
22
|
+
parseError(raw: unknown): MeridianError;
|
|
23
|
+
private parseHttpError;
|
|
24
|
+
authStrategy(config: AuthConfig): Promise<AuthToken>;
|
|
25
|
+
rateLimitPolicy(_headers: Headers): RateLimitInfo;
|
|
26
|
+
paginationStrategy(): PaginationStrategy;
|
|
27
|
+
getIdempotencyConfig(): IdempotencyConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Verifies an S3 Event Notification delivered via SNS/EventBridge webhook —
|
|
30
|
+
* an HMAC-SHA256 digest of the raw request body, hex-encoded, keyed by a
|
|
31
|
+
* shared secret configured on the destination (S3 itself does not sign
|
|
32
|
+
* notifications; this supports the common "shared secret" relay pattern).
|
|
33
|
+
*/
|
|
34
|
+
verifyWebhook(payload: string | Buffer, signature: string, secret: string): boolean;
|
|
35
|
+
private createMeridianError;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/s3/adapter.ts"],"names":[],"mappings":"AAEA,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,EAAoB,aAAa,EAAe,MAAM,qBAAqB,CAAC;AA+CnF;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,YAAW,eAAe;IAC/C,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,SAA8B;IAIjD,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY;IAqC/C,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,kBAAkB;IAOnD,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa;IAkCvC,OAAO,CAAC,cAAc;IAkGhB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IA8B1D,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,aAAa;IASjD,kBAAkB,IAAI,kBAAkB;IAIxC,oBAAoB,IAAI,iBAAiB;IAOzC;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAYnF,OAAO,CAAC,mBAAmB;CAU5B"}
|