@vrplatform/kysely 1.3.45-6561 → 1.3.45-736
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 +137 -0
- package/build/main/control-plane/index.js.map +1 -1
- package/build/main/index.d.ts +11 -0
- package/build/main/index.js +131 -26
- package/build/main/index.js.map +1 -1
- package/build/main/local/generate.js +1 -0
- package/build/main/local/generate.js.map +1 -1
- package/build/main/local/index.js +109 -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 +4 -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 +23 -3
- package/build/main/test/index.js +35 -13
- package/build/main/test/index.js.map +1 -1
- package/build/main/v1.generated.d.ts +338 -37
- package/build/main/v1.generated.js.map +1 -1
- package/build/migrations-v2/0000000000015-durable-flow-events.ts +163 -0
- package/build/migrations-v2/0000000000016-billing-listing-facts.ts +539 -0
- package/build/migrations-v2/0000000000017-webhook-secret-reencryption-failures.ts +18 -0
- package/build/migrations-v2/0000000000018-durable-flow-event-sensitive-input.ts +28 -0
- package/build/migrations-v2/0000000000019-asynchronous-operations.ts +736 -0
- 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-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/module/control-plane/index.d.ts +137 -0
- package/build/module/control-plane/index.js.map +1 -1
- package/build/module/index.d.ts +11 -0
- package/build/module/index.js +131 -26
- package/build/module/index.js.map +1 -1
- package/build/module/local/generate.js +1 -0
- package/build/module/local/generate.js.map +1 -1
- package/build/module/local/index.js +109 -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 +4 -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 +23 -3
- package/build/module/test/index.js +34 -13
- package/build/module/test/index.js.map +1 -1
- package/build/module/v1.generated.d.ts +338 -37
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +4 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ColumnType, type Kysely } from 'kysely';
|
|
2
|
+
import type { TenantDataRegion } from '../regional';
|
|
2
3
|
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
3
4
|
export type Json = JsonValue;
|
|
4
5
|
export type JsonArray = JsonValue[];
|
|
@@ -9,6 +10,11 @@ export type JsonPrimitive = boolean | number | string | null;
|
|
|
9
10
|
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
10
11
|
export type Int8 = ColumnType<string, number | string | bigint, number | string | bigint>;
|
|
11
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' | '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';
|
|
12
18
|
export interface ControlPlaneApp {
|
|
13
19
|
authentication: Generated<Json>;
|
|
14
20
|
category: string | null;
|
|
@@ -104,6 +110,92 @@ export interface ControlPlaneBookingChannelIconCandidate {
|
|
|
104
110
|
export interface ControlPlaneCurrency {
|
|
105
111
|
name: string;
|
|
106
112
|
}
|
|
113
|
+
export type DestructiveJobStep = 'completed' | 'completion_effects' | 'control_plane_deleted' | 'control_plane_deleting' | 'queued' | 'regional_deleted' | 'regional_deleting' | 'validated';
|
|
114
|
+
export interface ControlPlaneDestructiveJob {
|
|
115
|
+
attempts: Generated<number>;
|
|
116
|
+
authorizedByTenantId: string;
|
|
117
|
+
availableAt: Generated<Timestamp>;
|
|
118
|
+
claimedAt: Timestamp | null;
|
|
119
|
+
claimedBy: string | null;
|
|
120
|
+
completedAt: Timestamp | null;
|
|
121
|
+
completionData: Json | null;
|
|
122
|
+
completionWarningCode: string | null;
|
|
123
|
+
completionWarningDetails: Json | null;
|
|
124
|
+
createdAt: Generated<Timestamp>;
|
|
125
|
+
dataRegion: TenantDataRegion;
|
|
126
|
+
failureCode: string | null;
|
|
127
|
+
failureDetails: Json | null;
|
|
128
|
+
force: Generated<boolean>;
|
|
129
|
+
id: Generated<string>;
|
|
130
|
+
jobType: 'tenant.delete';
|
|
131
|
+
maxAttempts: Generated<number>;
|
|
132
|
+
requestId: string | null;
|
|
133
|
+
requestedByActorType: 'api_key' | 'system' | 'user';
|
|
134
|
+
requestedByTenantId: string;
|
|
135
|
+
requestedByUserId: string | null;
|
|
136
|
+
startedAt: Timestamp | null;
|
|
137
|
+
status: Generated<'canceled' | 'completed' | 'failed' | 'queued' | 'running'>;
|
|
138
|
+
step: Generated<DestructiveJobStep>;
|
|
139
|
+
targetId: string;
|
|
140
|
+
triggerRunId: string | null;
|
|
141
|
+
updatedAt: Generated<Timestamp>;
|
|
142
|
+
}
|
|
143
|
+
export interface ControlPlaneDestructiveJobAttempt {
|
|
144
|
+
attemptNumber: number;
|
|
145
|
+
failureCode: string | null;
|
|
146
|
+
failureDetails: Json | null;
|
|
147
|
+
finishedAt: Timestamp | null;
|
|
148
|
+
id: Generated<string>;
|
|
149
|
+
jobId: string;
|
|
150
|
+
startedAt: Generated<Timestamp>;
|
|
151
|
+
status: Generated<'completed' | 'failed' | 'running' | 'superseded'>;
|
|
152
|
+
step: DestructiveJobStep;
|
|
153
|
+
triggerRunId: string | null;
|
|
154
|
+
}
|
|
155
|
+
export interface ControlPlaneDestructiveJobOperation {
|
|
156
|
+
action: 'abandon' | 'cancel' | 'retry';
|
|
157
|
+
actor: string;
|
|
158
|
+
createdAt: Generated<Timestamp>;
|
|
159
|
+
id: Generated<string>;
|
|
160
|
+
jobId: string;
|
|
161
|
+
previousStatus: string;
|
|
162
|
+
previousStep: string;
|
|
163
|
+
reasonCode: string;
|
|
164
|
+
}
|
|
165
|
+
export interface ControlPlaneOperation {
|
|
166
|
+
createdAt: Generated<Timestamp>;
|
|
167
|
+
failureCode: string | null;
|
|
168
|
+
failureMessage: string | null;
|
|
169
|
+
finishedAt: Timestamp | null;
|
|
170
|
+
id: Generated<string>;
|
|
171
|
+
initiatedByUserId: string | null;
|
|
172
|
+
requesterTenantId: string;
|
|
173
|
+
retainUntil: Timestamp | null;
|
|
174
|
+
sourceRegion: TenantDataRegion | null;
|
|
175
|
+
sourceVersion: Generated<number>;
|
|
176
|
+
startedAt: Timestamp | null;
|
|
177
|
+
status: Generated<ControlPlaneOperationStatus>;
|
|
178
|
+
type: ControlPlaneOperationType;
|
|
179
|
+
updatedAt: Generated<Timestamp>;
|
|
180
|
+
}
|
|
181
|
+
export interface ControlPlaneOperationResource {
|
|
182
|
+
createdAt: Generated<Timestamp>;
|
|
183
|
+
isPrimary: Generated<boolean>;
|
|
184
|
+
operationId: string;
|
|
185
|
+
resourceId: string;
|
|
186
|
+
resourceType: ControlPlaneOperationResourceType;
|
|
187
|
+
role: ControlPlaneOperationResourceRole;
|
|
188
|
+
}
|
|
189
|
+
export interface ControlPlaneOperationSource {
|
|
190
|
+
finishedAt: Timestamp | null;
|
|
191
|
+
operationId: string;
|
|
192
|
+
required: Generated<boolean>;
|
|
193
|
+
sourceId: string;
|
|
194
|
+
sourceType: ControlPlaneOperationSourceType;
|
|
195
|
+
sourceVersion: Generated<number>;
|
|
196
|
+
startedAt: Timestamp | null;
|
|
197
|
+
status: Generated<ControlPlaneOperationStatus>;
|
|
198
|
+
}
|
|
107
199
|
export interface ControlPlaneEvent {
|
|
108
200
|
createdAt: Generated<Timestamp>;
|
|
109
201
|
id: Generated<string>;
|
|
@@ -115,6 +207,27 @@ export interface ControlPlaneEvent {
|
|
|
115
207
|
trackedAt: Generated<Timestamp | null>;
|
|
116
208
|
userId: string | null;
|
|
117
209
|
}
|
|
210
|
+
export interface ControlPlaneTrackingQueueFailure {
|
|
211
|
+
bodyFingerprint: string | null;
|
|
212
|
+
capturedAt: Generated<Timestamp>;
|
|
213
|
+
dispositionAt: Timestamp | null;
|
|
214
|
+
dispositionHistory: Generated<Json[]>;
|
|
215
|
+
dispositionReasonCode: string | null;
|
|
216
|
+
dispositionActor: string | null;
|
|
217
|
+
environment: 'production' | 'staging';
|
|
218
|
+
event: Json | null;
|
|
219
|
+
eventId: string | null;
|
|
220
|
+
expiresAt: Timestamp;
|
|
221
|
+
failureCode: string;
|
|
222
|
+
id: Generated<string>;
|
|
223
|
+
lastReplayedAt: Timestamp | null;
|
|
224
|
+
queueMessageId: string;
|
|
225
|
+
replayCount: Generated<number>;
|
|
226
|
+
recurrenceCount: Generated<number>;
|
|
227
|
+
status: Generated<'captured' | 'discarded' | 'replayed'>;
|
|
228
|
+
updatedAt: Generated<Timestamp>;
|
|
229
|
+
validationIssues: Json | null;
|
|
230
|
+
}
|
|
118
231
|
export interface ControlPlaneConnectionRoute {
|
|
119
232
|
connectionId: string;
|
|
120
233
|
createdAt: Generated<Timestamp>;
|
|
@@ -262,6 +375,22 @@ export interface ControlPlanePartnerManagedTeamAssignment {
|
|
|
262
375
|
partnerTenantId: string;
|
|
263
376
|
userId: string;
|
|
264
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
|
+
}
|
|
265
394
|
export interface ControlPlaneTenant {
|
|
266
395
|
billingPartnerId: string | null;
|
|
267
396
|
billingPlan: string | null;
|
|
@@ -345,6 +474,9 @@ export interface ControlPlaneDB {
|
|
|
345
474
|
'controlPlane.connectionRoute': ControlPlaneConnectionRoute;
|
|
346
475
|
'controlPlane.controlPlaneOutbox': ControlPlaneOutbox;
|
|
347
476
|
'controlPlane.currency': ControlPlaneCurrency;
|
|
477
|
+
'controlPlane.destructiveJob': ControlPlaneDestructiveJob;
|
|
478
|
+
'controlPlane.destructiveJobAttempt': ControlPlaneDestructiveJobAttempt;
|
|
479
|
+
'controlPlane.destructiveJobOperation': ControlPlaneDestructiveJobOperation;
|
|
348
480
|
'controlPlane.events': ControlPlaneEvent;
|
|
349
481
|
'controlPlane.feature': ControlPlaneFeature;
|
|
350
482
|
'controlPlane.featureApproval': ControlPlaneFeatureApproval;
|
|
@@ -353,12 +485,17 @@ export interface ControlPlaneDB {
|
|
|
353
485
|
'controlPlane.generalLedgerDefaultVersion': ControlPlaneGeneralLedgerDefaultVersion;
|
|
354
486
|
'controlPlane.lineClassification': ControlPlaneLineClassification;
|
|
355
487
|
'controlPlane.lineClassificationTeamUsage': ControlPlaneLineClassificationTeamUsage;
|
|
488
|
+
'controlPlane.operation': ControlPlaneOperation;
|
|
489
|
+
'controlPlane.operationResource': ControlPlaneOperationResource;
|
|
490
|
+
'controlPlane.operationSource': ControlPlaneOperationSource;
|
|
356
491
|
'controlPlane.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;
|
|
357
492
|
'controlPlane.reservationLineDefault': ControlPlaneReservationLineDefault;
|
|
358
493
|
'controlPlane.rolloutMonitorSnapshot': ControlPlaneRolloutMonitorSnapshot;
|
|
494
|
+
'controlPlane.ownerPortal': ControlPlaneOwnerPortal;
|
|
359
495
|
'controlPlane.tenant': ControlPlaneTenant;
|
|
360
496
|
'controlPlane.tenantRegionMigration': ControlPlaneTenantRegionMigration;
|
|
361
497
|
'controlPlane.tenantUser': ControlPlaneTenantUser;
|
|
498
|
+
'controlPlane.trackingQueueFailure': ControlPlaneTrackingQueueFailure;
|
|
362
499
|
'controlPlane.token': ControlPlaneToken;
|
|
363
500
|
'controlPlane.transactionLineMapping': ControlPlaneTransactionLineMapping;
|
|
364
501
|
'controlPlane.user': ControlPlaneUser;
|
|
@@ -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;AA4ZhB,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';\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 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 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.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.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;\n 'controlPlane.reservationLineDefault': ControlPlaneReservationLineDefault;\n 'controlPlane.rolloutMonitorSnapshot': ControlPlaneRolloutMonitorSnapshot;\n 'controlPlane.tenant': ControlPlaneTenant;\n 'controlPlane.tenantRegionMigration': ControlPlaneTenantRegionMigration;\n 'controlPlane.tenantUser': ControlPlaneTenantUser;\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;AAymBhB,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 | '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/module/index.d.ts
CHANGED
|
@@ -8,12 +8,22 @@ 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;
|
|
@@ -25,5 +35,6 @@ export type ControlPlaneTransaction = T<ControlPlaneDB>;
|
|
|
25
35
|
export declare function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts): K<Database>;
|
|
26
36
|
export declare function useAsyncPostgres(connectionString: string, opt?: PgOpt): Promise<postgres.Sql<{}>>;
|
|
27
37
|
export declare function useAsyncKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<DB>>;
|
|
38
|
+
export declare function useAsyncNeonWebSocketKysely(connectionString: string, opt?: Pick<PgOpt, 'probe'> & KyselyOpts): Promise<K<DB>>;
|
|
28
39
|
export declare function useAsyncControlPlaneKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<ControlPlaneDB>>;
|
|
29
40
|
export declare function forceCloseAllPostgres(timeoutMs?: number): Promise<void>;
|
package/build/module/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
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';
|
|
@@ -22,19 +24,74 @@ function isRetryableConnectionError(error) {
|
|
|
22
24
|
const message = error instanceof Error ? error.message : String(error);
|
|
23
25
|
return retryableMessages.some((retryable) => message.includes(retryable));
|
|
24
26
|
}
|
|
25
|
-
function
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
function isConnectionReset(error) {
|
|
28
|
+
return (error instanceof Error && 'code' in error && error.code === 'ECONNRESET');
|
|
29
|
+
}
|
|
30
|
+
function isRetryableConnectionAcquisitionError(error) {
|
|
31
|
+
return (isRetryableConnectionError(error) ||
|
|
32
|
+
isConnectionReset(error) ||
|
|
33
|
+
(error instanceof Error &&
|
|
34
|
+
(error.message === 'connection attempt failed' ||
|
|
35
|
+
('code' in error && error.code === 'CONNECTION_DESTROYED'))));
|
|
36
|
+
}
|
|
37
|
+
function isQueryRetryDiagnosticError(error) {
|
|
38
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39
|
+
return (isRetryableConnectionError(error) ||
|
|
40
|
+
isConnectionReset(error) ||
|
|
41
|
+
message === 'Egress connection severed outside of Hyperdrive' ||
|
|
42
|
+
message === 'Network connection lost.' ||
|
|
43
|
+
message === 'Node shutting down' ||
|
|
44
|
+
message === 'Node shutting down.');
|
|
45
|
+
}
|
|
46
|
+
async function retryPostgres(operation, retry, diagnostic) {
|
|
47
|
+
let attemptCount = 0;
|
|
48
|
+
let retried = false;
|
|
49
|
+
const emitDiagnostic = (outcome) => {
|
|
50
|
+
if (!diagnostic)
|
|
51
|
+
return;
|
|
52
|
+
diagnostic.emit({
|
|
53
|
+
attemptCount,
|
|
54
|
+
dataRegion: diagnostic.dataRegion,
|
|
55
|
+
operationKind: diagnostic.operationKind,
|
|
56
|
+
outcome,
|
|
57
|
+
repositoryName: diagnostic.repositoryName,
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
try {
|
|
61
|
+
return await backOff(async () => {
|
|
62
|
+
attemptCount++;
|
|
63
|
+
return await operation();
|
|
64
|
+
}, {
|
|
65
|
+
numOfAttempts: postgresRetryAttempts,
|
|
66
|
+
startingDelay: parseDuration('1s'),
|
|
67
|
+
maxDelay: parseDuration('5s'),
|
|
68
|
+
async retry(error, attemptNumber) {
|
|
69
|
+
const shouldRetry = attemptNumber < postgresRetryAttempts &&
|
|
70
|
+
(await retry(error, attemptNumber));
|
|
71
|
+
if (shouldRetry && diagnostic) {
|
|
72
|
+
retried = true;
|
|
73
|
+
emitDiagnostic('retrying');
|
|
74
|
+
}
|
|
75
|
+
return shouldRetry;
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (diagnostic?.shouldEmit(error)) {
|
|
81
|
+
emitDiagnostic(retried && attemptCount === postgresRetryAttempts
|
|
82
|
+
? 'exhausted'
|
|
83
|
+
: 'notRetryable');
|
|
84
|
+
}
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
32
87
|
}
|
|
33
88
|
class RetryingPostgresJSDialect extends PostgresJSDialect {
|
|
34
89
|
config;
|
|
35
|
-
|
|
90
|
+
retryDiagnostic;
|
|
91
|
+
constructor(config, retryDiagnostic) {
|
|
36
92
|
super(config);
|
|
37
93
|
this.config = config;
|
|
94
|
+
this.retryDiagnostic = retryDiagnostic;
|
|
38
95
|
}
|
|
39
96
|
createDriver() {
|
|
40
97
|
const driver = new PostgresJSDriver(this.config);
|
|
@@ -53,21 +110,37 @@ class RetryingPostgresJSDialect extends PostgresJSDialect {
|
|
|
53
110
|
inTransaction: false,
|
|
54
111
|
};
|
|
55
112
|
const connection = {
|
|
56
|
-
executeQuery: (compiledQuery) =>
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
113
|
+
executeQuery: (compiledQuery) => {
|
|
114
|
+
const operationKind = state.inTransaction
|
|
115
|
+
? 'transaction'
|
|
116
|
+
: compiledQuery.query.kind === 'SelectQueryNode'
|
|
117
|
+
? 'select'
|
|
118
|
+
: 'mutation';
|
|
119
|
+
return retryPostgres(() => state.connection.executeQuery(compiledQuery), async (error) => {
|
|
120
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
121
|
+
if (state.inTransaction ||
|
|
122
|
+
(!isRetryableConnectionError(error) &&
|
|
123
|
+
(compiledQuery.query.kind !== 'SelectQueryNode' ||
|
|
124
|
+
(!isConnectionReset(error) &&
|
|
125
|
+
message !==
|
|
126
|
+
'Egress connection severed outside of Hyperdrive' &&
|
|
127
|
+
message !== 'Network connection lost.' &&
|
|
128
|
+
message !== 'Node shutting down' &&
|
|
129
|
+
message !== 'Node shutting down.')))) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// Postgres.js already ejects a severed reserved connection.
|
|
133
|
+
// Acquire a new reservation before replaying the safe read.
|
|
134
|
+
state.connection = await driver.acquireConnection();
|
|
135
|
+
return true;
|
|
136
|
+
}, this.retryDiagnostic
|
|
137
|
+
? {
|
|
138
|
+
...this.retryDiagnostic,
|
|
139
|
+
operationKind,
|
|
140
|
+
shouldEmit: isQueryRetryDiagnosticError,
|
|
141
|
+
}
|
|
142
|
+
: undefined);
|
|
143
|
+
},
|
|
71
144
|
streamQuery: (compiledQuery, chunkSize) => {
|
|
72
145
|
if (chunkSize === undefined) {
|
|
73
146
|
throw new Error('Postgres stream chunk size is required');
|
|
@@ -120,16 +193,35 @@ class RetryingPostgresJSDialect extends PostgresJSDialect {
|
|
|
120
193
|
}
|
|
121
194
|
export function useKysely(postgres, options) {
|
|
122
195
|
console.debug('Creating Kysely instance');
|
|
196
|
+
const emitRetryDiagnostic = options?.onRetryDiagnostic ??
|
|
197
|
+
(options?.repositoryName
|
|
198
|
+
? (diagnostic) => console.warn('Postgres operation retry diagnostic', diagnostic)
|
|
199
|
+
: undefined);
|
|
123
200
|
const reserveConnection = postgres.reserve.bind(postgres);
|
|
124
201
|
postgres.reserve = async () => {
|
|
125
|
-
const connection = await retryPostgres(reserveConnection,
|
|
202
|
+
const connection = await retryPostgres(reserveConnection, isRetryableConnectionAcquisitionError, emitRetryDiagnostic
|
|
203
|
+
? {
|
|
204
|
+
dataRegion: options?.dataRegion,
|
|
205
|
+
emit: emitRetryDiagnostic,
|
|
206
|
+
operationKind: 'acquisition',
|
|
207
|
+
repositoryName: options?.repositoryName,
|
|
208
|
+
shouldEmit: isRetryableConnectionAcquisitionError,
|
|
209
|
+
}
|
|
210
|
+
: undefined);
|
|
126
211
|
if (options?.hyperdrive) {
|
|
127
212
|
const unsafe = connection.unsafe;
|
|
128
213
|
connection.unsafe = (query, parameters, queryOptions) => unsafe(query, parameters, { ...queryOptions, prepare: true });
|
|
129
214
|
}
|
|
130
215
|
return connection;
|
|
131
216
|
};
|
|
132
|
-
const kysely = getKysely(new RetryingPostgresJSDialect({ postgres }
|
|
217
|
+
const kysely = getKysely(new RetryingPostgresJSDialect({ postgres }, emitRetryDiagnostic
|
|
218
|
+
? {
|
|
219
|
+
dataRegion: options?.dataRegion,
|
|
220
|
+
emit: emitRetryDiagnostic,
|
|
221
|
+
repositoryName: options?.repositoryName,
|
|
222
|
+
shouldEmit: isQueryRetryDiagnosticError,
|
|
223
|
+
}
|
|
224
|
+
: undefined), {
|
|
133
225
|
repositoryName: options?.repositoryName,
|
|
134
226
|
log: options?.log,
|
|
135
227
|
});
|
|
@@ -153,8 +245,9 @@ export async function useAsyncPostgres(connectionString, opt) {
|
|
|
153
245
|
if (_connections.length > 0)
|
|
154
246
|
console.warn(`We already have ${_connections.length} Postgres connections`);
|
|
155
247
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
248
|
+
let sql;
|
|
156
249
|
try {
|
|
157
|
-
|
|
250
|
+
sql = postgres(connectionString, {
|
|
158
251
|
ssl: ssl ? 'require' : false,
|
|
159
252
|
target_session_attrs: 'read-write',
|
|
160
253
|
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
@@ -180,6 +273,7 @@ export async function useAsyncPostgres(connectionString, opt) {
|
|
|
180
273
|
return sql;
|
|
181
274
|
}
|
|
182
275
|
catch (err) {
|
|
276
|
+
await sql?.end({ timeout: 0 }).catch(() => undefined);
|
|
183
277
|
if (attempt === retries)
|
|
184
278
|
throw err;
|
|
185
279
|
console.warn(`Postgres connection failed (attempt ${attempt}), retrying...`);
|
|
@@ -193,6 +287,17 @@ export async function useAsyncKysely(connectionString, opt) {
|
|
|
193
287
|
const sql = await useAsyncPostgres(connectionString, opt);
|
|
194
288
|
return useKysely(sql, opt);
|
|
195
289
|
}
|
|
290
|
+
export async function useAsyncNeonWebSocketKysely(connectionString, opt) {
|
|
291
|
+
const pool = new Pool({ connectionString, max: 5 });
|
|
292
|
+
const kysely = getKysely(new PostgresDialect({ pool }), opt ?? {});
|
|
293
|
+
kysely.destroy = async () => {
|
|
294
|
+
console.debug('Closing Neon WebSocket Kysely connection');
|
|
295
|
+
await pool.end();
|
|
296
|
+
};
|
|
297
|
+
if (opt?.probe)
|
|
298
|
+
await pool.query('select 1');
|
|
299
|
+
return kysely;
|
|
300
|
+
}
|
|
196
301
|
export async function useAsyncControlPlaneKysely(connectionString, opt) {
|
|
197
302
|
const sql = await useAsyncPostgres(connectionString, opt);
|
|
198
303
|
return withControlPlaneSchema(useKysely(sql, opt), 'public');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { backOff } from 'exponential-backoff';\nimport type {\n DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\n Transaction as T,\n} from 'kysely';\nimport {\n PostgresJSDialect,\n type PostgresJSDialectConfig,\n PostgresJSDriver,\n} from 'kysely-postgres-js';\nimport postgres, { type Sql } from 'postgres';\nimport { type ControlPlaneDB, withControlPlaneSchema } from './control-plane';\nimport { KyselyError } from './error';\nimport { getKysely } from './plugins';\n\nexport type { Insertable, LogEvent } from 'kysely';\nexport * from './error';\nexport * from './isomorphic';\nexport * from './postgres-error';\nexport * from './query';\nexport * from './regional';\nexport * from './transaction';\n\nimport { parseDuration } from '@vrplatform/utils';\nimport type { DB } from './v1.generated';\n\ntype KyselyOpts = {\n hyperdrive?: true;\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\ntype PgOpt = {\n forceDisableSSL?: boolean;\n probe?: true;\n retries?: false | number;\n} & Pick<KyselyOpts, 'hyperdrive'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n];\nconst postgresRetryAttempts = 3;\n\nfunction isRetryableConnectionError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return retryableMessages.some((retryable) => message.includes(retryable));\n}\n\nfunction retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>\n) {\n return backOff(operation, {\n numOfAttempts: postgresRetryAttempts,\n startingDelay: parseDuration('1s'),\n maxDelay: parseDuration('5s'),\n retry: (error, attemptNumber) =>\n attemptNumber < postgresRetryAttempts && retry(error, attemptNumber),\n });\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(private readonly config: PostgresJSDialectConfig) {\n super(config);\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n const connections = new WeakMap<\n DatabaseConnection,\n { connection: DatabaseConnection; inTransaction: boolean }\n >();\n const getConnection = (connection: DatabaseConnection) => {\n const state = connections.get(connection);\n if (!state) throw new Error('Postgres connection state is unavailable');\n return state;\n };\n\n return {\n init: () => driver.init(),\n acquireConnection: async () => {\n const state = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: (compiledQuery) =>\n retryPostgres(\n () => state.connection.executeQuery(compiledQuery),\n async (error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n if (\n state.inTransaction ||\n (!isRetryableConnectionError(error) &&\n (compiledQuery.query.kind !== 'SelectQueryNode' ||\n (message !==\n 'Egress connection severed outside of Hyperdrive' &&\n message !== 'Network connection lost.')))\n ) {\n return false;\n }\n\n // Postgres.js already ejects a severed reserved connection.\n // Acquire a new reservation before replaying the safe read.\n state.connection = await driver.acquireConnection();\n return true;\n }\n ),\n streamQuery: (compiledQuery, chunkSize) => {\n if (chunkSize === undefined) {\n throw new Error('Postgres stream chunk size is required');\n }\n return state.connection.streamQuery(compiledQuery, chunkSize);\n },\n };\n connections.set(connection, state);\n return connection;\n },\n beginTransaction: async (connection, settings) => {\n const state = getConnection(connection);\n state.inTransaction = true;\n try {\n await driver.beginTransaction(state.connection, settings);\n } catch (error) {\n state.inTransaction = false;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.commitTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.rollbackTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n driver.savepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n driver.rollbackToSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n driver.releaseSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseConnection: async (connection) => {\n await driver.releaseConnection(getConnection(connection).connection);\n connections.delete(connection);\n },\n destroy: () => driver.destroy(),\n };\n }\n}\n\nexport type Kysely = K<DB>;\nexport type ControlPlaneKysely = K<ControlPlaneDB>;\nexport type ControlPlaneTransaction = T<ControlPlaneDB>;\nexport function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts) {\n console.debug('Creating Kysely instance');\n const reserveConnection = postgres.reserve.bind(postgres);\n postgres.reserve = async () => {\n const connection = await retryPostgres(\n reserveConnection,\n isRetryableConnectionError\n );\n if (options?.hyperdrive) {\n const unsafe = connection.unsafe;\n connection.unsafe = (query, parameters, queryOptions) =>\n unsafe(query, parameters, { ...queryOptions, prepare: true });\n }\n return connection;\n };\n const kysely = getKysely<Database>(\n new RetryingPostgresJSDialect({ postgres }),\n {\n repositoryName: options?.repositoryName,\n log: options?.log,\n }\n );\n kysely.destroy = async () => {\n console.debug('Closing Kysely connection');\n await postgres.end({ timeout: 5 }).catch(() => undefined);\n const index = _connections.indexOf(postgres);\n if (index !== -1) _connections.splice(index, 1);\n };\n\n return kysely;\n}\n\nlet _connections: postgres.Sql[] = [];\nexport async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {\n const delayMs = 2500;\n const probe = opt?.probe === true;\n const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;\n const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${ssl}, and port=${url.port}`\n );\n if (_connections.length > 0)\n console.warn(`We already have ${_connections.length} Postgres connections`);\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // enable prepare statements, pgbouncer on crunchy allows for prepared statements\n prepare: true,\n ...(opt?.hyperdrive\n ? {\n max: 5,\n // Retire idle clients before Hyperdrive can close them asynchronously.\n idle_timeout: 10,\n }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\n }),\n });\n\n if (probe) {\n await sql`select 1`;\n }\n // statement_timeout/lock_timeout are role-level settings on the cluster\n // (ALTER ROLE application SET ...) so they cover every pooled\n // connection; per-session SETs here only ever applied to one of them\n\n _connections.push(sql);\n return sql;\n } catch (err) {\n if (attempt === retries) throw err;\n console.warn(\n `Postgres connection failed (attempt ${attempt}), retrying...`\n );\n console.error('error', err);\n await new Promise((res) => setTimeout(res, delayMs));\n }\n }\n throw new KyselyError('Unable to connect to Postgres');\n}\n\nexport async function useAsyncKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return useKysely(sql, opt);\n}\n\nexport async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return withControlPlaneSchema(useKysely<ControlPlaneDB>(sql, opt), 'public');\n}\n\nexport async function forceCloseAllPostgres(timeoutMs = 5000) {\n await Promise.race([\n Promise.all(\n _connections.map((pg) =>\n pg.end({ timeout: timeoutMs / 1000 }).catch(() => undefined)\n )\n ),\n new Promise((res) => setTimeout(res, timeoutMs + 1000)),\n ]);\n _connections = [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { backOff } from 'exponential-backoff';\nimport { Pool } from '@neondatabase/serverless';\nimport type {\n DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\n Transaction as T,\n} from 'kysely';\nimport { PostgresDialect } from 'kysely';\nimport {\n PostgresJSDialect,\n type PostgresJSDialectConfig,\n PostgresJSDriver,\n} from 'kysely-postgres-js';\nimport postgres, { type Sql } from 'postgres';\nimport { type ControlPlaneDB, withControlPlaneSchema } from './control-plane';\nimport { KyselyError } from './error';\nimport { getKysely } from './plugins';\n\nexport type { Insertable, LogEvent } from 'kysely';\nexport * from './error';\nexport * from './isomorphic';\nexport * from './postgres-error';\nexport * from './query';\nexport * from './regional';\nexport * from './transaction';\n\nimport { parseDuration } from '@vrplatform/utils';\nimport type { TenantDataRegion } from './regional';\nimport type { DB } from './v1.generated';\n\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: true;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\n operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';\n outcome: 'exhausted' | 'notRetryable' | 'retrying';\n repositoryName?: string;\n};\n\ntype PgOpt = {\n forceDisableSSL?: boolean;\n probe?: true;\n retries?: false | number;\n} & Pick<KyselyOpts, 'hyperdrive'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n];\nconst postgresRetryAttempts = 3;\n\nfunction isRetryableConnectionError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return retryableMessages.some((retryable) => message.includes(retryable));\n}\n\nfunction isConnectionReset(error: unknown) {\n return (\n error instanceof Error && 'code' in error && error.code === 'ECONNRESET'\n );\n}\n\nfunction isRetryableConnectionAcquisitionError(error: unknown) {\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\n );\n}\n\nfunction isQueryRetryDiagnosticError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n message === 'Egress connection severed outside of Hyperdrive' ||\n message === 'Network connection lost.' ||\n message === 'Node shutting down' ||\n message === 'Node shutting down.'\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<PostgresRetryDiagnostic, 'attemptCount' | 'outcome'> & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\n operationKind: diagnostic.operationKind,\n outcome,\n repositoryName: diagnostic.repositoryName,\n });\n };\n try {\n return await backOff(\n async () => {\n attemptCount++;\n return await operation();\n },\n {\n numOfAttempts: postgresRetryAttempts,\n startingDelay: parseDuration('1s'),\n maxDelay: parseDuration('5s'),\n async retry(error, attemptNumber) {\n const shouldRetry =\n attemptNumber < postgresRetryAttempts &&\n (await retry(error, attemptNumber));\n if (shouldRetry && diagnostic) {\n retried = true;\n emitDiagnostic('retrying');\n }\n return shouldRetry;\n },\n }\n );\n } catch (error) {\n if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n ) {\n super(config);\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n const connections = new WeakMap<\n DatabaseConnection,\n { connection: DatabaseConnection; inTransaction: boolean }\n >();\n const getConnection = (connection: DatabaseConnection) => {\n const state = connections.get(connection);\n if (!state) throw new Error('Postgres connection state is unavailable');\n return state;\n };\n\n return {\n init: () => driver.init(),\n acquireConnection: async () => {\n const state = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: (compiledQuery) => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres(\n () => state.connection.executeQuery(compiledQuery),\n async (error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n if (\n state.inTransaction ||\n (!isRetryableConnectionError(error) &&\n (compiledQuery.query.kind !== 'SelectQueryNode' ||\n (!isConnectionReset(error) &&\n message !==\n 'Egress connection severed outside of Hyperdrive' &&\n message !== 'Network connection lost.' &&\n message !== 'Node shutting down' &&\n message !== 'Node shutting down.')))\n ) {\n return false;\n }\n\n // Postgres.js already ejects a severed reserved connection.\n // Acquire a new reservation before replaying the safe read.\n state.connection = await driver.acquireConnection();\n return true;\n },\n this.retryDiagnostic\n ? {\n ...this.retryDiagnostic,\n operationKind,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined\n );\n },\n streamQuery: (compiledQuery, chunkSize) => {\n if (chunkSize === undefined) {\n throw new Error('Postgres stream chunk size is required');\n }\n return state.connection.streamQuery(compiledQuery, chunkSize);\n },\n };\n connections.set(connection, state);\n return connection;\n },\n beginTransaction: async (connection, settings) => {\n const state = getConnection(connection);\n state.inTransaction = true;\n try {\n await driver.beginTransaction(state.connection, settings);\n } catch (error) {\n state.inTransaction = false;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.commitTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.rollbackTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n driver.savepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n driver.rollbackToSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n driver.releaseSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseConnection: async (connection) => {\n await driver.releaseConnection(getConnection(connection).connection);\n connections.delete(connection);\n },\n destroy: () => driver.destroy(),\n };\n }\n}\n\nexport type Kysely = K<DB>;\nexport type ControlPlaneKysely = K<ControlPlaneDB>;\nexport type ControlPlaneTransaction = T<ControlPlaneDB>;\nexport function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts) {\n console.debug('Creating Kysely instance');\n const emitRetryDiagnostic =\n options?.onRetryDiagnostic ??\n (options?.repositoryName\n ? (diagnostic: PostgresRetryDiagnostic) =>\n console.warn('Postgres operation retry diagnostic', diagnostic)\n : undefined);\n const reserveConnection = postgres.reserve.bind(postgres);\n postgres.reserve = async () => {\n const connection = await retryPostgres(\n reserveConnection,\n isRetryableConnectionAcquisitionError,\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n operationKind: 'acquisition',\n repositoryName: options?.repositoryName,\n shouldEmit: isRetryableConnectionAcquisitionError,\n }\n : undefined\n );\n if (options?.hyperdrive) {\n const unsafe = connection.unsafe;\n connection.unsafe = (query, parameters, queryOptions) =>\n unsafe(query, parameters, { ...queryOptions, prepare: true });\n }\n return connection;\n };\n const kysely = getKysely<Database>(\n new RetryingPostgresJSDialect(\n { postgres },\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n repositoryName: options?.repositoryName,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined\n ),\n {\n repositoryName: options?.repositoryName,\n log: options?.log,\n }\n );\n kysely.destroy = async () => {\n console.debug('Closing Kysely connection');\n await postgres.end({ timeout: 5 }).catch(() => undefined);\n const index = _connections.indexOf(postgres);\n if (index !== -1) _connections.splice(index, 1);\n };\n\n return kysely;\n}\n\nlet _connections: postgres.Sql[] = [];\nexport async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {\n const delayMs = 2500;\n const probe = opt?.probe === true;\n const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;\n const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${ssl}, and port=${url.port}`\n );\n if (_connections.length > 0)\n console.warn(`We already have ${_connections.length} Postgres connections`);\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n let sql: Sql | undefined;\n try {\n sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // enable prepare statements, pgbouncer on crunchy allows for prepared statements\n prepare: true,\n ...(opt?.hyperdrive\n ? {\n max: 5,\n // Retire idle clients before Hyperdrive can close them asynchronously.\n idle_timeout: 10,\n }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\n }),\n });\n\n if (probe) {\n await sql`select 1`;\n }\n // statement_timeout/lock_timeout are role-level settings on the cluster\n // (ALTER ROLE application SET ...) so they cover every pooled\n // connection; per-session SETs here only ever applied to one of them\n\n _connections.push(sql);\n return sql;\n } catch (err) {\n await sql?.end({ timeout: 0 }).catch(() => undefined);\n if (attempt === retries) throw err;\n console.warn(\n `Postgres connection failed (attempt ${attempt}), retrying...`\n );\n console.error('error', err);\n await new Promise((res) => setTimeout(res, delayMs));\n }\n }\n throw new KyselyError('Unable to connect to Postgres');\n}\n\nexport async function useAsyncKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return useKysely(sql, opt);\n}\n\nexport async function useAsyncNeonWebSocketKysely(\n connectionString: string,\n opt?: Pick<PgOpt, 'probe'> & KyselyOpts\n) {\n const pool = new Pool({ connectionString, max: 5 });\n const kysely = getKysely<DB>(new PostgresDialect({ pool }), opt ?? {});\n kysely.destroy = async () => {\n console.debug('Closing Neon WebSocket Kysely connection');\n await pool.end();\n };\n if (opt?.probe) await pool.query('select 1');\n return kysely;\n}\n\nexport async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return withControlPlaneSchema(useKysely<ControlPlaneDB>(sql, opt), 'public');\n}\n\nexport async function forceCloseAllPostgres(timeoutMs = 5000) {\n await Promise.race([\n Promise.all(\n _connections.map((pg) =>\n pg.end({ timeout: timeoutMs / 1000 }).catch(() => undefined)\n )\n ),\n new Promise((res) => setTimeout(res, timeoutMs + 1000)),\n ]);\n _connections = [];\n}\n"]}
|