@vrplatform/kysely 1.3.45-stage.11 → 1.3.45-stage.1101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/build/.data.tar +2 -2
  2. package/build/main/control-plane/index.d.ts +28 -6
  3. package/build/main/control-plane/index.js.map +1 -1
  4. package/build/main/index.d.ts +20 -0
  5. package/build/main/index.js +183 -49
  6. package/build/main/index.js.map +1 -1
  7. package/build/main/local/index.js +115 -8
  8. package/build/main/local/index.js.map +1 -1
  9. package/build/main/postgres-error.d.ts +3 -3
  10. package/build/main/postgres-error.js +4 -3
  11. package/build/main/postgres-error.js.map +1 -1
  12. package/build/main/query/tenant/status.d.ts +1 -1
  13. package/build/main/query/tenant/status.js +5 -2
  14. package/build/main/query/tenant/status.js.map +1 -1
  15. package/build/main/regional.d.ts +1 -0
  16. package/build/main/regional.js +1 -0
  17. package/build/main/regional.js.map +1 -1
  18. package/build/main/test/index.d.ts +25 -2
  19. package/build/main/test/index.js +40 -8
  20. package/build/main/test/index.js.map +1 -1
  21. package/build/main/v1.generated.d.ts +193 -19
  22. package/build/main/v1.generated.js.map +1 -1
  23. package/build/migrations-v2/0000000000031-ui-permission-role-simplification.ts +70 -0
  24. package/build/migrations-v2/0000000000032-tenant-delete-ownership-cascades.ts +44 -0
  25. package/build/migrations-v2/0000000000033-plaid-connect-session-telemetry.ts +31 -0
  26. package/build/migrations-v2/0000000000033-reservation-issue-seed-bucket-index.ts +19 -0
  27. package/build/migrations-v2/0000000000034-retire-recent-classification-indexes.ts +29 -0
  28. package/build/migrations-v2/0000000000035-core-change-autovacuum.ts +24 -0
  29. package/build/migrations-v2/0000000000036-journal-entry-inactive-reason-constraint.ts +33 -0
  30. package/build/migrations-v2/0000000000037-journal-entry-inactive-reasons.ts +19 -0
  31. package/build/migrations-v2/0000000000038-journal-entry-group-inactive-reason.ts +14 -0
  32. package/build/migrations-v2/0000000000039-reservation-guest-breakdown.ts +19 -0
  33. package/build/migrations-v2/0000000000040-csv-import-source-identity-index.ts +23 -0
  34. package/build/migrations-v2/0000000000041-payment-returns.ts +38 -0
  35. package/build/migrations-v2/0000000000042-operation-resource-types.ts +609 -0
  36. package/build/migrations-v2/0000000000043-reservation-journal-freshness.ts +149 -0
  37. package/build/migrations-v2/0000000000044-reservation-journal-freshness-backfill.ts +254 -0
  38. package/build/migrations-v2/0000000000045-reservation-journal-freshness-revision-repair.ts +83 -0
  39. package/build/migrations-v2/0000000000046-materialized-reservation-journal-operations.ts +709 -0
  40. package/build/migrations-v2/0000000000047-public-audit-completion.ts +77 -0
  41. package/build/migrations-v2/0000000000048-reservation-journal-full-refresh-repair.ts +136 -0
  42. package/build/migrations-v2/0000000000049-queued-journal-operation-failures.ts +60 -0
  43. package/build/migrations-v2/0000000000050-connection-oauth-state.ts +43 -0
  44. package/build/migrations-v2/0000000000051-owner-statement-email-delivery.ts +134 -0
  45. package/build/migrations-v2/0000000000052-fee-journal-lock-skip-operations.ts +59 -0
  46. package/build/migrations-v2/0000000000053-fee-journal-lock-skip-null-attempt.ts +44 -0
  47. package/build/migrations-v2/0000000000054-journal-refresh-issue-codes.ts +16 -0
  48. package/build/migrations-v2/0000000000055-tenant-billing-subscription.ts +8 -0
  49. package/build/migrations-v2/0000000000056-journal-operation-failure-precedence.ts +306 -0
  50. package/build/migrations-v2/0000000000057-journal-invalidation-failure-code.ts +28 -0
  51. package/build/migrations-v2/0000000000058-journal-invalidation-locked-failure.ts +16 -0
  52. package/build/migrations-v2/0000000000059-billing-active-listing-cross-region-partner.ts +135 -0
  53. package/build/migrations-v2/0000000000060-accounting-integrity-change-driven.ts +99 -0
  54. package/build/migrations-v2/0000000000061-tenant-pending-onboarding-status.ts +37 -0
  55. package/build/migrations-v2/0000000000062-statement-payout-operations.ts +16 -0
  56. package/build/migrations-v2/0000000000063-missing-account-assignments-issue-code.ts +13 -0
  57. package/build/module/control-plane/index.d.ts +28 -6
  58. package/build/module/control-plane/index.js.map +1 -1
  59. package/build/module/index.d.ts +20 -0
  60. package/build/module/index.js +180 -49
  61. package/build/module/index.js.map +1 -1
  62. package/build/module/local/index.js +115 -8
  63. package/build/module/local/index.js.map +1 -1
  64. package/build/module/postgres-error.d.ts +3 -3
  65. package/build/module/postgres-error.js +4 -3
  66. package/build/module/postgres-error.js.map +1 -1
  67. package/build/module/query/tenant/status.d.ts +1 -1
  68. package/build/module/query/tenant/status.js +5 -2
  69. package/build/module/query/tenant/status.js.map +1 -1
  70. package/build/module/regional.d.ts +1 -0
  71. package/build/module/regional.js +1 -0
  72. package/build/module/regional.js.map +1 -1
  73. package/build/module/test/index.d.ts +25 -2
  74. package/build/module/test/index.js +39 -8
  75. package/build/module/test/index.js.map +1 -1
  76. package/build/module/v1.generated.d.ts +193 -19
  77. package/build/module/v1.generated.js.map +1 -1
  78. package/package.json +9 -7
@@ -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<'completed' | 'failed' | 'queued' | 'running'>;
173
- type: string;
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: string;
182
- role: 'result' | 'source' | 'target';
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: 'destructive-job' | 'regional-operation';
194
+ sourceType: ControlPlaneOperationSourceType;
190
195
  sourceVersion: Generated<number>;
191
196
  startedAt: Timestamp | null;
192
- status: Generated<'completed' | 'failed' | 'queued' | 'running'>;
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":"AAAA,OAAO,EAGL,cAAc,EAGd,wBAAwB,GAQzB,MAAM,QAAQ,CAAC;AA+hBhB,MAAM,6BAA8B,SAAQ,wBAAwB;IAEvD;IACA;IAFX,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,cAAc,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,cAAc,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;IACnB,YAAY,CAAgC;IAErD,YAAY,MAAc,EAAE,2BAAmC;QAC7D,IAAI,CAAC,YAAY,GAAG,IAAI,6BAA6B,CACnD,MAAM,EACN,2BAA2B,CAC5B,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,IAA8B;QAC3C,OAAO,IAAI,CAAC,YAAY,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,MAAM,UAAU,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":"AAAA,OAAO,EAGL,cAAc,EAGd,wBAAwB,GAQzB,MAAM,QAAQ,CAAC;AA2mBhB,MAAM,6BAA8B,SAAQ,wBAAwB;IAEvD;IACA;IAFX,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,cAAc,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,cAAc,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;IACnB,YAAY,CAAgC;IAErD,YAAY,MAAc,EAAE,2BAAmC;QAC7D,IAAI,CAAC,YAAY,GAAG,IAAI,6BAA6B,CACnD,MAAM,EACN,2BAA2B,CAC5B,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,IAA8B;QAC3C,OAAO,IAAI,CAAC,YAAY,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,MAAM,UAAU,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"]}
@@ -8,22 +8,42 @@ 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';
12
13
  type KyselyOpts = {
14
+ dataRegion?: TenantDataRegion;
13
15
  hyperdrive?: true;
16
+ onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;
14
17
  repositoryName?: string;
15
18
  log?: true | LogConfig;
16
19
  };
20
+ type PostgresRetryDiagnostic = {
21
+ attemptCount: number;
22
+ dataRegion?: TenantDataRegion;
23
+ operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';
24
+ outcome: 'exhausted' | 'notRetryable' | 'retrying';
25
+ repositoryName?: string;
26
+ };
17
27
  type PgOpt = {
18
28
  forceDisableSSL?: boolean;
19
29
  probe?: true;
20
30
  retries?: false | number;
21
31
  } & Pick<KyselyOpts, 'hyperdrive'>;
32
+ /**
33
+ * Replays a complete database operation after a PostgreSQL deadlock (40P01)
34
+ * or lock timeout (55P03), using the same three-attempt jittered budget as
35
+ * connection retries. The operation must own its transaction and must not
36
+ * contain external side effects such as partner API writes.
37
+ */
38
+ export declare function retryPostgresLockFailure<T>(operation: () => Promise<T>): Promise<T>;
22
39
  export type Kysely = K<DB>;
23
40
  export type ControlPlaneKysely = K<ControlPlaneDB>;
24
41
  export type ControlPlaneTransaction = T<ControlPlaneDB>;
25
42
  export declare function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts): K<Database>;
43
+ export declare function usePostgres(connectionString: string, opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive'>): postgres.Sql<{}>;
26
44
  export declare function useAsyncPostgres(connectionString: string, opt?: PgOpt): Promise<postgres.Sql<{}>>;
27
45
  export declare function useAsyncKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<DB>>;
46
+ export declare function useAsyncNeonWebSocketKysely(connectionString: string, opt?: Pick<PgOpt, 'probe'> & KyselyOpts): Promise<K<DB>>;
47
+ export declare function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts): K<ControlPlaneDB>;
28
48
  export declare function useAsyncControlPlaneKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<ControlPlaneDB>>;
29
49
  export declare function forceCloseAllPostgres(timeoutMs?: number): Promise<void>;
@@ -1,9 +1,12 @@
1
1
  import { backOff } from 'exponential-backoff';
2
+ import { Pool } from '@neondatabase/serverless';
3
+ import { PostgresDialect } from 'kysely';
2
4
  import { PostgresJSDialect, PostgresJSDriver, } from 'kysely-postgres-js';
3
5
  import postgres from 'postgres';
4
6
  import { withControlPlaneSchema } from './control-plane';
5
7
  import { KyselyError } from './error';
6
8
  import { getKysely } from './plugins';
9
+ import { isPostgresError } from './postgres-error';
7
10
  export * from './error';
8
11
  export * from './isomorphic';
9
12
  export * from './postgres-error';
@@ -16,25 +19,95 @@ const retryableMessages = [
16
19
  'CONNECT_TIMEOUT',
17
20
  'Idle connection closed by Hyperdrive.',
18
21
  'server_login_retry',
22
+ 'Timed out while creating a new server connection.',
19
23
  ];
20
24
  const postgresRetryAttempts = 3;
21
25
  function isRetryableConnectionError(error) {
22
26
  const message = error instanceof Error ? error.message : String(error);
23
27
  return retryableMessages.some((retryable) => message.includes(retryable));
24
28
  }
25
- function retryPostgres(operation, retry) {
26
- return backOff(operation, {
27
- numOfAttempts: postgresRetryAttempts,
28
- startingDelay: parseDuration('1s'),
29
- maxDelay: parseDuration('5s'),
30
- retry: (error, attemptNumber) => attemptNumber < postgresRetryAttempts && retry(error, attemptNumber),
31
- });
29
+ function isConnectionReset(error) {
30
+ return (error instanceof Error && 'code' in error && error.code === 'ECONNRESET');
31
+ }
32
+ function isRetryableConnectionAcquisitionError(error) {
33
+ return (isRetryableConnectionError(error) ||
34
+ isConnectionReset(error) ||
35
+ (error instanceof Error &&
36
+ (error.message === 'connection attempt failed' ||
37
+ ('code' in error && error.code === 'CONNECTION_DESTROYED'))));
38
+ }
39
+ function isQueryRetryDiagnosticError(error) {
40
+ const message = error instanceof Error ? error.message : String(error);
41
+ return (isRetryableConnectionError(error) ||
42
+ isConnectionReset(error) ||
43
+ message === 'Egress connection severed outside of Hyperdrive' ||
44
+ message === 'Network connection lost.' ||
45
+ message === 'Node shutting down' ||
46
+ message === 'Node shutting down.' ||
47
+ message === 'shutting down');
48
+ }
49
+ async function retryPostgres(operation, retry, diagnostic) {
50
+ let attemptCount = 0;
51
+ let retried = false;
52
+ const emitDiagnostic = (outcome) => {
53
+ if (!diagnostic)
54
+ return;
55
+ diagnostic.emit({
56
+ attemptCount,
57
+ dataRegion: diagnostic.dataRegion,
58
+ operationKind: diagnostic.operationKind,
59
+ outcome,
60
+ repositoryName: diagnostic.repositoryName,
61
+ });
62
+ };
63
+ try {
64
+ return await backOff(async () => {
65
+ attemptCount++;
66
+ return await operation();
67
+ }, {
68
+ numOfAttempts: postgresRetryAttempts,
69
+ startingDelay: parseDuration('1s'),
70
+ maxDelay: parseDuration('5s'),
71
+ // Scheduled chunk fan-outs open many connections at once; full jitter
72
+ // keeps their retries from reconnecting in lockstep.
73
+ jitter: 'full',
74
+ async retry(error, attemptNumber) {
75
+ const shouldRetry = attemptNumber < postgresRetryAttempts &&
76
+ (await retry(error, attemptNumber));
77
+ if (shouldRetry && diagnostic) {
78
+ retried = true;
79
+ emitDiagnostic('retrying');
80
+ }
81
+ return shouldRetry;
82
+ },
83
+ });
84
+ }
85
+ catch (error) {
86
+ if (diagnostic?.shouldEmit(error)) {
87
+ emitDiagnostic(retried && attemptCount === postgresRetryAttempts
88
+ ? 'exhausted'
89
+ : 'notRetryable');
90
+ }
91
+ throw error;
92
+ }
93
+ }
94
+ /**
95
+ * Replays a complete database operation after a PostgreSQL deadlock (40P01)
96
+ * or lock timeout (55P03), using the same three-attempt jittered budget as
97
+ * connection retries. The operation must own its transaction and must not
98
+ * contain external side effects such as partner API writes.
99
+ */
100
+ export function retryPostgresLockFailure(operation) {
101
+ return retryPostgres(operation, (error) => isPostgresError(error, { code: '40P01' }) ||
102
+ isPostgresError(error, { code: '55P03' }));
32
103
  }
33
104
  class RetryingPostgresJSDialect extends PostgresJSDialect {
34
105
  config;
35
- constructor(config) {
106
+ retryDiagnostic;
107
+ constructor(config, retryDiagnostic) {
36
108
  super(config);
37
109
  this.config = config;
110
+ this.retryDiagnostic = retryDiagnostic;
38
111
  }
39
112
  createDriver() {
40
113
  const driver = new PostgresJSDriver(this.config);
@@ -53,21 +126,38 @@ class RetryingPostgresJSDialect extends PostgresJSDialect {
53
126
  inTransaction: false,
54
127
  };
55
128
  const connection = {
56
- executeQuery: (compiledQuery) => retryPostgres(() => state.connection.executeQuery(compiledQuery), async (error) => {
57
- const message = error instanceof Error ? error.message : String(error);
58
- if (state.inTransaction ||
59
- (!isRetryableConnectionError(error) &&
60
- (compiledQuery.query.kind !== 'SelectQueryNode' ||
61
- (message !==
62
- 'Egress connection severed outside of Hyperdrive' &&
63
- message !== 'Network connection lost.')))) {
64
- return false;
65
- }
66
- // Postgres.js already ejects a severed reserved connection.
67
- // Acquire a new reservation before replaying the safe read.
68
- state.connection = await driver.acquireConnection();
69
- return true;
70
- }),
129
+ executeQuery: (compiledQuery) => {
130
+ const operationKind = state.inTransaction
131
+ ? 'transaction'
132
+ : compiledQuery.query.kind === 'SelectQueryNode'
133
+ ? 'select'
134
+ : 'mutation';
135
+ return retryPostgres(() => state.connection.executeQuery(compiledQuery), async (error) => {
136
+ const message = error instanceof Error ? error.message : String(error);
137
+ if (state.inTransaction ||
138
+ (!isRetryableConnectionError(error) &&
139
+ (compiledQuery.query.kind !== 'SelectQueryNode' ||
140
+ (!isConnectionReset(error) &&
141
+ message !==
142
+ 'Egress connection severed outside of Hyperdrive' &&
143
+ message !== 'Network connection lost.' &&
144
+ message !== 'Node shutting down' &&
145
+ message !== 'Node shutting down.' &&
146
+ message !== 'shutting down')))) {
147
+ return false;
148
+ }
149
+ // Postgres.js already ejects a severed reserved connection.
150
+ // Acquire a new reservation before replaying the safe read.
151
+ state.connection = await driver.acquireConnection();
152
+ return true;
153
+ }, this.retryDiagnostic
154
+ ? {
155
+ ...this.retryDiagnostic,
156
+ operationKind,
157
+ shouldEmit: isQueryRetryDiagnosticError,
158
+ }
159
+ : undefined);
160
+ },
71
161
  streamQuery: (compiledQuery, chunkSize) => {
72
162
  if (chunkSize === undefined) {
73
163
  throw new Error('Postgres stream chunk size is required');
@@ -120,16 +210,35 @@ class RetryingPostgresJSDialect extends PostgresJSDialect {
120
210
  }
121
211
  export function useKysely(postgres, options) {
122
212
  console.debug('Creating Kysely instance');
213
+ const emitRetryDiagnostic = options?.onRetryDiagnostic ??
214
+ (options?.repositoryName
215
+ ? (diagnostic) => console.warn('Postgres operation retry diagnostic', diagnostic)
216
+ : undefined);
123
217
  const reserveConnection = postgres.reserve.bind(postgres);
124
218
  postgres.reserve = async () => {
125
- const connection = await retryPostgres(reserveConnection, isRetryableConnectionError);
219
+ const connection = await retryPostgres(reserveConnection, isRetryableConnectionAcquisitionError, emitRetryDiagnostic
220
+ ? {
221
+ dataRegion: options?.dataRegion,
222
+ emit: emitRetryDiagnostic,
223
+ operationKind: 'acquisition',
224
+ repositoryName: options?.repositoryName,
225
+ shouldEmit: isRetryableConnectionAcquisitionError,
226
+ }
227
+ : undefined);
126
228
  if (options?.hyperdrive) {
127
229
  const unsafe = connection.unsafe;
128
230
  connection.unsafe = (query, parameters, queryOptions) => unsafe(query, parameters, { ...queryOptions, prepare: true });
129
231
  }
130
232
  return connection;
131
233
  };
132
- const kysely = getKysely(new RetryingPostgresJSDialect({ postgres }), {
234
+ const kysely = getKysely(new RetryingPostgresJSDialect({ postgres }, emitRetryDiagnostic
235
+ ? {
236
+ dataRegion: options?.dataRegion,
237
+ emit: emitRetryDiagnostic,
238
+ repositoryName: options?.repositoryName,
239
+ shouldEmit: isQueryRetryDiagnosticError,
240
+ }
241
+ : undefined), {
133
242
  repositoryName: options?.repositoryName,
134
243
  log: options?.log,
135
244
  });
@@ -143,43 +252,52 @@ export function useKysely(postgres, options) {
143
252
  return kysely;
144
253
  }
145
254
  let _connections = [];
255
+ export function usePostgres(connectionString, opt) {
256
+ const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
257
+ const sql = postgres(connectionString, {
258
+ ssl: ssl ? 'require' : false,
259
+ target_session_attrs: 'read-write',
260
+ // enable prepare statements, pgbouncer on crunchy allows for prepared statements
261
+ prepare: true,
262
+ ...(opt?.hyperdrive
263
+ ? {
264
+ max: 5,
265
+ // Retire idle clients before Hyperdrive can close them asynchronously.
266
+ idle_timeout: 10,
267
+ }
268
+ : {
269
+ connect_timeout: 10,
270
+ idle_timeout: 60,
271
+ }),
272
+ });
273
+ // statement_timeout/lock_timeout are role-level settings on the cluster
274
+ // (ALTER ROLE application SET ...) so they cover every pooled
275
+ // connection; per-session SETs here only ever applied to one of them
276
+ _connections.push(sql);
277
+ return sql;
278
+ }
146
279
  export async function useAsyncPostgres(connectionString, opt) {
147
280
  const delayMs = 2500;
148
281
  const probe = opt?.probe === true;
149
282
  const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;
150
- const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
151
283
  const url = new URL(connectionString);
152
- console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${ssl}, and port=${url.port}`);
284
+ console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && opt?.hyperdrive !== true}, and port=${url.port}`);
153
285
  if (_connections.length > 0)
154
286
  console.warn(`We already have ${_connections.length} Postgres connections`);
155
287
  for (let attempt = 1; attempt <= retries; attempt++) {
288
+ let sql;
156
289
  try {
157
- const sql = postgres(connectionString, {
158
- ssl: ssl ? 'require' : false,
159
- target_session_attrs: 'read-write',
160
- // enable prepare statements, pgbouncer on crunchy allows for prepared statements
161
- prepare: true,
162
- ...(opt?.hyperdrive
163
- ? {
164
- max: 5,
165
- // Retire idle clients before Hyperdrive can close them asynchronously.
166
- idle_timeout: 10,
167
- }
168
- : {
169
- connect_timeout: 10,
170
- idle_timeout: 60,
171
- }),
172
- });
290
+ sql = usePostgres(connectionString, opt);
173
291
  if (probe) {
174
292
  await sql `select 1`;
175
293
  }
176
- // statement_timeout/lock_timeout are role-level settings on the cluster
177
- // (ALTER ROLE application SET ...) so they cover every pooled
178
- // connection; per-session SETs here only ever applied to one of them
179
- _connections.push(sql);
180
294
  return sql;
181
295
  }
182
296
  catch (err) {
297
+ if (sql) {
298
+ await sql.end({ timeout: 0 }).catch(() => undefined);
299
+ _connections.splice(_connections.indexOf(sql), 1);
300
+ }
183
301
  if (attempt === retries)
184
302
  throw err;
185
303
  console.warn(`Postgres connection failed (attempt ${attempt}), retrying...`);
@@ -193,9 +311,22 @@ export async function useAsyncKysely(connectionString, opt) {
193
311
  const sql = await useAsyncPostgres(connectionString, opt);
194
312
  return useKysely(sql, opt);
195
313
  }
314
+ export async function useAsyncNeonWebSocketKysely(connectionString, opt) {
315
+ const pool = new Pool({ connectionString, max: 5 });
316
+ const kysely = getKysely(new PostgresDialect({ pool }), opt ?? {});
317
+ kysely.destroy = async () => {
318
+ console.debug('Closing Neon WebSocket Kysely connection');
319
+ await pool.end();
320
+ };
321
+ if (opt?.probe)
322
+ await pool.query('select 1');
323
+ return kysely;
324
+ }
325
+ export function useControlPlaneKysely(postgres, options) {
326
+ return withControlPlaneSchema(useKysely(postgres, options), 'public');
327
+ }
196
328
  export async function useAsyncControlPlaneKysely(connectionString, opt) {
197
- const sql = await useAsyncPostgres(connectionString, opt);
198
- return withControlPlaneSchema(useKysely(sql, opt), 'public');
329
+ return useControlPlaneKysely(await useAsyncPostgres(connectionString, opt), opt);
199
330
  }
200
331
  export async function forceCloseAllPostgres(timeoutMs = 5000) {
201
332
  await Promise.race([