@vrplatform/kysely 1.3.45-stage.11 → 1.3.45-stage.1104
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/build/.data.tar +2 -2
- package/build/main/control-plane/index.d.ts +28 -6
- package/build/main/control-plane/index.js.map +1 -1
- package/build/main/index.d.ts +23 -1
- package/build/main/index.js +209 -50
- package/build/main/index.js.map +1 -1
- package/build/main/local/index.js +115 -8
- package/build/main/local/index.js.map +1 -1
- package/build/main/postgres-error.d.ts +3 -3
- package/build/main/postgres-error.js +4 -3
- package/build/main/postgres-error.js.map +1 -1
- package/build/main/query/tenant/status.d.ts +1 -1
- package/build/main/query/tenant/status.js +5 -2
- package/build/main/query/tenant/status.js.map +1 -1
- package/build/main/regional.d.ts +1 -0
- package/build/main/regional.js +1 -0
- package/build/main/regional.js.map +1 -1
- package/build/main/test/index.d.ts +25 -2
- package/build/main/test/index.js +40 -8
- package/build/main/test/index.js.map +1 -1
- package/build/main/v1.generated.d.ts +193 -19
- package/build/main/v1.generated.js.map +1 -1
- package/build/migrations-v2/0000000000031-ui-permission-role-simplification.ts +70 -0
- package/build/migrations-v2/0000000000032-tenant-delete-ownership-cascades.ts +44 -0
- package/build/migrations-v2/0000000000033-plaid-connect-session-telemetry.ts +31 -0
- package/build/migrations-v2/0000000000033-reservation-issue-seed-bucket-index.ts +19 -0
- package/build/migrations-v2/0000000000034-retire-recent-classification-indexes.ts +29 -0
- package/build/migrations-v2/0000000000035-core-change-autovacuum.ts +24 -0
- package/build/migrations-v2/0000000000036-journal-entry-inactive-reason-constraint.ts +33 -0
- package/build/migrations-v2/0000000000037-journal-entry-inactive-reasons.ts +19 -0
- package/build/migrations-v2/0000000000038-journal-entry-group-inactive-reason.ts +14 -0
- package/build/migrations-v2/0000000000039-reservation-guest-breakdown.ts +19 -0
- package/build/migrations-v2/0000000000040-csv-import-source-identity-index.ts +23 -0
- package/build/migrations-v2/0000000000041-payment-returns.ts +38 -0
- package/build/migrations-v2/0000000000042-operation-resource-types.ts +609 -0
- package/build/migrations-v2/0000000000043-reservation-journal-freshness.ts +149 -0
- package/build/migrations-v2/0000000000044-reservation-journal-freshness-backfill.ts +254 -0
- package/build/migrations-v2/0000000000045-reservation-journal-freshness-revision-repair.ts +83 -0
- package/build/migrations-v2/0000000000046-materialized-reservation-journal-operations.ts +709 -0
- package/build/migrations-v2/0000000000047-public-audit-completion.ts +77 -0
- package/build/migrations-v2/0000000000048-reservation-journal-full-refresh-repair.ts +136 -0
- package/build/migrations-v2/0000000000049-queued-journal-operation-failures.ts +60 -0
- package/build/migrations-v2/0000000000050-connection-oauth-state.ts +43 -0
- package/build/migrations-v2/0000000000051-owner-statement-email-delivery.ts +134 -0
- package/build/migrations-v2/0000000000052-fee-journal-lock-skip-operations.ts +59 -0
- package/build/migrations-v2/0000000000053-fee-journal-lock-skip-null-attempt.ts +44 -0
- package/build/migrations-v2/0000000000054-journal-refresh-issue-codes.ts +16 -0
- package/build/migrations-v2/0000000000055-tenant-billing-subscription.ts +8 -0
- package/build/migrations-v2/0000000000056-journal-operation-failure-precedence.ts +306 -0
- package/build/migrations-v2/0000000000057-journal-invalidation-failure-code.ts +28 -0
- package/build/migrations-v2/0000000000058-journal-invalidation-locked-failure.ts +16 -0
- package/build/migrations-v2/0000000000059-billing-active-listing-cross-region-partner.ts +135 -0
- package/build/migrations-v2/0000000000060-accounting-integrity-change-driven.ts +99 -0
- package/build/migrations-v2/0000000000061-tenant-pending-onboarding-status.ts +37 -0
- package/build/migrations-v2/0000000000062-statement-payout-operations.ts +16 -0
- package/build/migrations-v2/0000000000063-missing-account-assignments-issue-code.ts +13 -0
- package/build/module/control-plane/index.d.ts +28 -6
- package/build/module/control-plane/index.js.map +1 -1
- package/build/module/index.d.ts +23 -1
- package/build/module/index.js +206 -50
- package/build/module/index.js.map +1 -1
- package/build/module/local/index.js +115 -8
- package/build/module/local/index.js.map +1 -1
- package/build/module/postgres-error.d.ts +3 -3
- package/build/module/postgres-error.js +4 -3
- package/build/module/postgres-error.js.map +1 -1
- package/build/module/query/tenant/status.d.ts +1 -1
- package/build/module/query/tenant/status.js +5 -2
- package/build/module/query/tenant/status.js.map +1 -1
- package/build/module/regional.d.ts +1 -0
- package/build/module/regional.js +1 -0
- package/build/module/regional.js.map +1 -1
- package/build/module/test/index.d.ts +25 -2
- package/build/module/test/index.js +39 -8
- package/build/module/test/index.js.map +1 -1
- package/build/module/v1.generated.d.ts +193 -19
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +9 -7
package/build/.data.tar
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/build/.data.tar
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 50941952 bytes
|
|
4
|
+
sha256: dc736c159970f20a56de35a3ec6afe8ab91d7062228f85a853d3d44268cf76b1
|
|
@@ -10,6 +10,11 @@ export type JsonPrimitive = boolean | number | string | null;
|
|
|
10
10
|
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
11
11
|
export type Int8 = ColumnType<string, number | string | bigint, number | string | bigint>;
|
|
12
12
|
export type Timestamp = ColumnType<Date | string, Date | string, Date | string>;
|
|
13
|
+
export type ControlPlaneOperationStatus = 'completed' | 'failed' | 'queued' | 'running';
|
|
14
|
+
export type ControlPlaneOperationType = 'ach-verification' | 'bank-rule-run' | 'calendar-block' | 'calendar-unblock' | 'connection-archive' | 'connection-connect' | 'connection-extract' | 'connection-sync' | 'csv-import' | 'csv-import-preview' | 'export' | 'flow-run' | 'historical-gl-import' | 'historical-statement-import' | 'listing-journal-refresh' | 'plaid-initial-sync' | 'pms-cutover' | 'pms-cutover-preview' | 'provider-payment' | 'provider-payment-recovery' | 'recurring-transaction-run' | 'reservation-journal-refresh' | 'statement-payout' | 'statement-payout-preview' | 'team-delete' | 'team-demo-data' | 'team-duplicate' | 'team-initialize' | 'transaction-journal-refresh' | 'vri-statement-import' | 'vri-team-migration' | 'webhook-test';
|
|
15
|
+
export type ControlPlaneOperationResourceRole = 'result' | 'source' | 'target';
|
|
16
|
+
export type ControlPlaneOperationResourceType = 'bank-rule' | 'connection' | 'contact' | 'file' | 'flow' | 'listing' | 'recurring-fee' | 'recurring-transaction-template' | 'reservation' | 'statement' | 'team' | 'transaction' | 'webhook';
|
|
17
|
+
export type ControlPlaneOperationSourceType = 'destructive-job' | 'regional-operation';
|
|
13
18
|
export interface ControlPlaneApp {
|
|
14
19
|
authentication: Generated<Json>;
|
|
15
20
|
category: string | null;
|
|
@@ -169,8 +174,8 @@ export interface ControlPlaneOperation {
|
|
|
169
174
|
sourceRegion: TenantDataRegion | null;
|
|
170
175
|
sourceVersion: Generated<number>;
|
|
171
176
|
startedAt: Timestamp | null;
|
|
172
|
-
status: Generated<
|
|
173
|
-
type:
|
|
177
|
+
status: Generated<ControlPlaneOperationStatus>;
|
|
178
|
+
type: ControlPlaneOperationType;
|
|
174
179
|
updatedAt: Generated<Timestamp>;
|
|
175
180
|
}
|
|
176
181
|
export interface ControlPlaneOperationResource {
|
|
@@ -178,18 +183,18 @@ export interface ControlPlaneOperationResource {
|
|
|
178
183
|
isPrimary: Generated<boolean>;
|
|
179
184
|
operationId: string;
|
|
180
185
|
resourceId: string;
|
|
181
|
-
resourceType:
|
|
182
|
-
role:
|
|
186
|
+
resourceType: ControlPlaneOperationResourceType;
|
|
187
|
+
role: ControlPlaneOperationResourceRole;
|
|
183
188
|
}
|
|
184
189
|
export interface ControlPlaneOperationSource {
|
|
185
190
|
finishedAt: Timestamp | null;
|
|
186
191
|
operationId: string;
|
|
187
192
|
required: Generated<boolean>;
|
|
188
193
|
sourceId: string;
|
|
189
|
-
sourceType:
|
|
194
|
+
sourceType: ControlPlaneOperationSourceType;
|
|
190
195
|
sourceVersion: Generated<number>;
|
|
191
196
|
startedAt: Timestamp | null;
|
|
192
|
-
status: Generated<
|
|
197
|
+
status: Generated<ControlPlaneOperationStatus>;
|
|
193
198
|
}
|
|
194
199
|
export interface ControlPlaneEvent {
|
|
195
200
|
createdAt: Generated<Timestamp>;
|
|
@@ -370,6 +375,22 @@ export interface ControlPlanePartnerManagedTeamAssignment {
|
|
|
370
375
|
partnerTenantId: string;
|
|
371
376
|
userId: string;
|
|
372
377
|
}
|
|
378
|
+
export interface ControlPlaneOwnerPortal {
|
|
379
|
+
hostname: string;
|
|
380
|
+
tenantId: string;
|
|
381
|
+
status: Generated<'pending' | 'active' | 'disabled'>;
|
|
382
|
+
name: string;
|
|
383
|
+
logo: string | null;
|
|
384
|
+
colorPrimary: string;
|
|
385
|
+
showPlatformBranding: Generated<boolean>;
|
|
386
|
+
linksEnabled: Generated<boolean>;
|
|
387
|
+
sender: {
|
|
388
|
+
from: string;
|
|
389
|
+
replyTo: string;
|
|
390
|
+
} | null;
|
|
391
|
+
revision: Generated<number>;
|
|
392
|
+
updatedAt: Generated<Timestamp>;
|
|
393
|
+
}
|
|
373
394
|
export interface ControlPlaneTenant {
|
|
374
395
|
billingPartnerId: string | null;
|
|
375
396
|
billingPlan: string | null;
|
|
@@ -470,6 +491,7 @@ export interface ControlPlaneDB {
|
|
|
470
491
|
'controlPlane.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;
|
|
471
492
|
'controlPlane.reservationLineDefault': ControlPlaneReservationLineDefault;
|
|
472
493
|
'controlPlane.rolloutMonitorSnapshot': ControlPlaneRolloutMonitorSnapshot;
|
|
494
|
+
'controlPlane.ownerPortal': ControlPlaneOwnerPortal;
|
|
473
495
|
'controlPlane.tenant': ControlPlaneTenant;
|
|
474
496
|
'controlPlane.tenantRegionMigration': ControlPlaneTenantRegionMigration;
|
|
475
497
|
'controlPlane.tenantUser': ControlPlaneTenantUser;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["control-plane/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AA+mBA,wDAQC;AAvnBD,mCAcgB;AA+hBhB,MAAM,6BAA8B,SAAQ,iCAAwB;IAClE,YACW,MAAc,EACd,2BAAmC;QAE5C,KAAK,EAAE,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,gCAA2B,GAA3B,2BAA2B,CAAQ;IAG9C,CAAC;IAEkB,4BAA4B,CAC7C,IAA6B,EAC7B,OAAgB;QAEhB,MAAM,WAAW,GAAG,KAAK,CAAC,4BAA4B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtE,IACE,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc;YAC3C,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,eAAe,EAC5C,CAAC;YACD,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,uBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACxE,CAAC;QACD,IACE,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,kBAAkB;YAC/C,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,oBAAoB,EACjD,CAAC;YACD,OAAO;gBACL,GAAG,WAAW;gBACd,MAAM,EAAE,uBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC;aAChE,CAAC;QACJ,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAEkB,iBAAiB,CAClC,IAAkB,EAClB,OAAgB;QAEhB,MAAM,WAAW,GAAG,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;YAC1C,CAAC,CAAC;gBACE,GAAG,WAAW;gBACd,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE;aACzE;YACH,CAAC,CAAC,WAAW,CAAC;IAClB,CAAC;CACF;AAED,MAAM,wBAAwB;IAG5B,YAAY,MAAc,EAAE,2BAAmC;QAFtD,wDAA4C;QAGnD,uBAAA,IAAI,yCAAgB,IAAI,6BAA6B,CACnD,MAAM,EACN,2BAA2B,CAC5B,MAAA,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,IAA8B;QAC3C,OAAO,uBAAA,IAAI,6CAAa,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,IAA+B;QAE/B,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;;AAED,SAAgB,sBAAsB,CACpC,MAA8B,EAC9B,MAAc,EACd,2BAA2B,GAAG,MAAM;IAEpC,OAAO,MAAM,CAAC,UAAU,CACtB,IAAI,wBAAwB,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAClE,CAAC;AACJ,CAAC","sourcesContent":["import {\n type ColumnType,\n type FunctionNode,\n IdentifierNode,\n type Kysely,\n type KyselyPlugin,\n OperationNodeTransformer,\n type PluginTransformQueryArgs,\n type PluginTransformResultArgs,\n type QueryId,\n type QueryResult,\n type RootOperationNode,\n type SchemableIdentifierNode,\n type UnknownRow,\n} from 'kysely';\nimport type { TenantDataRegion } from '../regional';\n\nexport type Generated<T> =\n T extends ColumnType<infer S, infer I, infer U>\n ? ColumnType<S, I | undefined, U>\n : ColumnType<T, T | undefined, T>;\n\nexport type Json = JsonValue;\n\nexport type JsonArray = JsonValue[];\n\nexport type JsonObject = {\n [x: string]: JsonValue | undefined;\n};\n\nexport type JsonPrimitive = boolean | number | string | null;\n\nexport type JsonValue = JsonArray | JsonObject | JsonPrimitive;\n\nexport type Int8 = ColumnType<\n string,\n number | string | bigint,\n number | string | bigint\n>;\n\nexport type Timestamp = ColumnType<Date | string, Date | string, Date | string>;\n\nexport interface ControlPlaneApp {\n authentication: Generated<Json>;\n category: string | null;\n color: string | null;\n createdAt: Generated<Timestamp>;\n icon: string | null;\n iconRound: string | null;\n id: Generated<string>;\n info: Json | null;\n name: string;\n type: string;\n version: Generated<number>;\n}\n\nexport interface ControlPlaneAccountingIntegrityEvaluation {\n caseCount: Generated<Int8>;\n completedAt: Timestamp | null;\n completedRunCount: Generated<number>;\n createdAt: Generated<Timestamp>;\n environment: string;\n error: Json | null;\n expectedRunCount: number;\n failedRunCount: Generated<number>;\n findingRowCount: Generated<Int8>;\n gitRevision: string;\n id: string;\n results: Generated<Json>;\n rowsScanned: Generated<Int8>;\n skippedRunCount: Generated<number>;\n source: string;\n startedAt: Timestamp;\n status: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneAccountingIntegrityDefinitionDraft {\n artifact: Json;\n artifactHash: string;\n code: string;\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n ownerId: string;\n previewResult: Json | null;\n rationale: string;\n revision: Generated<number>;\n status: string;\n templateId: string;\n templateVersion: number;\n title: string;\n updatedAt: Generated<Timestamp>;\n validationResult: Json | null;\n}\n\nexport interface ControlPlaneAccountingIntegrityDefinitionVersion {\n artifact: Json;\n artifactHash: string;\n code: string;\n draftId: string;\n id: Generated<string>;\n publishedAt: Generated<Timestamp>;\n publishedBy: string;\n rollout: string;\n templateId: string;\n templateVersion: number;\n version: number;\n}\n\nexport interface ControlPlaneBookingChannel {\n channelRef: string | null;\n color: string | null;\n createdAt: Generated<Timestamp>;\n icon: string | null;\n iconProvider: string | null;\n id: Generated<string>;\n lastGenerateRun: Timestamp | null;\n logo: string | null;\n logoProvider: string | null;\n selectedBookingChannelIconCandidateId: string | null;\n selectedBookingChannelLogoCandidateId: string | null;\n uniqueRef: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneBookingChannelIconCandidate {\n bookingChannelId: string;\n cloudflareImageId: string | null;\n color: string | null;\n comment: string | null;\n createdAt: Generated<Timestamp>;\n externalIcon: string | null;\n height: number | null;\n id: Generated<string>;\n provider: Generated<string>;\n source: string | null;\n updatedAt: Generated<Timestamp>;\n width: number | null;\n}\n\nexport interface ControlPlaneCurrency {\n name: string;\n}\n\nexport type DestructiveJobStep =\n | 'completed'\n | 'completion_effects'\n | 'control_plane_deleted'\n | 'control_plane_deleting'\n | 'queued'\n | 'regional_deleted'\n | 'regional_deleting'\n | 'validated';\n\nexport interface ControlPlaneDestructiveJob {\n attempts: Generated<number>;\n authorizedByTenantId: string;\n availableAt: Generated<Timestamp>;\n claimedAt: Timestamp | null;\n claimedBy: string | null;\n completedAt: Timestamp | null;\n completionData: Json | null;\n completionWarningCode: string | null;\n completionWarningDetails: Json | null;\n createdAt: Generated<Timestamp>;\n dataRegion: TenantDataRegion;\n failureCode: string | null;\n failureDetails: Json | null;\n force: Generated<boolean>;\n id: Generated<string>;\n jobType: 'tenant.delete';\n maxAttempts: Generated<number>;\n requestId: string | null;\n requestedByActorType: 'api_key' | 'system' | 'user';\n requestedByTenantId: string;\n requestedByUserId: string | null;\n startedAt: Timestamp | null;\n status: Generated<'canceled' | 'completed' | 'failed' | 'queued' | 'running'>;\n step: Generated<DestructiveJobStep>;\n targetId: string;\n triggerRunId: string | null;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneDestructiveJobAttempt {\n attemptNumber: number;\n failureCode: string | null;\n failureDetails: Json | null;\n finishedAt: Timestamp | null;\n id: Generated<string>;\n jobId: string;\n startedAt: Generated<Timestamp>;\n status: Generated<'completed' | 'failed' | 'running' | 'superseded'>;\n step: DestructiveJobStep;\n triggerRunId: string | null;\n}\n\nexport interface ControlPlaneDestructiveJobOperation {\n action: 'abandon' | 'cancel' | 'retry';\n actor: string;\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n jobId: string;\n previousStatus: string;\n previousStep: string;\n reasonCode: string;\n}\n\nexport interface ControlPlaneOperation {\n createdAt: Generated<Timestamp>;\n failureCode: string | null;\n failureMessage: string | null;\n finishedAt: Timestamp | null;\n id: Generated<string>;\n initiatedByUserId: string | null;\n requesterTenantId: string;\n retainUntil: Timestamp | null;\n sourceRegion: TenantDataRegion | null;\n sourceVersion: Generated<number>;\n startedAt: Timestamp | null;\n status: Generated<'completed' | 'failed' | 'queued' | 'running'>;\n type: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneOperationResource {\n createdAt: Generated<Timestamp>;\n isPrimary: Generated<boolean>;\n operationId: string;\n resourceId: string;\n resourceType: string;\n role: 'result' | 'source' | 'target';\n}\n\nexport interface ControlPlaneOperationSource {\n finishedAt: Timestamp | null;\n operationId: string;\n required: Generated<boolean>;\n sourceId: string;\n sourceType: 'destructive-job' | 'regional-operation';\n sourceVersion: Generated<number>;\n startedAt: Timestamp | null;\n status: Generated<'completed' | 'failed' | 'queued' | 'running'>;\n}\n\nexport interface ControlPlaneEvent {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n name: string;\n packageName: string;\n props: Json;\n tenantId: string | null;\n timestamp: Generated<Timestamp>;\n trackedAt: Generated<Timestamp | null>;\n userId: string | null;\n}\n\nexport interface ControlPlaneTrackingQueueFailure {\n bodyFingerprint: string | null;\n capturedAt: Generated<Timestamp>;\n dispositionAt: Timestamp | null;\n dispositionHistory: Generated<Json[]>;\n dispositionReasonCode: string | null;\n dispositionActor: string | null;\n environment: 'production' | 'staging';\n event: Json | null;\n eventId: string | null;\n expiresAt: Timestamp;\n failureCode: string;\n id: Generated<string>;\n lastReplayedAt: Timestamp | null;\n queueMessageId: string;\n replayCount: Generated<number>;\n recurrenceCount: Generated<number>;\n status: Generated<'captured' | 'discarded' | 'replayed'>;\n updatedAt: Generated<Timestamp>;\n validationIssues: Json | null;\n}\n\nexport interface ControlPlaneConnectionRoute {\n connectionId: string;\n createdAt: Generated<Timestamp>;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneFeature {\n createdAt: Generated<Timestamp>;\n description: string | null;\n id: Generated<string>;\n issueUrl: string | null;\n requiredApprovals: Generated<Json | null>;\n status: Generated<string | null>;\n tenantId: string | null;\n title: string;\n updatedAt: Generated<Timestamp>;\n url: string | null;\n}\n\nexport interface ControlPlaneFeatureEnabledTeam {\n createdAt: Generated<Timestamp>;\n featureId: string;\n id: Generated<string>;\n status: Generated<string | null>;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneFeatureApproval {\n createdAt: Generated<Timestamp>;\n featureId: string;\n id: Generated<string>;\n status: Generated<string | null>;\n updatedAt: Generated<Timestamp>;\n userId: string;\n}\n\nexport interface ControlPlaneFlow {\n appId: string;\n createdAt: Generated<Timestamp>;\n description: string | null;\n eventListening: Generated<Json>;\n id: Generated<string>;\n isPublic: Generated<boolean>;\n leftType: string | null;\n mappingSchema: Generated<Json>;\n revision: Generated<number>;\n rightType: string | null;\n runSchema: Generated<Json>;\n settingSchema: Generated<Json>;\n title: string;\n type: 'pull' | 'push' | null;\n uniqueRef: string;\n updatedAt: Generated<Timestamp>;\n useGlobalMapping: Generated<boolean>;\n}\n\nexport interface ControlPlaneIssueMessageOverwrite {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n message: string;\n pattern: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneLineClassification {\n appConflict: Generated<boolean>;\n appId: string | null;\n createdAt: Generated<Timestamp>;\n firstSeenAt: Timestamp;\n id: Generated<string>;\n kind: string;\n lastSeenAt: Timestamp;\n name: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneLineClassificationTeamUsage {\n classificationId: string;\n createdAt: Generated<Timestamp>;\n dataRegion: string;\n firstSeenAt: Timestamp;\n lastSeenAt: Timestamp;\n mappingStatus: string | null;\n revision: number;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneReservationLineDefault {\n accountKey: string | null;\n bookingChannel: string | null;\n bookingChannelKey: Generated<string>;\n classificationId: string;\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n partnerTenantId: string | null;\n revenueRecognition: string | null;\n revision: Generated<number>;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneRolloutMonitorSnapshot {\n monitorName: string;\n result: Json;\n snapshotDate: Timestamp;\n}\n\nexport interface ControlPlaneTransactionLineMapping {\n accountAssignmentType: string | null;\n createdAt: Generated<Timestamp>;\n deletedAt: Timestamp | null;\n id: Generated<string>;\n lineType: string;\n revision: Generated<number>;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneGeneralLedgerDefaultSet {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n partnerTenantId: string | null;\n publishedVersion: number | null;\n sourceDataRegion: string;\n sourceDigest: string | null;\n sourceTenantId: string;\n templateKey: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneGeneralLedgerDefaultVersion {\n dataJson: Json;\n defaultSetId: string;\n id: Generated<string>;\n publishedAt: Generated<Timestamp>;\n sourceDigest: string;\n sourceTenantId: string;\n version: number;\n}\n\nexport interface ControlPlaneOutbox {\n aggregateId: string;\n aggregateType: string;\n attempts: Generated<number>;\n createdAt: Generated<Timestamp>;\n dataRegion: string | null;\n eventType: string;\n eventVersion: number;\n id: Generated<string>;\n lastError: string | null;\n payload: Generated<Json>;\n publishedAt: Timestamp | null;\n}\n\nexport interface ControlPlanePartnerManagedTeamAssignment {\n createdAt: Generated<Timestamp>;\n managedTeamId: string;\n partnerTenantId: string;\n userId: string;\n}\n\nexport interface ControlPlaneTenant {\n billingPartnerId: string | null;\n billingPlan: string | null;\n createdAt: Generated<Timestamp>;\n dataRegion: Generated<string>;\n id: Generated<string>;\n migrationStatus: Generated<string>;\n name: string;\n partnerId: string | null;\n partnerDeniedPermissions: Generated<string[]>;\n slug: string;\n status: Generated<string | null>;\n storageRealm: Generated<string>;\n type: Generated<string | null>;\n uniqueRef: string | null;\n updatedAt: Generated<Timestamp | null>;\n}\n\nexport interface ControlPlaneTenantRegionMigration {\n actor: string;\n completedAt: Timestamp | null;\n error: Json | null;\n id: string;\n reason: string;\n sourceManifest: Json | null;\n sourceRegion: string;\n startedAt: Generated<Timestamp>;\n status: Generated<string>;\n targetManifest: Json | null;\n targetRegion: string;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneTenantUser {\n createdAt: Generated<Timestamp | null>;\n id: Generated<string>;\n lastInvitedAt: Timestamp | null;\n managedTeamAccess: Generated<'all' | 'assigned'>;\n permissionBundles: Generated<string[]>;\n role: Generated<string | null>;\n status: Generated<string | null>;\n tenantId: string;\n updatedAt: Generated<Timestamp | null>;\n userId: string;\n}\n\nexport interface ControlPlaneToken {\n createdAt: Generated<Timestamp>;\n expiresAt: Timestamp | null;\n id: Generated<string>;\n nanoId: Generated<string>;\n payload: Generated<Json>;\n tenantId: string | null;\n type: string | null;\n userId: string | null;\n}\n\nexport interface ControlPlaneUser {\n clerkId: string | null;\n createdAt: Generated<Timestamp | null>;\n email: string | null;\n firstName: string | null;\n id: Generated<string>;\n internalOperationGrants: Generated<string[]>;\n isAdmin: Generated<boolean>;\n lastName: string | null;\n lastSeen: Timestamp | null;\n name: string | null;\n partnerId: string | null;\n phone: string | null;\n secondaryEmails: Generated<Json>;\n status: Generated<string | null>;\n sub: string | null;\n type: Generated<string | null>;\n updatedAt: Generated<Timestamp | null>;\n}\n\nexport interface ControlPlaneDB {\n 'controlPlane.accountingIntegrityDefinitionDraft': ControlPlaneAccountingIntegrityDefinitionDraft;\n 'controlPlane.accountingIntegrityDefinitionVersion': ControlPlaneAccountingIntegrityDefinitionVersion;\n 'controlPlane.accountingIntegrityEvaluation': ControlPlaneAccountingIntegrityEvaluation;\n 'controlPlane.app': ControlPlaneApp;\n 'controlPlane.bookingChannel': ControlPlaneBookingChannel;\n 'controlPlane.bookingChannelIconCandidate': ControlPlaneBookingChannelIconCandidate;\n 'controlPlane.connectionRoute': ControlPlaneConnectionRoute;\n 'controlPlane.controlPlaneOutbox': ControlPlaneOutbox;\n 'controlPlane.currency': ControlPlaneCurrency;\n 'controlPlane.destructiveJob': ControlPlaneDestructiveJob;\n 'controlPlane.destructiveJobAttempt': ControlPlaneDestructiveJobAttempt;\n 'controlPlane.destructiveJobOperation': ControlPlaneDestructiveJobOperation;\n 'controlPlane.events': ControlPlaneEvent;\n 'controlPlane.feature': ControlPlaneFeature;\n 'controlPlane.featureApproval': ControlPlaneFeatureApproval;\n 'controlPlane.featureEnabledTeam': ControlPlaneFeatureEnabledTeam;\n 'controlPlane.generalLedgerDefaultSet': ControlPlaneGeneralLedgerDefaultSet;\n 'controlPlane.generalLedgerDefaultVersion': ControlPlaneGeneralLedgerDefaultVersion;\n 'controlPlane.lineClassification': ControlPlaneLineClassification;\n 'controlPlane.lineClassificationTeamUsage': ControlPlaneLineClassificationTeamUsage;\n 'controlPlane.operation': ControlPlaneOperation;\n 'controlPlane.operationResource': ControlPlaneOperationResource;\n 'controlPlane.operationSource': ControlPlaneOperationSource;\n 'controlPlane.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;\n 'controlPlane.reservationLineDefault': ControlPlaneReservationLineDefault;\n 'controlPlane.rolloutMonitorSnapshot': ControlPlaneRolloutMonitorSnapshot;\n 'controlPlane.tenant': ControlPlaneTenant;\n 'controlPlane.tenantRegionMigration': ControlPlaneTenantRegionMigration;\n 'controlPlane.tenantUser': ControlPlaneTenantUser;\n 'controlPlane.trackingQueueFailure': ControlPlaneTrackingQueueFailure;\n 'controlPlane.token': ControlPlaneToken;\n 'controlPlane.transactionLineMapping': ControlPlaneTransactionLineMapping;\n 'controlPlane.user': ControlPlaneUser;\n 'controlPlaneCore.flow': ControlPlaneFlow;\n 'controlPlaneCore.issueMessageOverwrite': ControlPlaneIssueMessageOverwrite;\n}\n\nclass ControlPlaneSchemaTransformer extends OperationNodeTransformer {\n constructor(\n readonly schema: string,\n readonly issueMessageOverwriteSchema: string\n ) {\n super();\n }\n\n protected override transformSchemableIdentifier(\n node: SchemableIdentifierNode,\n queryId: QueryId\n ): SchemableIdentifierNode {\n const transformed = super.transformSchemableIdentifier(node, queryId);\n if (\n transformed.schema?.name === 'controlPlane' ||\n transformed.schema?.name === 'control_plane'\n ) {\n return { ...transformed, schema: IdentifierNode.create(this.schema) };\n }\n if (\n transformed.schema?.name === 'controlPlaneCore' ||\n transformed.schema?.name === 'control_plane_core'\n ) {\n return {\n ...transformed,\n schema: IdentifierNode.create(this.issueMessageOverwriteSchema),\n };\n }\n return transformed;\n }\n\n protected override transformFunction(\n node: FunctionNode,\n queryId: QueryId\n ): FunctionNode {\n const transformed = super.transformFunction(node, queryId);\n return node.func.startsWith('controlPlane.')\n ? {\n ...transformed,\n func: `${this.schema}.${transformed.func.slice('controlPlane.'.length)}`,\n }\n : transformed;\n }\n}\n\nclass ControlPlaneSchemaPlugin implements KyselyPlugin {\n readonly #transformer: ControlPlaneSchemaTransformer;\n\n constructor(schema: string, issueMessageOverwriteSchema: string) {\n this.#transformer = new ControlPlaneSchemaTransformer(\n schema,\n issueMessageOverwriteSchema\n );\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n return this.#transformer.transformNode(args.node, args.queryId);\n }\n\n async transformResult(\n args: PluginTransformResultArgs\n ): Promise<QueryResult<UnknownRow>> {\n return args.result;\n }\n}\n\nexport function withControlPlaneSchema(\n kysely: Kysely<ControlPlaneDB>,\n schema: string,\n issueMessageOverwriteSchema = 'core'\n) {\n return kysely.withPlugin(\n new ControlPlaneSchemaPlugin(schema, issueMessageOverwriteSchema)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["control-plane/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AA2rBA,wDAQC;AAnsBD,mCAcgB;AA2mBhB,MAAM,6BAA8B,SAAQ,iCAAwB;IAClE,YACW,MAAc,EACd,2BAAmC;QAE5C,KAAK,EAAE,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,gCAA2B,GAA3B,2BAA2B,CAAQ;IAG9C,CAAC;IAEkB,4BAA4B,CAC7C,IAA6B,EAC7B,OAAgB;QAEhB,MAAM,WAAW,GAAG,KAAK,CAAC,4BAA4B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtE,IACE,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc;YAC3C,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,eAAe,EAC5C,CAAC;YACD,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,uBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACxE,CAAC;QACD,IACE,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,kBAAkB;YAC/C,WAAW,CAAC,MAAM,EAAE,IAAI,KAAK,oBAAoB,EACjD,CAAC;YACD,OAAO;gBACL,GAAG,WAAW;gBACd,MAAM,EAAE,uBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC;aAChE,CAAC;QACJ,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAEkB,iBAAiB,CAClC,IAAkB,EAClB,OAAgB;QAEhB,MAAM,WAAW,GAAG,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;YAC1C,CAAC,CAAC;gBACE,GAAG,WAAW;gBACd,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE;aACzE;YACH,CAAC,CAAC,WAAW,CAAC;IAClB,CAAC;CACF;AAED,MAAM,wBAAwB;IAG5B,YAAY,MAAc,EAAE,2BAAmC;QAFtD,wDAA4C;QAGnD,uBAAA,IAAI,yCAAgB,IAAI,6BAA6B,CACnD,MAAM,EACN,2BAA2B,CAC5B,MAAA,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,IAA8B;QAC3C,OAAO,uBAAA,IAAI,6CAAa,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,IAA+B;QAE/B,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;;AAED,SAAgB,sBAAsB,CACpC,MAA8B,EAC9B,MAAc,EACd,2BAA2B,GAAG,MAAM;IAEpC,OAAO,MAAM,CAAC,UAAU,CACtB,IAAI,wBAAwB,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAClE,CAAC;AACJ,CAAC","sourcesContent":["import {\n type ColumnType,\n type FunctionNode,\n IdentifierNode,\n type Kysely,\n type KyselyPlugin,\n OperationNodeTransformer,\n type PluginTransformQueryArgs,\n type PluginTransformResultArgs,\n type QueryId,\n type QueryResult,\n type RootOperationNode,\n type SchemableIdentifierNode,\n type UnknownRow,\n} from 'kysely';\nimport type { TenantDataRegion } from '../regional';\n\nexport type Generated<T> =\n T extends ColumnType<infer S, infer I, infer U>\n ? ColumnType<S, I | undefined, U>\n : ColumnType<T, T | undefined, T>;\n\nexport type Json = JsonValue;\n\nexport type JsonArray = JsonValue[];\n\nexport type JsonObject = {\n [x: string]: JsonValue | undefined;\n};\n\nexport type JsonPrimitive = boolean | number | string | null;\n\nexport type JsonValue = JsonArray | JsonObject | JsonPrimitive;\n\nexport type Int8 = ColumnType<\n string,\n number | string | bigint,\n number | string | bigint\n>;\n\nexport type Timestamp = ColumnType<Date | string, Date | string, Date | string>;\n\nexport type ControlPlaneOperationStatus =\n | 'completed'\n | 'failed'\n | 'queued'\n | 'running';\n\nexport type ControlPlaneOperationType =\n | 'ach-verification'\n | 'bank-rule-run'\n | 'calendar-block'\n | 'calendar-unblock'\n | 'connection-archive'\n | 'connection-connect'\n | 'connection-extract'\n | 'connection-sync'\n | 'csv-import'\n | 'csv-import-preview'\n | 'export'\n | 'flow-run'\n | 'historical-gl-import'\n | 'historical-statement-import'\n | 'listing-journal-refresh'\n | 'plaid-initial-sync'\n | 'pms-cutover'\n | 'pms-cutover-preview'\n | 'provider-payment'\n | 'provider-payment-recovery'\n | 'recurring-transaction-run'\n | 'reservation-journal-refresh'\n | 'statement-payout'\n | 'statement-payout-preview'\n | 'team-delete'\n | 'team-demo-data'\n | 'team-duplicate'\n | 'team-initialize'\n | 'transaction-journal-refresh'\n | 'vri-statement-import'\n | 'vri-team-migration'\n | 'webhook-test';\n\nexport type ControlPlaneOperationResourceRole = 'result' | 'source' | 'target';\n\nexport type ControlPlaneOperationResourceType =\n | 'bank-rule'\n | 'connection'\n | 'contact'\n | 'file'\n | 'flow'\n | 'listing'\n | 'recurring-fee'\n | 'recurring-transaction-template'\n | 'reservation'\n | 'statement'\n | 'team'\n | 'transaction'\n | 'webhook';\n\nexport type ControlPlaneOperationSourceType =\n | 'destructive-job'\n | 'regional-operation';\n\nexport interface ControlPlaneApp {\n authentication: Generated<Json>;\n category: string | null;\n color: string | null;\n createdAt: Generated<Timestamp>;\n icon: string | null;\n iconRound: string | null;\n id: Generated<string>;\n info: Json | null;\n name: string;\n type: string;\n version: Generated<number>;\n}\n\nexport interface ControlPlaneAccountingIntegrityEvaluation {\n caseCount: Generated<Int8>;\n completedAt: Timestamp | null;\n completedRunCount: Generated<number>;\n createdAt: Generated<Timestamp>;\n environment: string;\n error: Json | null;\n expectedRunCount: number;\n failedRunCount: Generated<number>;\n findingRowCount: Generated<Int8>;\n gitRevision: string;\n id: string;\n results: Generated<Json>;\n rowsScanned: Generated<Int8>;\n skippedRunCount: Generated<number>;\n source: string;\n startedAt: Timestamp;\n status: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneAccountingIntegrityDefinitionDraft {\n artifact: Json;\n artifactHash: string;\n code: string;\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n ownerId: string;\n previewResult: Json | null;\n rationale: string;\n revision: Generated<number>;\n status: string;\n templateId: string;\n templateVersion: number;\n title: string;\n updatedAt: Generated<Timestamp>;\n validationResult: Json | null;\n}\n\nexport interface ControlPlaneAccountingIntegrityDefinitionVersion {\n artifact: Json;\n artifactHash: string;\n code: string;\n draftId: string;\n id: Generated<string>;\n publishedAt: Generated<Timestamp>;\n publishedBy: string;\n rollout: string;\n templateId: string;\n templateVersion: number;\n version: number;\n}\n\nexport interface ControlPlaneBookingChannel {\n channelRef: string | null;\n color: string | null;\n createdAt: Generated<Timestamp>;\n icon: string | null;\n iconProvider: string | null;\n id: Generated<string>;\n lastGenerateRun: Timestamp | null;\n logo: string | null;\n logoProvider: string | null;\n selectedBookingChannelIconCandidateId: string | null;\n selectedBookingChannelLogoCandidateId: string | null;\n uniqueRef: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneBookingChannelIconCandidate {\n bookingChannelId: string;\n cloudflareImageId: string | null;\n color: string | null;\n comment: string | null;\n createdAt: Generated<Timestamp>;\n externalIcon: string | null;\n height: number | null;\n id: Generated<string>;\n provider: Generated<string>;\n source: string | null;\n updatedAt: Generated<Timestamp>;\n width: number | null;\n}\n\nexport interface ControlPlaneCurrency {\n name: string;\n}\n\nexport type DestructiveJobStep =\n | 'completed'\n | 'completion_effects'\n | 'control_plane_deleted'\n | 'control_plane_deleting'\n | 'queued'\n | 'regional_deleted'\n | 'regional_deleting'\n | 'validated';\n\nexport interface ControlPlaneDestructiveJob {\n attempts: Generated<number>;\n authorizedByTenantId: string;\n availableAt: Generated<Timestamp>;\n claimedAt: Timestamp | null;\n claimedBy: string | null;\n completedAt: Timestamp | null;\n completionData: Json | null;\n completionWarningCode: string | null;\n completionWarningDetails: Json | null;\n createdAt: Generated<Timestamp>;\n dataRegion: TenantDataRegion;\n failureCode: string | null;\n failureDetails: Json | null;\n force: Generated<boolean>;\n id: Generated<string>;\n jobType: 'tenant.delete';\n maxAttempts: Generated<number>;\n requestId: string | null;\n requestedByActorType: 'api_key' | 'system' | 'user';\n requestedByTenantId: string;\n requestedByUserId: string | null;\n startedAt: Timestamp | null;\n status: Generated<'canceled' | 'completed' | 'failed' | 'queued' | 'running'>;\n step: Generated<DestructiveJobStep>;\n targetId: string;\n triggerRunId: string | null;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneDestructiveJobAttempt {\n attemptNumber: number;\n failureCode: string | null;\n failureDetails: Json | null;\n finishedAt: Timestamp | null;\n id: Generated<string>;\n jobId: string;\n startedAt: Generated<Timestamp>;\n status: Generated<'completed' | 'failed' | 'running' | 'superseded'>;\n step: DestructiveJobStep;\n triggerRunId: string | null;\n}\n\nexport interface ControlPlaneDestructiveJobOperation {\n action: 'abandon' | 'cancel' | 'retry';\n actor: string;\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n jobId: string;\n previousStatus: string;\n previousStep: string;\n reasonCode: string;\n}\n\nexport interface ControlPlaneOperation {\n createdAt: Generated<Timestamp>;\n failureCode: string | null;\n failureMessage: string | null;\n finishedAt: Timestamp | null;\n id: Generated<string>;\n initiatedByUserId: string | null;\n requesterTenantId: string;\n retainUntil: Timestamp | null;\n sourceRegion: TenantDataRegion | null;\n sourceVersion: Generated<number>;\n startedAt: Timestamp | null;\n status: Generated<ControlPlaneOperationStatus>;\n type: ControlPlaneOperationType;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneOperationResource {\n createdAt: Generated<Timestamp>;\n isPrimary: Generated<boolean>;\n operationId: string;\n resourceId: string;\n resourceType: ControlPlaneOperationResourceType;\n role: ControlPlaneOperationResourceRole;\n}\n\nexport interface ControlPlaneOperationSource {\n finishedAt: Timestamp | null;\n operationId: string;\n required: Generated<boolean>;\n sourceId: string;\n sourceType: ControlPlaneOperationSourceType;\n sourceVersion: Generated<number>;\n startedAt: Timestamp | null;\n status: Generated<ControlPlaneOperationStatus>;\n}\n\nexport interface ControlPlaneEvent {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n name: string;\n packageName: string;\n props: Json;\n tenantId: string | null;\n timestamp: Generated<Timestamp>;\n trackedAt: Generated<Timestamp | null>;\n userId: string | null;\n}\n\nexport interface ControlPlaneTrackingQueueFailure {\n bodyFingerprint: string | null;\n capturedAt: Generated<Timestamp>;\n dispositionAt: Timestamp | null;\n dispositionHistory: Generated<Json[]>;\n dispositionReasonCode: string | null;\n dispositionActor: string | null;\n environment: 'production' | 'staging';\n event: Json | null;\n eventId: string | null;\n expiresAt: Timestamp;\n failureCode: string;\n id: Generated<string>;\n lastReplayedAt: Timestamp | null;\n queueMessageId: string;\n replayCount: Generated<number>;\n recurrenceCount: Generated<number>;\n status: Generated<'captured' | 'discarded' | 'replayed'>;\n updatedAt: Generated<Timestamp>;\n validationIssues: Json | null;\n}\n\nexport interface ControlPlaneConnectionRoute {\n connectionId: string;\n createdAt: Generated<Timestamp>;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneFeature {\n createdAt: Generated<Timestamp>;\n description: string | null;\n id: Generated<string>;\n issueUrl: string | null;\n requiredApprovals: Generated<Json | null>;\n status: Generated<string | null>;\n tenantId: string | null;\n title: string;\n updatedAt: Generated<Timestamp>;\n url: string | null;\n}\n\nexport interface ControlPlaneFeatureEnabledTeam {\n createdAt: Generated<Timestamp>;\n featureId: string;\n id: Generated<string>;\n status: Generated<string | null>;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneFeatureApproval {\n createdAt: Generated<Timestamp>;\n featureId: string;\n id: Generated<string>;\n status: Generated<string | null>;\n updatedAt: Generated<Timestamp>;\n userId: string;\n}\n\nexport interface ControlPlaneFlow {\n appId: string;\n createdAt: Generated<Timestamp>;\n description: string | null;\n eventListening: Generated<Json>;\n id: Generated<string>;\n isPublic: Generated<boolean>;\n leftType: string | null;\n mappingSchema: Generated<Json>;\n revision: Generated<number>;\n rightType: string | null;\n runSchema: Generated<Json>;\n settingSchema: Generated<Json>;\n title: string;\n type: 'pull' | 'push' | null;\n uniqueRef: string;\n updatedAt: Generated<Timestamp>;\n useGlobalMapping: Generated<boolean>;\n}\n\nexport interface ControlPlaneIssueMessageOverwrite {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n message: string;\n pattern: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneLineClassification {\n appConflict: Generated<boolean>;\n appId: string | null;\n createdAt: Generated<Timestamp>;\n firstSeenAt: Timestamp;\n id: Generated<string>;\n kind: string;\n lastSeenAt: Timestamp;\n name: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneLineClassificationTeamUsage {\n classificationId: string;\n createdAt: Generated<Timestamp>;\n dataRegion: string;\n firstSeenAt: Timestamp;\n lastSeenAt: Timestamp;\n mappingStatus: string | null;\n revision: number;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneReservationLineDefault {\n accountKey: string | null;\n bookingChannel: string | null;\n bookingChannelKey: Generated<string>;\n classificationId: string;\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n partnerTenantId: string | null;\n revenueRecognition: string | null;\n revision: Generated<number>;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneRolloutMonitorSnapshot {\n monitorName: string;\n result: Json;\n snapshotDate: Timestamp;\n}\n\nexport interface ControlPlaneTransactionLineMapping {\n accountAssignmentType: string | null;\n createdAt: Generated<Timestamp>;\n deletedAt: Timestamp | null;\n id: Generated<string>;\n lineType: string;\n revision: Generated<number>;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneGeneralLedgerDefaultSet {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n partnerTenantId: string | null;\n publishedVersion: number | null;\n sourceDataRegion: string;\n sourceDigest: string | null;\n sourceTenantId: string;\n templateKey: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneGeneralLedgerDefaultVersion {\n dataJson: Json;\n defaultSetId: string;\n id: Generated<string>;\n publishedAt: Generated<Timestamp>;\n sourceDigest: string;\n sourceTenantId: string;\n version: number;\n}\n\nexport interface ControlPlaneOutbox {\n aggregateId: string;\n aggregateType: string;\n attempts: Generated<number>;\n createdAt: Generated<Timestamp>;\n dataRegion: string | null;\n eventType: string;\n eventVersion: number;\n id: Generated<string>;\n lastError: string | null;\n payload: Generated<Json>;\n publishedAt: Timestamp | null;\n}\n\nexport interface ControlPlanePartnerManagedTeamAssignment {\n createdAt: Generated<Timestamp>;\n managedTeamId: string;\n partnerTenantId: string;\n userId: string;\n}\n\nexport interface ControlPlaneOwnerPortal {\n hostname: string;\n tenantId: string;\n status: Generated<'pending' | 'active' | 'disabled'>;\n name: string;\n logo: string | null;\n colorPrimary: string;\n showPlatformBranding: Generated<boolean>;\n linksEnabled: Generated<boolean>;\n sender: { from: string; replyTo: string } | null;\n revision: Generated<number>;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneTenant {\n billingPartnerId: string | null;\n billingPlan: string | null;\n createdAt: Generated<Timestamp>;\n dataRegion: Generated<string>;\n id: Generated<string>;\n migrationStatus: Generated<string>;\n name: string;\n partnerId: string | null;\n partnerDeniedPermissions: Generated<string[]>;\n slug: string;\n status: Generated<string | null>;\n storageRealm: Generated<string>;\n type: Generated<string | null>;\n uniqueRef: string | null;\n updatedAt: Generated<Timestamp | null>;\n}\n\nexport interface ControlPlaneTenantRegionMigration {\n actor: string;\n completedAt: Timestamp | null;\n error: Json | null;\n id: string;\n reason: string;\n sourceManifest: Json | null;\n sourceRegion: string;\n startedAt: Generated<Timestamp>;\n status: Generated<string>;\n targetManifest: Json | null;\n targetRegion: string;\n tenantId: string;\n updatedAt: Generated<Timestamp>;\n}\n\nexport interface ControlPlaneTenantUser {\n createdAt: Generated<Timestamp | null>;\n id: Generated<string>;\n lastInvitedAt: Timestamp | null;\n managedTeamAccess: Generated<'all' | 'assigned'>;\n permissionBundles: Generated<string[]>;\n role: Generated<string | null>;\n status: Generated<string | null>;\n tenantId: string;\n updatedAt: Generated<Timestamp | null>;\n userId: string;\n}\n\nexport interface ControlPlaneToken {\n createdAt: Generated<Timestamp>;\n expiresAt: Timestamp | null;\n id: Generated<string>;\n nanoId: Generated<string>;\n payload: Generated<Json>;\n tenantId: string | null;\n type: string | null;\n userId: string | null;\n}\n\nexport interface ControlPlaneUser {\n clerkId: string | null;\n createdAt: Generated<Timestamp | null>;\n email: string | null;\n firstName: string | null;\n id: Generated<string>;\n internalOperationGrants: Generated<string[]>;\n isAdmin: Generated<boolean>;\n lastName: string | null;\n lastSeen: Timestamp | null;\n name: string | null;\n partnerId: string | null;\n phone: string | null;\n secondaryEmails: Generated<Json>;\n status: Generated<string | null>;\n sub: string | null;\n type: Generated<string | null>;\n updatedAt: Generated<Timestamp | null>;\n}\n\nexport interface ControlPlaneDB {\n 'controlPlane.accountingIntegrityDefinitionDraft': ControlPlaneAccountingIntegrityDefinitionDraft;\n 'controlPlane.accountingIntegrityDefinitionVersion': ControlPlaneAccountingIntegrityDefinitionVersion;\n 'controlPlane.accountingIntegrityEvaluation': ControlPlaneAccountingIntegrityEvaluation;\n 'controlPlane.app': ControlPlaneApp;\n 'controlPlane.bookingChannel': ControlPlaneBookingChannel;\n 'controlPlane.bookingChannelIconCandidate': ControlPlaneBookingChannelIconCandidate;\n 'controlPlane.connectionRoute': ControlPlaneConnectionRoute;\n 'controlPlane.controlPlaneOutbox': ControlPlaneOutbox;\n 'controlPlane.currency': ControlPlaneCurrency;\n 'controlPlane.destructiveJob': ControlPlaneDestructiveJob;\n 'controlPlane.destructiveJobAttempt': ControlPlaneDestructiveJobAttempt;\n 'controlPlane.destructiveJobOperation': ControlPlaneDestructiveJobOperation;\n 'controlPlane.events': ControlPlaneEvent;\n 'controlPlane.feature': ControlPlaneFeature;\n 'controlPlane.featureApproval': ControlPlaneFeatureApproval;\n 'controlPlane.featureEnabledTeam': ControlPlaneFeatureEnabledTeam;\n 'controlPlane.generalLedgerDefaultSet': ControlPlaneGeneralLedgerDefaultSet;\n 'controlPlane.generalLedgerDefaultVersion': ControlPlaneGeneralLedgerDefaultVersion;\n 'controlPlane.lineClassification': ControlPlaneLineClassification;\n 'controlPlane.lineClassificationTeamUsage': ControlPlaneLineClassificationTeamUsage;\n 'controlPlane.operation': ControlPlaneOperation;\n 'controlPlane.operationResource': ControlPlaneOperationResource;\n 'controlPlane.operationSource': ControlPlaneOperationSource;\n 'controlPlane.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;\n 'controlPlane.reservationLineDefault': ControlPlaneReservationLineDefault;\n 'controlPlane.rolloutMonitorSnapshot': ControlPlaneRolloutMonitorSnapshot;\n 'controlPlane.ownerPortal': ControlPlaneOwnerPortal;\n 'controlPlane.tenant': ControlPlaneTenant;\n 'controlPlane.tenantRegionMigration': ControlPlaneTenantRegionMigration;\n 'controlPlane.tenantUser': ControlPlaneTenantUser;\n 'controlPlane.trackingQueueFailure': ControlPlaneTrackingQueueFailure;\n 'controlPlane.token': ControlPlaneToken;\n 'controlPlane.transactionLineMapping': ControlPlaneTransactionLineMapping;\n 'controlPlane.user': ControlPlaneUser;\n 'controlPlaneCore.flow': ControlPlaneFlow;\n 'controlPlaneCore.issueMessageOverwrite': ControlPlaneIssueMessageOverwrite;\n}\n\nclass ControlPlaneSchemaTransformer extends OperationNodeTransformer {\n constructor(\n readonly schema: string,\n readonly issueMessageOverwriteSchema: string\n ) {\n super();\n }\n\n protected override transformSchemableIdentifier(\n node: SchemableIdentifierNode,\n queryId: QueryId\n ): SchemableIdentifierNode {\n const transformed = super.transformSchemableIdentifier(node, queryId);\n if (\n transformed.schema?.name === 'controlPlane' ||\n transformed.schema?.name === 'control_plane'\n ) {\n return { ...transformed, schema: IdentifierNode.create(this.schema) };\n }\n if (\n transformed.schema?.name === 'controlPlaneCore' ||\n transformed.schema?.name === 'control_plane_core'\n ) {\n return {\n ...transformed,\n schema: IdentifierNode.create(this.issueMessageOverwriteSchema),\n };\n }\n return transformed;\n }\n\n protected override transformFunction(\n node: FunctionNode,\n queryId: QueryId\n ): FunctionNode {\n const transformed = super.transformFunction(node, queryId);\n return node.func.startsWith('controlPlane.')\n ? {\n ...transformed,\n func: `${this.schema}.${transformed.func.slice('controlPlane.'.length)}`,\n }\n : transformed;\n }\n}\n\nclass ControlPlaneSchemaPlugin implements KyselyPlugin {\n readonly #transformer: ControlPlaneSchemaTransformer;\n\n constructor(schema: string, issueMessageOverwriteSchema: string) {\n this.#transformer = new ControlPlaneSchemaTransformer(\n schema,\n issueMessageOverwriteSchema\n );\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n return this.#transformer.transformNode(args.node, args.queryId);\n }\n\n async transformResult(\n args: PluginTransformResultArgs\n ): Promise<QueryResult<UnknownRow>> {\n return args.result;\n }\n}\n\nexport function withControlPlaneSchema(\n kysely: Kysely<ControlPlaneDB>,\n schema: string,\n issueMessageOverwriteSchema = 'core'\n) {\n return kysely.withPlugin(\n new ControlPlaneSchemaPlugin(schema, issueMessageOverwriteSchema)\n );\n}\n"]}
|
package/build/main/index.d.ts
CHANGED
|
@@ -8,22 +8,44 @@ export * from './postgres-error';
|
|
|
8
8
|
export * from './query';
|
|
9
9
|
export * from './regional';
|
|
10
10
|
export * from './transaction';
|
|
11
|
+
import type { TenantDataRegion } from './regional';
|
|
11
12
|
import type { DB } from './v1.generated';
|
|
13
|
+
/** The database a Worker reaches through its Hyperdrive binding. */
|
|
14
|
+
type HyperdriveDatabase = 'controlPlane' | 'regional';
|
|
12
15
|
type KyselyOpts = {
|
|
13
|
-
|
|
16
|
+
dataRegion?: TenantDataRegion;
|
|
17
|
+
hyperdrive?: HyperdriveDatabase;
|
|
18
|
+
onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;
|
|
14
19
|
repositoryName?: string;
|
|
15
20
|
log?: true | LogConfig;
|
|
16
21
|
};
|
|
22
|
+
type PostgresRetryDiagnostic = {
|
|
23
|
+
attemptCount: number;
|
|
24
|
+
dataRegion?: TenantDataRegion;
|
|
25
|
+
operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';
|
|
26
|
+
outcome: 'exhausted' | 'notRetryable' | 'retrying';
|
|
27
|
+
repositoryName?: string;
|
|
28
|
+
};
|
|
17
29
|
type PgOpt = {
|
|
18
30
|
forceDisableSSL?: boolean;
|
|
19
31
|
probe?: true;
|
|
20
32
|
retries?: false | number;
|
|
21
33
|
} & Pick<KyselyOpts, 'hyperdrive'>;
|
|
34
|
+
/**
|
|
35
|
+
* Replays a complete database operation after a PostgreSQL deadlock (40P01)
|
|
36
|
+
* or lock timeout (55P03), using the same three-attempt jittered budget as
|
|
37
|
+
* connection retries. The operation must own its transaction and must not
|
|
38
|
+
* contain external side effects such as partner API writes.
|
|
39
|
+
*/
|
|
40
|
+
export declare function retryPostgresLockFailure<T>(operation: () => Promise<T>): Promise<T>;
|
|
22
41
|
export type Kysely = K<DB>;
|
|
23
42
|
export type ControlPlaneKysely = K<ControlPlaneDB>;
|
|
24
43
|
export type ControlPlaneTransaction = T<ControlPlaneDB>;
|
|
25
44
|
export declare function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts): K<Database>;
|
|
45
|
+
export declare function usePostgres(connectionString: string, opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive'>): postgres.Sql<{}>;
|
|
26
46
|
export declare function useAsyncPostgres(connectionString: string, opt?: PgOpt): Promise<postgres.Sql<{}>>;
|
|
27
47
|
export declare function useAsyncKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<DB>>;
|
|
48
|
+
export declare function useAsyncNeonWebSocketKysely(connectionString: string, opt?: Pick<PgOpt, 'probe'> & KyselyOpts): Promise<K<DB>>;
|
|
49
|
+
export declare function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts): K<ControlPlaneDB>;
|
|
28
50
|
export declare function useAsyncControlPlaneKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<ControlPlaneDB>>;
|
|
29
51
|
export declare function forceCloseAllPostgres(timeoutMs?: number): Promise<void>;
|
package/build/main/index.js
CHANGED
|
@@ -17,17 +17,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.retryPostgresLockFailure = retryPostgresLockFailure;
|
|
20
21
|
exports.useKysely = useKysely;
|
|
22
|
+
exports.usePostgres = usePostgres;
|
|
21
23
|
exports.useAsyncPostgres = useAsyncPostgres;
|
|
22
24
|
exports.useAsyncKysely = useAsyncKysely;
|
|
25
|
+
exports.useAsyncNeonWebSocketKysely = useAsyncNeonWebSocketKysely;
|
|
26
|
+
exports.useControlPlaneKysely = useControlPlaneKysely;
|
|
23
27
|
exports.useAsyncControlPlaneKysely = useAsyncControlPlaneKysely;
|
|
24
28
|
exports.forceCloseAllPostgres = forceCloseAllPostgres;
|
|
25
29
|
const exponential_backoff_1 = require("exponential-backoff");
|
|
30
|
+
const serverless_1 = require("@neondatabase/serverless");
|
|
31
|
+
const kysely_1 = require("kysely");
|
|
26
32
|
const kysely_postgres_js_1 = require("kysely-postgres-js");
|
|
27
33
|
const postgres_1 = __importDefault(require("postgres"));
|
|
28
34
|
const control_plane_1 = require("./control-plane");
|
|
29
35
|
const error_1 = require("./error");
|
|
30
36
|
const plugins_1 = require("./plugins");
|
|
37
|
+
const postgres_error_1 = require("./postgres-error");
|
|
31
38
|
__exportStar(require("./error"), exports);
|
|
32
39
|
__exportStar(require("./isomorphic"), exports);
|
|
33
40
|
__exportStar(require("./postgres-error"), exports);
|
|
@@ -40,24 +47,115 @@ const retryableMessages = [
|
|
|
40
47
|
'CONNECT_TIMEOUT',
|
|
41
48
|
'Idle connection closed by Hyperdrive.',
|
|
42
49
|
'server_login_retry',
|
|
50
|
+
'Timed out while creating a new server connection.',
|
|
43
51
|
];
|
|
44
52
|
const postgresRetryAttempts = 3;
|
|
53
|
+
/**
|
|
54
|
+
* Parameter types PostgreSQL described per statement signature (PRO-18871).
|
|
55
|
+
* Postgres.js describes a statement in a round trip of its own before it can
|
|
56
|
+
* execute it when a parameter type is unknown, and a Worker request always
|
|
57
|
+
* starts on new connections. The patched driver reads and fills this map
|
|
58
|
+
* through its `statement_types` option and then parses, describes, binds and
|
|
59
|
+
* executes a known statement in one round trip. It forgets a statement's
|
|
60
|
+
* types when the statement fails, so a schema change is described again.
|
|
61
|
+
*/
|
|
62
|
+
class StatementTypes extends Map {
|
|
63
|
+
set(signature, types) {
|
|
64
|
+
if (!this.has(signature) && this.size >= 2000) {
|
|
65
|
+
this.delete(this.keys().next().value);
|
|
66
|
+
}
|
|
67
|
+
return super.set(signature, types);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Kept for the isolate's lifetime, one map per Hyperdrive database. */
|
|
71
|
+
const hyperdriveStatementTypes = {
|
|
72
|
+
controlPlane: new StatementTypes(),
|
|
73
|
+
regional: new StatementTypes(),
|
|
74
|
+
};
|
|
45
75
|
function isRetryableConnectionError(error) {
|
|
46
76
|
const message = error instanceof Error ? error.message : String(error);
|
|
47
77
|
return retryableMessages.some((retryable) => message.includes(retryable));
|
|
48
78
|
}
|
|
49
|
-
function
|
|
50
|
-
return (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
79
|
+
function isConnectionReset(error) {
|
|
80
|
+
return (error instanceof Error && 'code' in error && error.code === 'ECONNRESET');
|
|
81
|
+
}
|
|
82
|
+
function isRetryableConnectionAcquisitionError(error) {
|
|
83
|
+
return (isRetryableConnectionError(error) ||
|
|
84
|
+
isConnectionReset(error) ||
|
|
85
|
+
(error instanceof Error &&
|
|
86
|
+
(error.message === 'connection attempt failed' ||
|
|
87
|
+
('code' in error && error.code === 'CONNECTION_DESTROYED'))));
|
|
88
|
+
}
|
|
89
|
+
function isQueryRetryDiagnosticError(error) {
|
|
90
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
91
|
+
return (isRetryableConnectionError(error) ||
|
|
92
|
+
isConnectionReset(error) ||
|
|
93
|
+
message === 'Egress connection severed outside of Hyperdrive' ||
|
|
94
|
+
message === 'Network connection lost.' ||
|
|
95
|
+
message === 'Node shutting down' ||
|
|
96
|
+
message === 'Node shutting down.' ||
|
|
97
|
+
message === 'shutting down');
|
|
98
|
+
}
|
|
99
|
+
async function retryPostgres(operation, retry, diagnostic) {
|
|
100
|
+
let attemptCount = 0;
|
|
101
|
+
let retried = false;
|
|
102
|
+
const emitDiagnostic = (outcome) => {
|
|
103
|
+
if (!diagnostic)
|
|
104
|
+
return;
|
|
105
|
+
diagnostic.emit({
|
|
106
|
+
attemptCount,
|
|
107
|
+
dataRegion: diagnostic.dataRegion,
|
|
108
|
+
operationKind: diagnostic.operationKind,
|
|
109
|
+
outcome,
|
|
110
|
+
repositoryName: diagnostic.repositoryName,
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
return await (0, exponential_backoff_1.backOff)(async () => {
|
|
115
|
+
attemptCount++;
|
|
116
|
+
return await operation();
|
|
117
|
+
}, {
|
|
118
|
+
numOfAttempts: postgresRetryAttempts,
|
|
119
|
+
startingDelay: (0, utils_1.parseDuration)('1s'),
|
|
120
|
+
maxDelay: (0, utils_1.parseDuration)('5s'),
|
|
121
|
+
// Scheduled chunk fan-outs open many connections at once; full jitter
|
|
122
|
+
// keeps their retries from reconnecting in lockstep.
|
|
123
|
+
jitter: 'full',
|
|
124
|
+
async retry(error, attemptNumber) {
|
|
125
|
+
const shouldRetry = attemptNumber < postgresRetryAttempts &&
|
|
126
|
+
(await retry(error, attemptNumber));
|
|
127
|
+
if (shouldRetry && diagnostic) {
|
|
128
|
+
retried = true;
|
|
129
|
+
emitDiagnostic('retrying');
|
|
130
|
+
}
|
|
131
|
+
return shouldRetry;
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (diagnostic?.shouldEmit(error)) {
|
|
137
|
+
emitDiagnostic(retried && attemptCount === postgresRetryAttempts
|
|
138
|
+
? 'exhausted'
|
|
139
|
+
: 'notRetryable');
|
|
140
|
+
}
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Replays a complete database operation after a PostgreSQL deadlock (40P01)
|
|
146
|
+
* or lock timeout (55P03), using the same three-attempt jittered budget as
|
|
147
|
+
* connection retries. The operation must own its transaction and must not
|
|
148
|
+
* contain external side effects such as partner API writes.
|
|
149
|
+
*/
|
|
150
|
+
function retryPostgresLockFailure(operation) {
|
|
151
|
+
return retryPostgres(operation, (error) => (0, postgres_error_1.isPostgresError)(error, { code: '40P01' }) ||
|
|
152
|
+
(0, postgres_error_1.isPostgresError)(error, { code: '55P03' }));
|
|
56
153
|
}
|
|
57
154
|
class RetryingPostgresJSDialect extends kysely_postgres_js_1.PostgresJSDialect {
|
|
58
|
-
constructor(config) {
|
|
155
|
+
constructor(config, retryDiagnostic) {
|
|
59
156
|
super(config);
|
|
60
157
|
this.config = config;
|
|
158
|
+
this.retryDiagnostic = retryDiagnostic;
|
|
61
159
|
}
|
|
62
160
|
createDriver() {
|
|
63
161
|
const driver = new kysely_postgres_js_1.PostgresJSDriver(this.config);
|
|
@@ -76,21 +174,38 @@ class RetryingPostgresJSDialect extends kysely_postgres_js_1.PostgresJSDialect {
|
|
|
76
174
|
inTransaction: false,
|
|
77
175
|
};
|
|
78
176
|
const connection = {
|
|
79
|
-
executeQuery: (compiledQuery) =>
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
177
|
+
executeQuery: (compiledQuery) => {
|
|
178
|
+
const operationKind = state.inTransaction
|
|
179
|
+
? 'transaction'
|
|
180
|
+
: compiledQuery.query.kind === 'SelectQueryNode'
|
|
181
|
+
? 'select'
|
|
182
|
+
: 'mutation';
|
|
183
|
+
return retryPostgres(() => state.connection.executeQuery(compiledQuery), async (error) => {
|
|
184
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
185
|
+
if (state.inTransaction ||
|
|
186
|
+
(!isRetryableConnectionError(error) &&
|
|
187
|
+
(compiledQuery.query.kind !== 'SelectQueryNode' ||
|
|
188
|
+
(!isConnectionReset(error) &&
|
|
189
|
+
message !==
|
|
190
|
+
'Egress connection severed outside of Hyperdrive' &&
|
|
191
|
+
message !== 'Network connection lost.' &&
|
|
192
|
+
message !== 'Node shutting down' &&
|
|
193
|
+
message !== 'Node shutting down.' &&
|
|
194
|
+
message !== 'shutting down')))) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
// Postgres.js already ejects a severed reserved connection.
|
|
198
|
+
// Acquire a new reservation before replaying the safe read.
|
|
199
|
+
state.connection = await driver.acquireConnection();
|
|
200
|
+
return true;
|
|
201
|
+
}, this.retryDiagnostic
|
|
202
|
+
? {
|
|
203
|
+
...this.retryDiagnostic,
|
|
204
|
+
operationKind,
|
|
205
|
+
shouldEmit: isQueryRetryDiagnosticError,
|
|
206
|
+
}
|
|
207
|
+
: undefined);
|
|
208
|
+
},
|
|
94
209
|
streamQuery: (compiledQuery, chunkSize) => {
|
|
95
210
|
if (chunkSize === undefined) {
|
|
96
211
|
throw new Error('Postgres stream chunk size is required');
|
|
@@ -143,16 +258,35 @@ class RetryingPostgresJSDialect extends kysely_postgres_js_1.PostgresJSDialect {
|
|
|
143
258
|
}
|
|
144
259
|
function useKysely(postgres, options) {
|
|
145
260
|
console.debug('Creating Kysely instance');
|
|
261
|
+
const emitRetryDiagnostic = options?.onRetryDiagnostic ??
|
|
262
|
+
(options?.repositoryName
|
|
263
|
+
? (diagnostic) => console.warn('Postgres operation retry diagnostic', diagnostic)
|
|
264
|
+
: undefined);
|
|
146
265
|
const reserveConnection = postgres.reserve.bind(postgres);
|
|
147
266
|
postgres.reserve = async () => {
|
|
148
|
-
const connection = await retryPostgres(reserveConnection,
|
|
267
|
+
const connection = await retryPostgres(reserveConnection, isRetryableConnectionAcquisitionError, emitRetryDiagnostic
|
|
268
|
+
? {
|
|
269
|
+
dataRegion: options?.dataRegion,
|
|
270
|
+
emit: emitRetryDiagnostic,
|
|
271
|
+
operationKind: 'acquisition',
|
|
272
|
+
repositoryName: options?.repositoryName,
|
|
273
|
+
shouldEmit: isRetryableConnectionAcquisitionError,
|
|
274
|
+
}
|
|
275
|
+
: undefined);
|
|
149
276
|
if (options?.hyperdrive) {
|
|
150
277
|
const unsafe = connection.unsafe;
|
|
151
278
|
connection.unsafe = (query, parameters, queryOptions) => unsafe(query, parameters, { ...queryOptions, prepare: true });
|
|
152
279
|
}
|
|
153
280
|
return connection;
|
|
154
281
|
};
|
|
155
|
-
const kysely = (0, plugins_1.getKysely)(new RetryingPostgresJSDialect({ postgres }
|
|
282
|
+
const kysely = (0, plugins_1.getKysely)(new RetryingPostgresJSDialect({ postgres }, emitRetryDiagnostic
|
|
283
|
+
? {
|
|
284
|
+
dataRegion: options?.dataRegion,
|
|
285
|
+
emit: emitRetryDiagnostic,
|
|
286
|
+
repositoryName: options?.repositoryName,
|
|
287
|
+
shouldEmit: isQueryRetryDiagnosticError,
|
|
288
|
+
}
|
|
289
|
+
: undefined), {
|
|
156
290
|
repositoryName: options?.repositoryName,
|
|
157
291
|
log: options?.log,
|
|
158
292
|
});
|
|
@@ -166,43 +300,55 @@ function useKysely(postgres, options) {
|
|
|
166
300
|
return kysely;
|
|
167
301
|
}
|
|
168
302
|
let _connections = [];
|
|
303
|
+
function usePostgres(connectionString, opt) {
|
|
304
|
+
const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;
|
|
305
|
+
const sql = (0, postgres_1.default)(connectionString, {
|
|
306
|
+
ssl: ssl ? 'require' : false,
|
|
307
|
+
target_session_attrs: 'read-write',
|
|
308
|
+
// Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).
|
|
309
|
+
prepare: true,
|
|
310
|
+
...(opt?.hyperdrive
|
|
311
|
+
? {
|
|
312
|
+
max: 5,
|
|
313
|
+
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
314
|
+
idle_timeout: 10,
|
|
315
|
+
statement_types: hyperdriveStatementTypes[opt.hyperdrive],
|
|
316
|
+
}
|
|
317
|
+
: {
|
|
318
|
+
connect_timeout: 10,
|
|
319
|
+
idle_timeout: 60,
|
|
320
|
+
}),
|
|
321
|
+
});
|
|
322
|
+
// statement_timeout/lock_timeout are role-level settings on the cluster
|
|
323
|
+
// (ALTER ROLE application SET ...) so they cover every pooled
|
|
324
|
+
// connection; per-session SETs here only ever applied to one of them
|
|
325
|
+
_connections.push(sql);
|
|
326
|
+
return sql;
|
|
327
|
+
}
|
|
169
328
|
async function useAsyncPostgres(connectionString, opt) {
|
|
170
329
|
const delayMs = 2500;
|
|
171
330
|
const probe = opt?.probe === true;
|
|
172
331
|
const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;
|
|
173
|
-
const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
|
|
174
332
|
const url = new URL(connectionString);
|
|
175
|
-
console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${
|
|
333
|
+
console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && !opt?.hyperdrive}, and port=${url.port}`);
|
|
176
334
|
if (_connections.length > 0)
|
|
177
335
|
console.warn(`We already have ${_connections.length} Postgres connections`);
|
|
178
336
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
337
|
+
let sql;
|
|
179
338
|
try {
|
|
180
|
-
|
|
181
|
-
ssl: ssl ? 'require' : false,
|
|
182
|
-
target_session_attrs: 'read-write',
|
|
183
|
-
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
184
|
-
prepare: true,
|
|
185
|
-
...(opt?.hyperdrive
|
|
186
|
-
? {
|
|
187
|
-
max: 5,
|
|
188
|
-
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
189
|
-
idle_timeout: 10,
|
|
190
|
-
}
|
|
191
|
-
: {
|
|
192
|
-
connect_timeout: 10,
|
|
193
|
-
idle_timeout: 60,
|
|
194
|
-
}),
|
|
195
|
-
});
|
|
339
|
+
sql = usePostgres(connectionString, opt);
|
|
196
340
|
if (probe) {
|
|
197
|
-
|
|
341
|
+
// Opening a connection already checks that the session is writable
|
|
342
|
+
// and loads the array types; a probe query would add a round trip.
|
|
343
|
+
(await sql.reserve()).release();
|
|
198
344
|
}
|
|
199
|
-
// statement_timeout/lock_timeout are role-level settings on the cluster
|
|
200
|
-
// (ALTER ROLE application SET ...) so they cover every pooled
|
|
201
|
-
// connection; per-session SETs here only ever applied to one of them
|
|
202
|
-
_connections.push(sql);
|
|
203
345
|
return sql;
|
|
204
346
|
}
|
|
205
347
|
catch (err) {
|
|
348
|
+
if (sql) {
|
|
349
|
+
await sql.end({ timeout: 0 }).catch(() => undefined);
|
|
350
|
+
_connections.splice(_connections.indexOf(sql), 1);
|
|
351
|
+
}
|
|
206
352
|
if (attempt === retries)
|
|
207
353
|
throw err;
|
|
208
354
|
console.warn(`Postgres connection failed (attempt ${attempt}), retrying...`);
|
|
@@ -216,9 +362,22 @@ async function useAsyncKysely(connectionString, opt) {
|
|
|
216
362
|
const sql = await useAsyncPostgres(connectionString, opt);
|
|
217
363
|
return useKysely(sql, opt);
|
|
218
364
|
}
|
|
365
|
+
async function useAsyncNeonWebSocketKysely(connectionString, opt) {
|
|
366
|
+
const pool = new serverless_1.Pool({ connectionString, max: 5 });
|
|
367
|
+
const kysely = (0, plugins_1.getKysely)(new kysely_1.PostgresDialect({ pool }), opt ?? {});
|
|
368
|
+
kysely.destroy = async () => {
|
|
369
|
+
console.debug('Closing Neon WebSocket Kysely connection');
|
|
370
|
+
await pool.end();
|
|
371
|
+
};
|
|
372
|
+
if (opt?.probe)
|
|
373
|
+
await pool.query('select 1');
|
|
374
|
+
return kysely;
|
|
375
|
+
}
|
|
376
|
+
function useControlPlaneKysely(postgres, options) {
|
|
377
|
+
return (0, control_plane_1.withControlPlaneSchema)(useKysely(postgres, options), 'public');
|
|
378
|
+
}
|
|
219
379
|
async function useAsyncControlPlaneKysely(connectionString, opt) {
|
|
220
|
-
|
|
221
|
-
return (0, control_plane_1.withControlPlaneSchema)(useKysely(sql, opt), 'public');
|
|
380
|
+
return useControlPlaneKysely(await useAsyncPostgres(connectionString, opt), opt);
|
|
222
381
|
}
|
|
223
382
|
async function forceCloseAllPostgres(timeoutMs = 5000) {
|
|
224
383
|
await Promise.race([
|