better-ship 0.40.0 → 0.42.0
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/{application-xXTCe8o0.js → application-BwevrnLI.js} +75 -10
- package/dist/application-BwevrnLI.js.map +1 -0
- package/dist/application.d.ts +3 -3
- package/dist/application.js +2 -2
- package/dist/{auth-secondary-storage-CcNkkEk0.d.ts → auth-secondary-storage-DlzjamBm.d.ts} +2 -2
- package/dist/{auth-secondary-storage-CcNkkEk0.d.ts.map → auth-secondary-storage-DlzjamBm.d.ts.map} +1 -1
- package/dist/better-auth/apple-client-secret.d.ts +1 -1
- package/dist/better-auth/apple-client-secret.js +1 -1
- package/dist/better-auth/auth-client.js +1 -1
- package/dist/better-auth/rate-limit.d.ts +1 -1
- package/dist/better-auth/rate-limit.js +1 -1
- package/dist/better-auth/secondary-storage.d.ts +1 -1
- package/dist/better-auth.js +1 -1
- package/dist/billing/client.d.ts +1 -1
- package/dist/billing/client.js +1 -1
- package/dist/browser-support/floor.d.ts +1 -1
- package/dist/browser-support/floor.js +1 -1
- package/dist/browser-support/oxlint.js +1 -1
- package/dist/client-BZgpmuSp.js +27 -0
- package/dist/client-BZgpmuSp.js.map +1 -0
- package/dist/cloudflare/auth-secondary-storage.d.ts +1 -1
- package/dist/cloudflare/auth-secondary-storage.js +1 -1
- package/dist/cloudflare/durable-object-client.js +2 -2
- package/dist/cloudflare/durable-object-errors.d.ts +1 -1
- package/dist/cloudflare/durable-object-errors.js +1 -1
- package/dist/cloudflare/kv-client.js +2 -2
- package/dist/cloudflare/kv-errors.d.ts +1 -1
- package/dist/cloudflare/kv-errors.js +1 -1
- package/dist/cloudflare/queue.d.ts +3 -21
- package/dist/cloudflare/queue.d.ts.map +1 -1
- package/dist/cloudflare/queue.js +11 -52
- package/dist/cloudflare/queue.js.map +1 -1
- package/dist/cloudflare/r2-client.js +2 -2
- package/dist/cloudflare/r2-errors.d.ts +1 -1
- package/dist/cloudflare/r2-errors.js +1 -1
- package/dist/cloudflare/rate-limiter.d.ts +1 -1
- package/dist/cloudflare/rate-limiter.js +1 -1
- package/dist/cloudflare/scheduled.d.ts +1 -1
- package/dist/cloudflare/scheduled.js +1 -1
- package/dist/cloudflare/turnstile.d.ts +1 -1
- package/dist/cloudflare/turnstile.js +1 -1
- package/dist/cloudflare.d.ts +3 -3
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +6 -5
- package/dist/cloudflare.js.map +1 -1
- package/dist/{core-DOBZeYSX.js → core-CV8SQv01.js} +65 -4
- package/dist/core-CV8SQv01.js.map +1 -0
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/{durable-object-errors-CcfTu0PQ.js → durable-object-errors-C7e7essH.js} +2 -2
- package/dist/{durable-object-errors-CcfTu0PQ.js.map → durable-object-errors-C7e7essH.js.map} +1 -1
- package/dist/{floor-BTBtPI9_.js → floor-BdRTO_LO.js} +2 -2
- package/dist/{floor-BTBtPI9_.js.map → floor-BdRTO_LO.js.map} +1 -1
- package/dist/http.d.ts +2 -2
- package/dist/http.js +2 -2
- package/dist/{index-Db2GV9ZP.d.ts → index-DIHLfC-p.d.ts} +44 -4
- package/dist/index-DIHLfC-p.d.ts.map +1 -0
- package/dist/{index-CtIdbnEZ.d.ts → index-tJzJUgTh.d.ts} +30 -4
- package/dist/index-tJzJUgTh.d.ts.map +1 -0
- package/dist/{kv-errors-B2k_2lyY.js → kv-errors-DXbnO7cB.js} +2 -2
- package/dist/{kv-errors-B2k_2lyY.js.map → kv-errors-DXbnO7cB.js.map} +1 -1
- package/dist/{metrics-DRCoGBNF.d.ts → metrics-CdpccKGI.d.ts} +2 -2
- package/dist/{metrics-DRCoGBNF.d.ts.map → metrics-CdpccKGI.d.ts.map} +1 -1
- package/dist/{outbox-repository-options-Dd-s5SxA.js → outbox-repository-options-BKapMX7X.js} +2 -2
- package/dist/{outbox-repository-options-Dd-s5SxA.js.map → outbox-repository-options-BKapMX7X.js.map} +1 -1
- package/dist/{outbox-repository-options-Cmf0vbBQ.d.ts → outbox-repository-options-BtAq0nAG.d.ts} +3 -3
- package/dist/{outbox-repository-options-Cmf0vbBQ.d.ts.map → outbox-repository-options-BtAq0nAG.d.ts.map} +1 -1
- package/dist/{payment-service.error-BR10zqxk.js → payment-service.error-oW2bKAfU.js} +2 -2
- package/dist/{payment-service.error-BR10zqxk.js.map → payment-service.error-oW2bKAfU.js.map} +1 -1
- package/dist/postgres.d.ts +3 -3
- package/dist/postgres.d.ts.map +1 -1
- package/dist/postgres.js +6 -5
- package/dist/postgres.js.map +1 -1
- package/dist/posthog/metrics.d.ts +1 -1
- package/dist/posthog/server.d.ts +3 -3
- package/dist/posthog/server.js +1 -1
- package/dist/{r2-errors-BF49eqU_.js → r2-errors-DzpOvciV.js} +2 -2
- package/dist/{r2-errors-BF49eqU_.js.map → r2-errors-DzpOvciV.js.map} +1 -1
- package/dist/{request-BYQodKDU.js → request-C5k8ME_7.js} +2 -2
- package/dist/{request-BYQodKDU.js.map → request-C5k8ME_7.js.map} +1 -1
- package/dist/resend.d.ts +3 -3
- package/dist/resend.js +2 -2
- package/dist/sentry/client.d.ts +1 -1
- package/dist/sentry/client.js +1 -1
- package/dist/sentry/server.d.ts +2 -2
- package/dist/sentry/tanstack.d.ts +1 -1
- package/dist/stripe/client.d.ts +7 -2
- package/dist/stripe/client.d.ts.map +1 -1
- package/dist/stripe/client.js +1 -1
- package/dist/stripe/payment-service.error.d.ts +1 -1
- package/dist/stripe/payment-service.error.js +1 -1
- package/dist/stripe/payment-service.js +1 -1
- package/dist/stripe/payment-webhook.d.ts +1 -1
- package/dist/stripe/payment-webhook.js +1 -1
- package/dist/stripe/request.js +1 -1
- package/dist/{stripe-fixture-yFUknTJO.js → stripe-fixture-11EmnD6F.js} +2 -2
- package/dist/{stripe-fixture-yFUknTJO.js.map → stripe-fixture-11EmnD6F.js.map} +1 -1
- package/dist/tanstack.d.ts +1 -1
- package/dist/tanstack.js +1 -1
- package/dist/testing/outbox-repository.d.ts +2 -2
- package/dist/testing/payment-service.js +2 -2
- package/dist/testing/stripe.js +1 -1
- package/dist/{webhook-verification-C4R6OO7f.js → webhook-verification-B8v3-LQ2.js} +2 -2
- package/dist/{webhook-verification-C4R6OO7f.js.map → webhook-verification-B8v3-LQ2.js.map} +1 -1
- package/dist/{webhook-verification-DL4L3zbu.d.ts → webhook-verification-Cy4Z5djk.d.ts} +2 -2
- package/dist/{webhook-verification-DL4L3zbu.d.ts.map → webhook-verification-Cy4Z5djk.d.ts.map} +1 -1
- package/package.json +1 -1
- package/src/application/index.ts +6 -0
- package/src/application/outbox-relay.ts +35 -13
- package/src/application/outbox-repository.ts +2 -0
- package/src/application/queue-or-rpc-publisher.ts +70 -0
- package/src/core/classify-failure.ts +12 -2
- package/src/core/index.ts +6 -0
- package/src/core/redelivery-policy.ts +66 -0
- package/src/infrastructure/cloudflare/d1-outbox-repository.ts +4 -1
- package/src/infrastructure/cloudflare/queue/index.ts +0 -1
- package/src/infrastructure/cloudflare/queue/queue-consumer.ts +11 -4
- package/src/infrastructure/postgres/postgres-outbox-repository.ts +4 -1
- package/src/infrastructure/stripe/client.ts +7 -3
- package/dist/application-xXTCe8o0.js.map +0 -1
- package/dist/client-Dv1Ch7yY.js +0 -20
- package/dist/client-Dv1Ch7yY.js.map +0 -1
- package/dist/core-DOBZeYSX.js.map +0 -1
- package/dist/index-CtIdbnEZ.d.ts.map +0 -1
- package/dist/index-Db2GV9ZP.d.ts.map +0 -1
- package/src/infrastructure/cloudflare/queue/redelivery-policy.ts +0 -64
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv-errors-
|
|
1
|
+
{"version":3,"file":"kv-errors-DXbnO7cB.js","names":[],"sources":["../src/infrastructure/cloudflare/kv-errors.ts"],"sourcesContent":["import {\n AppError,\n isCloudflareOverloadedError,\n isCloudflareRetryableError,\n isTransientTransportError,\n type FailureClassification,\n} from '@/core'\n\n/** KV operations recognized in binding error messages. */\nexport type KVOperation = 'get' | 'put' | 'delete' | 'list'\n\n/** KV failure kinds retained from Typist's binding tests. */\nexport type KVErrorKind =\n | 'invalid_key'\n | 'key_too_large'\n | 'invalid_expiration_ttl'\n | 'invalid_expiration'\n | 'invalid_cache_ttl'\n | 'invalid_list_limit'\n | 'value_too_large'\n | 'client_error'\n | 'rate_limited'\n | 'server_error'\n\n/** Evidence extracted from a KV error and its causes. */\nexport interface KVErrorMeta {\n kind: KVErrorKind\n message: string\n status?: number | undefined\n operation?: Uppercase<KVOperation> | undefined\n}\n\n/** Extract Typist's verified KV message formats, including nested causes. */\nexport function extractKVMeta(cause: unknown): KVErrorMeta | undefined {\n const message = getDeepErrorMessage(cause)\n if (!message) return undefined\n const statusMatch = message.match(/\\bKV\\s+(GET|PUT|DELETE|LIST)\\s+failed:\\s+(\\d{3})\\b/)\n // SAFETY: The regular expression permits only uppercase KV operation names in this capture.\n const operation = statusMatch?.[1] as Uppercase<KVOperation> | undefined\n const status = statusMatch ? Number(statusMatch[2]) : undefined\n\n if (/Key name cannot be empty/i.test(message)) {\n return { kind: 'invalid_key', message, status, operation }\n }\n if (/exceeds key length limit/i.test(message)) {\n return { kind: 'key_too_large', message, status, operation }\n }\n if (/Invalid expiration_ttl/i.test(message)) {\n return { kind: 'invalid_expiration_ttl', message, status, operation }\n }\n if (/Invalid expiration of/i.test(message)) {\n return { kind: 'invalid_expiration', message, status, operation }\n }\n if (/Invalid cache_ttl/i.test(message)) {\n return { kind: 'invalid_cache_ttl', message, status, operation }\n }\n if (/Invalid key_count_limit/i.test(message)) {\n return { kind: 'invalid_list_limit', message, status, operation }\n }\n if (/value.*(too large|exceeds)|exceeds.*value/i.test(message)) {\n return { kind: 'value_too_large', message, status, operation }\n }\n if (status === 429) return { kind: 'rate_limited', message, status, operation }\n if (status !== undefined && status >= 500) {\n return { kind: 'server_error', message, status, operation }\n }\n if (status !== undefined && status >= 400) {\n return { kind: 'client_error', message, status, operation }\n }\n return undefined\n}\n\n/** Identify recognized KV failures that another attempt cannot resolve. */\nexport function isTerminalKVError(cause: unknown): boolean {\n const meta = extractKVMeta(cause)\n if (!meta) return false\n if (meta.kind === 'rate_limited' || meta.kind === 'server_error') return false\n if (meta.status === 408) return false\n return true\n}\n\n/** Identify a PUT rate limit that requires at least one second before retrying. */\nexport function isKVPutRateLimitError(cause: unknown): boolean {\n const meta = extractKVMeta(cause)\n return meta?.operation === 'PUT' && meta.kind === 'rate_limited'\n}\n\n/** Identify PUT rate limits, server failures, and request timeouts. */\nexport function isTransientKVError(cause: unknown): boolean {\n const meta = extractKVMeta(cause)\n if (!meta) return false\n return isKVPutRateLimitError(cause) || meta.kind === 'server_error' || meta.status === 408\n}\n\n/** Apply Typist's KV, overload, platform, and transport checks in their original order. */\nexport function isRetryableKVError(cause: unknown): boolean {\n if (isTerminalKVError(cause)) return false\n if (isTransientKVError(cause)) return true\n if (isCloudflareOverloadedError(cause)) return false\n return isCloudflareRetryableError(cause) || isTransientTransportError(cause)\n}\n\n/** Return the existing retry decision and minimum delay in milliseconds. */\nexport function decideKVRetry(\n cause: unknown,\n): { retry: false } | { retry: true; retryAfterMs: number } {\n if (!isRetryableKVError(cause)) return { retry: false }\n return { retry: true, retryAfterMs: isKVPutRateLimitError(cause) ? 1_000 : 0 }\n}\n\n/** A final KV failure with Typist's diagnostics and Better Ship's error classification. */\nexport class KVError extends AppError {\n readonly _tag = 'KVError'\n readonly classification: FailureClassification\n retryable: boolean\n readonly operation: KVOperation\n readonly key?: string | undefined\n override readonly cause: unknown\n readonly kv?: KVErrorMeta | undefined\n readonly context: {\n operation: KVOperation\n key?: string | undefined\n kv?: KVErrorMeta | undefined\n }\n\n constructor(args: { operation: KVOperation; key?: string | undefined; cause: unknown }) {\n const kv = extractKVMeta(args.cause)\n const causeMessage = getDeepErrorMessage(args.cause) || String(args.cause)\n const keyContext = args.key === undefined ? '' : ` for key \"${args.key}\"`\n super(`KV ${args.operation} failed${keyContext}: ${causeMessage}`, { cause: args.cause })\n this.operation = args.operation\n this.key = args.key\n this.cause = args.cause\n this.kv = kv\n this.context = { operation: args.operation, key: args.key, kv }\n this.retryable = isRetryableKVError(args.cause)\n this.classification = isTerminalKVError(args.cause)\n ? 'terminal'\n : this.retryable\n ? 'transient'\n : 'unknown'\n }\n}\n\n// oxlint-disable anti-slop/no-runtime-typeof -- Preserve Typist's primitive messages and nested causes at the raw binding boundary.\nfunction getDeepErrorMessage(cause: unknown): string {\n if (typeof cause === 'string') return cause\n if (cause === null || cause === undefined) return ''\n if (typeof cause === 'number' || typeof cause === 'boolean' || typeof cause === 'bigint') {\n return String(cause)\n }\n if (typeof cause !== 'object') return ''\n const message = 'message' in cause && typeof cause.message === 'string' ? cause.message : ''\n const causeMessage = 'cause' in cause ? getDeepErrorMessage(cause.cause) : ''\n return `${message} ${causeMessage}`.trim()\n}\n// oxlint-enable anti-slop/no-runtime-typeof\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { it as MetricsService, rt as MetricOptions } from "./index-DIHLfC-p.js";
|
|
2
2
|
import { PostHog } from "posthog-node";
|
|
3
3
|
//#region src/infrastructure/posthog/metrics.d.ts
|
|
4
4
|
/** PostHog Metrics with Worker lifetime management, ported from Typist's metrics-service.ts. */
|
|
@@ -16,4 +16,4 @@ declare class PostHogMetricsService implements MetricsService {
|
|
|
16
16
|
}
|
|
17
17
|
//#endregion
|
|
18
18
|
export { PostHogMetricsService as t };
|
|
19
|
-
//# sourceMappingURL=metrics-
|
|
19
|
+
//# sourceMappingURL=metrics-CdpccKGI.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-
|
|
1
|
+
{"version":3,"file":"metrics-CdpccKGI.d.ts","names":[],"sources":["../src/infrastructure/posthog/metrics.ts"],"mappings":";;;;cAKa,iCAAiC;mBAGzB;mBACA;;EAFnB,YACmB,QAAQ,KAAK,qBACb,YAAY,SAAS;;EAIxC,MAAM,cAAc,gBAAW,UAAU;;EAMzC,MAAM,cAAc,eAAe,UAAU;;EAM7C,UAAU,cAAc,eAAe,UAAU"}
|
package/dist/{outbox-repository-options-Dd-s5SxA.js → outbox-repository-options-BKapMX7X.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as UnitOfWorkAlreadyActiveError } from "./application-
|
|
1
|
+
import { t as UnitOfWorkAlreadyActiveError } from "./application-BwevrnLI.js";
|
|
2
2
|
import { panic } from "better-result";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
|
|
@@ -50,4 +50,4 @@ const OUTBOX_REPOSITORY_DEFAULTS = { leaseMs: 6e4 };
|
|
|
50
50
|
|
|
51
51
|
//#endregion
|
|
52
52
|
export { stageD1Statement as a, runWithUnitOfWorkContext as i, collectD1Statements as n, eventCollector as r, OUTBOX_REPOSITORY_DEFAULTS as t };
|
|
53
|
-
//# sourceMappingURL=outbox-repository-options-
|
|
53
|
+
//# sourceMappingURL=outbox-repository-options-BKapMX7X.js.map
|
package/dist/{outbox-repository-options-Dd-s5SxA.js.map → outbox-repository-options-BKapMX7X.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox-repository-options-
|
|
1
|
+
{"version":3,"file":"outbox-repository-options-BKapMX7X.js","names":[],"sources":["../src/infrastructure/unit-of-work-context.ts","../src/infrastructure/outbox-repository-options.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { panic } from 'better-result'\nimport type { BatchItem } from 'drizzle-orm/batch'\n\nimport { UnitOfWorkAlreadyActiveError, type IEventCollector } from '@/application'\nimport type { DomainEvent } from '@/core'\n\ntype UnitOfWorkContext = { readonly events: DomainEvent[] } & (\n | { readonly database: 'd1'; readonly statements: BatchItem<'sqlite'>[] }\n | { readonly database: 'postgres' }\n)\n\n// One async scope isolates events and D1 statements and rejects nesting across both adapters.\nconst storage = new AsyncLocalStorage<UnitOfWorkContext>()\n\n/** Reject nested transactions before database work starts; preserve independent concurrent execution. */\nexport async function runWithUnitOfWorkContext<T>(\n database: UnitOfWorkContext['database'],\n work: () => Promise<T>,\n): Promise<T> {\n if (storage.getStore() !== undefined) throw new UnitOfWorkAlreadyActiveError()\n const context: UnitOfWorkContext =\n database === 'd1' ? { database, events: [], statements: [] } : { database, events: [] }\n return storage.run(context, work)\n}\n\n/** Inject this shared scope into the unit of work and expose its emitter to application handlers. */\nexport const eventCollector: IEventCollector = {\n emit(event) {\n currentContext().events.push(event)\n },\n collect() {\n return [...currentContext().events]\n },\n}\n\n/** Queue one native D1 statement for the active batch; other contexts cannot accept D1 writes. */\nexport function stageD1Statement(statement: BatchItem<'sqlite'>): void {\n d1Context().statements.push(statement)\n}\n\n/** Read the active D1 batch in staging order for commit. */\nexport function collectD1Statements(): ReadonlyArray<BatchItem<'sqlite'>> {\n return [...d1Context().statements]\n}\n\nfunction d1Context(): Extract<UnitOfWorkContext, { database: 'd1' }> {\n const context = currentContext()\n if (context.database !== 'd1') return panic('D1 statements require a D1 unit of work')\n return context\n}\n\nfunction currentContext(): UnitOfWorkContext {\n return storage.getStore() ?? panic('operation requires an active unit of work')\n}\n","/** Shared lease default for both database adapters. */\nexport const OUTBOX_REPOSITORY_DEFAULTS = {\n leaseMs: 60_000,\n}\n\n/** Override the lease length at the composition root. */\nexport type OutboxRepositoryOptions = Readonly<Partial<typeof OUTBOX_REPOSITORY_DEFAULTS>>\n"],"mappings":";;;;;AAcA,MAAM,UAAU,IAAI,kBAAqC;;AAGzD,eAAsB,yBACpB,UACA,MACY;CACZ,IAAI,QAAQ,SAAS,MAAM,QAAW,MAAM,IAAI,6BAA6B;CAC7E,MAAM,UACJ,aAAa,OAAO;EAAE;EAAU,QAAQ,CAAC;EAAG,YAAY,CAAC;CAAE,IAAI;EAAE;EAAU,QAAQ,CAAC;CAAE;CACxF,OAAO,QAAQ,IAAI,SAAS,IAAI;AAClC;;AAGA,MAAa,iBAAkC;CAC7C,KAAK,OAAO;EACV,eAAe,CAAC,CAAC,OAAO,KAAK,KAAK;CACpC;CACA,UAAU;EACR,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC,MAAM;CACpC;AACF;;AAGA,SAAgB,iBAAiB,WAAsC;CACrE,UAAU,CAAC,CAAC,WAAW,KAAK,SAAS;AACvC;;AAGA,SAAgB,sBAA0D;CACxE,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,UAAU;AACnC;AAEA,SAAS,YAA4D;CACnE,MAAM,UAAU,eAAe;CAC/B,IAAI,QAAQ,aAAa,MAAM,OAAO,MAAM,yCAAyC;CACrF,OAAO;AACT;AAEA,SAAS,iBAAoC;CAC3C,OAAO,QAAQ,SAAS,KAAK,MAAM,2CAA2C;AAChF;;;;;ACtDA,MAAa,6BAA6B,EACxC,SAAS,IACX"}
|
package/dist/{outbox-repository-options-Cmf0vbBQ.d.ts → outbox-repository-options-BtAq0nAG.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./index-
|
|
2
|
-
import {
|
|
1
|
+
import "./index-tJzJUgTh.js";
|
|
2
|
+
import { B as IEventCollector } from "./index-DIHLfC-p.js";
|
|
3
3
|
import { BatchItem } from "drizzle-orm/batch";
|
|
4
4
|
//#region src/infrastructure/drizzle-schema.d.ts
|
|
5
5
|
/**
|
|
@@ -21,4 +21,4 @@ declare const OUTBOX_REPOSITORY_DEFAULTS: {
|
|
|
21
21
|
type OutboxRepositoryOptions = Readonly<Partial<typeof OUTBOX_REPOSITORY_DEFAULTS>>;
|
|
22
22
|
//#endregion
|
|
23
23
|
export { eventCollector as n, DrizzleSchema as r, OutboxRepositoryOptions as t };
|
|
24
|
-
//# sourceMappingURL=outbox-repository-options-
|
|
24
|
+
//# sourceMappingURL=outbox-repository-options-BtAq0nAG.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox-repository-options-
|
|
1
|
+
{"version":3,"file":"outbox-repository-options-BtAq0nAG.d.ts","names":[],"sources":["../src/infrastructure/drizzle-schema.ts","../src/infrastructure/unit-of-work-context.ts","../src/infrastructure/outbox-repository-options.ts"],"mappings":";;;;;;;;KAKY,gBAAgB;;;;cCuBf,gBAAgB;;;;cC3BhB;EACX;;;KAIU,0BAA0B,SAAS,eAAe"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { rt as AppError } from "./core-CV8SQv01.js";
|
|
2
2
|
import Stripe from "stripe";
|
|
3
3
|
|
|
4
4
|
//#region src/infrastructure/stripe/payment-service.error.ts
|
|
@@ -27,4 +27,4 @@ function classifyStripeError(error) {
|
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
29
|
export { PaymentServiceError as t };
|
|
30
|
-
//# sourceMappingURL=payment-service.error-
|
|
30
|
+
//# sourceMappingURL=payment-service.error-oW2bKAfU.js.map
|
package/dist/{payment-service.error-BR10zqxk.js.map → payment-service.error-oW2bKAfU.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-service.error-
|
|
1
|
+
{"version":3,"file":"payment-service.error-oW2bKAfU.js","names":[],"sources":["../src/infrastructure/stripe/payment-service.error.ts"],"sourcesContent":["import Stripe from 'stripe'\n\nimport { AppError, type FailureClassification } from '@/core'\n\n/** A final Stripe request failure. The caller logs once; native details remain in cause. */\nexport class PaymentServiceError extends AppError {\n readonly _tag = 'PaymentServiceError'\n readonly classification: FailureClassification\n\n /** Classify the final SDK error without scheduling another payment attempt. */\n constructor(\n readonly operation: string,\n cause: Stripe.errors.StripeError,\n ) {\n super(`Stripe request failed: ${operation}`, { cause })\n this.classification = classifyStripeError(cause)\n }\n}\n\nfunction classifyStripeError(error: Stripe.errors.StripeError): FailureClassification {\n if (error.headers?.['stripe-should-retry'] === 'false') return 'terminal'\n const status = error.statusCode\n if (status !== undefined && status >= 400 && status < 500 && status !== 409 && status !== 429)\n return 'terminal'\n if (\n error instanceof Stripe.errors.StripeAuthenticationError ||\n error instanceof Stripe.errors.StripePermissionError ||\n error instanceof Stripe.errors.StripeInvalidRequestError ||\n error instanceof Stripe.errors.StripeIdempotencyError ||\n error instanceof Stripe.errors.StripeCardError\n )\n return 'terminal'\n if (error.headers?.['stripe-should-retry'] === 'true') return 'transient'\n if (status === 409 || status === 429 || (status !== undefined && status >= 500))\n return 'transient'\n if (\n error instanceof Stripe.errors.StripeConnectionError ||\n error instanceof Stripe.errors.StripeAPIError ||\n error instanceof Stripe.errors.StripeRateLimitError\n )\n return 'transient'\n return 'unknown'\n}\n"],"mappings":";;;;;AAKA,IAAa,sBAAb,cAAyC,SAAS;CAMrC;CALX,AAAS,OAAO;CAChB,AAAS;;CAGT,YACE,AAAS,WACT,OACA;EACA,MAAM,0BAA0B,aAAa,EAAE,MAAM,CAAC;EAH7C;EAIT,KAAK,iBAAiB,oBAAoB,KAAK;CACjD;AACF;AAEA,SAAS,oBAAoB,OAAyD;CACpF,IAAI,MAAM,UAAU,2BAA2B,SAAS,OAAO;CAC/D,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,UAAa,UAAU,OAAO,SAAS,OAAO,WAAW,OAAO,WAAW,KACxF,OAAO;CACT,IACE,iBAAiB,OAAO,OAAO,6BAC/B,iBAAiB,OAAO,OAAO,yBAC/B,iBAAiB,OAAO,OAAO,6BAC/B,iBAAiB,OAAO,OAAO,0BAC/B,iBAAiB,OAAO,OAAO,iBAE/B,OAAO;CACT,IAAI,MAAM,UAAU,2BAA2B,QAAQ,OAAO;CAC9D,IAAI,WAAW,OAAO,WAAW,OAAQ,WAAW,UAAa,UAAU,KACzE,OAAO;CACT,IACE,iBAAiB,OAAO,OAAO,yBAC/B,iBAAiB,OAAO,OAAO,kBAC/B,iBAAiB,OAAO,OAAO,sBAE/B,OAAO;CACT,OAAO;AACT"}
|
package/dist/postgres.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as eventCollector, r as DrizzleSchema, t as OutboxRepositoryOptions } from "./outbox-repository-options-
|
|
1
|
+
import { J as DomainEvent, Qt as AppError, Z as MessageId, at as DatabaseError, ot as DatabaseFailure } from "./index-tJzJUgTh.js";
|
|
2
|
+
import { L as ITransaction, f as IOutboxRepository, g as OutboxRow, h as OutboxFailureReason, m as OutboxBatch, z as IMessageStore } from "./index-DIHLfC-p.js";
|
|
3
|
+
import { n as eventCollector, r as DrizzleSchema, t as OutboxRepositoryOptions } from "./outbox-repository-options-BtAq0nAG.js";
|
|
4
4
|
import { ExtractTablesWithRelations } from "drizzle-orm";
|
|
5
5
|
import { NodePgDatabase, NodePgTransaction } from "drizzle-orm/node-postgres";
|
|
6
6
|
import { Pool } from "pg";
|
package/dist/postgres.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","names":[],"sources":["../src/infrastructure/postgres/postgres-database-types.ts","../src/infrastructure/postgres/base-postgres-repository.ts","../src/infrastructure/postgres/postgres-message-store.ts","../src/infrastructure/postgres/postgres-schema.ts","../src/infrastructure/postgres/postgres-transaction.ts","../src/infrastructure/postgres/postgres-client.ts","../src/infrastructure/postgres/statement-outside-transaction.error.ts","../src/infrastructure/postgres/postgres-database-execution.ts","../src/infrastructure/postgres/classify-postgres-error.ts","../src/infrastructure/postgres/postgres-outbox-repository.ts"],"mappings":";;;;;;;;KAOY,qBAAqB;;KAGrB,WAAW,eAAe,iBAAiB,eAAe;;KAG1D,eAAe,eAAe,iBAAiB,KACzD,WAAW;;KAKD,sBAAsB,eAAe,iBAAiB,kBAChE,QACA,2BAA2B;;KAIjB,WAAW,eAAe;WAC3B,IAAI,sBAAsB;;;;;UClBpB;EACf,iBAAiB,cAAc;EAC/B;;;8BAIoB,uBAAuB,eAAe;qBAC3B,IAAI,sBAAsB;EAAzD,YAA+B,IAAI,sBAAsB;;YAG/C,KAAK,GAAG,mBAAmB,aAAa,YAAY,KAAK,QAAQ;;YAKjE,eAAe,WAAW;;;;;qBCfzB,qBAAqB,eAAe,0BAA0B;mBAC5C;EAA7B,YAA6B,IAAI,sBAAsB;EAEjD,MAAM,WAAW,YAAY;EAU7B,cAAc,QAAQ,cAAc,eAAe;;;;;qBCf9C,iDAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAMjB,6CAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBCAb,oBAAoB,eAAe,0BAA0B,aACxE,WAAW;mBAEkB;EAA7B,YAA6B,IAAI,WAAW;EAE5C,YAAY,GAAG,OAAO,IAAI,WAAW,YAAY,QAAQ,KAAK,QAAQ;;;;;;;;;;;;wBCFxD,gBAAgB,eAAe,eAC7C,0BACA,QAAQ,QACR,UAAU;EAqBR,wCAAE,eAAA;;;;EAEF,aAAK;;;;;;;;qBCnCI,yCAAyC;WAC3C;WACA;EAET;;;;;;;;;;wBCMoB,gBAAgB,GACpC,mBACA,YAAY,YAAY,IACxB;WAAoB;IACnB,QAAQ;;;;wBCkBK,sBACd,gBACA,oBACC;;;;;;;qBCxBU,oCAAoC;mBAI5B;mBAEA;mBALF;EAEjB,YACmB,IAAI,WAAW,gBAChC,UAAS,yBACQ,YAAW;;EAMxB,aAAa,oBAAoB,QAAQ;;
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","names":[],"sources":["../src/infrastructure/postgres/postgres-database-types.ts","../src/infrastructure/postgres/base-postgres-repository.ts","../src/infrastructure/postgres/postgres-message-store.ts","../src/infrastructure/postgres/postgres-schema.ts","../src/infrastructure/postgres/postgres-transaction.ts","../src/infrastructure/postgres/postgres-client.ts","../src/infrastructure/postgres/statement-outside-transaction.error.ts","../src/infrastructure/postgres/postgres-database-execution.ts","../src/infrastructure/postgres/classify-postgres-error.ts","../src/infrastructure/postgres/postgres-outbox-repository.ts"],"mappings":";;;;;;;;KAOY,qBAAqB;;KAGrB,WAAW,eAAe,iBAAiB,eAAe;;KAG1D,eAAe,eAAe,iBAAiB,KACzD,WAAW;;KAKD,sBAAsB,eAAe,iBAAiB,kBAChE,QACA,2BAA2B;;KAIjB,WAAW,eAAe;WAC3B,IAAI,sBAAsB;;;;;UClBpB;EACf,iBAAiB,cAAc;EAC/B;;;8BAIoB,uBAAuB,eAAe;qBAC3B,IAAI,sBAAsB;EAAzD,YAA+B,IAAI,sBAAsB;;YAG/C,KAAK,GAAG,mBAAmB,aAAa,YAAY,KAAK,QAAQ;;YAKjE,eAAe,WAAW;;;;;qBCfzB,qBAAqB,eAAe,0BAA0B;mBAC5C;EAA7B,YAA6B,IAAI,sBAAsB;EAEjD,MAAM,WAAW,YAAY;EAU7B,cAAc,QAAQ,cAAc,eAAe;;;;;qBCf9C,iDAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAMjB,6CAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBCAb,oBAAoB,eAAe,0BAA0B,aACxE,WAAW;mBAEkB;EAA7B,YAA6B,IAAI,WAAW;EAE5C,YAAY,GAAG,OAAO,IAAI,WAAW,YAAY,QAAQ,KAAK,QAAQ;;;;;;;;;;;;wBCFxD,gBAAgB,eAAe,eAC7C,0BACA,QAAQ,QACR,UAAU;EAqBR,wCAAE,eAAA;;;;EAEF,aAAK;;;;;;;;qBCnCI,yCAAyC;WAC3C;WACA;EAET;;;;;;;;;;wBCMoB,gBAAgB,GACpC,mBACA,YAAY,YAAY,IACxB;WAAoB;IACnB,QAAQ;;;;wBCkBK,sBACd,gBACA,oBACC;;;;;;;qBCxBU,oCAAoC;mBAI5B;mBAEA;mBALF;EAEjB,YACmB,IAAI,WAAW,gBAChC,UAAS,yBACQ,YAAW;;EAMxB,aAAa,oBAAoB,QAAQ;;EAuDzC,cAAc,oBAAoB,MAAM,cAAc,aAAa;;EAmBnE,aACJ,oBACA,MAAM,cAAc,YACpB,aAAa,OACZ;;EAWG,WACJ,oBACA,MAAM,cAAc,YACpB,QAAQ,qBACR,uBACC;;EAwBG,sBAAsB,QAAQ,MAAM,oBAAoB;;EAqBxD,mBAAmB,QAAQ,MAAM,oBAAoB;;EAqBrD,qBAAqB,QAAQ,MAAM,oBAAoB"}
|
package/dist/postgres.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { i as runWithUnitOfWorkContext, r as eventCollector, t as OUTBOX_REPOSITORY_DEFAULTS } from "./outbox-repository-options-
|
|
1
|
+
import { A as DatabaseError, rt as AppError } from "./core-CV8SQv01.js";
|
|
2
|
+
import { s as MessageAlreadyProcessedError } from "./application-BwevrnLI.js";
|
|
3
|
+
import { i as runWithUnitOfWorkContext, r as eventCollector, t as OUTBOX_REPOSITORY_DEFAULTS } from "./outbox-repository-options-BKapMX7X.js";
|
|
4
4
|
import { Result } from "better-result";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { DrizzleQueryError } from "drizzle-orm/errors";
|
|
@@ -329,9 +329,10 @@ var PostgresOutboxRepository = class {
|
|
|
329
329
|
rows.sort((a, b) => a.availableAt.getTime() - b.availableAt.getTime() || a.createdAt.getTime() - b.createdAt.getTime() || a.payload.id.localeCompare(b.payload.id));
|
|
330
330
|
return {
|
|
331
331
|
token,
|
|
332
|
-
rows: rows.map(({ payload, attempts }) => ({
|
|
332
|
+
rows: rows.map(({ payload, attempts, createdAt }) => ({
|
|
333
333
|
payload,
|
|
334
|
-
attempts
|
|
334
|
+
attempts,
|
|
335
|
+
createdAt
|
|
335
336
|
}))
|
|
336
337
|
};
|
|
337
338
|
}
|
package/dist/postgres.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.js","names":["text"],"sources":["../src/infrastructure/postgres/classify-postgres-error.ts","../src/infrastructure/postgres/postgres-database-execution.ts","../src/infrastructure/postgres/base-postgres-repository.ts","../src/infrastructure/postgres/postgres-schema.ts","../src/infrastructure/postgres/postgres-message-store.ts","../src/infrastructure/postgres/connection-scope.ts","../src/infrastructure/postgres/postgres-transaction.ts","../src/infrastructure/postgres/statement-outside-transaction.error.ts","../src/infrastructure/postgres/postgres-client.ts","../src/infrastructure/postgres/postgres-outbox-repository.ts"],"sourcesContent":["import { DrizzleQueryError } from 'drizzle-orm/errors'\n\nimport { AppError, DatabaseError, type FailureClassification } from '@/core'\n\nconst TRANSIENT_CODES = new Set([\n '40001',\n '40P01',\n '58000',\n '08000',\n '08001',\n '08003',\n '08006',\n '57P01',\n '57P02',\n '57P03',\n 'CONNECT_TIMEOUT',\n 'CONNECTION_CLOSED',\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'EPIPE',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n])\nconst TERMINAL_CODES = new Set(['57014', 'CONNECTION_ENDED', 'CONNECTION_DESTROYED', 'ECANCELED'])\nconst DRIVER_CODES = new Set([\n 'CONNECT_TIMEOUT',\n 'CONNECTION_CLOSED',\n 'CONNECTION_ENDED',\n 'CONNECTION_DESTROYED',\n])\nconst TERMINAL_CLASSES = new Set(['0A', '22', '23', '25', '28', '3D', '3F', '42', '54'])\nconst DEAD_SOCKET_MESSAGES = new Set([\n 'Connection terminated unexpectedly',\n 'Client has encountered a connection error and is not queryable',\n])\n\n/* oxlint-disable anti-slop/no-runtime-typeof -- Raw driver exceptions have no shared schema; this boundary validates the fields it exposes. */\n/** Read SQLSTATE or driver codes; unknown callback exceptions remain unchanged. */\nexport function classifyPostgresError(\n cause: unknown,\n operation: string,\n): DatabaseError | undefined {\n let error = cause\n const seen = new Set<unknown>()\n while (error instanceof DrizzleQueryError && !seen.has(error)) {\n seen.add(error)\n error = error.cause\n }\n if (error instanceof AppError || (error instanceof Error && error.name === 'AbortError'))\n return undefined\n const code =\n error instanceof Error && 'code' in error && typeof error.code === 'string'\n ? error.code\n : undefined\n const serverError =\n error instanceof Error &&\n (error.name === 'PostgresError' || error.name === 'error') &&\n code !== undefined &&\n /^[0-9A-Z]{5}$/.test(code)\n const driverError = code !== undefined && DRIVER_CODES.has(code)\n const deadSocket = error instanceof Error && DEAD_SOCKET_MESSAGES.has(error.message)\n if (!(cause instanceof DrizzleQueryError) && !serverError && !driverError) return undefined\n\n return new DatabaseError(\n operation,\n classificationOf(code, deadSocket),\n {\n database: 'postgres',\n code,\n table_name: error instanceof Error ? text(error, 'table', 'table_name') : undefined,\n column_name: error instanceof Error ? text(error, 'column', 'column_name') : undefined,\n constraint_name:\n error instanceof Error ? text(error, 'constraint', 'constraint_name') : undefined,\n },\n { cause },\n )\n}\n\nfunction text(error: Error, pgName: string, jsName: string): string | undefined {\n return read(error, pgName) ?? read(error, jsName)\n}\n\nfunction read(error: Error, name: string): string | undefined {\n switch (name) {\n case 'table':\n return 'table' in error && typeof error.table === 'string' ? error.table : undefined\n case 'column':\n return 'column' in error && typeof error.column === 'string' ? error.column : undefined\n case 'constraint':\n return 'constraint' in error && typeof error.constraint === 'string'\n ? error.constraint\n : undefined\n case 'table_name':\n return 'table_name' in error && typeof error.table_name === 'string'\n ? error.table_name\n : undefined\n case 'column_name':\n return 'column_name' in error && typeof error.column_name === 'string'\n ? error.column_name\n : undefined\n case 'constraint_name':\n return 'constraint_name' in error && typeof error.constraint_name === 'string'\n ? error.constraint_name\n : undefined\n default:\n return undefined\n }\n}\n\n/* oxlint-enable anti-slop/no-runtime-typeof */\n\nfunction classificationOf(code: string | undefined, deadSocket: boolean): FailureClassification {\n if (deadSocket) return 'transient'\n if (code === undefined) return 'unknown'\n if (TRANSIENT_CODES.has(code)) return 'transient'\n if (TERMINAL_CODES.has(code) || TERMINAL_CLASSES.has(code.slice(0, 2))) return 'terminal'\n return 'unknown'\n}\n","import { Result } from 'better-result'\nimport { DrizzleQueryError } from 'drizzle-orm/errors'\n\nimport { AppError, DatabaseError } from '@/core'\n\nimport { classifyPostgresError } from './classify-postgres-error.ts'\n\n/** SQLSTATE values that leave the pg socket usable, so the same client can run the statement again. */\nconst RETRYABLE_ON_SESSION = new Set(['40001', '40P01', '58000'])\n\n/**\n * Convert database failures and preserve other exceptions. The default executes once.\n * Opt-in retries allow three attempts for serialization failure, deadlock, and a Hyperdrive pool acquire.\n * A dropped socket stays transient and is not retried here: pg cannot reconnect the client.\n * Delays use full jitter with backoff caps of 250 ms and 500 ms.\n */\nexport async function executeDatabase<T>(\n operation: string,\n work: () => PromiseLike<T>,\n options: { readonly retry?: 'never' | 'transient' } = {},\n): Promise<T> {\n const result = await Result.tryPromise(\n {\n try: async () => await work(),\n catch: (cause) =>\n classifyPostgresError(cause, operation) ?? appErrorUnderDrizzle(cause) ?? cause,\n },\n {\n retry: {\n times: options.retry === 'transient' ? 2 : 0,\n delayMs: 250,\n backoff: 'exponential',\n jitter: true,\n shouldRetry: (error) =>\n error instanceof DatabaseError &&\n error.classification === 'transient' &&\n error.details.database === 'postgres' &&\n error.details.code !== undefined &&\n RETRYABLE_ON_SESSION.has(error.details.code),\n },\n },\n )\n if (result.isErr()) throw result.error\n return result.value\n}\n\n// Drizzle wraps every `query` failure once; the typed error inside is the one the caller handles.\nfunction appErrorUnderDrizzle(cause: unknown): AppError | undefined {\n if (cause instanceof DrizzleQueryError && cause.cause instanceof AppError) return cause.cause\n return undefined\n}\n","import type { DomainEvent } from '@/core'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport { eventCollector } from '../unit-of-work-context.ts'\nimport { executeDatabase } from './postgres-database-execution.ts'\nimport type { PostgresDbTransaction } from './postgres-database-types.ts'\n\n/** A domain aggregate that accumulates events for the unit of work to drain. */\nexport interface AggregateEvents {\n collectEvents(): ReadonlyArray<DomainEvent>\n clearEvents(): void\n}\n\n/** Shared plumbing for a repository that writes inside a Postgres unit of work. */\nexport abstract class BasePostgresRepository<Schema extends DrizzleSchema> {\n constructor(protected readonly db: PostgresDbTransaction<Schema>) {}\n\n /** Execute one read with database error conversion and no automatic retries. */\n protected read<T>(operation: string, query: () => PromiseLike<T>): Promise<T> {\n return executeDatabase(operation, query)\n }\n\n /** Drain an aggregate's pending events into the active boundary. */\n protected dispatchEvents(aggregate: AggregateEvents): void {\n const events = aggregate.collectEvents()\n if (events.length === 0) return\n for (const event of events) eventCollector.emit(event)\n aggregate.clearEvents()\n }\n}\n","import { isNull } from 'drizzle-orm'\nimport { index, integer, jsonb, pgTable, text, timestamp } from 'drizzle-orm/pg-core'\n\nimport type { DomainEvent } from '@/core'\n\n/** One row per committed message. The primary key is the idempotency claim. */\nexport const processedMessages = pgTable('processed_messages', {\n messageId: text('message_id').primaryKey(),\n processedAt: timestamp('processed_at', { withTimezone: true }).notNull().defaultNow(),\n})\n\n/** Events committed with their state change, waiting for the relay to deliver them. */\nexport const messageOutbox = pgTable(\n 'message_outbox',\n {\n id: text('id').primaryKey(),\n payload: jsonb('payload').$type<DomainEvent>().notNull(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n availableAt: timestamp('available_at', { withTimezone: true }).notNull().defaultNow(),\n attempts: integer('attempts').notNull().default(0),\n claimToken: text('claim_token'),\n claimExpiresAt: timestamp('claim_expires_at', { withTimezone: true }),\n publishedAt: timestamp('published_at', { withTimezone: true }),\n failedAt: timestamp('failed_at', { withTimezone: true }),\n lastError: text('last_error'),\n },\n (table) => [\n index('idx_message_outbox_due')\n .on(table.availableAt, table.createdAt)\n .where(isNull(table.publishedAt)),\n index('idx_message_outbox_claim_token').on(table.claimToken),\n ],\n)\n","import { MessageAlreadyProcessedError, type IMessageStore, type MessageId } from '@/application'\nimport type { DomainEvent } from '@/core'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport type { PostgresDbTransaction } from './postgres-database-types.ts'\nimport { messageOutbox, processedMessages } from './postgres-schema.ts'\n\n/** Processed messages and outbox events share the active Postgres transaction; the insert result establishes the claim. */\nexport class PostgresMessageStore<Schema extends DrizzleSchema> implements IMessageStore {\n constructor(private readonly db: PostgresDbTransaction<Schema>) {}\n\n async claim(messageId: MessageId): Promise<void> {\n const claimed = await this.db\n .insert(processedMessages)\n .values({ messageId })\n .onConflictDoNothing()\n .returning({ messageId: processedMessages.messageId })\n // Thrown inside the transaction, so drizzle rolls back everything written before the claim.\n if (claimed.length === 0) throw new MessageAlreadyProcessedError(messageId)\n }\n\n async persistEvents(events: ReadonlyArray<DomainEvent>): Promise<void> {\n if (events.length === 0) return\n await this.db\n .insert(messageOutbox)\n .values(events.map((event) => ({ id: event.id, payload: event })))\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\n\n// Marks the async path that holds the invocation pool's one connection for a transaction.\nconst scope = new AsyncLocalStorage<true>()\n\n/** Run a transaction on the path that holds the pool's one connection. */\nexport function holdConnection<T>(work: () => Promise<T>): Promise<T> {\n return scope.run(true, work)\n}\n\n/** True inside a transaction: a pool statement here would wait for its own connection forever. */\nexport function holdsConnection(): boolean {\n return scope.getStore() === true\n}\n","import type { ITransaction } from '@/application'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport { runWithUnitOfWorkContext } from '../unit-of-work-context.ts'\nimport { holdConnection } from './connection-scope.ts'\nimport { executeDatabase } from './postgres-database-execution.ts'\nimport type { PostgresDb, PostgresTx } from './postgres-database-types.ts'\n\n/**\n * One Drizzle transaction on the invocation's pool: `BEGIN`, the work, `COMMIT`, or `ROLLBACK` on a throw.\n * Drizzle checks out the pool's one connection for the call; a second call waits until it is released.\n */\nexport class PostgresTransaction<Schema extends DrizzleSchema> implements ITransaction<\n PostgresTx<Schema>\n> {\n constructor(private readonly db: PostgresDb<Schema>) {}\n\n transaction<T>(work: (tx: PostgresTx<Schema>) => Promise<T>): Promise<T> {\n return runWithUnitOfWorkContext('postgres', () =>\n executeDatabase('unit of work transaction', () =>\n holdConnection(() => this.db.transaction((db) => work({ db }))),\n ),\n )\n }\n}\n","import { AppError } from '@/core'\n\n/**\n * A pool statement started while this async path is inside a unit of work.\n * The pool's one connection is already checked out, so the statement would wait forever.\n */\nexport class StatementOutsideTransactionError extends AppError {\n readonly _tag = 'StatementOutsideTransactionError'\n readonly classification = 'terminal'\n\n constructor() {\n super('a statement outside the transaction cannot run while a unit of work is open')\n }\n}\n","import { drizzle } from 'drizzle-orm/node-postgres'\nimport { Pool, type QueryResult } from 'pg'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport { holdsConnection } from './connection-scope.ts'\nimport { StatementOutsideTransactionError } from './statement-outside-transaction.error.ts'\n\n/**\n * Open the invocation's database: one `pg` Pool with `max: 1` through Hyperdrive.\n * Call it inside the handler, the queue consumer, the schedule, the Workflow step, or the Durable Object method.\n * `db` is ready at once; the first query connects. A transaction checks out the connection, and other statements wait.\n * A fetch, queue, cron, or Workflow step does not call `close()`: Hyperdrive drops the socket when the invocation ends.\n * A Durable Object calls `close()` at the end of each method or alarm, after that call's background work.\n * Pass `tracing` to record one span per statement. The statement text keeps placeholders; parameter values stay off.\n */\nexport function connectPostgres<Schema extends DrizzleSchema>(\n connectionString: string,\n schema: Schema,\n tracing?: Tracing,\n) {\n const pool = new Pool({ connectionString, max: 1 })\n // The pool emits `error` when it drops a client; the waiting statement rejects with that error.\n pool.on('error', () => {})\n pool.on('connect', (client) => {\n // pg-cloudflare reports the socket that `pool.end()` closed as a client error.\n client.on('error', () => {})\n if (tracing === undefined) return\n // SAFETY: a transaction's statements run here in promise form, and `traced` forwards every overload.\n client.query = traced(client.query.bind(client) as Query, tracing) as typeof client.query\n })\n // SAFETY: `pool.query` returns a promise in promise form and nothing in callback form.\n const poolQuery = pool.query.bind(pool) as Query\n const query = tracing ? traced(poolQuery, tracing) : poolQuery\n const guarded: Query = (...args) =>\n holdsConnection() ? Promise.reject(new StatementOutsideTransactionError()) : query(...args)\n // SAFETY: `guarded` forwards every `pool.query` overload unchanged.\n pool.query = guarded as Pool['query']\n let ending: Promise<void> | undefined\n return {\n db: drizzle(pool, { schema }),\n /** Ends the pool after the checked-out client is released. A second call returns the same promise. */\n close: () => {\n if (holdsConnection()) return Promise.reject(new StatementOutsideTransactionError())\n return (ending ??= pool.end())\n },\n }\n}\n\n/** `pool.query` and `client.query`: a promise in promise form, nothing in callback form. */\ntype Query = (...args: readonly unknown[]) => Promise<QueryResult> | void\n\n/* oxlint-disable anti-slop/no-runtime-typeof -- pg query takes a string, a config object, a callback, or a Submittable. */\n/** Spans promise-form calls. A callback-form call is the pool's own checkout, already spanned by `pool.query`. */\nfunction traced(query: Query, tracing: Tracing): Query {\n return (...args) => {\n const text = statementText(args)\n if (text === undefined || typeof args.at(-1) === 'function') return query(...args)\n const operation = /^\\s*([A-Za-z]+)/.exec(text)?.[1]?.toUpperCase() ?? 'QUERY'\n return tracing.enterSpan(operation, async (span) => {\n span.setAttributes({\n 'db.system.name': 'postgresql',\n 'db.query.summary': operation,\n 'db.operation.name': operation,\n 'db.query.text': text,\n })\n const result = await query(...args)\n // A multi-statement text resolves to an array of results, which has no `rows`.\n if (result?.rows) span.setAttributes({ 'db.response.returned_rows': result.rows.length })\n // SAFETY: the promise form always resolves to a result.\n return result as QueryResult\n })\n }\n}\n\nfunction statementText(args: readonly unknown[]): string | undefined {\n const first = args[0]\n if (typeof first === 'string') return first\n if (typeof first !== 'object' || first === null || 'submit' in first) return undefined\n return 'text' in first && typeof first.text === 'string' ? first.text : undefined\n}\n/* oxlint-enable anti-slop/no-runtime-typeof */\n","import { and, asc, eq, inArray, isNull, lt, lte, or, sql } from 'drizzle-orm'\n\nimport type { IOutboxRepository, OutboxBatch, OutboxFailureReason, OutboxRow } from '@/application'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport {\n OUTBOX_REPOSITORY_DEFAULTS,\n type OutboxRepositoryOptions,\n} from '../outbox-repository-options.ts'\nimport { executeDatabase } from './postgres-database-execution.ts'\nimport type { PostgresDb } from './postgres-database-types.ts'\nimport { messageOutbox, processedMessages } from './postgres-schema.ts'\n\n/**\n * Typist's lease protocol with riposte's SKIP LOCKED selection on a plain connection, outside a unit of work.\n * Every write runs once; lease expiry and the scheduled sweep recover interrupted operations.\n */\nexport class PostgresOutboxRepository implements IOutboxRepository {\n private readonly options: Required<OutboxRepositoryOptions>\n\n constructor(\n private readonly db: PostgresDb<DrizzleSchema>,\n options: OutboxRepositoryOptions = {},\n private readonly now: () => Date = () => new Date(),\n ) {\n this.options = { ...OUTBOX_REPOSITORY_DEFAULTS, ...options }\n }\n\n /** Lease due rows in one statement; increment attempts even when reclaiming an expired lease. */\n async claimDueRows(batchSize: number): Promise<OutboxBatch> {\n const token = crypto.randomUUID()\n const now = this.now()\n const rows = await executeDatabase('claim due outbox rows', () =>\n this.db\n .update(messageOutbox)\n .set({\n claimToken: token,\n claimExpiresAt: new Date(now.getTime() + this.options.leaseMs),\n attempts: sql`${messageOutbox.attempts} + 1`,\n })\n .where(\n inArray(\n messageOutbox.id,\n this.db\n .select({ id: messageOutbox.id })\n .from(messageOutbox)\n .where(\n and(\n isNull(messageOutbox.publishedAt),\n isNull(messageOutbox.failedAt),\n lte(messageOutbox.availableAt, now),\n or(isNull(messageOutbox.claimExpiresAt), lte(messageOutbox.claimExpiresAt, now)),\n ),\n )\n .orderBy(\n asc(messageOutbox.availableAt),\n asc(messageOutbox.createdAt),\n asc(messageOutbox.id),\n )\n .limit(batchSize)\n .for('update', { skipLocked: true }),\n ),\n )\n .returning({\n payload: messageOutbox.payload,\n attempts: messageOutbox.attempts,\n availableAt: messageOutbox.availableAt,\n createdAt: messageOutbox.createdAt,\n }),\n )\n // UPDATE RETURNING does not preserve the selection order.\n rows.sort(\n (a, b) =>\n a.availableAt.getTime() - b.availableAt.getTime() ||\n a.createdAt.getTime() - b.createdAt.getTime() ||\n a.payload.id.localeCompare(b.payload.id),\n )\n return { token, rows: rows.map(({ payload, attempts }) => ({ payload, attempts })) }\n }\n\n /** Mark only supplied rows that still hold this token as published. */\n async markPublished(claimToken: string, rows: ReadonlyArray<OutboxRow>): Promise<void> {\n if (rows.length === 0) return\n await executeDatabase('mark outbox rows published', () =>\n this.db\n .update(messageOutbox)\n .set({ publishedAt: this.now(), claimToken: null, claimExpiresAt: null })\n .where(\n and(\n inArray(\n messageOutbox.id,\n rows.map((row) => row.payload.id),\n ),\n eq(messageOutbox.claimToken, claimToken),\n ),\n ),\n )\n }\n\n /** Release supplied rows until `availableAt`; a stale token cannot change a newer claim. */\n async releaseClaim(\n claimToken: string,\n rows: ReadonlyArray<OutboxRow>,\n availableAt: Date,\n ): Promise<void> {\n const ids = rows.map((row) => row.payload.id)\n await executeDatabase('release outbox rows', () =>\n this.db\n .update(messageOutbox)\n .set({ availableAt, claimToken: null, claimExpiresAt: null })\n .where(and(inArray(messageOutbox.id, ids), eq(messageOutbox.claimToken, claimToken))),\n )\n }\n\n /** Set `failed_at`, keep the full payload, and record the reason with a readable error message. */\n async markFailed(\n claimToken: string,\n rows: ReadonlyArray<OutboxRow>,\n reason: OutboxFailureReason,\n errorMessage: string,\n ): Promise<void> {\n if (rows.length === 0) return\n await executeDatabase('mark outbox rows failed', () =>\n this.db\n .update(messageOutbox)\n .set({\n failedAt: this.now(),\n lastError: `${reason}: ${errorMessage}`,\n claimToken: null,\n claimExpiresAt: null,\n })\n .where(\n and(\n inArray(\n messageOutbox.id,\n rows.map((row) => row.payload.id),\n ),\n eq(messageOutbox.claimToken, claimToken),\n ),\n ),\n )\n }\n\n /** Delete at most batchSize published rows, strictly before the cutoff. */\n async deletePublishedBefore(cutoff: Date, batchSize: number): Promise<number> {\n const rows = await executeDatabase('delete published outbox messages', () =>\n this.db\n .delete(messageOutbox)\n .where(\n inArray(\n messageOutbox.id,\n this.db\n .select({ id: messageOutbox.id })\n .from(messageOutbox)\n .where(lt(messageOutbox.publishedAt, cutoff))\n .orderBy(asc(messageOutbox.publishedAt), asc(messageOutbox.id))\n .limit(batchSize),\n ),\n )\n .returning({ id: messageOutbox.id }),\n )\n return rows.length\n }\n\n /** Delete at most batchSize failed rows; pending and published rows remain untouched. */\n async deleteFailedBefore(cutoff: Date, batchSize: number): Promise<number> {\n const rows = await executeDatabase('delete failed outbox messages', () =>\n this.db\n .delete(messageOutbox)\n .where(\n inArray(\n messageOutbox.id,\n this.db\n .select({ id: messageOutbox.id })\n .from(messageOutbox)\n .where(and(isNull(messageOutbox.publishedAt), lt(messageOutbox.failedAt, cutoff)))\n .orderBy(asc(messageOutbox.failedAt), asc(messageOutbox.id))\n .limit(batchSize),\n ),\n )\n .returning({ id: messageOutbox.id }),\n )\n return rows.length\n }\n\n /** Delete at most batchSize receipts, strictly before the cutoff. */\n async deleteReceiptsBefore(cutoff: Date, batchSize: number): Promise<number> {\n const rows = await executeDatabase('delete message receipts', () =>\n this.db\n .delete(processedMessages)\n .where(\n inArray(\n processedMessages.messageId,\n this.db\n .select({ messageId: processedMessages.messageId })\n .from(processedMessages)\n .where(lt(processedMessages.processedAt, cutoff))\n .orderBy(asc(processedMessages.processedAt), asc(processedMessages.messageId))\n .limit(batchSize),\n ),\n )\n .returning({ messageId: processedMessages.messageId }),\n )\n return rows.length\n }\n}\n"],"mappings":";;;;;;;;;;;;AAIA,MAAM,kCAAkB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AACD,MAAM,iCAAiB,IAAI,IAAI;CAAC;CAAS;CAAoB;CAAwB;AAAW,CAAC;AACjG,MAAM,+BAAe,IAAI,IAAI;CAC3B;CACA;CACA;CACA;AACF,CAAC;AACD,MAAM,mCAAmB,IAAI,IAAI;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;AAAI,CAAC;AACvF,MAAM,uCAAuB,IAAI,IAAI,CACnC,sCACA,gEACF,CAAC;;AAID,SAAgB,sBACd,OACA,WAC2B;CAC3B,IAAI,QAAQ;CACZ,MAAM,uBAAO,IAAI,IAAa;CAC9B,OAAO,iBAAiB,qBAAqB,CAAC,KAAK,IAAI,KAAK,GAAG;EAC7D,KAAK,IAAI,KAAK;EACd,QAAQ,MAAM;CAChB;CACA,IAAI,iBAAiB,YAAa,iBAAiB,SAAS,MAAM,SAAS,cACzE,OAAO;CACT,MAAM,OACJ,iBAAiB,SAAS,UAAU,SAAS,OAAO,MAAM,SAAS,WAC/D,MAAM,OACN;CACN,MAAM,cACJ,iBAAiB,UAChB,MAAM,SAAS,mBAAmB,MAAM,SAAS,YAClD,SAAS,UACT,gBAAgB,KAAK,IAAI;CAC3B,MAAM,cAAc,SAAS,UAAa,aAAa,IAAI,IAAI;CAC/D,MAAM,aAAa,iBAAiB,SAAS,qBAAqB,IAAI,MAAM,OAAO;CACnF,IAAI,EAAE,iBAAiB,sBAAsB,CAAC,eAAe,CAAC,aAAa,OAAO;CAElF,OAAO,IAAI,cACT,WACA,iBAAiB,MAAM,UAAU,GACjC;EACE,UAAU;EACV;EACA,YAAY,iBAAiB,QAAQA,OAAK,OAAO,SAAS,YAAY,IAAI;EAC1E,aAAa,iBAAiB,QAAQA,OAAK,OAAO,UAAU,aAAa,IAAI;EAC7E,iBACE,iBAAiB,QAAQA,OAAK,OAAO,cAAc,iBAAiB,IAAI;CAC5E,GACA,EAAE,MAAM,CACV;AACF;AAEA,SAASA,OAAK,OAAc,QAAgB,QAAoC;CAC9E,OAAO,KAAK,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM;AAClD;AAEA,SAAS,KAAK,OAAc,MAAkC;CAC5D,QAAQ,MAAR;EACE,KAAK,SACH,OAAO,WAAW,SAAS,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;EAC7E,KAAK,UACH,OAAO,YAAY,SAAS,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;EAChF,KAAK,cACH,OAAO,gBAAgB,SAAS,OAAO,MAAM,eAAe,WACxD,MAAM,aACN;EACN,KAAK,cACH,OAAO,gBAAgB,SAAS,OAAO,MAAM,eAAe,WACxD,MAAM,aACN;EACN,KAAK,eACH,OAAO,iBAAiB,SAAS,OAAO,MAAM,gBAAgB,WAC1D,MAAM,cACN;EACN,KAAK,mBACH,OAAO,qBAAqB,SAAS,OAAO,MAAM,oBAAoB,WAClE,MAAM,kBACN;EACN,SACE;CACJ;AACF;AAIA,SAAS,iBAAiB,MAA0B,YAA4C;CAC9F,IAAI,YAAY,OAAO;CACvB,IAAI,SAAS,QAAW,OAAO;CAC/B,IAAI,gBAAgB,IAAI,IAAI,GAAG,OAAO;CACtC,IAAI,eAAe,IAAI,IAAI,KAAK,iBAAiB,IAAI,KAAK,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO;CAC/E,OAAO;AACT;;;;;AC7GA,MAAM,uCAAuB,IAAI,IAAI;CAAC;CAAS;CAAS;AAAO,CAAC;;;;;;;AAQhE,eAAsB,gBACpB,WACA,MACA,UAAsD,CAAC,GAC3C;CACZ,MAAM,SAAS,MAAM,OAAO,WAC1B;EACE,KAAK,YAAY,MAAM,KAAK;EAC5B,QAAQ,UACN,sBAAsB,OAAO,SAAS,KAAK,qBAAqB,KAAK,KAAK;CAC9E,GACA,EACE,OAAO;EACL,OAAO,QAAQ,UAAU,cAAc,IAAI;EAC3C,SAAS;EACT,SAAS;EACT,QAAQ;EACR,cAAc,UACZ,iBAAiB,iBACjB,MAAM,mBAAmB,eACzB,MAAM,QAAQ,aAAa,cAC3B,MAAM,QAAQ,SAAS,UACvB,qBAAqB,IAAI,MAAM,QAAQ,IAAI;CAC/C,EACF,CACF;CACA,IAAI,OAAO,MAAM,GAAG,MAAM,OAAO;CACjC,OAAO,OAAO;AAChB;AAGA,SAAS,qBAAqB,OAAsC;CAClE,IAAI,iBAAiB,qBAAqB,MAAM,iBAAiB,UAAU,OAAO,MAAM;AAE1F;;;;;ACpCA,IAAsB,yBAAtB,MAA2E;CAC1C;CAA/B,YAAY,AAAmB,IAAmC;EAAnC;CAAoC;;CAGnE,AAAU,KAAQ,WAAmB,OAAyC;EAC5E,OAAO,gBAAgB,WAAW,KAAK;CACzC;;CAGA,AAAU,eAAe,WAAkC;EACzD,MAAM,SAAS,UAAU,cAAc;EACvC,IAAI,OAAO,WAAW,GAAG;EACzB,KAAK,MAAM,SAAS,QAAQ,eAAe,KAAK,KAAK;EACrD,UAAU,YAAY;CACxB;AACF;;;;;ACvBA,MAAa,oBAAoB,QAAQ,sBAAsB;CAC7D,WAAW,KAAK,YAAY,CAAC,CAAC,WAAW;CACzC,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;AACtF,CAAC;;AAGD,MAAa,gBAAgB,QAC3B,kBACA;CACE,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,SAAS,MAAM,SAAS,CAAC,CAAC,MAAmB,CAAC,CAAC,QAAQ;CACvD,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;CAChF,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;CACpF,UAAU,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;CACjD,YAAY,KAAK,aAAa;CAC9B,gBAAgB,UAAU,oBAAoB,EAAE,cAAc,KAAK,CAAC;CACpE,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC;CAC7D,UAAU,UAAU,aAAa,EAAE,cAAc,KAAK,CAAC;CACvD,WAAW,KAAK,YAAY;AAC9B,IACC,UAAU,CACT,MAAM,wBAAwB,CAAC,CAC5B,GAAG,MAAM,aAAa,MAAM,SAAS,CAAC,CACtC,MAAM,OAAO,MAAM,WAAW,CAAC,GAClC,MAAM,gCAAgC,CAAC,CAAC,GAAG,MAAM,UAAU,CAC7D,CACF;;;;;ACxBA,IAAa,uBAAb,MAAyF;CAC1D;CAA7B,YAAY,AAAiB,IAAmC;EAAnC;CAAoC;CAEjE,MAAM,MAAM,WAAqC;EAO/C,KAAI,MANkB,KAAK,GACxB,OAAO,iBAAiB,CAAC,CACzB,OAAO,EAAE,UAAU,CAAC,CAAC,CACrB,oBAAoB,CAAC,CACrB,UAAU,EAAE,WAAW,kBAAkB,UAAU,CAAC,EAE5C,CAAC,WAAW,GAAG,MAAM,IAAI,6BAA6B,SAAS;CAC5E;CAEA,MAAM,cAAc,QAAmD;EACrE,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,KAAK,GACR,OAAO,aAAa,CAAC,CACrB,OAAO,OAAO,KAAK,WAAW;GAAE,IAAI,MAAM;GAAI,SAAS;EAAM,EAAE,CAAC;CACrE;AACF;;;;ACxBA,MAAM,QAAQ,IAAI,kBAAwB;;AAG1C,SAAgB,eAAkB,MAAoC;CACpE,OAAO,MAAM,IAAI,MAAM,IAAI;AAC7B;;AAGA,SAAgB,kBAA2B;CACzC,OAAO,MAAM,SAAS,MAAM;AAC9B;;;;;;;;ACDA,IAAa,sBAAb,MAEE;CAC6B;CAA7B,YAAY,AAAiB,IAAwB;EAAxB;CAAyB;CAEtD,YAAe,MAA0D;EACvE,OAAO,yBAAyB,kBAC9B,gBAAgB,kCACd,qBAAqB,KAAK,GAAG,aAAa,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAChE,CACF;CACF;AACF;;;;;;;;AClBA,IAAa,mCAAb,cAAsD,SAAS;CAC7D,AAAS,OAAO;CAChB,AAAS,iBAAiB;CAE1B,cAAc;EACZ,MAAM,6EAA6E;CACrF;AACF;;;;;;;;;;;;ACEA,SAAgB,gBACd,kBACA,QACA,SACA;CACA,MAAM,OAAO,IAAI,KAAK;EAAE;EAAkB,KAAK;CAAE,CAAC;CAElD,KAAK,GAAG,eAAe,CAAC,CAAC;CACzB,KAAK,GAAG,YAAY,WAAW;EAE7B,OAAO,GAAG,eAAe,CAAC,CAAC;EAC3B,IAAI,YAAY,QAAW;EAE3B,OAAO,QAAQ,OAAO,OAAO,MAAM,KAAK,MAAM,GAAY,OAAO;CACnE,CAAC;CAED,MAAM,YAAY,KAAK,MAAM,KAAK,IAAI;CACtC,MAAM,QAAQ,UAAU,OAAO,WAAW,OAAO,IAAI;CACrD,MAAM,WAAkB,GAAG,SACzB,gBAAgB,IAAI,QAAQ,OAAO,IAAI,iCAAiC,CAAC,IAAI,MAAM,GAAG,IAAI;CAE5F,KAAK,QAAQ;CACb,IAAI;CACJ,OAAO;EACL,IAAI,QAAQ,MAAM,EAAE,OAAO,CAAC;;EAE5B,aAAa;GACX,IAAI,gBAAgB,GAAG,OAAO,QAAQ,OAAO,IAAI,iCAAiC,CAAC;GACnF,OAAQ,WAAW,KAAK,IAAI;EAC9B;CACF;AACF;;AAOA,SAAS,OAAO,OAAc,SAAyB;CACrD,QAAQ,GAAG,SAAS;EAClB,MAAM,OAAO,cAAc,IAAI;EAC/B,IAAI,SAAS,UAAa,OAAO,KAAK,GAAG,EAAE,MAAM,YAAY,OAAO,MAAM,GAAG,IAAI;EACjF,MAAM,YAAY,kBAAkB,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,YAAY,KAAK;EACtE,OAAO,QAAQ,UAAU,WAAW,OAAO,SAAS;GAClD,KAAK,cAAc;IACjB,kBAAkB;IAClB,oBAAoB;IACpB,qBAAqB;IACrB,iBAAiB;GACnB,CAAC;GACD,MAAM,SAAS,MAAM,MAAM,GAAG,IAAI;GAElC,IAAI,QAAQ,MAAM,KAAK,cAAc,EAAE,6BAA6B,OAAO,KAAK,OAAO,CAAC;GAExF,OAAO;EACT,CAAC;CACH;AACF;AAEA,SAAS,cAAc,MAA8C;CACnE,MAAM,QAAQ,KAAK;CACnB,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,OAAO,OAAO;CAC7E,OAAO,UAAU,SAAS,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC1E;;;;;;;;AC9DA,IAAa,2BAAb,MAAmE;CAI9C;CAEA;CALnB,AAAiB;CAEjB,YACE,AAAiB,IACjB,UAAmC,CAAC,GACpC,AAAiB,4BAAwB,IAAI,KAAK,GAClD;EAHiB;EAEA;EAEjB,KAAK,UAAU;GAAE,GAAG;GAA4B,GAAG;EAAQ;CAC7D;;CAGA,MAAM,aAAa,WAAyC;EAC1D,MAAM,QAAQ,OAAO,WAAW;EAChC,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,OAAO,MAAM,gBAAgB,+BACjC,KAAK,GACF,OAAO,aAAa,CAAC,CACrB,IAAI;GACH,YAAY;GACZ,gBAAgB,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,QAAQ,OAAO;GAC7D,UAAU,GAAG,GAAG,cAAc,SAAS;EACzC,CAAC,CAAC,CACD,MACC,QACE,cAAc,IACd,KAAK,GACF,OAAO,EAAE,IAAI,cAAc,GAAG,CAAC,CAAC,CAChC,KAAK,aAAa,CAAC,CACnB,MACC,IACE,OAAO,cAAc,WAAW,GAChC,OAAO,cAAc,QAAQ,GAC7B,IAAI,cAAc,aAAa,GAAG,GAClC,GAAG,OAAO,cAAc,cAAc,GAAG,IAAI,cAAc,gBAAgB,GAAG,CAAC,CACjF,CACF,CAAC,CACA,QACC,IAAI,cAAc,WAAW,GAC7B,IAAI,cAAc,SAAS,GAC3B,IAAI,cAAc,EAAE,CACtB,CAAC,CACA,MAAM,SAAS,CAAC,CAChB,IAAI,UAAU,EAAE,YAAY,KAAK,CAAC,CACvC,CACF,CAAC,CACA,UAAU;GACT,SAAS,cAAc;GACvB,UAAU,cAAc;GACxB,aAAa,cAAc;GAC3B,WAAW,cAAc;EAC3B,CAAC,CACL;EAEA,KAAK,MACF,GAAG,MACF,EAAE,YAAY,QAAQ,IAAI,EAAE,YAAY,QAAQ,KAChD,EAAE,UAAU,QAAQ,IAAI,EAAE,UAAU,QAAQ,KAC5C,EAAE,QAAQ,GAAG,cAAc,EAAE,QAAQ,EAAE,CAC3C;EACA,OAAO;GAAE;GAAO,MAAM,KAAK,KAAK,EAAE,SAAS,gBAAgB;IAAE;IAAS;GAAS,EAAE;EAAE;CACrF;;CAGA,MAAM,cAAc,YAAoB,MAA+C;EACrF,IAAI,KAAK,WAAW,GAAG;EACvB,MAAM,gBAAgB,oCACpB,KAAK,GACF,OAAO,aAAa,CAAC,CACrB,IAAI;GAAE,aAAa,KAAK,IAAI;GAAG,YAAY;GAAM,gBAAgB;EAAK,CAAC,CAAC,CACxE,MACC,IACE,QACE,cAAc,IACd,KAAK,KAAK,QAAQ,IAAI,QAAQ,EAAE,CAClC,GACA,GAAG,cAAc,YAAY,UAAU,CACzC,CACF,CACJ;CACF;;CAGA,MAAM,aACJ,YACA,MACA,aACe;EACf,MAAM,MAAM,KAAK,KAAK,QAAQ,IAAI,QAAQ,EAAE;EAC5C,MAAM,gBAAgB,6BACpB,KAAK,GACF,OAAO,aAAa,CAAC,CACrB,IAAI;GAAE;GAAa,YAAY;GAAM,gBAAgB;EAAK,CAAC,CAAC,CAC5D,MAAM,IAAI,QAAQ,cAAc,IAAI,GAAG,GAAG,GAAG,cAAc,YAAY,UAAU,CAAC,CAAC,CACxF;CACF;;CAGA,MAAM,WACJ,YACA,MACA,QACA,cACe;EACf,IAAI,KAAK,WAAW,GAAG;EACvB,MAAM,gBAAgB,iCACpB,KAAK,GACF,OAAO,aAAa,CAAC,CACrB,IAAI;GACH,UAAU,KAAK,IAAI;GACnB,WAAW,GAAG,OAAO,IAAI;GACzB,YAAY;GACZ,gBAAgB;EAClB,CAAC,CAAC,CACD,MACC,IACE,QACE,cAAc,IACd,KAAK,KAAK,QAAQ,IAAI,QAAQ,EAAE,CAClC,GACA,GAAG,cAAc,YAAY,UAAU,CACzC,CACF,CACJ;CACF;;CAGA,MAAM,sBAAsB,QAAc,WAAoC;EAiB5E,QAAO,MAhBY,gBAAgB,0CACjC,KAAK,GACF,OAAO,aAAa,CAAC,CACrB,MACC,QACE,cAAc,IACd,KAAK,GACF,OAAO,EAAE,IAAI,cAAc,GAAG,CAAC,CAAC,CAChC,KAAK,aAAa,CAAC,CACnB,MAAM,GAAG,cAAc,aAAa,MAAM,CAAC,CAAC,CAC5C,QAAQ,IAAI,cAAc,WAAW,GAAG,IAAI,cAAc,EAAE,CAAC,CAAC,CAC9D,MAAM,SAAS,CACpB,CACF,CAAC,CACA,UAAU,EAAE,IAAI,cAAc,GAAG,CAAC,CACvC,EACW,CAAC;CACd;;CAGA,MAAM,mBAAmB,QAAc,WAAoC;EAiBzE,QAAO,MAhBY,gBAAgB,uCACjC,KAAK,GACF,OAAO,aAAa,CAAC,CACrB,MACC,QACE,cAAc,IACd,KAAK,GACF,OAAO,EAAE,IAAI,cAAc,GAAG,CAAC,CAAC,CAChC,KAAK,aAAa,CAAC,CACnB,MAAM,IAAI,OAAO,cAAc,WAAW,GAAG,GAAG,cAAc,UAAU,MAAM,CAAC,CAAC,CAAC,CACjF,QAAQ,IAAI,cAAc,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC,CAAC,CAC3D,MAAM,SAAS,CACpB,CACF,CAAC,CACA,UAAU,EAAE,IAAI,cAAc,GAAG,CAAC,CACvC,EACW,CAAC;CACd;;CAGA,MAAM,qBAAqB,QAAc,WAAoC;EAiB3E,QAAO,MAhBY,gBAAgB,iCACjC,KAAK,GACF,OAAO,iBAAiB,CAAC,CACzB,MACC,QACE,kBAAkB,WAClB,KAAK,GACF,OAAO,EAAE,WAAW,kBAAkB,UAAU,CAAC,CAAC,CAClD,KAAK,iBAAiB,CAAC,CACvB,MAAM,GAAG,kBAAkB,aAAa,MAAM,CAAC,CAAC,CAChD,QAAQ,IAAI,kBAAkB,WAAW,GAAG,IAAI,kBAAkB,SAAS,CAAC,CAAC,CAC7E,MAAM,SAAS,CACpB,CACF,CAAC,CACA,UAAU,EAAE,WAAW,kBAAkB,UAAU,CAAC,CACzD,EACW,CAAC;CACd;AACF"}
|
|
1
|
+
{"version":3,"file":"postgres.js","names":["text"],"sources":["../src/infrastructure/postgres/classify-postgres-error.ts","../src/infrastructure/postgres/postgres-database-execution.ts","../src/infrastructure/postgres/base-postgres-repository.ts","../src/infrastructure/postgres/postgres-schema.ts","../src/infrastructure/postgres/postgres-message-store.ts","../src/infrastructure/postgres/connection-scope.ts","../src/infrastructure/postgres/postgres-transaction.ts","../src/infrastructure/postgres/statement-outside-transaction.error.ts","../src/infrastructure/postgres/postgres-client.ts","../src/infrastructure/postgres/postgres-outbox-repository.ts"],"sourcesContent":["import { DrizzleQueryError } from 'drizzle-orm/errors'\n\nimport { AppError, DatabaseError, type FailureClassification } from '@/core'\n\nconst TRANSIENT_CODES = new Set([\n '40001',\n '40P01',\n '58000',\n '08000',\n '08001',\n '08003',\n '08006',\n '57P01',\n '57P02',\n '57P03',\n 'CONNECT_TIMEOUT',\n 'CONNECTION_CLOSED',\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'EPIPE',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n])\nconst TERMINAL_CODES = new Set(['57014', 'CONNECTION_ENDED', 'CONNECTION_DESTROYED', 'ECANCELED'])\nconst DRIVER_CODES = new Set([\n 'CONNECT_TIMEOUT',\n 'CONNECTION_CLOSED',\n 'CONNECTION_ENDED',\n 'CONNECTION_DESTROYED',\n])\nconst TERMINAL_CLASSES = new Set(['0A', '22', '23', '25', '28', '3D', '3F', '42', '54'])\nconst DEAD_SOCKET_MESSAGES = new Set([\n 'Connection terminated unexpectedly',\n 'Client has encountered a connection error and is not queryable',\n])\n\n/* oxlint-disable anti-slop/no-runtime-typeof -- Raw driver exceptions have no shared schema; this boundary validates the fields it exposes. */\n/** Read SQLSTATE or driver codes; unknown callback exceptions remain unchanged. */\nexport function classifyPostgresError(\n cause: unknown,\n operation: string,\n): DatabaseError | undefined {\n let error = cause\n const seen = new Set<unknown>()\n while (error instanceof DrizzleQueryError && !seen.has(error)) {\n seen.add(error)\n error = error.cause\n }\n if (error instanceof AppError || (error instanceof Error && error.name === 'AbortError'))\n return undefined\n const code =\n error instanceof Error && 'code' in error && typeof error.code === 'string'\n ? error.code\n : undefined\n const serverError =\n error instanceof Error &&\n (error.name === 'PostgresError' || error.name === 'error') &&\n code !== undefined &&\n /^[0-9A-Z]{5}$/.test(code)\n const driverError = code !== undefined && DRIVER_CODES.has(code)\n const deadSocket = error instanceof Error && DEAD_SOCKET_MESSAGES.has(error.message)\n if (!(cause instanceof DrizzleQueryError) && !serverError && !driverError) return undefined\n\n return new DatabaseError(\n operation,\n classificationOf(code, deadSocket),\n {\n database: 'postgres',\n code,\n table_name: error instanceof Error ? text(error, 'table', 'table_name') : undefined,\n column_name: error instanceof Error ? text(error, 'column', 'column_name') : undefined,\n constraint_name:\n error instanceof Error ? text(error, 'constraint', 'constraint_name') : undefined,\n },\n { cause },\n )\n}\n\nfunction text(error: Error, pgName: string, jsName: string): string | undefined {\n return read(error, pgName) ?? read(error, jsName)\n}\n\nfunction read(error: Error, name: string): string | undefined {\n switch (name) {\n case 'table':\n return 'table' in error && typeof error.table === 'string' ? error.table : undefined\n case 'column':\n return 'column' in error && typeof error.column === 'string' ? error.column : undefined\n case 'constraint':\n return 'constraint' in error && typeof error.constraint === 'string'\n ? error.constraint\n : undefined\n case 'table_name':\n return 'table_name' in error && typeof error.table_name === 'string'\n ? error.table_name\n : undefined\n case 'column_name':\n return 'column_name' in error && typeof error.column_name === 'string'\n ? error.column_name\n : undefined\n case 'constraint_name':\n return 'constraint_name' in error && typeof error.constraint_name === 'string'\n ? error.constraint_name\n : undefined\n default:\n return undefined\n }\n}\n\n/* oxlint-enable anti-slop/no-runtime-typeof */\n\nfunction classificationOf(code: string | undefined, deadSocket: boolean): FailureClassification {\n if (deadSocket) return 'transient'\n if (code === undefined) return 'unknown'\n if (TRANSIENT_CODES.has(code)) return 'transient'\n if (TERMINAL_CODES.has(code) || TERMINAL_CLASSES.has(code.slice(0, 2))) return 'terminal'\n return 'unknown'\n}\n","import { Result } from 'better-result'\nimport { DrizzleQueryError } from 'drizzle-orm/errors'\n\nimport { AppError, DatabaseError } from '@/core'\n\nimport { classifyPostgresError } from './classify-postgres-error.ts'\n\n/** SQLSTATE values that leave the pg socket usable, so the same client can run the statement again. */\nconst RETRYABLE_ON_SESSION = new Set(['40001', '40P01', '58000'])\n\n/**\n * Convert database failures and preserve other exceptions. The default executes once.\n * Opt-in retries allow three attempts for serialization failure, deadlock, and a Hyperdrive pool acquire.\n * A dropped socket stays transient and is not retried here: pg cannot reconnect the client.\n * Delays use full jitter with backoff caps of 250 ms and 500 ms.\n */\nexport async function executeDatabase<T>(\n operation: string,\n work: () => PromiseLike<T>,\n options: { readonly retry?: 'never' | 'transient' } = {},\n): Promise<T> {\n const result = await Result.tryPromise(\n {\n try: async () => await work(),\n catch: (cause) =>\n classifyPostgresError(cause, operation) ?? appErrorUnderDrizzle(cause) ?? cause,\n },\n {\n retry: {\n times: options.retry === 'transient' ? 2 : 0,\n delayMs: 250,\n backoff: 'exponential',\n jitter: true,\n shouldRetry: (error) =>\n error instanceof DatabaseError &&\n error.classification === 'transient' &&\n error.details.database === 'postgres' &&\n error.details.code !== undefined &&\n RETRYABLE_ON_SESSION.has(error.details.code),\n },\n },\n )\n if (result.isErr()) throw result.error\n return result.value\n}\n\n// Drizzle wraps every `query` failure once; the typed error inside is the one the caller handles.\nfunction appErrorUnderDrizzle(cause: unknown): AppError | undefined {\n if (cause instanceof DrizzleQueryError && cause.cause instanceof AppError) return cause.cause\n return undefined\n}\n","import type { DomainEvent } from '@/core'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport { eventCollector } from '../unit-of-work-context.ts'\nimport { executeDatabase } from './postgres-database-execution.ts'\nimport type { PostgresDbTransaction } from './postgres-database-types.ts'\n\n/** A domain aggregate that accumulates events for the unit of work to drain. */\nexport interface AggregateEvents {\n collectEvents(): ReadonlyArray<DomainEvent>\n clearEvents(): void\n}\n\n/** Shared plumbing for a repository that writes inside a Postgres unit of work. */\nexport abstract class BasePostgresRepository<Schema extends DrizzleSchema> {\n constructor(protected readonly db: PostgresDbTransaction<Schema>) {}\n\n /** Execute one read with database error conversion and no automatic retries. */\n protected read<T>(operation: string, query: () => PromiseLike<T>): Promise<T> {\n return executeDatabase(operation, query)\n }\n\n /** Drain an aggregate's pending events into the active boundary. */\n protected dispatchEvents(aggregate: AggregateEvents): void {\n const events = aggregate.collectEvents()\n if (events.length === 0) return\n for (const event of events) eventCollector.emit(event)\n aggregate.clearEvents()\n }\n}\n","import { isNull } from 'drizzle-orm'\nimport { index, integer, jsonb, pgTable, text, timestamp } from 'drizzle-orm/pg-core'\n\nimport type { DomainEvent } from '@/core'\n\n/** One row per committed message. The primary key is the idempotency claim. */\nexport const processedMessages = pgTable('processed_messages', {\n messageId: text('message_id').primaryKey(),\n processedAt: timestamp('processed_at', { withTimezone: true }).notNull().defaultNow(),\n})\n\n/** Events committed with their state change, waiting for the relay to deliver them. */\nexport const messageOutbox = pgTable(\n 'message_outbox',\n {\n id: text('id').primaryKey(),\n payload: jsonb('payload').$type<DomainEvent>().notNull(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n availableAt: timestamp('available_at', { withTimezone: true }).notNull().defaultNow(),\n attempts: integer('attempts').notNull().default(0),\n claimToken: text('claim_token'),\n claimExpiresAt: timestamp('claim_expires_at', { withTimezone: true }),\n publishedAt: timestamp('published_at', { withTimezone: true }),\n failedAt: timestamp('failed_at', { withTimezone: true }),\n lastError: text('last_error'),\n },\n (table) => [\n index('idx_message_outbox_due')\n .on(table.availableAt, table.createdAt)\n .where(isNull(table.publishedAt)),\n index('idx_message_outbox_claim_token').on(table.claimToken),\n ],\n)\n","import { MessageAlreadyProcessedError, type IMessageStore, type MessageId } from '@/application'\nimport type { DomainEvent } from '@/core'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport type { PostgresDbTransaction } from './postgres-database-types.ts'\nimport { messageOutbox, processedMessages } from './postgres-schema.ts'\n\n/** Processed messages and outbox events share the active Postgres transaction; the insert result establishes the claim. */\nexport class PostgresMessageStore<Schema extends DrizzleSchema> implements IMessageStore {\n constructor(private readonly db: PostgresDbTransaction<Schema>) {}\n\n async claim(messageId: MessageId): Promise<void> {\n const claimed = await this.db\n .insert(processedMessages)\n .values({ messageId })\n .onConflictDoNothing()\n .returning({ messageId: processedMessages.messageId })\n // Thrown inside the transaction, so drizzle rolls back everything written before the claim.\n if (claimed.length === 0) throw new MessageAlreadyProcessedError(messageId)\n }\n\n async persistEvents(events: ReadonlyArray<DomainEvent>): Promise<void> {\n if (events.length === 0) return\n await this.db\n .insert(messageOutbox)\n .values(events.map((event) => ({ id: event.id, payload: event })))\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\n\n// Marks the async path that holds the invocation pool's one connection for a transaction.\nconst scope = new AsyncLocalStorage<true>()\n\n/** Run a transaction on the path that holds the pool's one connection. */\nexport function holdConnection<T>(work: () => Promise<T>): Promise<T> {\n return scope.run(true, work)\n}\n\n/** True inside a transaction: a pool statement here would wait for its own connection forever. */\nexport function holdsConnection(): boolean {\n return scope.getStore() === true\n}\n","import type { ITransaction } from '@/application'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport { runWithUnitOfWorkContext } from '../unit-of-work-context.ts'\nimport { holdConnection } from './connection-scope.ts'\nimport { executeDatabase } from './postgres-database-execution.ts'\nimport type { PostgresDb, PostgresTx } from './postgres-database-types.ts'\n\n/**\n * One Drizzle transaction on the invocation's pool: `BEGIN`, the work, `COMMIT`, or `ROLLBACK` on a throw.\n * Drizzle checks out the pool's one connection for the call; a second call waits until it is released.\n */\nexport class PostgresTransaction<Schema extends DrizzleSchema> implements ITransaction<\n PostgresTx<Schema>\n> {\n constructor(private readonly db: PostgresDb<Schema>) {}\n\n transaction<T>(work: (tx: PostgresTx<Schema>) => Promise<T>): Promise<T> {\n return runWithUnitOfWorkContext('postgres', () =>\n executeDatabase('unit of work transaction', () =>\n holdConnection(() => this.db.transaction((db) => work({ db }))),\n ),\n )\n }\n}\n","import { AppError } from '@/core'\n\n/**\n * A pool statement started while this async path is inside a unit of work.\n * The pool's one connection is already checked out, so the statement would wait forever.\n */\nexport class StatementOutsideTransactionError extends AppError {\n readonly _tag = 'StatementOutsideTransactionError'\n readonly classification = 'terminal'\n\n constructor() {\n super('a statement outside the transaction cannot run while a unit of work is open')\n }\n}\n","import { drizzle } from 'drizzle-orm/node-postgres'\nimport { Pool, type QueryResult } from 'pg'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport { holdsConnection } from './connection-scope.ts'\nimport { StatementOutsideTransactionError } from './statement-outside-transaction.error.ts'\n\n/**\n * Open the invocation's database: one `pg` Pool with `max: 1` through Hyperdrive.\n * Call it inside the handler, the queue consumer, the schedule, the Workflow step, or the Durable Object method.\n * `db` is ready at once; the first query connects. A transaction checks out the connection, and other statements wait.\n * A fetch, queue, cron, or Workflow step does not call `close()`: Hyperdrive drops the socket when the invocation ends.\n * A Durable Object calls `close()` at the end of each method or alarm, after that call's background work.\n * Pass `tracing` to record one span per statement. The statement text keeps placeholders; parameter values stay off.\n */\nexport function connectPostgres<Schema extends DrizzleSchema>(\n connectionString: string,\n schema: Schema,\n tracing?: Tracing,\n) {\n const pool = new Pool({ connectionString, max: 1 })\n // The pool emits `error` when it drops a client; the waiting statement rejects with that error.\n pool.on('error', () => {})\n pool.on('connect', (client) => {\n // pg-cloudflare reports the socket that `pool.end()` closed as a client error.\n client.on('error', () => {})\n if (tracing === undefined) return\n // SAFETY: a transaction's statements run here in promise form, and `traced` forwards every overload.\n client.query = traced(client.query.bind(client) as Query, tracing) as typeof client.query\n })\n // SAFETY: `pool.query` returns a promise in promise form and nothing in callback form.\n const poolQuery = pool.query.bind(pool) as Query\n const query = tracing ? traced(poolQuery, tracing) : poolQuery\n const guarded: Query = (...args) =>\n holdsConnection() ? Promise.reject(new StatementOutsideTransactionError()) : query(...args)\n // SAFETY: `guarded` forwards every `pool.query` overload unchanged.\n pool.query = guarded as Pool['query']\n let ending: Promise<void> | undefined\n return {\n db: drizzle(pool, { schema }),\n /** Ends the pool after the checked-out client is released. A second call returns the same promise. */\n close: () => {\n if (holdsConnection()) return Promise.reject(new StatementOutsideTransactionError())\n return (ending ??= pool.end())\n },\n }\n}\n\n/** `pool.query` and `client.query`: a promise in promise form, nothing in callback form. */\ntype Query = (...args: readonly unknown[]) => Promise<QueryResult> | void\n\n/* oxlint-disable anti-slop/no-runtime-typeof -- pg query takes a string, a config object, a callback, or a Submittable. */\n/** Spans promise-form calls. A callback-form call is the pool's own checkout, already spanned by `pool.query`. */\nfunction traced(query: Query, tracing: Tracing): Query {\n return (...args) => {\n const text = statementText(args)\n if (text === undefined || typeof args.at(-1) === 'function') return query(...args)\n const operation = /^\\s*([A-Za-z]+)/.exec(text)?.[1]?.toUpperCase() ?? 'QUERY'\n return tracing.enterSpan(operation, async (span) => {\n span.setAttributes({\n 'db.system.name': 'postgresql',\n 'db.query.summary': operation,\n 'db.operation.name': operation,\n 'db.query.text': text,\n })\n const result = await query(...args)\n // A multi-statement text resolves to an array of results, which has no `rows`.\n if (result?.rows) span.setAttributes({ 'db.response.returned_rows': result.rows.length })\n // SAFETY: the promise form always resolves to a result.\n return result as QueryResult\n })\n }\n}\n\nfunction statementText(args: readonly unknown[]): string | undefined {\n const first = args[0]\n if (typeof first === 'string') return first\n if (typeof first !== 'object' || first === null || 'submit' in first) return undefined\n return 'text' in first && typeof first.text === 'string' ? first.text : undefined\n}\n/* oxlint-enable anti-slop/no-runtime-typeof */\n","import { and, asc, eq, inArray, isNull, lt, lte, or, sql } from 'drizzle-orm'\n\nimport type { IOutboxRepository, OutboxBatch, OutboxFailureReason, OutboxRow } from '@/application'\n\nimport type { DrizzleSchema } from '../drizzle-schema.ts'\nimport {\n OUTBOX_REPOSITORY_DEFAULTS,\n type OutboxRepositoryOptions,\n} from '../outbox-repository-options.ts'\nimport { executeDatabase } from './postgres-database-execution.ts'\nimport type { PostgresDb } from './postgres-database-types.ts'\nimport { messageOutbox, processedMessages } from './postgres-schema.ts'\n\n/**\n * Typist's lease protocol with riposte's SKIP LOCKED selection on a plain connection, outside a unit of work.\n * Every write runs once; lease expiry and the scheduled sweep recover interrupted operations.\n */\nexport class PostgresOutboxRepository implements IOutboxRepository {\n private readonly options: Required<OutboxRepositoryOptions>\n\n constructor(\n private readonly db: PostgresDb<DrizzleSchema>,\n options: OutboxRepositoryOptions = {},\n private readonly now: () => Date = () => new Date(),\n ) {\n this.options = { ...OUTBOX_REPOSITORY_DEFAULTS, ...options }\n }\n\n /** Lease due rows in one statement; increment attempts even when reclaiming an expired lease. */\n async claimDueRows(batchSize: number): Promise<OutboxBatch> {\n const token = crypto.randomUUID()\n const now = this.now()\n const rows = await executeDatabase('claim due outbox rows', () =>\n this.db\n .update(messageOutbox)\n .set({\n claimToken: token,\n claimExpiresAt: new Date(now.getTime() + this.options.leaseMs),\n attempts: sql`${messageOutbox.attempts} + 1`,\n })\n .where(\n inArray(\n messageOutbox.id,\n this.db\n .select({ id: messageOutbox.id })\n .from(messageOutbox)\n .where(\n and(\n isNull(messageOutbox.publishedAt),\n isNull(messageOutbox.failedAt),\n lte(messageOutbox.availableAt, now),\n or(isNull(messageOutbox.claimExpiresAt), lte(messageOutbox.claimExpiresAt, now)),\n ),\n )\n .orderBy(\n asc(messageOutbox.availableAt),\n asc(messageOutbox.createdAt),\n asc(messageOutbox.id),\n )\n .limit(batchSize)\n .for('update', { skipLocked: true }),\n ),\n )\n .returning({\n payload: messageOutbox.payload,\n attempts: messageOutbox.attempts,\n availableAt: messageOutbox.availableAt,\n createdAt: messageOutbox.createdAt,\n }),\n )\n // UPDATE RETURNING does not preserve the selection order.\n rows.sort(\n (a, b) =>\n a.availableAt.getTime() - b.availableAt.getTime() ||\n a.createdAt.getTime() - b.createdAt.getTime() ||\n a.payload.id.localeCompare(b.payload.id),\n )\n return {\n token,\n rows: rows.map(({ payload, attempts, createdAt }) => ({ payload, attempts, createdAt })),\n }\n }\n\n /** Mark only supplied rows that still hold this token as published. */\n async markPublished(claimToken: string, rows: ReadonlyArray<OutboxRow>): Promise<void> {\n if (rows.length === 0) return\n await executeDatabase('mark outbox rows published', () =>\n this.db\n .update(messageOutbox)\n .set({ publishedAt: this.now(), claimToken: null, claimExpiresAt: null })\n .where(\n and(\n inArray(\n messageOutbox.id,\n rows.map((row) => row.payload.id),\n ),\n eq(messageOutbox.claimToken, claimToken),\n ),\n ),\n )\n }\n\n /** Release supplied rows until `availableAt`; a stale token cannot change a newer claim. */\n async releaseClaim(\n claimToken: string,\n rows: ReadonlyArray<OutboxRow>,\n availableAt: Date,\n ): Promise<void> {\n const ids = rows.map((row) => row.payload.id)\n await executeDatabase('release outbox rows', () =>\n this.db\n .update(messageOutbox)\n .set({ availableAt, claimToken: null, claimExpiresAt: null })\n .where(and(inArray(messageOutbox.id, ids), eq(messageOutbox.claimToken, claimToken))),\n )\n }\n\n /** Set `failed_at`, keep the full payload, and record the reason with a readable error message. */\n async markFailed(\n claimToken: string,\n rows: ReadonlyArray<OutboxRow>,\n reason: OutboxFailureReason,\n errorMessage: string,\n ): Promise<void> {\n if (rows.length === 0) return\n await executeDatabase('mark outbox rows failed', () =>\n this.db\n .update(messageOutbox)\n .set({\n failedAt: this.now(),\n lastError: `${reason}: ${errorMessage}`,\n claimToken: null,\n claimExpiresAt: null,\n })\n .where(\n and(\n inArray(\n messageOutbox.id,\n rows.map((row) => row.payload.id),\n ),\n eq(messageOutbox.claimToken, claimToken),\n ),\n ),\n )\n }\n\n /** Delete at most batchSize published rows, strictly before the cutoff. */\n async deletePublishedBefore(cutoff: Date, batchSize: number): Promise<number> {\n const rows = await executeDatabase('delete published outbox messages', () =>\n this.db\n .delete(messageOutbox)\n .where(\n inArray(\n messageOutbox.id,\n this.db\n .select({ id: messageOutbox.id })\n .from(messageOutbox)\n .where(lt(messageOutbox.publishedAt, cutoff))\n .orderBy(asc(messageOutbox.publishedAt), asc(messageOutbox.id))\n .limit(batchSize),\n ),\n )\n .returning({ id: messageOutbox.id }),\n )\n return rows.length\n }\n\n /** Delete at most batchSize failed rows; pending and published rows remain untouched. */\n async deleteFailedBefore(cutoff: Date, batchSize: number): Promise<number> {\n const rows = await executeDatabase('delete failed outbox messages', () =>\n this.db\n .delete(messageOutbox)\n .where(\n inArray(\n messageOutbox.id,\n this.db\n .select({ id: messageOutbox.id })\n .from(messageOutbox)\n .where(and(isNull(messageOutbox.publishedAt), lt(messageOutbox.failedAt, cutoff)))\n .orderBy(asc(messageOutbox.failedAt), asc(messageOutbox.id))\n .limit(batchSize),\n ),\n )\n .returning({ id: messageOutbox.id }),\n )\n return rows.length\n }\n\n /** Delete at most batchSize receipts, strictly before the cutoff. */\n async deleteReceiptsBefore(cutoff: Date, batchSize: number): Promise<number> {\n const rows = await executeDatabase('delete message receipts', () =>\n this.db\n .delete(processedMessages)\n .where(\n inArray(\n processedMessages.messageId,\n this.db\n .select({ messageId: processedMessages.messageId })\n .from(processedMessages)\n .where(lt(processedMessages.processedAt, cutoff))\n .orderBy(asc(processedMessages.processedAt), asc(processedMessages.messageId))\n .limit(batchSize),\n ),\n )\n .returning({ messageId: processedMessages.messageId }),\n )\n return rows.length\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as PostHogMetricsService } from "../metrics-
|
|
1
|
+
import { t as PostHogMetricsService } from "../metrics-CdpccKGI.js";
|
|
2
2
|
export { PostHogMetricsService };
|
package/dist/posthog/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as PostHogMetricsService } from "../metrics-
|
|
1
|
+
import { Jt as AnalyticsProperties, Xt as AnalyticsTarget, qt as AnalyticsEventInput } from "../index-tJzJUgTh.js";
|
|
2
|
+
import { st as AnalyticsService } from "../index-DIHLfC-p.js";
|
|
3
|
+
import { t as PostHogMetricsService } from "../metrics-CdpccKGI.js";
|
|
4
4
|
import { PostHog, PostHogOptions } from "posthog-node";
|
|
5
5
|
//#region src/infrastructure/posthog/server.d.ts
|
|
6
6
|
/** Deployment values and SDK options; the runtime owns delivery promises. */
|
package/dist/posthog/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { nt as MissingConfigurationError } from "../core-CV8SQv01.js";
|
|
2
2
|
import { t as PostHogMetricsService } from "../metrics-CWv37yf9.js";
|
|
3
3
|
import { v5, validate } from "uuid";
|
|
4
4
|
import { PostHog } from "posthog-node";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as isAbortError, f as classifyBoundaryError, rt as AppError } from "./core-CV8SQv01.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
//#region src/infrastructure/cloudflare/r2-errors.ts
|
|
@@ -87,4 +87,4 @@ var R2JsonError = class extends AppError {
|
|
|
87
87
|
|
|
88
88
|
//#endregion
|
|
89
89
|
export { R2JsonError as n, R2Error as t };
|
|
90
|
-
//# sourceMappingURL=r2-errors-
|
|
90
|
+
//# sourceMappingURL=r2-errors-DzpOvciV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"r2-errors-
|
|
1
|
+
{"version":3,"file":"r2-errors-DzpOvciV.js","names":[],"sources":["../src/infrastructure/cloudflare/r2-errors.ts"],"sourcesContent":["import { z } from 'zod'\n\nimport { AppError, classifyBoundaryError, isAbortError, type FailureClassification } from '@/core'\n\n/** The storage operation that failed. */\nexport type R2Operation =\n | 'head'\n | 'get'\n | 'getJson'\n | 'put'\n | 'delete'\n | 'list'\n | 'createMultipartUpload'\n | 'uploadPart'\n | 'complete'\n | 'abort'\n\n/** Provider diagnostics from the outer failure, without request bodies or credentials. */\nexport type R2Failure = {\n readonly code: number\n readonly action?: string | undefined\n}\n\nconst R2FailureSchema = z.object({\n code: z.number().int().positive(),\n action: z.string().optional(),\n})\n\n// R2 codes describe failures; the caller owns retry decisions and repeat safety.\nconst classifications: ReadonlyMap<number, FailureClassification> = new Map([\n [10001, 'transient'],\n [10043, 'transient'],\n [10054, 'transient'],\n [10058, 'transient'],\n [10013, 'transient'],\n [10002, 'terminal'],\n [10003, 'terminal'],\n [10018, 'terminal'],\n [10035, 'terminal'],\n [10042, 'terminal'],\n [10005, 'terminal'],\n [10006, 'terminal'],\n [10008, 'terminal'],\n [10009, 'terminal'],\n [10073, 'terminal'],\n [10007, 'terminal'],\n [10020, 'terminal'],\n [100100, 'terminal'],\n [10012, 'terminal'],\n [10069, 'terminal'],\n [10033, 'terminal'],\n [10014, 'terminal'],\n [10037, 'terminal'],\n [10039, 'terminal'],\n [10031, 'terminal'],\n [10011, 'terminal'],\n [10024, 'terminal'],\n [10025, 'terminal'],\n [10048, 'terminal'],\n])\n\nfunction extractR2Failure(cause: unknown): R2Failure | undefined {\n if (!(cause instanceof Error)) return undefined\n const parsed = R2FailureSchema.safeParse(cause)\n if (parsed.success) return parsed.data\n // Cloudflare documents the numeric suffix for bindings that omit structured fields.\n const match = /\\((\\d{5,6})\\)\\s*$/.exec(cause.message)\n return match?.[1] === undefined ? undefined : { code: Number(match[1]) }\n}\n\nfunction classifyR2Code(cause: unknown): FailureClassification | undefined {\n const failure = extractR2Failure(cause)\n return failure === undefined ? undefined : (classifications.get(failure.code) ?? 'unknown')\n}\n\nfunction classifyR2Error(cause: unknown): FailureClassification {\n if (isAbortError(cause)) return 'terminal'\n if (cause instanceof AppError) return cause.classification\n return classifyBoundaryError({ cause, classifyBoundary: classifyR2Code, includeCloudflare: true })\n}\n\n/** A raw binding failure after one attempt. Classification does not establish whether a mutation committed. */\nexport class R2Error extends AppError {\n readonly _tag = 'R2Error'\n readonly classification: FailureClassification\n readonly operation: R2Operation\n readonly r2?: R2Failure | undefined\n override readonly cause: unknown\n\n constructor(input: { operation: R2Operation; cause: unknown }) {\n super(`R2 ${input.operation} failed`, { cause: input.cause })\n this.operation = input.operation\n this.cause = input.cause\n this.r2 = extractR2Failure(input.cause)\n this.classification = classifyR2Error(input.cause)\n }\n}\n\n/** JSON serialization or syntax failed. Binding and body-read failures use R2Error. */\nexport class R2JsonError extends AppError {\n readonly _tag = 'R2JsonError'\n readonly classification = 'terminal'\n readonly operation: 'encode' | 'decode'\n override readonly cause: unknown\n\n constructor(input: { operation: 'encode' | 'decode'; cause: unknown }) {\n super(`R2 JSON ${input.operation} failed`, { cause: input.cause })\n this.operation = input.operation\n this.cause = input.cause\n }\n}\n"],"mappings":";;;;AAuBA,MAAM,kBAAkB,EAAE,OAAO;CAC/B,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;CAChC,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS;AAC9B,CAAC;AAGD,MAAM,kCAA8D,IAAI,IAAI;CAC1E,CAAC,OAAO,WAAW;CACnB,CAAC,OAAO,WAAW;CACnB,CAAC,OAAO,WAAW;CACnB,CAAC,OAAO,WAAW;CACnB,CAAC,OAAO,WAAW;CACnB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,QAAQ,UAAU;CACnB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;CAClB,CAAC,OAAO,UAAU;AACpB,CAAC;AAED,SAAS,iBAAiB,OAAuC;CAC/D,IAAI,EAAE,iBAAiB,QAAQ,OAAO;CACtC,MAAM,SAAS,gBAAgB,UAAU,KAAK;CAC9C,IAAI,OAAO,SAAS,OAAO,OAAO;CAElC,MAAM,QAAQ,oBAAoB,KAAK,MAAM,OAAO;CACpD,OAAO,QAAQ,OAAO,SAAY,SAAY,EAAE,MAAM,OAAO,MAAM,EAAE,EAAE;AACzE;AAEA,SAAS,eAAe,OAAmD;CACzE,MAAM,UAAU,iBAAiB,KAAK;CACtC,OAAO,YAAY,SAAY,SAAa,gBAAgB,IAAI,QAAQ,IAAI,KAAK;AACnF;AAEA,SAAS,gBAAgB,OAAuC;CAC9D,IAAI,aAAa,KAAK,GAAG,OAAO;CAChC,IAAI,iBAAiB,UAAU,OAAO,MAAM;CAC5C,OAAO,sBAAsB;EAAE;EAAO,kBAAkB;EAAgB,mBAAmB;CAAK,CAAC;AACnG;;AAGA,IAAa,UAAb,cAA6B,SAAS;CACpC,AAAS,OAAO;CAChB,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAkB;CAElB,YAAY,OAAmD;EAC7D,MAAM,MAAM,MAAM,UAAU,UAAU,EAAE,OAAO,MAAM,MAAM,CAAC;EAC5D,KAAK,YAAY,MAAM;EACvB,KAAK,QAAQ,MAAM;EACnB,KAAK,KAAK,iBAAiB,MAAM,KAAK;EACtC,KAAK,iBAAiB,gBAAgB,MAAM,KAAK;CACnD;AACF;;AAGA,IAAa,cAAb,cAAiC,SAAS;CACxC,AAAS,OAAO;CAChB,AAAS,iBAAiB;CAC1B,AAAS;CACT,AAAkB;CAElB,YAAY,OAA2D;EACrE,MAAM,WAAW,MAAM,UAAU,UAAU,EAAE,OAAO,MAAM,MAAM,CAAC;EACjE,KAAK,YAAY,MAAM;EACvB,KAAK,QAAQ,MAAM;CACrB;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as PaymentServiceError } from "./payment-service.error-
|
|
1
|
+
import { t as PaymentServiceError } from "./payment-service.error-oW2bKAfU.js";
|
|
2
2
|
import Stripe from "stripe";
|
|
3
3
|
|
|
4
4
|
//#region src/infrastructure/stripe/request.ts
|
|
@@ -18,4 +18,4 @@ async function stripeRequest(operation, work) {
|
|
|
18
18
|
|
|
19
19
|
//#endregion
|
|
20
20
|
export { stripeRequest as t };
|
|
21
|
-
//# sourceMappingURL=request-
|
|
21
|
+
//# sourceMappingURL=request-C5k8ME_7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-
|
|
1
|
+
{"version":3,"file":"request-C5k8ME_7.js","names":[],"sources":["../src/infrastructure/stripe/request.ts"],"sourcesContent":["import Stripe from 'stripe'\n\nimport { PaymentServiceError } from './payment-service.error.ts'\n\n/**\n * Invoke one SDK operation; the SDK owns retries configured on its client or request.\n * Convert every Stripe error to PaymentServiceError without logging; preserve the original error in cause.\n * Non-Stripe failures propagate unchanged.\n */\nexport async function stripeRequest<T>(operation: string, work: () => Promise<T>): Promise<T> {\n try {\n return await work()\n } catch (cause) {\n if (!(cause instanceof Stripe.errors.StripeError)) throw cause\n throw new PaymentServiceError(operation, cause)\n }\n}\n"],"mappings":";;;;;;;;;AASA,eAAsB,cAAiB,WAAmB,MAAoC;CAC5F,IAAI;EACF,OAAO,MAAM,KAAK;CACpB,SAAS,OAAO;EACd,IAAI,EAAE,iBAAiB,OAAO,OAAO,cAAc,MAAM;EACzD,MAAM,IAAI,oBAAoB,WAAW,KAAK;CAChD;AACF"}
|
package/dist/resend.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as WebhookVerifier } from "./webhook-verification-
|
|
1
|
+
import { Ft as BounceType } from "./index-tJzJUgTh.js";
|
|
2
|
+
import { G as OutboundEmail, J as ReceivedEmail, U as IEmailService, V as EmailAccepted, q as ReceivedContent } from "./index-DIHLfC-p.js";
|
|
3
|
+
import { n as WebhookVerifier } from "./webhook-verification-Cy4Z5djk.js";
|
|
4
4
|
import "resend";
|
|
5
5
|
//#region src/infrastructure/resend/resend-email-service.d.ts
|
|
6
6
|
/**
|
package/dist/resend.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as WebhookVerificationError } from "./webhook-verification-
|
|
1
|
+
import { Q as EmailServiceError, X as parseBounceType, tt as EmailAddressSchema } from "./core-CV8SQv01.js";
|
|
2
|
+
import { t as WebhookVerificationError } from "./webhook-verification-B8v3-LQ2.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
5
|
|
package/dist/sentry/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as LoggerErrorHook } from "../index-
|
|
1
|
+
import { u as LoggerErrorHook } from "../index-tJzJUgTh.js";
|
|
2
2
|
import * as Sentry from "@sentry/tanstackstart-react";
|
|
3
3
|
//#region src/infrastructure/sentry/client.d.ts
|
|
4
4
|
/** Application settings use Sentry's names; enablement and environment belong to the application. */
|
package/dist/sentry/client.js
CHANGED
package/dist/sentry/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { u as LoggerErrorHook } from "../index-
|
|
2
|
-
import {
|
|
1
|
+
import { u as LoggerErrorHook } from "../index-tJzJUgTh.js";
|
|
2
|
+
import { $ as ObservabilityService, Q as ObservabilityScope, et as ObservabilityUser } from "../index-DIHLfC-p.js";
|
|
3
3
|
import * as Sentry from "@sentry/cloudflare";
|
|
4
4
|
//#region src/infrastructure/sentry/server.d.ts
|
|
5
5
|
/** Application-owned deployment settings with the full Cloudflare SDK option contract. */
|
package/dist/stripe/client.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import Stripe from "stripe";
|
|
2
2
|
//#region src/infrastructure/stripe/client.d.ts
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Default SDK retries and per-request timeout; client configuration and individual requests can
|
|
5
|
+
* override them. Three tries of 8 s plus the SDK's short waits stay under a Worker's 30 s `waitUntil`
|
|
6
|
+
* limit and the outbox's 60 s lease. The SDK's own timeout is 80 s.
|
|
7
|
+
*/
|
|
4
8
|
export declare const STRIPE_REQUEST_OPTIONS: Readonly<{
|
|
5
9
|
maxNetworkRetries: 2;
|
|
10
|
+
timeout: 8000;
|
|
6
11
|
}>;
|
|
7
12
|
/**
|
|
8
|
-
* Construct a native Stripe client with fetch transport
|
|
13
|
+
* Construct a native Stripe client with fetch transport, two SDK retries and an 8 s timeout by default.
|
|
9
14
|
* Native configuration overrides these defaults. Inject the client into application services.
|
|
10
15
|
*/
|
|
11
16
|
export declare function createStripeClient(secretKey: string, options?: Stripe.StripeConfig): Stripe;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/infrastructure/stripe/client.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/infrastructure/stripe/client.ts"],"mappings":";;;;;;;qBAOa,wBAAsB;;;;;;;;wBAMnB,mBAAmB,mBAAmB,UAAS,OAAO,eAAoB"}
|
package/dist/stripe/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $t as FailureClassification, Qt as AppError } from "../index-tJzJUgTh.js";
|
|
2
2
|
import Stripe from "stripe";
|
|
3
3
|
//#region src/infrastructure/stripe/payment-service.error.d.ts
|
|
4
4
|
/** A final Stripe request failure. The caller logs once; native details remain in cause. */
|
package/dist/stripe/request.js
CHANGED