@vrplatform/kysely 1.3.45-stage.6299 → 1.3.45-stage.63
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 +0 -0
- package/build/main/control-plane/index.d.ts +260 -0
- package/build/main/control-plane/index.js.map +1 -1
- package/build/main/index.d.ts +2 -2
- package/build/main/index.js +100 -20
- 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 +12 -0
- package/build/main/local/index.js.map +1 -1
- package/build/main/test/index.d.ts +0 -3
- package/build/main/test/index.js +0 -9
- package/build/main/test/index.js.map +1 -1
- package/build/main/v1.generated.d.ts +242 -0
- 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/0000000000023-line-classification-usage.ts +325 -0
- package/build/migrations-v2/0000000000024-tenant-region-migration.ts +108 -0
- package/build/migrations-v2/0000000000025-partner-ach-denial-default.ts +30 -0
- package/build/migrations-v2/0000000000026-line-classification-usage-capture.ts +399 -0
- package/build/migrations-v2/0000000000027-payout-replacement-chain.ts +27 -0
- package/build/migrations-v2/0000000000028-accounting-integrity-operator-workflow.ts +108 -0
- package/build/migrations-v2/0000000000029-accounting-integrity-definition-artifacts.ts +40 -0
- package/build/migrations-v2/0000000000030-accounting-integrity-review-metadata-compatibility.ts +49 -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/module/control-plane/index.d.ts +260 -0
- package/build/module/control-plane/index.js.map +1 -1
- package/build/module/index.d.ts +2 -2
- package/build/module/index.js +102 -21
- 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 +12 -0
- package/build/module/local/index.js.map +1 -1
- package/build/module/test/index.d.ts +0 -3
- package/build/module/test/index.js +0 -9
- package/build/module/test/index.js.map +1 -1
- package/build/module/v1.generated.d.ts +242 -0
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import { sql } from 'kysely';
|
|
3
|
+
|
|
4
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
5
|
+
await sql`
|
|
6
|
+
alter table public.connection
|
|
7
|
+
drop constraint connection_tenant_id_fkey,
|
|
8
|
+
add constraint connection_tenant_id_fkey
|
|
9
|
+
foreign key (tenant_id)
|
|
10
|
+
references public.tenant(id)
|
|
11
|
+
on update restrict
|
|
12
|
+
on delete cascade
|
|
13
|
+
`.execute(db);
|
|
14
|
+
await sql`
|
|
15
|
+
alter table accounting.account_reservation_line_type
|
|
16
|
+
drop constraint account_reservation_line_type_account_id_fkey,
|
|
17
|
+
add constraint account_reservation_line_type_account_id_fkey
|
|
18
|
+
foreign key (account_id)
|
|
19
|
+
references accounting.account(id)
|
|
20
|
+
on update restrict
|
|
21
|
+
on delete cascade
|
|
22
|
+
`.execute(db);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
26
|
+
await sql`
|
|
27
|
+
alter table accounting.account_reservation_line_type
|
|
28
|
+
drop constraint account_reservation_line_type_account_id_fkey,
|
|
29
|
+
add constraint account_reservation_line_type_account_id_fkey
|
|
30
|
+
foreign key (account_id)
|
|
31
|
+
references accounting.account(id)
|
|
32
|
+
on update restrict
|
|
33
|
+
on delete restrict
|
|
34
|
+
`.execute(db);
|
|
35
|
+
await sql`
|
|
36
|
+
alter table public.connection
|
|
37
|
+
drop constraint connection_tenant_id_fkey,
|
|
38
|
+
add constraint connection_tenant_id_fkey
|
|
39
|
+
foreign key (tenant_id)
|
|
40
|
+
references public.tenant(id)
|
|
41
|
+
on update restrict
|
|
42
|
+
on delete restrict
|
|
43
|
+
`.execute(db);
|
|
44
|
+
}
|
|
@@ -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[];
|
|
@@ -42,6 +43,36 @@ export interface ControlPlaneAccountingIntegrityEvaluation {
|
|
|
42
43
|
status: string;
|
|
43
44
|
updatedAt: Generated<Timestamp>;
|
|
44
45
|
}
|
|
46
|
+
export interface ControlPlaneAccountingIntegrityDefinitionDraft {
|
|
47
|
+
artifact: Json;
|
|
48
|
+
artifactHash: string;
|
|
49
|
+
code: string;
|
|
50
|
+
createdAt: Generated<Timestamp>;
|
|
51
|
+
id: Generated<string>;
|
|
52
|
+
ownerId: string;
|
|
53
|
+
previewResult: Json | null;
|
|
54
|
+
rationale: string;
|
|
55
|
+
revision: Generated<number>;
|
|
56
|
+
status: string;
|
|
57
|
+
templateId: string;
|
|
58
|
+
templateVersion: number;
|
|
59
|
+
title: string;
|
|
60
|
+
updatedAt: Generated<Timestamp>;
|
|
61
|
+
validationResult: Json | null;
|
|
62
|
+
}
|
|
63
|
+
export interface ControlPlaneAccountingIntegrityDefinitionVersion {
|
|
64
|
+
artifact: Json;
|
|
65
|
+
artifactHash: string;
|
|
66
|
+
code: string;
|
|
67
|
+
draftId: string;
|
|
68
|
+
id: Generated<string>;
|
|
69
|
+
publishedAt: Generated<Timestamp>;
|
|
70
|
+
publishedBy: string;
|
|
71
|
+
rollout: string;
|
|
72
|
+
templateId: string;
|
|
73
|
+
templateVersion: number;
|
|
74
|
+
version: number;
|
|
75
|
+
}
|
|
45
76
|
export interface ControlPlaneBookingChannel {
|
|
46
77
|
channelRef: string | null;
|
|
47
78
|
color: string | null;
|
|
@@ -74,6 +105,92 @@ export interface ControlPlaneBookingChannelIconCandidate {
|
|
|
74
105
|
export interface ControlPlaneCurrency {
|
|
75
106
|
name: string;
|
|
76
107
|
}
|
|
108
|
+
export type DestructiveJobStep = 'completed' | 'completion_effects' | 'control_plane_deleted' | 'control_plane_deleting' | 'queued' | 'regional_deleted' | 'regional_deleting' | 'validated';
|
|
109
|
+
export interface ControlPlaneDestructiveJob {
|
|
110
|
+
attempts: Generated<number>;
|
|
111
|
+
authorizedByTenantId: string;
|
|
112
|
+
availableAt: Generated<Timestamp>;
|
|
113
|
+
claimedAt: Timestamp | null;
|
|
114
|
+
claimedBy: string | null;
|
|
115
|
+
completedAt: Timestamp | null;
|
|
116
|
+
completionData: Json | null;
|
|
117
|
+
completionWarningCode: string | null;
|
|
118
|
+
completionWarningDetails: Json | null;
|
|
119
|
+
createdAt: Generated<Timestamp>;
|
|
120
|
+
dataRegion: TenantDataRegion;
|
|
121
|
+
failureCode: string | null;
|
|
122
|
+
failureDetails: Json | null;
|
|
123
|
+
force: Generated<boolean>;
|
|
124
|
+
id: Generated<string>;
|
|
125
|
+
jobType: 'tenant.delete';
|
|
126
|
+
maxAttempts: Generated<number>;
|
|
127
|
+
requestId: string | null;
|
|
128
|
+
requestedByActorType: 'api_key' | 'system' | 'user';
|
|
129
|
+
requestedByTenantId: string;
|
|
130
|
+
requestedByUserId: string | null;
|
|
131
|
+
startedAt: Timestamp | null;
|
|
132
|
+
status: Generated<'canceled' | 'completed' | 'failed' | 'queued' | 'running'>;
|
|
133
|
+
step: Generated<DestructiveJobStep>;
|
|
134
|
+
targetId: string;
|
|
135
|
+
triggerRunId: string | null;
|
|
136
|
+
updatedAt: Generated<Timestamp>;
|
|
137
|
+
}
|
|
138
|
+
export interface ControlPlaneDestructiveJobAttempt {
|
|
139
|
+
attemptNumber: number;
|
|
140
|
+
failureCode: string | null;
|
|
141
|
+
failureDetails: Json | null;
|
|
142
|
+
finishedAt: Timestamp | null;
|
|
143
|
+
id: Generated<string>;
|
|
144
|
+
jobId: string;
|
|
145
|
+
startedAt: Generated<Timestamp>;
|
|
146
|
+
status: Generated<'completed' | 'failed' | 'running' | 'superseded'>;
|
|
147
|
+
step: DestructiveJobStep;
|
|
148
|
+
triggerRunId: string | null;
|
|
149
|
+
}
|
|
150
|
+
export interface ControlPlaneDestructiveJobOperation {
|
|
151
|
+
action: 'abandon' | 'cancel' | 'retry';
|
|
152
|
+
actor: string;
|
|
153
|
+
createdAt: Generated<Timestamp>;
|
|
154
|
+
id: Generated<string>;
|
|
155
|
+
jobId: string;
|
|
156
|
+
previousStatus: string;
|
|
157
|
+
previousStep: string;
|
|
158
|
+
reasonCode: string;
|
|
159
|
+
}
|
|
160
|
+
export interface ControlPlaneOperation {
|
|
161
|
+
createdAt: Generated<Timestamp>;
|
|
162
|
+
failureCode: string | null;
|
|
163
|
+
failureMessage: string | null;
|
|
164
|
+
finishedAt: Timestamp | null;
|
|
165
|
+
id: Generated<string>;
|
|
166
|
+
initiatedByUserId: string | null;
|
|
167
|
+
requesterTenantId: string;
|
|
168
|
+
retainUntil: Timestamp | null;
|
|
169
|
+
sourceRegion: TenantDataRegion | null;
|
|
170
|
+
sourceVersion: Generated<number>;
|
|
171
|
+
startedAt: Timestamp | null;
|
|
172
|
+
status: Generated<'completed' | 'failed' | 'queued' | 'running'>;
|
|
173
|
+
type: string;
|
|
174
|
+
updatedAt: Generated<Timestamp>;
|
|
175
|
+
}
|
|
176
|
+
export interface ControlPlaneOperationResource {
|
|
177
|
+
createdAt: Generated<Timestamp>;
|
|
178
|
+
isPrimary: Generated<boolean>;
|
|
179
|
+
operationId: string;
|
|
180
|
+
resourceId: string;
|
|
181
|
+
resourceType: string;
|
|
182
|
+
role: 'result' | 'source' | 'target';
|
|
183
|
+
}
|
|
184
|
+
export interface ControlPlaneOperationSource {
|
|
185
|
+
finishedAt: Timestamp | null;
|
|
186
|
+
operationId: string;
|
|
187
|
+
required: Generated<boolean>;
|
|
188
|
+
sourceId: string;
|
|
189
|
+
sourceType: 'destructive-job' | 'regional-operation';
|
|
190
|
+
sourceVersion: Generated<number>;
|
|
191
|
+
startedAt: Timestamp | null;
|
|
192
|
+
status: Generated<'completed' | 'failed' | 'queued' | 'running'>;
|
|
193
|
+
}
|
|
77
194
|
export interface ControlPlaneEvent {
|
|
78
195
|
createdAt: Generated<Timestamp>;
|
|
79
196
|
id: Generated<string>;
|
|
@@ -85,6 +202,27 @@ export interface ControlPlaneEvent {
|
|
|
85
202
|
trackedAt: Generated<Timestamp | null>;
|
|
86
203
|
userId: string | null;
|
|
87
204
|
}
|
|
205
|
+
export interface ControlPlaneTrackingQueueFailure {
|
|
206
|
+
bodyFingerprint: string | null;
|
|
207
|
+
capturedAt: Generated<Timestamp>;
|
|
208
|
+
dispositionAt: Timestamp | null;
|
|
209
|
+
dispositionHistory: Generated<Json[]>;
|
|
210
|
+
dispositionReasonCode: string | null;
|
|
211
|
+
dispositionActor: string | null;
|
|
212
|
+
environment: 'production' | 'staging';
|
|
213
|
+
event: Json | null;
|
|
214
|
+
eventId: string | null;
|
|
215
|
+
expiresAt: Timestamp;
|
|
216
|
+
failureCode: string;
|
|
217
|
+
id: Generated<string>;
|
|
218
|
+
lastReplayedAt: Timestamp | null;
|
|
219
|
+
queueMessageId: string;
|
|
220
|
+
replayCount: Generated<number>;
|
|
221
|
+
recurrenceCount: Generated<number>;
|
|
222
|
+
status: Generated<'captured' | 'discarded' | 'replayed'>;
|
|
223
|
+
updatedAt: Generated<Timestamp>;
|
|
224
|
+
validationIssues: Json | null;
|
|
225
|
+
}
|
|
88
226
|
export interface ControlPlaneConnectionRoute {
|
|
89
227
|
connectionId: string;
|
|
90
228
|
createdAt: Generated<Timestamp>;
|
|
@@ -119,6 +257,25 @@ export interface ControlPlaneFeatureApproval {
|
|
|
119
257
|
updatedAt: Generated<Timestamp>;
|
|
120
258
|
userId: string;
|
|
121
259
|
}
|
|
260
|
+
export interface ControlPlaneFlow {
|
|
261
|
+
appId: string;
|
|
262
|
+
createdAt: Generated<Timestamp>;
|
|
263
|
+
description: string | null;
|
|
264
|
+
eventListening: Generated<Json>;
|
|
265
|
+
id: Generated<string>;
|
|
266
|
+
isPublic: Generated<boolean>;
|
|
267
|
+
leftType: string | null;
|
|
268
|
+
mappingSchema: Generated<Json>;
|
|
269
|
+
revision: Generated<number>;
|
|
270
|
+
rightType: string | null;
|
|
271
|
+
runSchema: Generated<Json>;
|
|
272
|
+
settingSchema: Generated<Json>;
|
|
273
|
+
title: string;
|
|
274
|
+
type: 'pull' | 'push' | null;
|
|
275
|
+
uniqueRef: string;
|
|
276
|
+
updatedAt: Generated<Timestamp>;
|
|
277
|
+
useGlobalMapping: Generated<boolean>;
|
|
278
|
+
}
|
|
122
279
|
export interface ControlPlaneIssueMessageOverwrite {
|
|
123
280
|
createdAt: Generated<Timestamp>;
|
|
124
281
|
id: Generated<string>;
|
|
@@ -126,6 +283,74 @@ export interface ControlPlaneIssueMessageOverwrite {
|
|
|
126
283
|
pattern: string;
|
|
127
284
|
updatedAt: Generated<Timestamp>;
|
|
128
285
|
}
|
|
286
|
+
export interface ControlPlaneLineClassification {
|
|
287
|
+
appConflict: Generated<boolean>;
|
|
288
|
+
appId: string | null;
|
|
289
|
+
createdAt: Generated<Timestamp>;
|
|
290
|
+
firstSeenAt: Timestamp;
|
|
291
|
+
id: Generated<string>;
|
|
292
|
+
kind: string;
|
|
293
|
+
lastSeenAt: Timestamp;
|
|
294
|
+
name: string;
|
|
295
|
+
updatedAt: Generated<Timestamp>;
|
|
296
|
+
}
|
|
297
|
+
export interface ControlPlaneLineClassificationTeamUsage {
|
|
298
|
+
classificationId: string;
|
|
299
|
+
createdAt: Generated<Timestamp>;
|
|
300
|
+
dataRegion: string;
|
|
301
|
+
firstSeenAt: Timestamp;
|
|
302
|
+
lastSeenAt: Timestamp;
|
|
303
|
+
mappingStatus: string | null;
|
|
304
|
+
revision: number;
|
|
305
|
+
tenantId: string;
|
|
306
|
+
updatedAt: Generated<Timestamp>;
|
|
307
|
+
}
|
|
308
|
+
export interface ControlPlaneReservationLineDefault {
|
|
309
|
+
accountKey: string | null;
|
|
310
|
+
bookingChannel: string | null;
|
|
311
|
+
bookingChannelKey: Generated<string>;
|
|
312
|
+
classificationId: string;
|
|
313
|
+
createdAt: Generated<Timestamp>;
|
|
314
|
+
id: Generated<string>;
|
|
315
|
+
partnerTenantId: string | null;
|
|
316
|
+
revenueRecognition: string | null;
|
|
317
|
+
revision: Generated<number>;
|
|
318
|
+
updatedAt: Generated<Timestamp>;
|
|
319
|
+
}
|
|
320
|
+
export interface ControlPlaneRolloutMonitorSnapshot {
|
|
321
|
+
monitorName: string;
|
|
322
|
+
result: Json;
|
|
323
|
+
snapshotDate: Timestamp;
|
|
324
|
+
}
|
|
325
|
+
export interface ControlPlaneTransactionLineMapping {
|
|
326
|
+
accountAssignmentType: string | null;
|
|
327
|
+
createdAt: Generated<Timestamp>;
|
|
328
|
+
deletedAt: Timestamp | null;
|
|
329
|
+
id: Generated<string>;
|
|
330
|
+
lineType: string;
|
|
331
|
+
revision: Generated<number>;
|
|
332
|
+
updatedAt: Generated<Timestamp>;
|
|
333
|
+
}
|
|
334
|
+
export interface ControlPlaneGeneralLedgerDefaultSet {
|
|
335
|
+
createdAt: Generated<Timestamp>;
|
|
336
|
+
id: Generated<string>;
|
|
337
|
+
partnerTenantId: string | null;
|
|
338
|
+
publishedVersion: number | null;
|
|
339
|
+
sourceDataRegion: string;
|
|
340
|
+
sourceDigest: string | null;
|
|
341
|
+
sourceTenantId: string;
|
|
342
|
+
templateKey: string;
|
|
343
|
+
updatedAt: Generated<Timestamp>;
|
|
344
|
+
}
|
|
345
|
+
export interface ControlPlaneGeneralLedgerDefaultVersion {
|
|
346
|
+
dataJson: Json;
|
|
347
|
+
defaultSetId: string;
|
|
348
|
+
id: Generated<string>;
|
|
349
|
+
publishedAt: Generated<Timestamp>;
|
|
350
|
+
sourceDigest: string;
|
|
351
|
+
sourceTenantId: string;
|
|
352
|
+
version: number;
|
|
353
|
+
}
|
|
129
354
|
export interface ControlPlaneOutbox {
|
|
130
355
|
aggregateId: string;
|
|
131
356
|
aggregateType: string;
|
|
@@ -151,6 +376,7 @@ export interface ControlPlaneTenant {
|
|
|
151
376
|
createdAt: Generated<Timestamp>;
|
|
152
377
|
dataRegion: Generated<string>;
|
|
153
378
|
id: Generated<string>;
|
|
379
|
+
migrationStatus: Generated<string>;
|
|
154
380
|
name: string;
|
|
155
381
|
partnerId: string | null;
|
|
156
382
|
partnerDeniedPermissions: Generated<string[]>;
|
|
@@ -161,6 +387,21 @@ export interface ControlPlaneTenant {
|
|
|
161
387
|
uniqueRef: string | null;
|
|
162
388
|
updatedAt: Generated<Timestamp | null>;
|
|
163
389
|
}
|
|
390
|
+
export interface ControlPlaneTenantRegionMigration {
|
|
391
|
+
actor: string;
|
|
392
|
+
completedAt: Timestamp | null;
|
|
393
|
+
error: Json | null;
|
|
394
|
+
id: string;
|
|
395
|
+
reason: string;
|
|
396
|
+
sourceManifest: Json | null;
|
|
397
|
+
sourceRegion: string;
|
|
398
|
+
startedAt: Generated<Timestamp>;
|
|
399
|
+
status: Generated<string>;
|
|
400
|
+
targetManifest: Json | null;
|
|
401
|
+
targetRegion: string;
|
|
402
|
+
tenantId: string;
|
|
403
|
+
updatedAt: Generated<Timestamp>;
|
|
404
|
+
}
|
|
164
405
|
export interface ControlPlaneTenantUser {
|
|
165
406
|
createdAt: Generated<Timestamp | null>;
|
|
166
407
|
id: Generated<string>;
|
|
@@ -189,6 +430,7 @@ export interface ControlPlaneUser {
|
|
|
189
430
|
email: string | null;
|
|
190
431
|
firstName: string | null;
|
|
191
432
|
id: Generated<string>;
|
|
433
|
+
internalOperationGrants: Generated<string[]>;
|
|
192
434
|
isAdmin: Generated<boolean>;
|
|
193
435
|
lastName: string | null;
|
|
194
436
|
lastSeen: Timestamp | null;
|
|
@@ -202,6 +444,8 @@ export interface ControlPlaneUser {
|
|
|
202
444
|
updatedAt: Generated<Timestamp | null>;
|
|
203
445
|
}
|
|
204
446
|
export interface ControlPlaneDB {
|
|
447
|
+
'controlPlane.accountingIntegrityDefinitionDraft': ControlPlaneAccountingIntegrityDefinitionDraft;
|
|
448
|
+
'controlPlane.accountingIntegrityDefinitionVersion': ControlPlaneAccountingIntegrityDefinitionVersion;
|
|
205
449
|
'controlPlane.accountingIntegrityEvaluation': ControlPlaneAccountingIntegrityEvaluation;
|
|
206
450
|
'controlPlane.app': ControlPlaneApp;
|
|
207
451
|
'controlPlane.bookingChannel': ControlPlaneBookingChannel;
|
|
@@ -209,15 +453,31 @@ export interface ControlPlaneDB {
|
|
|
209
453
|
'controlPlane.connectionRoute': ControlPlaneConnectionRoute;
|
|
210
454
|
'controlPlane.controlPlaneOutbox': ControlPlaneOutbox;
|
|
211
455
|
'controlPlane.currency': ControlPlaneCurrency;
|
|
456
|
+
'controlPlane.destructiveJob': ControlPlaneDestructiveJob;
|
|
457
|
+
'controlPlane.destructiveJobAttempt': ControlPlaneDestructiveJobAttempt;
|
|
458
|
+
'controlPlane.destructiveJobOperation': ControlPlaneDestructiveJobOperation;
|
|
212
459
|
'controlPlane.events': ControlPlaneEvent;
|
|
213
460
|
'controlPlane.feature': ControlPlaneFeature;
|
|
214
461
|
'controlPlane.featureApproval': ControlPlaneFeatureApproval;
|
|
215
462
|
'controlPlane.featureEnabledTeam': ControlPlaneFeatureEnabledTeam;
|
|
463
|
+
'controlPlane.generalLedgerDefaultSet': ControlPlaneGeneralLedgerDefaultSet;
|
|
464
|
+
'controlPlane.generalLedgerDefaultVersion': ControlPlaneGeneralLedgerDefaultVersion;
|
|
465
|
+
'controlPlane.lineClassification': ControlPlaneLineClassification;
|
|
466
|
+
'controlPlane.lineClassificationTeamUsage': ControlPlaneLineClassificationTeamUsage;
|
|
467
|
+
'controlPlane.operation': ControlPlaneOperation;
|
|
468
|
+
'controlPlane.operationResource': ControlPlaneOperationResource;
|
|
469
|
+
'controlPlane.operationSource': ControlPlaneOperationSource;
|
|
216
470
|
'controlPlane.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;
|
|
471
|
+
'controlPlane.reservationLineDefault': ControlPlaneReservationLineDefault;
|
|
472
|
+
'controlPlane.rolloutMonitorSnapshot': ControlPlaneRolloutMonitorSnapshot;
|
|
217
473
|
'controlPlane.tenant': ControlPlaneTenant;
|
|
474
|
+
'controlPlane.tenantRegionMigration': ControlPlaneTenantRegionMigration;
|
|
218
475
|
'controlPlane.tenantUser': ControlPlaneTenantUser;
|
|
476
|
+
'controlPlane.trackingQueueFailure': ControlPlaneTrackingQueueFailure;
|
|
219
477
|
'controlPlane.token': ControlPlaneToken;
|
|
478
|
+
'controlPlane.transactionLineMapping': ControlPlaneTransactionLineMapping;
|
|
220
479
|
'controlPlane.user': ControlPlaneUser;
|
|
480
|
+
'controlPlaneCore.flow': ControlPlaneFlow;
|
|
221
481
|
'controlPlaneCore.issueMessageOverwrite': ControlPlaneIssueMessageOverwrite;
|
|
222
482
|
}
|
|
223
483
|
export declare function withControlPlaneSchema(kysely: Kysely<ControlPlaneDB>, schema: string, issueMessageOverwriteSchema?: string): Kysely<ControlPlaneDB>;
|
|
@@ -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;AAgQhB,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 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 ControlPlaneIssueMessageOverwrite {\n createdAt: Generated<Timestamp>;\n id: Generated<string>;\n message: string;\n pattern: string;\n updatedAt: Generated<Timestamp>;\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 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 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 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.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.partnerManagedTeamAssignment': ControlPlanePartnerManagedTeamAssignment;\n 'controlPlane.tenant': ControlPlaneTenant;\n 'controlPlane.tenantUser': ControlPlaneTenantUser;\n 'controlPlane.token': ControlPlaneToken;\n 'controlPlane.user': ControlPlaneUser;\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;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"]}
|
package/build/module/index.d.ts
CHANGED
|
@@ -10,15 +10,15 @@ export * from './regional';
|
|
|
10
10
|
export * from './transaction';
|
|
11
11
|
import type { DB } from './v1.generated';
|
|
12
12
|
type KyselyOpts = {
|
|
13
|
+
hyperdrive?: true;
|
|
13
14
|
repositoryName?: string;
|
|
14
15
|
log?: true | LogConfig;
|
|
15
16
|
};
|
|
16
17
|
type PgOpt = {
|
|
17
18
|
forceDisableSSL?: boolean;
|
|
18
|
-
hyperdrive?: true;
|
|
19
19
|
probe?: true;
|
|
20
20
|
retries?: false | number;
|
|
21
|
-
}
|
|
21
|
+
} & Pick<KyselyOpts, 'hyperdrive'>;
|
|
22
22
|
export type Kysely = K<DB>;
|
|
23
23
|
export type ControlPlaneKysely = K<ControlPlaneDB>;
|
|
24
24
|
export type ControlPlaneTransaction = T<ControlPlaneDB>;
|
package/build/module/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { backOff } from 'exponential-backoff';
|
|
2
|
-
import { PostgresJSDialect } from 'kysely-postgres-js';
|
|
2
|
+
import { PostgresJSDialect, PostgresJSDriver, } from 'kysely-postgres-js';
|
|
3
3
|
import postgres from 'postgres';
|
|
4
4
|
import { withControlPlaneSchema } from './control-plane';
|
|
5
5
|
import { KyselyError } from './error';
|
|
@@ -15,40 +15,121 @@ const retryableMessages = [
|
|
|
15
15
|
'CONNECTION_CLOSED',
|
|
16
16
|
'CONNECT_TIMEOUT',
|
|
17
17
|
'Idle connection closed by Hyperdrive.',
|
|
18
|
+
'server_login_retry',
|
|
18
19
|
];
|
|
20
|
+
const postgresRetryAttempts = 3;
|
|
19
21
|
function isRetryableConnectionError(error) {
|
|
20
22
|
const message = error instanceof Error ? error.message : String(error);
|
|
21
23
|
return retryableMessages.some((retryable) => message.includes(retryable));
|
|
22
24
|
}
|
|
23
25
|
function retryPostgres(operation, retry) {
|
|
24
26
|
return backOff(operation, {
|
|
25
|
-
numOfAttempts:
|
|
27
|
+
numOfAttempts: postgresRetryAttempts,
|
|
26
28
|
startingDelay: parseDuration('1s'),
|
|
27
29
|
maxDelay: parseDuration('5s'),
|
|
28
|
-
retry,
|
|
30
|
+
retry: (error, attemptNumber) => attemptNumber < postgresRetryAttempts && retry(error, attemptNumber),
|
|
29
31
|
});
|
|
30
32
|
}
|
|
33
|
+
class RetryingPostgresJSDialect extends PostgresJSDialect {
|
|
34
|
+
config;
|
|
35
|
+
constructor(config) {
|
|
36
|
+
super(config);
|
|
37
|
+
this.config = config;
|
|
38
|
+
}
|
|
39
|
+
createDriver() {
|
|
40
|
+
const driver = new PostgresJSDriver(this.config);
|
|
41
|
+
const connections = new WeakMap();
|
|
42
|
+
const getConnection = (connection) => {
|
|
43
|
+
const state = connections.get(connection);
|
|
44
|
+
if (!state)
|
|
45
|
+
throw new Error('Postgres connection state is unavailable');
|
|
46
|
+
return state;
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
init: () => driver.init(),
|
|
50
|
+
acquireConnection: async () => {
|
|
51
|
+
const state = {
|
|
52
|
+
connection: await driver.acquireConnection(),
|
|
53
|
+
inTransaction: false,
|
|
54
|
+
};
|
|
55
|
+
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
|
+
}),
|
|
71
|
+
streamQuery: (compiledQuery, chunkSize) => {
|
|
72
|
+
if (chunkSize === undefined) {
|
|
73
|
+
throw new Error('Postgres stream chunk size is required');
|
|
74
|
+
}
|
|
75
|
+
return state.connection.streamQuery(compiledQuery, chunkSize);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
connections.set(connection, state);
|
|
79
|
+
return connection;
|
|
80
|
+
},
|
|
81
|
+
beginTransaction: async (connection, settings) => {
|
|
82
|
+
const state = getConnection(connection);
|
|
83
|
+
state.inTransaction = true;
|
|
84
|
+
try {
|
|
85
|
+
await driver.beginTransaction(state.connection, settings);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
state.inTransaction = false;
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
commitTransaction: async (connection) => {
|
|
93
|
+
const state = getConnection(connection);
|
|
94
|
+
try {
|
|
95
|
+
await driver.commitTransaction(state.connection);
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
state.inTransaction = false;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
rollbackTransaction: async (connection) => {
|
|
102
|
+
const state = getConnection(connection);
|
|
103
|
+
try {
|
|
104
|
+
await driver.rollbackTransaction(state.connection);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
state.inTransaction = false;
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
savepoint: (connection, savepointName, compileQuery) => driver.savepoint(getConnection(connection).connection, savepointName, compileQuery),
|
|
111
|
+
rollbackToSavepoint: (connection, savepointName, compileQuery) => driver.rollbackToSavepoint(getConnection(connection).connection, savepointName, compileQuery),
|
|
112
|
+
releaseSavepoint: (connection, savepointName, compileQuery) => driver.releaseSavepoint(getConnection(connection).connection, savepointName, compileQuery),
|
|
113
|
+
releaseConnection: async (connection) => {
|
|
114
|
+
await driver.releaseConnection(getConnection(connection).connection);
|
|
115
|
+
connections.delete(connection);
|
|
116
|
+
},
|
|
117
|
+
destroy: () => driver.destroy(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
31
121
|
export function useKysely(postgres, options) {
|
|
32
122
|
console.debug('Creating Kysely instance');
|
|
33
123
|
const reserveConnection = postgres.reserve.bind(postgres);
|
|
34
|
-
postgres.reserve = () =>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
(message ===
|
|
44
|
-
'Egress connection severed outside of Hyperdrive' ||
|
|
45
|
-
message === 'Network connection lost.'))) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
}), {
|
|
124
|
+
postgres.reserve = async () => {
|
|
125
|
+
const connection = await retryPostgres(reserveConnection, isRetryableConnectionError);
|
|
126
|
+
if (options?.hyperdrive) {
|
|
127
|
+
const unsafe = connection.unsafe;
|
|
128
|
+
connection.unsafe = (query, parameters, queryOptions) => unsafe(query, parameters, { ...queryOptions, prepare: true });
|
|
129
|
+
}
|
|
130
|
+
return connection;
|
|
131
|
+
};
|
|
132
|
+
const kysely = getKysely(new RetryingPostgresJSDialect({ postgres }), {
|
|
52
133
|
repositoryName: options?.repositoryName,
|
|
53
134
|
log: options?.log,
|
|
54
135
|
});
|