@vrplatform/kysely 1.3.45-stage.5710 → 1.3.45-stage.573
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 +331 -16
- package/build/main/control-plane/index.js +61 -0
- package/build/main/control-plane/index.js.map +1 -1
- package/build/main/index.d.ts +17 -4
- package/build/main/index.js +220 -25
- package/build/main/index.js.map +1 -1
- package/build/main/isomorphic.d.ts +4 -2
- package/build/main/isomorphic.js.map +1 -1
- package/build/main/local/digest.d.ts +3 -3
- package/build/main/local/digest.js.map +1 -1
- package/build/main/local/generate.js +2 -0
- package/build/main/local/generate.js.map +1 -1
- package/build/main/local/index.d.ts +5 -1
- package/build/main/local/index.js +316 -6
- 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/listing/status.js +2 -6
- package/build/main/query/listing/status.js.map +1 -1
- package/build/main/query/tenant/status.d.ts +5 -8
- package/build/main/query/tenant/status.js +16 -20
- package/build/main/query/tenant/status.js.map +1 -1
- package/build/main/regional.d.ts +7 -1
- package/build/main/regional.js +14 -9
- package/build/main/regional.js.map +1 -1
- package/build/main/test/index.d.ts +25 -7
- package/build/main/test/index.js +35 -13
- package/build/main/test/index.js.map +1 -1
- package/build/main/transaction.d.ts +3 -3
- package/build/main/transaction.js.map +1 -1
- package/build/main/v1.generated.d.ts +559 -6
- package/build/main/v1.generated.js.map +1 -1
- package/build/migrations-v2/0000000000010-bank-rule-application-bank-record-delete-cascade.ts +26 -0
- package/build/migrations-v2/0000000000011-guest-balance-journal-entry-lookup-index.ts +25 -0
- package/build/migrations-v2/0000000000012-trial-free-analytics-billing-status.ts +72 -0
- package/build/migrations-v2/0000000000013-ui-permission-bundles.ts +45 -0
- package/build/migrations-v2/0000000000014-ui-permission-bundle-top-up.ts +32 -0
- 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/0000000000016-managed-team-access.ts +34 -0
- package/build/migrations-v2/0000000000017-drop-trial-until.ts +42 -0
- package/build/migrations-v2/0000000000017-webhook-secret-reencryption-failures.ts +18 -0
- package/build/migrations-v2/0000000000018-accounting-integrity-monitoring.ts +276 -0
- package/build/migrations-v2/0000000000018-durable-flow-event-sensitive-input.ts +28 -0
- package/build/migrations-v2/0000000000019-accounting-integrity-run-shards.ts +26 -0
- package/build/migrations-v2/0000000000019-asynchronous-operations.ts +736 -0
- package/build/migrations-v2/0000000000020-accounting-integrity-case-classification.ts +52 -0
- package/build/migrations-v2/0000000000021-payment-line-classification-monitor-indexes.ts +31 -0
- package/build/migrations-v2/0000000000022-accounting-integrity-controlled-repairs.ts +281 -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/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/module/control-plane/index.d.ts +331 -16
- package/build/module/control-plane/index.js +49 -1
- package/build/module/control-plane/index.js.map +1 -1
- package/build/module/index.d.ts +17 -4
- package/build/module/index.js +222 -26
- package/build/module/index.js.map +1 -1
- package/build/module/isomorphic.d.ts +4 -2
- package/build/module/isomorphic.js.map +1 -1
- package/build/module/local/digest.d.ts +3 -3
- package/build/module/local/digest.js.map +1 -1
- package/build/module/local/generate.js +2 -0
- package/build/module/local/generate.js.map +1 -1
- package/build/module/local/index.d.ts +5 -1
- package/build/module/local/index.js +317 -7
- 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/listing/status.js +2 -6
- package/build/module/query/listing/status.js.map +1 -1
- package/build/module/query/tenant/status.d.ts +5 -8
- package/build/module/query/tenant/status.js +16 -20
- package/build/module/query/tenant/status.js.map +1 -1
- package/build/module/regional.d.ts +7 -1
- package/build/module/regional.js +14 -9
- package/build/module/regional.js.map +1 -1
- package/build/module/test/index.d.ts +25 -7
- package/build/module/test/index.js +35 -14
- package/build/module/test/index.js.map +1 -1
- package/build/module/transaction.d.ts +3 -3
- package/build/module/transaction.js.map +1 -1
- package/build/module/v1.generated.d.ts +559 -6
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +3 -2
|
@@ -40,6 +40,7 @@ const path = __importStar(require("node:path"));
|
|
|
40
40
|
const pglite_1 = require("@electric-sql/pglite");
|
|
41
41
|
const kysely_1 = require("kysely");
|
|
42
42
|
const kysely_pglite_dialect_1 = require("kysely-pglite-dialect");
|
|
43
|
+
const control_plane_1 = require("../control-plane");
|
|
43
44
|
const migration_1 = require("../migration");
|
|
44
45
|
const plugins_1 = require("../plugins");
|
|
45
46
|
const digest_1 = require("./digest");
|
|
@@ -47,6 +48,7 @@ exports.root = path.join(__dirname, '../..');
|
|
|
47
48
|
exports.dumpPath = path.join(exports.root, '.data.tar');
|
|
48
49
|
async function migrateToLatest(kysely) {
|
|
49
50
|
const migrator = new kysely_1.Migrator({
|
|
51
|
+
allowUnorderedMigrations: true,
|
|
50
52
|
db: kysely,
|
|
51
53
|
migrationTableSchema: migration_1.appMigrationEpoch.tableSchema,
|
|
52
54
|
migrationTableName: migration_1.appMigrationEpoch.tableName,
|
|
@@ -62,21 +64,329 @@ async function migrateToLatest(kysely) {
|
|
|
62
64
|
throw error;
|
|
63
65
|
}
|
|
64
66
|
}
|
|
67
|
+
// Every spec file used to replay this identical bootstrap - migrations, the
|
|
68
|
+
// schema surgery, and the control-plane seed copies - against a freshly loaded
|
|
69
|
+
// snapshot, which measured ~345ms per file against ~185ms for the snapshot load
|
|
70
|
+
// alone. None of it depends on the caller, so it runs once and is cached as a
|
|
71
|
+
// prepared snapshot keyed by everything that determines its content.
|
|
72
|
+
const preparedDumpPrefix = '.data.prepared.';
|
|
73
|
+
let preparedDumpPromise;
|
|
74
|
+
async function preparedDumpKey() {
|
|
75
|
+
const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([
|
|
76
|
+
node_fs_1.promises.stat(exports.dumpPath),
|
|
77
|
+
node_fs_1.promises.readdir(path.join(exports.root, migration_1.appMigrationEpoch.folder)),
|
|
78
|
+
node_fs_1.promises.readdir(path.join(exports.root, 'control-plane-migrations')),
|
|
79
|
+
]);
|
|
80
|
+
const hasher = new Bun.CryptoHasher('sha256');
|
|
81
|
+
hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);
|
|
82
|
+
hasher.update(appMigrations.sort().join(','));
|
|
83
|
+
hasher.update(controlPlaneMigrations.sort().join(','));
|
|
84
|
+
// Source of the bootstrap itself, so editing the surgery rebuilds the
|
|
85
|
+
// snapshot. Read through toString() rather than the file: this module is also
|
|
86
|
+
// published as CommonJS, where import.meta is a compile error.
|
|
87
|
+
for (const step of [
|
|
88
|
+
buildPreparedDump,
|
|
89
|
+
migrateToLatest,
|
|
90
|
+
digest_1.ensureDigestFunction,
|
|
91
|
+
digest_1.ensureGenRandomBytesFunction,
|
|
92
|
+
]) {
|
|
93
|
+
hasher.update(step.toString());
|
|
94
|
+
}
|
|
95
|
+
return hasher.digest('hex').slice(0, 16);
|
|
96
|
+
}
|
|
97
|
+
async function resolvePreparedDump() {
|
|
98
|
+
const key = await preparedDumpKey();
|
|
99
|
+
const target = path.join(exports.root, `${preparedDumpPrefix}${key}.tar`);
|
|
100
|
+
const cached = Bun.file(target);
|
|
101
|
+
if (await cached.exists()) {
|
|
102
|
+
return cached;
|
|
103
|
+
}
|
|
104
|
+
const content = await buildPreparedDump();
|
|
105
|
+
// Sibling workers build this concurrently on a cold cache; rename is atomic,
|
|
106
|
+
// so a reader never observes a half-written snapshot.
|
|
107
|
+
const staging = `${target}.${process.pid}.tmp`;
|
|
108
|
+
await Bun.write(staging, content);
|
|
109
|
+
await node_fs_1.promises.rename(staging, target);
|
|
110
|
+
// Only finished snapshots: a sibling worker's staging file also carries the
|
|
111
|
+
// prefix, and removing it would break its rename.
|
|
112
|
+
const current = path.basename(target);
|
|
113
|
+
for (const entry of await node_fs_1.promises.readdir(exports.root)) {
|
|
114
|
+
if (entry.startsWith(preparedDumpPrefix) &&
|
|
115
|
+
entry.endsWith('.tar') &&
|
|
116
|
+
entry !== current) {
|
|
117
|
+
await node_fs_1.promises.rm(path.join(exports.root, entry), { force: true });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return content;
|
|
121
|
+
}
|
|
122
|
+
async function buildPreparedDump() {
|
|
123
|
+
const pglite = new pglite_1.PGlite({
|
|
124
|
+
loadDataDir: Bun.file(exports.dumpPath),
|
|
125
|
+
});
|
|
126
|
+
const dialect = new kysely_pglite_dialect_1.PGliteDialect(pglite);
|
|
127
|
+
const kysely = (0, plugins_1.getKysely)(dialect, {
|
|
128
|
+
repositoryName: 'localTestingPrepare',
|
|
129
|
+
});
|
|
130
|
+
await (0, digest_1.ensureDigestFunction)(kysely);
|
|
131
|
+
await (0, digest_1.ensureGenRandomBytesFunction)(kysely);
|
|
132
|
+
await migrateToLatest(kysely);
|
|
133
|
+
await (0, kysely_1.sql) `alter schema public rename to regional_public`.execute(kysely);
|
|
134
|
+
await (0, kysely_1.sql) `alter schema core rename to regional_core`.execute(kysely);
|
|
135
|
+
await (0, kysely_1.sql) `create schema public`.execute(kysely);
|
|
136
|
+
await (0, kysely_1.sql) `create schema core`.execute(kysely);
|
|
137
|
+
const controlPlaneBootstrapKysely = (0, plugins_1.getKysely)(dialect, {
|
|
138
|
+
repositoryName: 'localTestingPrepare/control-plane-bootstrap',
|
|
139
|
+
});
|
|
140
|
+
const controlPlaneMigrator = new kysely_1.Migrator({
|
|
141
|
+
db: controlPlaneBootstrapKysely,
|
|
142
|
+
migrationTableSchema: 'public',
|
|
143
|
+
migrationTableName: 'control_plane_kysely_migration',
|
|
144
|
+
migrationLockTableName: 'control_plane_kysely_migration_lock',
|
|
145
|
+
provider: new kysely_1.FileMigrationProvider({
|
|
146
|
+
fs: node_fs_1.promises,
|
|
147
|
+
path,
|
|
148
|
+
migrationFolder: path.join(exports.root, 'control-plane-migrations'),
|
|
149
|
+
}),
|
|
150
|
+
});
|
|
151
|
+
const { error: controlPlaneMigrationError } = await controlPlaneMigrator.migrateToLatest();
|
|
152
|
+
if (controlPlaneMigrationError) {
|
|
153
|
+
throw controlPlaneMigrationError;
|
|
154
|
+
}
|
|
155
|
+
await (0, kysely_1.sql) `alter table core.flow set schema public`.execute(controlPlaneBootstrapKysely);
|
|
156
|
+
await (0, kysely_1.sql) `alter table core.issue_message_overwrite set schema public`.execute(controlPlaneBootstrapKysely);
|
|
157
|
+
await (0, kysely_1.sql) `drop schema core`.execute(controlPlaneBootstrapKysely);
|
|
158
|
+
await (0, kysely_1.sql) `alter schema public rename to control_plane`.execute(controlPlaneBootstrapKysely);
|
|
159
|
+
await (0, kysely_1.sql) `alter schema regional_public rename to public`.execute(controlPlaneBootstrapKysely);
|
|
160
|
+
await (0, kysely_1.sql) `alter schema regional_core rename to core`.execute(controlPlaneBootstrapKysely);
|
|
161
|
+
await (0, kysely_1.sql) `
|
|
162
|
+
do $$
|
|
163
|
+
declare
|
|
164
|
+
definition text;
|
|
165
|
+
begin
|
|
166
|
+
select pg_get_functiondef(
|
|
167
|
+
'control_plane.normalize_tenant_slug(text)'::regprocedure
|
|
168
|
+
) into definition;
|
|
169
|
+
execute replace(definition, 'public.', 'control_plane.');
|
|
170
|
+
|
|
171
|
+
select pg_get_functiondef(
|
|
172
|
+
'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure
|
|
173
|
+
) into definition;
|
|
174
|
+
execute replace(definition, 'public.', 'control_plane.');
|
|
175
|
+
|
|
176
|
+
select pg_get_functiondef(
|
|
177
|
+
'control_plane.refresh_operation_state(uuid)'::regprocedure
|
|
178
|
+
) into definition;
|
|
179
|
+
execute replace(definition, 'public.', 'control_plane.');
|
|
180
|
+
|
|
181
|
+
select pg_get_functiondef(
|
|
182
|
+
'control_plane.refresh_destructive_job_operation()'::regprocedure
|
|
183
|
+
) into definition;
|
|
184
|
+
execute replace(definition, 'public.', 'control_plane.');
|
|
185
|
+
end;
|
|
186
|
+
$$;
|
|
187
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
188
|
+
// The canonical VRPlatform tenant. Production code falls back to this exact id
|
|
189
|
+
// in getCalculatedBillingPartnerId, so specs need it to exist without each of
|
|
190
|
+
// them creating - and mutating - their own copy of a shared singleton.
|
|
191
|
+
await kysely
|
|
192
|
+
.insertInto('public.tenant')
|
|
193
|
+
.values({
|
|
194
|
+
id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',
|
|
195
|
+
name: 'VRPlatform',
|
|
196
|
+
type: 'partner',
|
|
197
|
+
status: 'active',
|
|
198
|
+
isActive: true,
|
|
199
|
+
isGeneralLedger: false,
|
|
200
|
+
isOnboarding: false,
|
|
201
|
+
partnerId: null,
|
|
202
|
+
billingPartnerId: null,
|
|
203
|
+
defaultCurrency: 'usd',
|
|
204
|
+
statementStartAt: new Date('2020-01-01T00:00:00Z'),
|
|
205
|
+
})
|
|
206
|
+
.onConflict((oc) => oc.column('id').doNothing())
|
|
207
|
+
.execute();
|
|
208
|
+
await (0, kysely_1.sql) `
|
|
209
|
+
insert into control_plane.app (
|
|
210
|
+
authentication,
|
|
211
|
+
category,
|
|
212
|
+
color,
|
|
213
|
+
created_at,
|
|
214
|
+
icon,
|
|
215
|
+
icon_round,
|
|
216
|
+
id,
|
|
217
|
+
info,
|
|
218
|
+
name,
|
|
219
|
+
type,
|
|
220
|
+
version
|
|
221
|
+
)
|
|
222
|
+
select
|
|
223
|
+
authentication,
|
|
224
|
+
category,
|
|
225
|
+
color,
|
|
226
|
+
created_at,
|
|
227
|
+
icon,
|
|
228
|
+
icon_round,
|
|
229
|
+
id,
|
|
230
|
+
info,
|
|
231
|
+
name,
|
|
232
|
+
type,
|
|
233
|
+
version
|
|
234
|
+
from public.app
|
|
235
|
+
on conflict (id) do nothing;
|
|
236
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
237
|
+
await (0, kysely_1.sql) `
|
|
238
|
+
insert into control_plane.currency (name)
|
|
239
|
+
select name
|
|
240
|
+
from public.currency
|
|
241
|
+
on conflict (name) do nothing;
|
|
242
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
243
|
+
await (0, kysely_1.sql) `
|
|
244
|
+
insert into control_plane.booking_channel (
|
|
245
|
+
channel_ref,
|
|
246
|
+
color,
|
|
247
|
+
created_at,
|
|
248
|
+
icon,
|
|
249
|
+
icon_provider,
|
|
250
|
+
id,
|
|
251
|
+
last_generate_run,
|
|
252
|
+
logo,
|
|
253
|
+
logo_provider,
|
|
254
|
+
selected_booking_channel_icon_candidate_id,
|
|
255
|
+
selected_booking_channel_logo_candidate_id,
|
|
256
|
+
unique_ref,
|
|
257
|
+
updated_at
|
|
258
|
+
)
|
|
259
|
+
select
|
|
260
|
+
channel_ref,
|
|
261
|
+
color,
|
|
262
|
+
created_at,
|
|
263
|
+
icon,
|
|
264
|
+
icon_provider,
|
|
265
|
+
id,
|
|
266
|
+
last_generate_run,
|
|
267
|
+
logo,
|
|
268
|
+
logo_provider,
|
|
269
|
+
selected_booking_channel_icon_candidate_id,
|
|
270
|
+
selected_booking_channel_logo_candidate_id,
|
|
271
|
+
unique_ref,
|
|
272
|
+
updated_at
|
|
273
|
+
from public.booking_channel
|
|
274
|
+
on conflict (id) do nothing;
|
|
275
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
276
|
+
await (0, kysely_1.sql) `
|
|
277
|
+
insert into control_plane.booking_channel_icon_candidate (
|
|
278
|
+
booking_channel_id,
|
|
279
|
+
cloudflare_image_id,
|
|
280
|
+
color,
|
|
281
|
+
comment,
|
|
282
|
+
created_at,
|
|
283
|
+
external_icon,
|
|
284
|
+
height,
|
|
285
|
+
id,
|
|
286
|
+
provider,
|
|
287
|
+
source,
|
|
288
|
+
updated_at,
|
|
289
|
+
width
|
|
290
|
+
)
|
|
291
|
+
select
|
|
292
|
+
booking_channel_id,
|
|
293
|
+
cloudflare_image_id,
|
|
294
|
+
color,
|
|
295
|
+
comment,
|
|
296
|
+
created_at,
|
|
297
|
+
external_icon,
|
|
298
|
+
height,
|
|
299
|
+
id,
|
|
300
|
+
provider,
|
|
301
|
+
source,
|
|
302
|
+
updated_at,
|
|
303
|
+
width
|
|
304
|
+
from public.booking_channel_icon_candidate
|
|
305
|
+
on conflict (id) do nothing;
|
|
306
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
307
|
+
await (0, kysely_1.sql) `
|
|
308
|
+
insert into control_plane.tenant (
|
|
309
|
+
billing_partner_id,
|
|
310
|
+
billing_plan,
|
|
311
|
+
created_at,
|
|
312
|
+
data_region,
|
|
313
|
+
id,
|
|
314
|
+
name,
|
|
315
|
+
partner_id,
|
|
316
|
+
slug,
|
|
317
|
+
status,
|
|
318
|
+
storage_realm,
|
|
319
|
+
type,
|
|
320
|
+
unique_ref,
|
|
321
|
+
updated_at
|
|
322
|
+
)
|
|
323
|
+
select
|
|
324
|
+
billing_partner_id,
|
|
325
|
+
billing_plan,
|
|
326
|
+
created_at,
|
|
327
|
+
data_region,
|
|
328
|
+
id,
|
|
329
|
+
name,
|
|
330
|
+
partner_id,
|
|
331
|
+
slug,
|
|
332
|
+
status,
|
|
333
|
+
storage_realm,
|
|
334
|
+
type,
|
|
335
|
+
unique_ref,
|
|
336
|
+
updated_at
|
|
337
|
+
from public.tenant
|
|
338
|
+
on conflict (id) do nothing;
|
|
339
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
340
|
+
await (0, kysely_1.sql) `
|
|
341
|
+
insert into control_plane.token (
|
|
342
|
+
created_at,
|
|
343
|
+
expires_at,
|
|
344
|
+
id,
|
|
345
|
+
nano_id,
|
|
346
|
+
payload,
|
|
347
|
+
tenant_id,
|
|
348
|
+
type,
|
|
349
|
+
user_id
|
|
350
|
+
)
|
|
351
|
+
select
|
|
352
|
+
created_at,
|
|
353
|
+
expires_at,
|
|
354
|
+
id,
|
|
355
|
+
nano_id,
|
|
356
|
+
payload,
|
|
357
|
+
tenant_id,
|
|
358
|
+
type,
|
|
359
|
+
user_id
|
|
360
|
+
from public.token
|
|
361
|
+
on conflict (id) do nothing;
|
|
362
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
363
|
+
const content = await pglite.dumpDataDir('none');
|
|
364
|
+
await kysely.destroy();
|
|
365
|
+
return content;
|
|
366
|
+
}
|
|
65
367
|
async function useLocalKysely(args = {}) {
|
|
66
368
|
let isDestroyed = false;
|
|
67
|
-
|
|
68
|
-
const dump = Bun.file(exports.dumpPath);
|
|
369
|
+
preparedDumpPromise ?? (preparedDumpPromise = resolvePreparedDump());
|
|
69
370
|
const pglite = new pglite_1.PGlite({
|
|
70
|
-
loadDataDir:
|
|
371
|
+
loadDataDir: await preparedDumpPromise,
|
|
71
372
|
});
|
|
373
|
+
// The constructor is lazy. The bootstrap this replaced forced the snapshot to
|
|
374
|
+
// load before returning, so keep that contract: a returned handle is usable,
|
|
375
|
+
// and a bad snapshot fails here instead of inside an unrelated test.
|
|
376
|
+
await pglite.waitReady;
|
|
72
377
|
const dialect = new kysely_pglite_dialect_1.PGliteDialect(pglite);
|
|
73
378
|
const kysely = (0, plugins_1.getKysely)(dialect, {
|
|
74
379
|
repositoryName: args?.repositoryName ?? 'localTesting',
|
|
75
380
|
log: args?.log,
|
|
76
381
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
382
|
+
const controlPlaneKysely = (0, control_plane_1.withControlPlaneSchema)((0, plugins_1.getKysely)(dialect, {
|
|
383
|
+
repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,
|
|
384
|
+
log: args.log,
|
|
385
|
+
}), 'control_plane', 'control_plane');
|
|
386
|
+
controlPlaneKysely.destroy = async () => { };
|
|
387
|
+
Object.defineProperty(kysely, 'controlPlaneKysely', {
|
|
388
|
+
value: controlPlaneKysely,
|
|
389
|
+
});
|
|
80
390
|
const originalDestroy = kysely.destroy.bind(kysely);
|
|
81
391
|
kysely.destroy = async () => {
|
|
82
392
|
if (isDestroyed)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,wCAgCC;AArED,qCAAyC;AACzC,gDAAkC;AAClC,iDAA8C;AAC9C,mCAAyE;AACzE,iEAAsD;AACtD,4CAAiD;AACjD,wCAAuC;AAEvC,qCAA8E;AAEjE,QAAA,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACrC,QAAA,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAI,EAAE,WAAW,CAAC,CAAC;AAOrD,KAAK,UAAU,eAAe,CAAC,MAAmC;IAChE,MAAM,QAAQ,GAAG,IAAI,iBAAQ,CAAC;QAC5B,EAAE,EAAE,MAAM;QACV,oBAAoB,EAAE,6BAAiB,CAAC,WAAW;QACnD,kBAAkB,EAAE,6BAAiB,CAAC,SAAS;QAC/C,sBAAsB,EAAE,6BAAiB,CAAC,aAAa;QACvD,QAAQ,EAAE,IAAI,8BAAqB,CAAC;YAClC,EAAE,EAAF,kBAAE;YACF,IAAI;YACJ,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,YAAI,EAAE,6BAAiB,CAAC,MAAM,CAAC;SAC3D,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,CAAC;IACnD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,cAAc,CAAC,OAA8B,EAAE;IACnE,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,iCAAiC;IAEjC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,gBAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC;QACxB,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,qCAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,OAAO,EAAE;QAChC,cAAc,EAAE,IAAI,EAAE,cAAc,IAAI,cAAc;QACtD,GAAG,EAAE,IAAI,EAAE,GAAG;KACf,CAAC,CAAC;IACH,MAAM,IAAA,6BAAoB,EAAC,MAAM,CAAC,CAAC;IACnC,MAAM,IAAA,qCAA4B,EAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,eAAe,CAAC,MAAqC,CAAC,CAAC;IAE7D,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,WAAW;YAAE,OAAO;QACxB,WAAW,GAAG,IAAI,CAAC;QACnB,wCAAwC;QACxC,MAAM,eAAe,EAAE,CAAC;QACxB,cAAc;QACd,0EAA0E;QAC1E,IAAI;IACN,CAAC,CAAC;IAEF,iFAAiF;IAEjF,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { FileMigrationProvider, type LogConfig, Migrator } from 'kysely';\nimport { PGliteDialect } from 'kysely-pglite-dialect';\nimport { appMigrationEpoch } from '../migration';\nimport { getKysely } from '../plugins';\nimport type { DB } from '../v1.generated';\nimport { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';\n\nexport const root = path.join(__dirname, '../..');\nexport const dumpPath = path.join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\nasync function migrateToLatest(kysely: import('kysely').Kysely<DB>) {\n const migrator = new Migrator({\n db: kysely,\n migrationTableSchema: appMigrationEpoch.tableSchema,\n migrationTableName: appMigrationEpoch.tableName,\n migrationLockTableName: appMigrationEpoch.lockTableName,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, appMigrationEpoch.folder),\n }),\n });\n\n const { error } = await migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n}\n\nexport async function useLocalKysely(args: UseLocalKyselyOptions = {}) {\n let isDestroyed = false;\n // const now = performance.now();\n\n const dump = Bun.file(dumpPath);\n\n const pglite = new PGlite({\n loadDataDir: dump,\n });\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely(dialect, {\n repositoryName: args?.repositoryName ?? 'localTesting',\n log: args?.log,\n });\n await ensureDigestFunction(kysely);\n await ensureGenRandomBytesFunction(kysely);\n await migrateToLatest(kysely as import('kysely').Kysely<DB>);\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n //const destroyTime = performance.now();\n await originalDestroy();\n //console.log(\n // `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n //);\n };\n\n // console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { FileMigrationProvider, type LogConfig, Migrator, sql } from 'kysely';\nimport { PGliteDialect } from 'kysely-pglite-dialect';\nimport { type ControlPlaneDB, withControlPlaneSchema } from '../control-plane';\nimport type { ControlPlaneKysely } from '../index';\nimport { appMigrationEpoch } from '../migration';\nimport { getKysely } from '../plugins';\nimport type { DB } from '../v1.generated';\nimport { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';\n\nexport const root = path.join(__dirname, '../..');\nexport const dumpPath = path.join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\nexport type LocalKysely = import('kysely').Kysely<DB> & {\n controlPlaneKysely: ControlPlaneKysely;\n};\n\nasync function migrateToLatest<Database>(\n kysely: import('kysely').Kysely<Database>\n) {\n const migrator = new Migrator({\n allowUnorderedMigrations: true,\n db: kysely,\n migrationTableSchema: appMigrationEpoch.tableSchema,\n migrationTableName: appMigrationEpoch.tableName,\n migrationLockTableName: appMigrationEpoch.lockTableName,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, appMigrationEpoch.folder),\n }),\n });\n\n const { error } = await migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n}\n\n// Every spec file used to replay this identical bootstrap - migrations, the\n// schema surgery, and the control-plane seed copies - against a freshly loaded\n// snapshot, which measured ~345ms per file against ~185ms for the snapshot load\n// alone. None of it depends on the caller, so it runs once and is cached as a\n// prepared snapshot keyed by everything that determines its content.\nconst preparedDumpPrefix = '.data.prepared.';\n\nlet preparedDumpPromise: Promise<Blob> | undefined;\n\nasync function preparedDumpKey(): Promise<string> {\n const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([\n fs.stat(dumpPath),\n fs.readdir(path.join(root, appMigrationEpoch.folder)),\n fs.readdir(path.join(root, 'control-plane-migrations')),\n ]);\n\n const hasher = new Bun.CryptoHasher('sha256');\n hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);\n hasher.update(appMigrations.sort().join(','));\n hasher.update(controlPlaneMigrations.sort().join(','));\n // Source of the bootstrap itself, so editing the surgery rebuilds the\n // snapshot. Read through toString() rather than the file: this module is also\n // published as CommonJS, where import.meta is a compile error.\n for (const step of [\n buildPreparedDump,\n migrateToLatest,\n ensureDigestFunction,\n ensureGenRandomBytesFunction,\n ]) {\n hasher.update(step.toString());\n }\n return hasher.digest('hex').slice(0, 16);\n}\n\nasync function resolvePreparedDump(): Promise<Blob> {\n const key = await preparedDumpKey();\n const target = path.join(root, `${preparedDumpPrefix}${key}.tar`);\n const cached = Bun.file(target);\n if (await cached.exists()) {\n return cached;\n }\n\n const content = await buildPreparedDump();\n // Sibling workers build this concurrently on a cold cache; rename is atomic,\n // so a reader never observes a half-written snapshot.\n const staging = `${target}.${process.pid}.tmp`;\n await Bun.write(staging, content);\n await fs.rename(staging, target);\n\n // Only finished snapshots: a sibling worker's staging file also carries the\n // prefix, and removing it would break its rename.\n const current = path.basename(target);\n for (const entry of await fs.readdir(root)) {\n if (\n entry.startsWith(preparedDumpPrefix) &&\n entry.endsWith('.tar') &&\n entry !== current\n ) {\n await fs.rm(path.join(root, entry), { force: true });\n }\n }\n\n return content;\n}\n\nasync function buildPreparedDump(): Promise<Blob> {\n const pglite = new PGlite({\n loadDataDir: Bun.file(dumpPath),\n });\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: 'localTestingPrepare',\n });\n await ensureDigestFunction(kysely);\n await ensureGenRandomBytesFunction(kysely);\n await migrateToLatest(kysely);\n\n await sql`alter schema public rename to regional_public`.execute(kysely);\n await sql`alter schema core rename to regional_core`.execute(kysely);\n await sql`create schema public`.execute(kysely);\n await sql`create schema core`.execute(kysely);\n\n const controlPlaneBootstrapKysely = getKysely<ControlPlaneDB>(dialect, {\n repositoryName: 'localTestingPrepare/control-plane-bootstrap',\n });\n const controlPlaneMigrator = new Migrator({\n db: controlPlaneBootstrapKysely,\n migrationTableSchema: 'public',\n migrationTableName: 'control_plane_kysely_migration',\n migrationLockTableName: 'control_plane_kysely_migration_lock',\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, 'control-plane-migrations'),\n }),\n });\n const { error: controlPlaneMigrationError } =\n await controlPlaneMigrator.migrateToLatest();\n if (controlPlaneMigrationError) {\n throw controlPlaneMigrationError;\n }\n\n await sql`alter table core.flow set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter table core.issue_message_overwrite set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`drop schema core`.execute(controlPlaneBootstrapKysely);\n await sql`alter schema public rename to control_plane`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_public rename to public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_core rename to core`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`\n do $$\n declare\n definition text;\n begin\n select pg_get_functiondef(\n 'control_plane.normalize_tenant_slug(text)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_operation_state(uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_destructive_job_operation()'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n end;\n $$;\n `.execute(controlPlaneBootstrapKysely);\n // The canonical VRPlatform tenant. Production code falls back to this exact id\n // in getCalculatedBillingPartnerId, so specs need it to exist without each of\n // them creating - and mutating - their own copy of a shared singleton.\n await kysely\n .insertInto('public.tenant')\n .values({\n id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',\n name: 'VRPlatform',\n type: 'partner',\n status: 'active',\n isActive: true,\n isGeneralLedger: false,\n isOnboarding: false,\n partnerId: null,\n billingPartnerId: null,\n defaultCurrency: 'usd',\n statementStartAt: new Date('2020-01-01T00:00:00Z'),\n })\n .onConflict((oc) => oc.column('id').doNothing())\n .execute();\n\n await sql`\n insert into control_plane.app (\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n )\n select\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n from public.app\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.currency (name)\n select name\n from public.currency\n on conflict (name) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel (\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n )\n select\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n from public.booking_channel\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel_icon_candidate (\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n )\n select\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n from public.booking_channel_icon_candidate\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.tenant (\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n )\n select\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n from public.tenant\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.token (\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n )\n select\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n from public.token\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n\n const content = await pglite.dumpDataDir('none');\n await kysely.destroy();\n return content;\n}\n\nexport async function useLocalKysely(\n args: UseLocalKyselyOptions = {}\n): Promise<LocalKysely> {\n let isDestroyed = false;\n\n preparedDumpPromise ??= resolvePreparedDump();\n const pglite = new PGlite({\n loadDataDir: await preparedDumpPromise,\n });\n // The constructor is lazy. The bootstrap this replaced forced the snapshot to\n // load before returning, so keep that contract: a returned handle is usable,\n // and a bad snapshot fails here instead of inside an unrelated test.\n await pglite.waitReady;\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: args?.repositoryName ?? 'localTesting',\n log: args?.log,\n });\n\n const controlPlaneKysely = withControlPlaneSchema(\n getKysely<ControlPlaneDB>(dialect, {\n repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,\n log: args.log,\n }),\n 'control_plane',\n 'control_plane'\n );\n controlPlaneKysely.destroy = async () => {};\n Object.defineProperty(kysely, 'controlPlaneKysely', {\n value: controlPlaneKysely,\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n //const destroyTime = performance.now();\n await originalDestroy();\n //console.log(\n // `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n //);\n };\n\n // console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely as LocalKysely;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Matches PostgreSQL errors
|
|
3
|
-
* PGlite
|
|
2
|
+
* Matches PostgreSQL errors by code and, when requested, constraint. Production
|
|
3
|
+
* postgres.js and PGlite expose constraint names under different properties.
|
|
4
4
|
*/
|
|
5
5
|
export declare function isPostgresError(error: unknown, expected: {
|
|
6
6
|
code: string;
|
|
7
|
-
constraint
|
|
7
|
+
constraint?: string;
|
|
8
8
|
}): boolean;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isPostgresError = isPostgresError;
|
|
4
4
|
/**
|
|
5
|
-
* Matches PostgreSQL errors
|
|
6
|
-
* PGlite
|
|
5
|
+
* Matches PostgreSQL errors by code and, when requested, constraint. Production
|
|
6
|
+
* postgres.js and PGlite expose constraint names under different properties.
|
|
7
7
|
*/
|
|
8
8
|
function isPostgresError(error, expected) {
|
|
9
9
|
if (!(error instanceof Error) ||
|
|
@@ -16,6 +16,7 @@ function isPostgresError(error, expected) {
|
|
|
16
16
|
: 'constraint_name' in error && typeof error.constraint_name === 'string'
|
|
17
17
|
? error.constraint_name
|
|
18
18
|
: undefined;
|
|
19
|
-
return error.code === expected.code &&
|
|
19
|
+
return (error.code === expected.code &&
|
|
20
|
+
(expected.constraint === undefined || constraint === expected.constraint));
|
|
20
21
|
}
|
|
21
22
|
//# sourceMappingURL=postgres-error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-error.js","sourceRoot":"src/","sources":["postgres-error.ts"],"names":[],"mappings":";;AAIA,
|
|
1
|
+
{"version":3,"file":"postgres-error.js","sourceRoot":"src/","sources":["postgres-error.ts"],"names":[],"mappings":";;AAIA,0CAuBC;AA3BD;;;GAGG;AACH,SAAgB,eAAe,CAC7B,KAAc,EACd,QAA+C;IAE/C,IACE,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QACzB,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC;QAClB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAC9B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,UAAU,GACd,YAAY,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QAC3D,CAAC,CAAC,KAAK,CAAC,UAAU;QAClB,CAAC,CAAC,iBAAiB,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ;YACvE,CAAC,CAAC,KAAK,CAAC,eAAe;YACvB,CAAC,CAAC,SAAS,CAAC;IAElB,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;QAC5B,CAAC,QAAQ,CAAC,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,QAAQ,CAAC,UAAU,CAAC,CAC1E,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Matches PostgreSQL errors by code and, when requested, constraint. Production\n * postgres.js and PGlite expose constraint names under different properties.\n */\nexport function isPostgresError(\n error: unknown,\n expected: { code: string; constraint?: string }\n): boolean {\n if (\n !(error instanceof Error) ||\n !('code' in error) ||\n typeof error.code !== 'string'\n ) {\n return false;\n }\n\n const constraint =\n 'constraint' in error && typeof error.constraint === 'string'\n ? error.constraint\n : 'constraint_name' in error && typeof error.constraint_name === 'string'\n ? error.constraint_name\n : undefined;\n\n return (\n error.code === expected.code &&\n (expected.constraint === undefined || constraint === expected.constraint)\n );\n}\n"]}
|
|
@@ -5,17 +5,13 @@ exports.whereListingIsActive = whereListingIsActive;
|
|
|
5
5
|
exports.selectListingStatus = selectListingStatus;
|
|
6
6
|
const utils_1 = require("@vrplatform/utils");
|
|
7
7
|
const isomorphic_1 = require("../../isomorphic");
|
|
8
|
+
const status_1 = require("../tenant/status");
|
|
8
9
|
function hasActiveListing(eb, today) {
|
|
9
10
|
return eb.exists(eb
|
|
10
11
|
.selectFrom('public.tenant as tenant')
|
|
11
|
-
.leftJoin('public.tenant as billingPartner', 'billingPartner.id', 'tenant.calculatedBillingPartnerId')
|
|
12
12
|
.select('tenant.id')
|
|
13
13
|
.whereRef('tenant.id', '=', 'l.tenantId')
|
|
14
|
-
.where(
|
|
15
|
-
.where((eb2) => eb2.or([
|
|
16
|
-
eb2('tenant.calculatedBillingPartnerId', 'is', null),
|
|
17
|
-
eb2('billingPartner.calculatedStatus', '=', 'active'),
|
|
18
|
-
]))
|
|
14
|
+
.where(status_1.whereTenantActive)
|
|
19
15
|
.where((eb2) => eb2.or([
|
|
20
16
|
eb2.and([
|
|
21
17
|
eb2('tenant.isGeneralLedger', '=', false),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/listing/status.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/listing/status.ts"],"names":[],"mappings":";;AAuFA,wDAKC;AAED,oDAKC;AAED,kDAUC;AA/GD,6CAAwC;AAExC,iDAAuC;AACvC,6CAAqD;AAErD,SAAS,gBAAgB,CACvB,EAAqD,EACrD,KAAa;IAEb,OAAO,EAAE,CAAC,MAAM,CACd,EAAE;SACC,UAAU,CAAC,yBAAyB,CAAC;SACrC,MAAM,CAAC,WAAW,CAAC;SACnB,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE,YAAY,CAAC;SACxC,KAAK,CAAC,0BAAiB,CAAC;SACxB,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACb,GAAG,CAAC,EAAE,CAAC;QACL,GAAG,CAAC,GAAG,CAAC;YACN,GAAG,CAAC,wBAAwB,EAAE,GAAG,EAAE,KAAK,CAAC;YACzC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE,QAAQ,CAAC;SACxC,CAAC;QACF,GAAG,CAAC,GAAG,CAAC;YACN,GAAG,CAAC,wBAAwB,EAAE,GAAG,EAAE,IAAI,CAAC;YACxC,EAAE,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;SACxC,CAAC;KACH,CAAC,CACH;SACA,KAAK,CAAC,CAAC,CAAC,CACZ,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,EAAqD,EACrD,KAAa;IAEb,MAAM,MAAM,GAAG,IAAA,WAAG,EAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,OAAO,EAAE,CAAC,MAAM,CACd,EAAE;SACC,UAAU,CAAC,sCAAsC,CAAC;SAClD,MAAM,CAAC,QAAQ,CAAC;SAChB,KAAK,CACJ,eAAe,EACf,GAAG,EACH,IAAA,gBAAG,EAAQ,YAAY,gBAAG,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,gBAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CACpE;SACA,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE,YAAY,CAAC;SAC3C,KAAK,CAAC,wBAAwB,EAAE,GAAG,EAAE,IAAI,CAAC;SAC1C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACb,GAAG,CAAC,EAAE,CAAC;QACL,GAAG,CAAC,GAAG,CAAC;YACN,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC;YAChC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC;SAC/B,CAAC;QACF,GAAG,CAAC,GAAG,CAAC;YACN,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC;YAChC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC;SAC7B,CAAC;KACH,CAAC,CACH;SACA,KAAK,CAAC,CAAC,CAAC,CACZ,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,EAAqD,EACrD,KAAa;IAEb,OAAO,EAAE,CAAC,MAAM,CACd,EAAE;SACC,UAAU,CAAC,yBAAyB,CAAC;SACrC,MAAM,CAAC,WAAW,CAAC;SACnB,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE,YAAY,CAAC;SACxC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACb,GAAG,CAAC,EAAE,CAAC;QACL,GAAG,CAAC,GAAG,CAAC;YACN,GAAG,CAAC,wBAAwB,EAAE,GAAG,EAAE,KAAK,CAAC;YACzC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE,UAAU,CAAC;SAC1C,CAAC;QACF,GAAG,CAAC,GAAG,CAAC;YACN,GAAG,CAAC,wBAAwB,EAAE,GAAG,EAAE,IAAI,CAAC;YACxC,oBAAoB,CAAC,EAAE,EAAE,KAAK,CAAC;SAChC,CAAC;KACH,CAAC,CACH,CACJ,CAAC;AACJ,CAAC;AAED,SAAgB,sBAAsB,CACpC,EAAqD,EACrD,QAAgB,IAAA,WAAG,GAAE,CAAC,QAAQ,EAAE;IAEhC,OAAO,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,oBAAoB,CAClC,EAAqD,EACrD,QAAgB,IAAA,WAAG,GAAE,CAAC,QAAQ,EAAE;IAEhC,OAAO,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,SAAgB,mBAAmB,CACjC,EAAqD,EACrD,QAAgB,IAAA,WAAG,GAAE,CAAC,QAAQ,EAAE;IAEhC,OAAO,EAAE;SACN,IAAI,EAAE;SACN,IAAI,CAAC,sBAAsB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;SACvC,IAAI,CAAC,UAAU,CAAC;SAChB,IAAI,CAAC,QAAQ,CAAC;SACd,GAAG,EAAE,CAAC;AACX,CAAC","sourcesContent":["import { day } from '@vrplatform/utils';\nimport type { DB, ExpressionBuilder, PublicListing } from '../../isomorphic';\nimport { sql } from '../../isomorphic';\nimport { whereTenantActive } from '../tenant/status';\n\nfunction hasActiveListing(\n eb: ExpressionBuilder<DB & { l: PublicListing }, 'l'>,\n today: string\n) {\n return eb.exists(\n eb\n .selectFrom('public.tenant as tenant')\n .select('tenant.id')\n .whereRef('tenant.id', '=', 'l.tenantId')\n .where(whereTenantActive)\n .where((eb2) =>\n eb2.or([\n eb2.and([\n eb2('tenant.isGeneralLedger', '=', false),\n eb('l.calculatedStatus', '=', 'active'),\n ]),\n eb2.and([\n eb2('tenant.isGeneralLedger', '=', true),\n eb.not(hasInactiveOwnership(eb, today)),\n ]),\n ])\n )\n .limit(1)\n );\n}\n\nfunction hasInactiveOwnership(\n eb: ExpressionBuilder<DB & { l: PublicListing }, 'l'>,\n today: string\n) {\n const onDate = day(today).toDate();\n return eb.exists(\n eb\n .selectFrom('public.listingOwnershipPeriod as lop')\n .select('lop.id')\n .where(\n 'lop.listingId',\n '=',\n sql<string>`coalesce(${sql.ref('l.parentId')}, ${sql.ref('l.id')})`\n )\n .whereRef('lop.tenantId', '=', 'l.tenantId')\n .where('lop.setListingInactive', '=', true)\n .where((eb2) =>\n eb2.or([\n eb2.and([\n eb2('lop.startAt', '<=', onDate),\n eb2('lop.endAt', '>=', onDate),\n ]),\n eb2.and([\n eb2('lop.startAt', '<=', onDate),\n eb2('lop.endAt', 'is', null),\n ]),\n ])\n )\n .limit(1)\n );\n}\n\nfunction hasInactiveListing(\n eb: ExpressionBuilder<DB & { l: PublicListing }, 'l'>,\n today: string\n) {\n return eb.exists(\n eb\n .selectFrom('public.tenant as tenant')\n .select('tenant.id')\n .whereRef('tenant.id', '=', 'l.tenantId')\n .where((eb2) =>\n eb2.or([\n eb2.and([\n eb2('tenant.isGeneralLedger', '=', false),\n eb('l.calculatedStatus', '=', 'inactive'),\n ]),\n eb2.and([\n eb2('tenant.isGeneralLedger', '=', true),\n hasInactiveOwnership(eb, today),\n ]),\n ])\n )\n );\n}\n\nexport function whereListingIsInactive(\n eb: ExpressionBuilder<DB & { l: PublicListing }, 'l'>,\n today: string = day().yyyymmdd()\n) {\n return hasInactiveListing(eb, today);\n}\n\nexport function whereListingIsActive(\n eb: ExpressionBuilder<DB & { l: PublicListing }, 'l'>,\n today: string = day().yyyymmdd()\n) {\n return hasActiveListing(eb, today);\n}\n\nexport function selectListingStatus(\n eb: ExpressionBuilder<DB & { l: PublicListing }, 'l'>,\n today: string = day().yyyymmdd()\n) {\n return eb\n .case()\n .when(whereListingIsInactive(eb, today))\n .then('inactive')\n .else('active')\n .end();\n}\n"]}
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type DB, type ExpressionBuilder, type PublicTenant, type SqlBool } from '../../isomorphic';
|
|
2
2
|
type TenantExpressionBuilder = ExpressionBuilder<DB & {
|
|
3
3
|
tenant: PublicTenant;
|
|
4
4
|
}, 'tenant'>;
|
|
5
5
|
export declare function whereTenantActive(eb: TenantExpressionBuilder): import("kysely").ExpressionWrapper<DB & {
|
|
6
6
|
tenant: PublicTenant;
|
|
7
|
-
}, "tenant",
|
|
8
|
-
export declare function whereTenantNotTestTeam(
|
|
9
|
-
|
|
10
|
-
}, "tenant", import("kysely/dist/cjs/util/type-utils").SqlBool>;
|
|
11
|
-
export declare function whereTenantShouldBePaid(eb: TenantExpressionBuilder, { includePartnerTeams, today, }?: {
|
|
7
|
+
}, "tenant", SqlBool>;
|
|
8
|
+
export declare function whereTenantNotTestTeam(testTeamId: string): import("kysely").RawBuilder<SqlBool>;
|
|
9
|
+
export declare function whereTenantShouldBePaid(eb: TenantExpressionBuilder, { includePartnerTeams, }?: {
|
|
12
10
|
includePartnerTeams?: boolean;
|
|
13
|
-
today?: Date | string;
|
|
14
11
|
}): import("kysely").ExpressionWrapper<DB & {
|
|
15
12
|
tenant: PublicTenant;
|
|
16
|
-
}, "tenant",
|
|
13
|
+
}, "tenant", SqlBool>;
|
|
17
14
|
export {};
|
|
@@ -3,39 +3,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.whereTenantActive = whereTenantActive;
|
|
4
4
|
exports.whereTenantNotTestTeam = whereTenantNotTestTeam;
|
|
5
5
|
exports.whereTenantShouldBePaid = whereTenantShouldBePaid;
|
|
6
|
-
const
|
|
6
|
+
const isomorphic_1 = require("../../isomorphic");
|
|
7
7
|
const billing_partner_1 = require("./billing-partner");
|
|
8
8
|
function whereTenantActive(eb) {
|
|
9
9
|
return eb.and([
|
|
10
10
|
eb('tenant.calculatedStatus', '=', 'active'),
|
|
11
|
-
eb.exists(eb
|
|
11
|
+
eb.not(eb.exists(eb
|
|
12
12
|
.selectFrom('public.tenant as billingPartner')
|
|
13
13
|
.select('billingPartner.id')
|
|
14
14
|
.where('billingPartner.id', '=', eb.fn.coalesce('tenant.calculatedBillingPartnerId', eb.val((0, billing_partner_1.getCalculatedBillingPartnerId)({}))))
|
|
15
|
-
.where('billingPartner.calculatedStatus', '
|
|
15
|
+
.where('billingPartner.calculatedStatus', 'is distinct from', 'active'))),
|
|
16
16
|
]);
|
|
17
17
|
}
|
|
18
|
-
function whereTenantNotTestTeam(
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
function whereTenantNotTestTeam(testTeamId) {
|
|
19
|
+
return (0, isomorphic_1.sql) `(
|
|
20
|
+
${isomorphic_1.sql.ref('tenant.id')} != ${testTeamId}
|
|
21
|
+
and (
|
|
22
|
+
${isomorphic_1.sql.ref('tenant.partnerId')} is null
|
|
23
|
+
or ${isomorphic_1.sql.ref('tenant.partnerId')} != ${testTeamId}
|
|
24
|
+
)
|
|
25
|
+
and (
|
|
26
|
+
${isomorphic_1.sql.ref('tenant.billingPartnerId')} is null
|
|
27
|
+
or ${isomorphic_1.sql.ref('tenant.billingPartnerId')} != ${testTeamId}
|
|
28
|
+
)
|
|
29
|
+
)`;
|
|
30
30
|
}
|
|
31
|
-
function whereTenantShouldBePaid(eb, { includePartnerTeams = false,
|
|
31
|
+
function whereTenantShouldBePaid(eb, { includePartnerTeams = false, } = {}) {
|
|
32
32
|
return eb.and([
|
|
33
33
|
whereTenantActive(eb),
|
|
34
34
|
eb('tenant.isOnboarding', '=', false),
|
|
35
|
-
eb.or([
|
|
36
|
-
eb('tenant.trialUntil', '<', today),
|
|
37
|
-
eb('tenant.trialUntil', 'is', null),
|
|
38
|
-
]),
|
|
39
35
|
...(includePartnerTeams
|
|
40
36
|
? []
|
|
41
37
|
: [eb('tenant.calculatedIsBillable', '=', true)]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/tenant/status.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/tenant/status.ts"],"names":[],"mappings":";;AAcA,8CAwBC;AAED,wDAYC;AAED,0DAeC;AArED,iDAM0B;AAC1B,uDAAkE;AAOlE,SAAgB,iBAAiB,CAAC,EAA2B;IAC3D,OAAO,EAAE,CAAC,GAAG,CAAC;QACZ,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE,QAAQ,CAAC;QAC5C,EAAE,CAAC,GAAG,CACJ,EAAE,CAAC,MAAM,CACP,EAAE;aACC,UAAU,CAAC,iCAAiC,CAAC;aAC7C,MAAM,CAAC,mBAAmB,CAAC;aAC3B,KAAK,CACJ,mBAAmB,EACnB,GAAG,EACH,EAAE,CAAC,EAAE,CAAC,QAAQ,CACZ,mCAAmC,EACnC,EAAE,CAAC,GAAG,CAAC,IAAA,+CAA6B,EAAC,EAAE,CAAC,CAAC,CAC1C,CACF;aACA,KAAK,CACJ,iCAAiC,EACjC,kBAAkB,EAClB,QAAQ,CACT,CACJ,CACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,sBAAsB,CAAC,UAAkB;IACvD,OAAO,IAAA,gBAAG,EAAS;MACf,gBAAG,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,UAAU;;QAEnC,gBAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC;WACxB,gBAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,UAAU;;;QAG/C,gBAAG,CAAC,GAAG,CAAC,yBAAyB,CAAC;WAC/B,gBAAG,CAAC,GAAG,CAAC,yBAAyB,CAAC,OAAO,UAAU;;IAE1D,CAAC;AACL,CAAC;AAED,SAAgB,uBAAuB,CACrC,EAA2B,EAC3B,EACE,mBAAmB,GAAG,KAAK,MAGzB,EAAE;IAEN,OAAO,EAAE,CAAC,GAAG,CAAC;QACZ,iBAAiB,CAAC,EAAE,CAAC;QACrB,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE,KAAK,CAAC;QACrC,GAAG,CAAC,mBAAmB;YACrB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;KACpD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n sql,\n type DB,\n type ExpressionBuilder,\n type PublicTenant,\n type SqlBool,\n} from '../../isomorphic';\nimport { getCalculatedBillingPartnerId } from './billing-partner';\n\ntype TenantExpressionBuilder = ExpressionBuilder<\n DB & { tenant: PublicTenant },\n 'tenant'\n>;\n\nexport function whereTenantActive(eb: TenantExpressionBuilder) {\n return eb.and([\n eb('tenant.calculatedStatus', '=', 'active'),\n eb.not(\n eb.exists(\n eb\n .selectFrom('public.tenant as billingPartner')\n .select('billingPartner.id')\n .where(\n 'billingPartner.id',\n '=',\n eb.fn.coalesce(\n 'tenant.calculatedBillingPartnerId',\n eb.val(getCalculatedBillingPartnerId({}))\n )\n )\n .where(\n 'billingPartner.calculatedStatus',\n 'is distinct from',\n 'active'\n )\n )\n ),\n ]);\n}\n\nexport function whereTenantNotTestTeam(testTeamId: string) {\n return sql<SqlBool>`(\n ${sql.ref('tenant.id')} != ${testTeamId}\n and (\n ${sql.ref('tenant.partnerId')} is null\n or ${sql.ref('tenant.partnerId')} != ${testTeamId}\n )\n and (\n ${sql.ref('tenant.billingPartnerId')} is null\n or ${sql.ref('tenant.billingPartnerId')} != ${testTeamId}\n )\n )`;\n}\n\nexport function whereTenantShouldBePaid(\n eb: TenantExpressionBuilder,\n {\n includePartnerTeams = false,\n }: {\n includePartnerTeams?: boolean;\n } = {}\n) {\n return eb.and([\n whereTenantActive(eb),\n eb('tenant.isOnboarding', '=', false),\n ...(includePartnerTeams\n ? []\n : [eb('tenant.calculatedIsBillable', '=', true)]),\n ]);\n}\n"]}
|
package/build/main/regional.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Kysely } from './index';
|
|
1
|
+
import type { ControlPlaneKysely, Kysely } from './index';
|
|
2
2
|
export declare const tenantDataRegions: readonly ["ap", "crunchy", "eu", "hostaway", "us"];
|
|
3
3
|
export type TenantDataRegion = (typeof tenantDataRegions)[number];
|
|
4
4
|
export type RegionEnvironment = Record<string, string | undefined>;
|
|
@@ -7,9 +7,14 @@ export declare function resolveTenantDatabaseUrl(dataRegion: TenantDataRegion, e
|
|
|
7
7
|
export declare function resolveTenantApiBaseUrl(dataRegion: TenantDataRegion, env: RegionEnvironment): string;
|
|
8
8
|
export declare function resolveConfiguredTenantDataRegions(env: RegionEnvironment): ("ap" | "crunchy" | "eu" | "hostaway" | "us")[];
|
|
9
9
|
type UseAsyncRegionalKysely = (connectionString: string, options?: {
|
|
10
|
+
dataRegion?: TenantDataRegion;
|
|
10
11
|
repositoryName?: string;
|
|
11
12
|
probe?: true;
|
|
12
13
|
}) => Promise<Kysely>;
|
|
14
|
+
type UseAsyncControlPlaneKysely = (connectionString: string, options?: {
|
|
15
|
+
repositoryName?: string;
|
|
16
|
+
probe?: true;
|
|
17
|
+
}) => Promise<ControlPlaneKysely>;
|
|
13
18
|
export declare function useTenantDatabaseKysely(dataRegion: TenantDataRegion, repositoryName: string, env: RegionEnvironment, options?: {
|
|
14
19
|
useAsyncKysely?: UseAsyncRegionalKysely;
|
|
15
20
|
probe?: true;
|
|
@@ -32,6 +37,7 @@ export declare function resolveTenantKysely({ connectionId, slug, tenantId, repo
|
|
|
32
37
|
tenantId?: string;
|
|
33
38
|
repositoryName: string;
|
|
34
39
|
env: RegionEnvironment;
|
|
40
|
+
useAsyncControlPlaneKysely?: UseAsyncControlPlaneKysely;
|
|
35
41
|
useAsyncKysely?: UseAsyncRegionalKysely;
|
|
36
42
|
probe?: true;
|
|
37
43
|
}): Promise<TenantKysely>;
|