@q32/core 0.1.27 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,6 +68,10 @@ import {
68
68
 
69
69
  See [docs/evaluation.md](docs/evaluation.md) for the project-inventory replacement matrix and [docs/jobs.md](docs/jobs.md) for the shared jobs model.
70
70
 
71
+ The root `@q32/core` export is kept dependency-light. Optional integrations that
72
+ need peer packages should be imported from their subpaths, for example
73
+ `@q32/core/pg-kysely` for Kysely/Postgres helpers.
74
+
71
75
  Framework adapters are deliberately thin. Put policy and persistence in `auth`,
72
76
  `jobs`, `ops-events`, and `api`; use `hono` or `react-router` only to translate a
73
77
  framework request/response shape into those shared services.
package/dist/aws.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ export type AwsCredentials = {
2
+ accessKeyId: string;
3
+ secretAccessKey: string;
4
+ sessionToken?: string;
5
+ };
6
+ export type AwsConfig = AwsCredentials & {
7
+ region: string;
8
+ };
9
+ export type AwsEnv = {
10
+ AWS_ACCESS_KEY?: string;
11
+ AWS_SECRET_KEY?: string;
12
+ AWS_ACCESS_KEY_ID?: string;
13
+ AWS_SECRET_ACCESS_KEY?: string;
14
+ AWS_SESSION_TOKEN?: string;
15
+ AWS_REGION?: string;
16
+ };
17
+ export declare function createAwsConfigFromEnv(env: AwsEnv, defaultRegion?: string): AwsConfig | null;
18
+ export type AwsFetchOptions = {
19
+ service: string;
20
+ region?: string;
21
+ fetcher?: typeof fetch;
22
+ };
23
+ export declare function awsFetch(config: AwsConfig, input: string | URL, init: RequestInit, options: AwsFetchOptions): Promise<Response>;
24
+ //# sourceMappingURL=aws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../src/aws.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,SAAc,GAAG,SAAS,GAAG,IAAI,CAUjG;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB,CAAC;AAEF,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,GAAG,GAAG,EACnB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,CAAC,CA4CnB"}
package/dist/aws.js ADDED
@@ -0,0 +1,109 @@
1
+ export function createAwsConfigFromEnv(env, defaultRegion = "us-east-1") {
2
+ const accessKeyId = env.AWS_ACCESS_KEY_ID ?? env.AWS_ACCESS_KEY;
3
+ const secretAccessKey = env.AWS_SECRET_ACCESS_KEY ?? env.AWS_SECRET_KEY;
4
+ if (!accessKeyId || !secretAccessKey)
5
+ return null;
6
+ return {
7
+ accessKeyId,
8
+ secretAccessKey,
9
+ sessionToken: env.AWS_SESSION_TOKEN,
10
+ region: env.AWS_REGION ?? defaultRegion,
11
+ };
12
+ }
13
+ export async function awsFetch(config, input, init, options) {
14
+ const url = new URL(input.toString());
15
+ const region = options.region ?? config.region;
16
+ const method = (init.method ?? "GET").toUpperCase();
17
+ const body = bodyToString(init.body);
18
+ const payloadHash = await sha256Hex(body);
19
+ const headers = new Headers(init.headers);
20
+ headers.set("host", url.host);
21
+ headers.set("x-amz-content-sha256", payloadHash);
22
+ const now = new Date();
23
+ const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, "");
24
+ const dateStamp = amzDate.slice(0, 8);
25
+ headers.set("x-amz-date", amzDate);
26
+ if (config.sessionToken)
27
+ headers.set("x-amz-security-token", config.sessionToken);
28
+ const signedHeaderNames = headerNames(headers).map((key) => key.toLowerCase()).sort();
29
+ const canonicalHeaders = signedHeaderNames.map((key) => `${key}:${normalizeHeaderValue(headers.get(key) ?? "")}\n`).join("");
30
+ const canonicalRequest = [
31
+ method,
32
+ canonicalPath(url),
33
+ canonicalQuery(url),
34
+ canonicalHeaders,
35
+ signedHeaderNames.join(";"),
36
+ payloadHash,
37
+ ].join("\n");
38
+ const credentialScope = `${dateStamp}/${region}/${options.service}/aws4_request`;
39
+ const stringToSign = [
40
+ "AWS4-HMAC-SHA256",
41
+ amzDate,
42
+ credentialScope,
43
+ await sha256Hex(canonicalRequest),
44
+ ].join("\n");
45
+ const signature = await hmacHex(await signingKey(config.secretAccessKey, dateStamp, region, options.service), stringToSign);
46
+ headers.set("authorization", `AWS4-HMAC-SHA256 Credential=${config.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaderNames.join(";")}, Signature=${signature}`);
47
+ return (options.fetcher ?? fetch)(url, {
48
+ ...init,
49
+ method,
50
+ headers,
51
+ body: init.body,
52
+ });
53
+ }
54
+ function bodyToString(body) {
55
+ if (!body)
56
+ return "";
57
+ if (typeof body === "string")
58
+ return body;
59
+ throw new Error("awsFetch currently supports string request bodies.");
60
+ }
61
+ function canonicalPath(url) {
62
+ return url.pathname
63
+ .split("/")
64
+ .map((part) => encodeURIComponent(decodeURIComponent(part)).replace(/[!'()*]/g, pctEncode))
65
+ .join("/");
66
+ }
67
+ function canonicalQuery(url) {
68
+ const entries = [];
69
+ url.searchParams.forEach((value, key) => entries.push([key, value]));
70
+ return entries
71
+ .map(([key, value]) => [encodeRfc3986(key), encodeRfc3986(value)])
72
+ .sort(([leftKey, leftValue], [rightKey, rightValue]) => leftKey.localeCompare(rightKey) || leftValue.localeCompare(rightValue))
73
+ .map(([key, value]) => `${key}=${value}`)
74
+ .join("&");
75
+ }
76
+ function headerNames(headers) {
77
+ const names = [];
78
+ headers.forEach((_value, key) => names.push(key));
79
+ return names;
80
+ }
81
+ function normalizeHeaderValue(value) {
82
+ return value.trim().replace(/\s+/g, " ");
83
+ }
84
+ function encodeRfc3986(value) {
85
+ return encodeURIComponent(value).replace(/[!'()*]/g, pctEncode);
86
+ }
87
+ function pctEncode(char) {
88
+ return `%${char.charCodeAt(0).toString(16).toUpperCase()}`;
89
+ }
90
+ async function signingKey(secret, date, region, service) {
91
+ const kDate = await hmacRaw(new TextEncoder().encode(`AWS4${secret}`), date);
92
+ const kRegion = await hmacRaw(kDate, region);
93
+ const kService = await hmacRaw(kRegion, service);
94
+ return hmacRaw(kService, "aws4_request");
95
+ }
96
+ async function hmacRaw(key, value) {
97
+ const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
98
+ return crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(value));
99
+ }
100
+ async function hmacHex(key, value) {
101
+ return bytesToHex(new Uint8Array(await hmacRaw(key, value)));
102
+ }
103
+ async function sha256Hex(value) {
104
+ return bytesToHex(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value))));
105
+ }
106
+ function bytesToHex(bytes) {
107
+ return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
108
+ }
109
+ //# sourceMappingURL=aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.js","sourceRoot":"","sources":["../src/aws.ts"],"names":[],"mappings":"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"}
package/dist/email.d.ts CHANGED
@@ -30,4 +30,12 @@ export interface EmailProvider {
30
30
  export declare function formatEmailAddress(address: EmailAddress): string;
31
31
  export declare function normalizeEmailAddress(email: string): string;
32
32
  export declare function appendUnsubscribeFooter(text: string, unsubscribeUrl: string): string;
33
+ export declare function sanitizeEmailHeaderValue(value: string): string;
34
+ export declare function encodeMimeHeader(value: string): string;
35
+ export declare function buildListUnsubscribeHeaders(url: string): Record<string, string>;
36
+ export type RawMimeMessageInput = Omit<SendEmailInput, "tags"> & {
37
+ headers?: Record<string, string>;
38
+ boundaryPrefix?: string;
39
+ };
40
+ export declare function buildRawMimeMessage(input: RawMimeMessageInput): string;
33
41
  //# sourceMappingURL=email.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,YAAY,EAAE,CAAC;IACnB,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACvD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAIhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAEpF"}
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,YAAY,EAAE,CAAC;IACnB,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACvD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAIhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK/E;AAED,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAiDtE"}
package/dist/email.js CHANGED
@@ -13,4 +13,91 @@ export function normalizeEmailAddress(email) {
13
13
  export function appendUnsubscribeFooter(text, unsubscribeUrl) {
14
14
  return `${text.trim()}\n\nUnsubscribe: ${unsubscribeUrl}\n`;
15
15
  }
16
+ export function sanitizeEmailHeaderValue(value) {
17
+ return value.replace(/[\r\n]+/g, " ").trim();
18
+ }
19
+ export function encodeMimeHeader(value) {
20
+ if (/^[\x20-\x7e]*$/.test(value))
21
+ return sanitizeEmailHeaderValue(value);
22
+ return `=?UTF-8?B?${base64Utf8(value)}?=`;
23
+ }
24
+ export function buildListUnsubscribeHeaders(url) {
25
+ return {
26
+ "List-Unsubscribe": `<${sanitizeEmailHeaderValue(url)}>`,
27
+ "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
28
+ };
29
+ }
30
+ export function buildRawMimeMessage(input) {
31
+ const mixedBoundary = `${input.boundaryPrefix ?? "q32"}-mixed-${crypto.randomUUID()}`;
32
+ const bodyBoundary = `${input.boundaryPrefix ?? "q32"}-body-${crypto.randomUUID()}`;
33
+ const attachments = input.attachments ?? [];
34
+ const headers = [
35
+ `From: ${formatEmailAddress(input.from)}`,
36
+ `To: ${input.to.map(formatEmailAddress).join(", ")}`,
37
+ ...(input.cc?.length ? [`Cc: ${input.cc.map(formatEmailAddress).join(", ")}`] : []),
38
+ `Subject: ${encodeMimeHeader(input.subject)}`,
39
+ "MIME-Version: 1.0",
40
+ ...(input.replyTo?.length ? [`Reply-To: ${input.replyTo.map(formatEmailAddress).join(", ")}`] : []),
41
+ ];
42
+ for (const [name, value] of Object.entries(input.headers ?? {})) {
43
+ const headerName = sanitizeHeaderName(name);
44
+ const headerValue = sanitizeEmailHeaderValue(value);
45
+ if (headerName && headerValue)
46
+ headers.push(`${headerName}: ${headerValue}`);
47
+ }
48
+ const parts = [...headers, `Content-Type: multipart/mixed; boundary="${mixedBoundary}"`, ""];
49
+ parts.push(`--${mixedBoundary}`);
50
+ if (input.text && input.html) {
51
+ parts.push(`Content-Type: multipart/alternative; boundary="${bodyBoundary}"`, "");
52
+ parts.push(`--${bodyBoundary}`);
53
+ parts.push("Content-Type: text/plain; charset=UTF-8");
54
+ parts.push("Content-Transfer-Encoding: base64", "", wrapBase64(base64Utf8(input.text)), "");
55
+ parts.push(`--${bodyBoundary}`);
56
+ parts.push("Content-Type: text/html; charset=UTF-8");
57
+ parts.push("Content-Transfer-Encoding: base64", "", wrapBase64(base64Utf8(input.html)), "");
58
+ parts.push(`--${bodyBoundary}--`, "");
59
+ }
60
+ else if (input.html) {
61
+ parts.push("Content-Type: text/html; charset=UTF-8");
62
+ parts.push("Content-Transfer-Encoding: base64", "", wrapBase64(base64Utf8(input.html)), "");
63
+ }
64
+ else {
65
+ parts.push("Content-Type: text/plain; charset=UTF-8");
66
+ parts.push("Content-Transfer-Encoding: base64", "", wrapBase64(base64Utf8(input.text ?? "")), "");
67
+ }
68
+ for (const attachment of attachments) {
69
+ parts.push(`--${mixedBoundary}`);
70
+ parts.push(`Content-Type: ${sanitizeEmailHeaderValue(attachment.contentType)}; name=${quoteHeaderParam(attachment.filename)}`);
71
+ parts.push("Content-Transfer-Encoding: base64");
72
+ parts.push(`Content-Disposition: attachment; filename=${quoteHeaderParam(attachment.filename)}`);
73
+ parts.push("", wrapBase64(attachmentDataToBase64(attachment.data)), "");
74
+ }
75
+ parts.push(`--${mixedBoundary}--`, "");
76
+ return parts.join("\r\n");
77
+ }
78
+ function sanitizeHeaderName(value) {
79
+ const name = value.trim();
80
+ return /^[A-Za-z0-9-]+$/.test(name) ? name : "";
81
+ }
82
+ function quoteHeaderParam(value) {
83
+ return `"${sanitizeEmailHeaderValue(value).replace(/(["\\])/g, "\\$1")}"`;
84
+ }
85
+ function attachmentDataToBase64(value) {
86
+ if (typeof value === "string")
87
+ return base64Utf8(value);
88
+ let binary = "";
89
+ for (const byte of value)
90
+ binary += String.fromCharCode(byte);
91
+ return btoa(binary);
92
+ }
93
+ function base64Utf8(value) {
94
+ const bytes = new TextEncoder().encode(value);
95
+ let binary = "";
96
+ for (const byte of bytes)
97
+ binary += String.fromCharCode(byte);
98
+ return btoa(binary);
99
+ }
100
+ function wrapBase64(value) {
101
+ return value.replace(/.{1,76}/g, "$&\r\n").trimEnd();
102
+ }
16
103
  //# sourceMappingURL=email.js.map
package/dist/email.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAkCA,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,IAAI,CAAC,OAAO,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClD,OAAO,IAAI,OAAO,MAAM,OAAO,CAAC,KAAK,GAAG,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;IACvG,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,cAAsB;IAC1E,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,oBAAoB,cAAc,IAAI,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./api.js";
2
2
  export * from "./ai.js";
3
3
  export * from "./auth.js";
4
+ export * from "./aws.js";
4
5
  export * from "./billing.js";
5
6
  export * from "./cloudflare.js";
6
7
  export * from "./crypto.js";
@@ -16,12 +17,13 @@ export * from "./mcp.js";
16
17
  export * from "./oauth.js";
17
18
  export * from "./ops-events.js";
18
19
  export * from "./pg.js";
19
- export * from "./pg-kysely.js";
20
20
  export * from "./r2-json.js";
21
21
  export * from "./rate-limit.js";
22
22
  export * from "./react-router.js";
23
23
  export * from "./seo.js";
24
24
  export * from "./session.js";
25
+ export * from "./ses.js";
26
+ export * from "./ses-sns.js";
25
27
  export * from "./testing.js";
26
28
  export * from "./time.js";
27
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./api.js";
2
2
  export * from "./ai.js";
3
3
  export * from "./auth.js";
4
+ export * from "./aws.js";
4
5
  export * from "./billing.js";
5
6
  export * from "./cloudflare.js";
6
7
  export * from "./crypto.js";
@@ -16,12 +17,13 @@ export * from "./mcp.js";
16
17
  export * from "./oauth.js";
17
18
  export * from "./ops-events.js";
18
19
  export * from "./pg.js";
19
- export * from "./pg-kysely.js";
20
20
  export * from "./r2-json.js";
21
21
  export * from "./rate-limit.js";
22
22
  export * from "./react-router.js";
23
23
  export * from "./seo.js";
24
24
  export * from "./session.js";
25
+ export * from "./ses.js";
26
+ export * from "./ses-sns.js";
25
27
  export * from "./testing.js";
26
28
  export * from "./time.js";
27
29
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,60 @@
1
+ export type SnsEnvelope = {
2
+ Type?: string;
3
+ Message?: string;
4
+ MessageId?: string;
5
+ TopicArn?: string;
6
+ SubscribeURL?: string;
7
+ };
8
+ export type SesFeedbackMessage = {
9
+ eventType?: string;
10
+ notificationType?: string;
11
+ mail?: {
12
+ destination?: unknown;
13
+ };
14
+ bounce?: {
15
+ bouncedRecipients?: Array<{
16
+ emailAddress?: unknown;
17
+ }>;
18
+ };
19
+ complaint?: {
20
+ complainedRecipients?: Array<{
21
+ emailAddress?: unknown;
22
+ }>;
23
+ };
24
+ };
25
+ export type SesFeedbackEvent = {
26
+ eventType: string;
27
+ emails: string[];
28
+ messageId?: string;
29
+ topicArn?: string;
30
+ };
31
+ export type SesReceiptMessage = {
32
+ mail?: {
33
+ messageId?: string;
34
+ source?: string;
35
+ commonHeaders?: {
36
+ subject?: string;
37
+ };
38
+ };
39
+ receipt?: {
40
+ recipients?: string[];
41
+ };
42
+ };
43
+ export type SesReceiptEvent = {
44
+ messageId: string;
45
+ source?: string;
46
+ subject?: string;
47
+ recipients: string[];
48
+ snsMessageId?: string;
49
+ topicArn?: string;
50
+ };
51
+ export declare function parseSnsEnvelope(body: string): SnsEnvelope | null;
52
+ export declare function isTrustedSnsSubscribeUrl(raw: string): boolean;
53
+ export declare function confirmSnsSubscription(envelope: SnsEnvelope, fetcher?: typeof fetch): Promise<boolean>;
54
+ export declare function parseSesFeedbackNotification(envelope: SnsEnvelope): SesFeedbackEvent | null;
55
+ export declare function extractSesFeedbackRecipients(message: SesFeedbackMessage): {
56
+ eventType: string;
57
+ emails: string[];
58
+ };
59
+ export declare function parseSesReceiptNotification(envelope: SnsEnvelope): SesReceiptEvent | null;
60
+ //# sourceMappingURL=ses-sns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ses-sns.d.ts","sourceRoot":"","sources":["../src/ses-sns.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE;QACL,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,iBAAiB,CAAC,EAAE,KAAK,CAAC;YAAE,YAAY,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KACvD,CAAC;IACF,SAAS,CAAC,EAAE;QACV,oBAAoB,CAAC,EAAE,KAAK,CAAC;YAAE,YAAY,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KAC1D,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,CAAC;IACF,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAIjE;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAY7D;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnH;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAY3F;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,kBAAkB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAYjH;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,CAczF"}
@@ -0,0 +1,96 @@
1
+ export function parseSnsEnvelope(body) {
2
+ const parsed = parseJsonObject(body);
3
+ if (!parsed)
4
+ return null;
5
+ return parsed;
6
+ }
7
+ export function isTrustedSnsSubscribeUrl(raw) {
8
+ let url;
9
+ try {
10
+ url = new URL(raw);
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ return (url.protocol === "https:" &&
16
+ (/^sns[.-][a-z0-9-]+\.amazonaws\.com$/i.test(url.hostname) ||
17
+ /^sns\.[a-z0-9-]+\.amazonaws\.com\.cn$/i.test(url.hostname)));
18
+ }
19
+ export async function confirmSnsSubscription(envelope, fetcher = fetch) {
20
+ if (envelope.Type !== "SubscriptionConfirmation" || typeof envelope.SubscribeURL !== "string")
21
+ return false;
22
+ if (!isTrustedSnsSubscribeUrl(envelope.SubscribeURL))
23
+ return false;
24
+ const response = await fetcher(envelope.SubscribeURL, { method: "GET" });
25
+ return response.ok;
26
+ }
27
+ export function parseSesFeedbackNotification(envelope) {
28
+ if (envelope.Type !== "Notification" || typeof envelope.Message !== "string")
29
+ return null;
30
+ const message = parseJsonObject(envelope.Message);
31
+ if (!message)
32
+ return null;
33
+ const { eventType, emails } = extractSesFeedbackRecipients(message);
34
+ if (!eventType)
35
+ return null;
36
+ return {
37
+ eventType,
38
+ emails,
39
+ ...(envelope.MessageId ? { messageId: envelope.MessageId } : {}),
40
+ ...(envelope.TopicArn ? { topicArn: envelope.TopicArn } : {}),
41
+ };
42
+ }
43
+ export function extractSesFeedbackRecipients(message) {
44
+ const eventType = String(message.eventType ?? message.notificationType ?? "");
45
+ const normalized = eventType.toLowerCase();
46
+ if (normalized === "bounce") {
47
+ const recipients = message.bounce?.bouncedRecipients?.map((recipient) => recipient.emailAddress) ?? [];
48
+ return { eventType, emails: uniqueEmails(recipients.length > 0 ? recipients : fallbackDestination(message)) };
49
+ }
50
+ if (normalized === "complaint") {
51
+ const recipients = message.complaint?.complainedRecipients?.map((recipient) => recipient.emailAddress) ?? [];
52
+ return { eventType, emails: uniqueEmails(recipients.length > 0 ? recipients : fallbackDestination(message)) };
53
+ }
54
+ return { eventType, emails: [] };
55
+ }
56
+ export function parseSesReceiptNotification(envelope) {
57
+ if (envelope.Type !== "Notification" || typeof envelope.Message !== "string")
58
+ return null;
59
+ const message = parseJsonObject(envelope.Message);
60
+ const messageId = message?.mail?.messageId;
61
+ const recipients = message?.receipt?.recipients ?? [];
62
+ if (!messageId || recipients.length === 0)
63
+ return null;
64
+ return {
65
+ messageId,
66
+ recipients,
67
+ ...(message.mail?.source ? { source: message.mail.source } : {}),
68
+ ...(message.mail?.commonHeaders?.subject ? { subject: message.mail.commonHeaders.subject } : {}),
69
+ ...(envelope.MessageId ? { snsMessageId: envelope.MessageId } : {}),
70
+ ...(envelope.TopicArn ? { topicArn: envelope.TopicArn } : {}),
71
+ };
72
+ }
73
+ function parseJsonObject(value) {
74
+ try {
75
+ const parsed = JSON.parse(value);
76
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ function fallbackDestination(message) {
83
+ return Array.isArray(message.mail?.destination) ? message.mail.destination : [];
84
+ }
85
+ function uniqueEmails(values) {
86
+ const emails = new Set();
87
+ for (const value of values) {
88
+ if (typeof value !== "string")
89
+ continue;
90
+ const email = value.trim().toLowerCase();
91
+ if (email.includes("@"))
92
+ emails.add(email);
93
+ }
94
+ return [...emails];
95
+ }
96
+ //# sourceMappingURL=ses-sns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ses-sns.js","sourceRoot":"","sources":["../src/ses-sns.ts"],"names":[],"mappings":"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"}
package/dist/ses.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import { type AwsConfig, type AwsEnv } from "./aws.js";
2
+ import { type EmailAddress, type SendEmailInput } from "./email.js";
3
+ export type SesEmailInput = Omit<SendEmailInput, "from"> & {
4
+ from?: EmailAddress;
5
+ headers?: Record<string, string>;
6
+ };
7
+ export type SesSendResult = {
8
+ messageId: string;
9
+ provider: "ses";
10
+ };
11
+ export type SesMailer = {
12
+ readonly enabled: boolean;
13
+ send(input: SesEmailInput): Promise<SesSendResult>;
14
+ };
15
+ export type SesMailerEnv = AwsEnv & {
16
+ FROM_EMAIL?: string;
17
+ EMAIL_FROM?: string;
18
+ NOTIFICATION_FROM_EMAIL?: string;
19
+ POSTMARK_FROM_EMAIL?: string;
20
+ SES_FROM_EMAIL?: string;
21
+ EMAIL_REPLY_TO?: string;
22
+ NOTIFICATION_REPLY_TO?: string;
23
+ };
24
+ export type SesSendOptions = {
25
+ fetcher?: typeof fetch;
26
+ };
27
+ export declare class NoopSesMailer implements SesMailer {
28
+ readonly enabled = false;
29
+ send(): Promise<SesSendResult>;
30
+ }
31
+ export declare class WorkerSesMailer implements SesMailer {
32
+ private readonly config;
33
+ private readonly defaults;
34
+ readonly enabled = true;
35
+ constructor(config: AwsConfig, defaults: {
36
+ from: EmailAddress;
37
+ replyTo?: EmailAddress[];
38
+ fetcher?: typeof fetch;
39
+ });
40
+ send(input: SesEmailInput): Promise<SesSendResult>;
41
+ }
42
+ export declare function createSesMailerFromEnv(env: SesMailerEnv, options?: {
43
+ fromEmail?: string;
44
+ fromName?: string;
45
+ replyTo?: string | string[] | null;
46
+ fetcher?: typeof fetch;
47
+ }): SesMailer;
48
+ export declare function sendSesEmail(config: AwsConfig, input: SendEmailInput & {
49
+ headers?: Record<string, string>;
50
+ }, options?: SesSendOptions): Promise<SesSendResult>;
51
+ export declare function sesQuery(config: AwsConfig, params: Record<string, string>, options?: SesSendOptions): Promise<string>;
52
+ export declare function inboundSesMxHost(region?: string): string;
53
+ //# sourceMappingURL=ses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../src/ses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AACzF,OAAO,EAA2C,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7G,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG;IACzD,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB,CAAC;AAEF,qBAAa,aAAc,YAAW,SAAS;IAC7C,QAAQ,CAAC,OAAO,SAAS;IAEnB,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;CAGrC;AAED,qBAAa,eAAgB,YAAW,SAAS;IAI7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,QAAQ,CAAC,OAAO,QAAQ;gBAGL,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE;QACzB,IAAI,EAAE,YAAY,CAAC;QACnB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;QACzB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;KACxB;IAGH,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAOnD;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,YAAY,EACjB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACnB,GACL,SAAS,CAcX;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,cAAc,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAC5D,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAaxB;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,SAAc,GAAG,MAAM,CAE7D"}