@vrplatform/kysely 1.3.45-stage.5592 → 1.3.45-stage.560

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/build/.data.tar +0 -0
  2. package/build/main/control-plane/index.d.ts +314 -16
  3. package/build/main/control-plane/index.js +61 -0
  4. package/build/main/control-plane/index.js.map +1 -1
  5. package/build/main/index.d.ts +17 -4
  6. package/build/main/index.js +226 -27
  7. package/build/main/index.js.map +1 -1
  8. package/build/main/isomorphic.d.ts +4 -2
  9. package/build/main/isomorphic.js.map +1 -1
  10. package/build/main/local/digest.d.ts +3 -3
  11. package/build/main/local/digest.js.map +1 -1
  12. package/build/main/local/generate.js +2 -0
  13. package/build/main/local/generate.js.map +1 -1
  14. package/build/main/local/index.d.ts +5 -1
  15. package/build/main/local/index.js +316 -6
  16. package/build/main/local/index.js.map +1 -1
  17. package/build/main/postgres-error.d.ts +3 -3
  18. package/build/main/postgres-error.js +4 -3
  19. package/build/main/postgres-error.js.map +1 -1
  20. package/build/main/query/listing/status.js +2 -6
  21. package/build/main/query/listing/status.js.map +1 -1
  22. package/build/main/query/tenant/status.d.ts +5 -8
  23. package/build/main/query/tenant/status.js +16 -20
  24. package/build/main/query/tenant/status.js.map +1 -1
  25. package/build/main/regional.d.ts +7 -1
  26. package/build/main/regional.js +14 -9
  27. package/build/main/regional.js.map +1 -1
  28. package/build/main/test/index.d.ts +25 -7
  29. package/build/main/test/index.js +35 -13
  30. package/build/main/test/index.js.map +1 -1
  31. package/build/main/transaction.d.ts +3 -3
  32. package/build/main/transaction.js.map +1 -1
  33. package/build/main/v1.generated.d.ts +559 -6
  34. package/build/main/v1.generated.js.map +1 -1
  35. package/build/migrations-v2/0000000000010-bank-rule-application-bank-record-delete-cascade.ts +26 -0
  36. package/build/migrations-v2/0000000000011-guest-balance-journal-entry-lookup-index.ts +25 -0
  37. package/build/migrations-v2/0000000000012-trial-free-analytics-billing-status.ts +72 -0
  38. package/build/migrations-v2/0000000000013-ui-permission-bundles.ts +45 -0
  39. package/build/migrations-v2/0000000000014-ui-permission-bundle-top-up.ts +32 -0
  40. package/build/migrations-v2/0000000000015-durable-flow-events.ts +163 -0
  41. package/build/migrations-v2/0000000000016-billing-listing-facts.ts +539 -0
  42. package/build/migrations-v2/0000000000016-managed-team-access.ts +34 -0
  43. package/build/migrations-v2/0000000000017-drop-trial-until.ts +42 -0
  44. package/build/migrations-v2/0000000000017-webhook-secret-reencryption-failures.ts +18 -0
  45. package/build/migrations-v2/0000000000018-accounting-integrity-monitoring.ts +276 -0
  46. package/build/migrations-v2/0000000000018-durable-flow-event-sensitive-input.ts +28 -0
  47. package/build/migrations-v2/0000000000019-accounting-integrity-run-shards.ts +26 -0
  48. package/build/migrations-v2/0000000000019-asynchronous-operations.ts +736 -0
  49. package/build/migrations-v2/0000000000020-accounting-integrity-case-classification.ts +52 -0
  50. package/build/migrations-v2/0000000000021-payment-line-classification-monitor-indexes.ts +31 -0
  51. package/build/migrations-v2/0000000000022-accounting-integrity-controlled-repairs.ts +281 -0
  52. package/build/migrations-v2/0000000000023-line-classification-usage.ts +325 -0
  53. package/build/migrations-v2/0000000000024-tenant-region-migration.ts +108 -0
  54. package/build/migrations-v2/0000000000025-partner-ach-denial-default.ts +30 -0
  55. package/build/migrations-v2/0000000000026-line-classification-usage-capture.ts +399 -0
  56. package/build/migrations-v2/0000000000027-payout-replacement-chain.ts +27 -0
  57. package/build/migrations-v2/0000000000028-accounting-integrity-operator-workflow.ts +108 -0
  58. package/build/migrations-v2/0000000000029-accounting-integrity-definition-artifacts.ts +40 -0
  59. package/build/migrations-v2/0000000000030-accounting-integrity-review-metadata-compatibility.ts +49 -0
  60. package/build/migrations-v2/0000000000031-ui-permission-role-simplification.ts +70 -0
  61. package/build/migrations-v2/0000000000032-tenant-delete-ownership-cascades.ts +44 -0
  62. package/build/migrations-v2/0000000000033-reservation-issue-seed-bucket-index.ts +19 -0
  63. package/build/migrations-v2/0000000000034-retire-recent-classification-indexes.ts +29 -0
  64. package/build/migrations-v2/0000000000035-core-change-autovacuum.ts +24 -0
  65. package/build/migrations-v2/0000000000036-journal-entry-inactive-reason-constraint.ts +33 -0
  66. package/build/migrations-v2/0000000000037-journal-entry-inactive-reasons.ts +19 -0
  67. package/build/migrations-v2/0000000000038-journal-entry-group-inactive-reason.ts +14 -0
  68. package/build/migrations-v2/0000000000039-reservation-guest-breakdown.ts +19 -0
  69. package/build/migrations-v2/0000000000040-csv-import-source-identity-index.ts +23 -0
  70. package/build/migrations-v2/0000000000041-payment-returns.ts +38 -0
  71. package/build/migrations-v2/0000000000042-operation-resource-types.ts +609 -0
  72. package/build/migrations-v2/0000000000043-reservation-journal-freshness.ts +149 -0
  73. package/build/migrations-v2/0000000000044-reservation-journal-freshness-backfill.ts +254 -0
  74. package/build/migrations-v2/0000000000045-reservation-journal-freshness-revision-repair.ts +83 -0
  75. package/build/migrations-v2/0000000000046-materialized-reservation-journal-operations.ts +709 -0
  76. package/build/migrations-v2/0000000000047-public-audit-completion.ts +77 -0
  77. package/build/migrations-v2/0000000000048-reservation-journal-full-refresh-repair.ts +136 -0
  78. package/build/migrations-v2/0000000000049-queued-journal-operation-failures.ts +60 -0
  79. package/build/migrations-v2/0000000000050-connection-oauth-state.ts +43 -0
  80. package/build/migrations-v2/0000000000051-owner-statement-email-delivery.ts +134 -0
  81. package/build/module/control-plane/index.d.ts +314 -16
  82. package/build/module/control-plane/index.js +49 -1
  83. package/build/module/control-plane/index.js.map +1 -1
  84. package/build/module/index.d.ts +17 -4
  85. package/build/module/index.js +228 -28
  86. package/build/module/index.js.map +1 -1
  87. package/build/module/isomorphic.d.ts +4 -2
  88. package/build/module/isomorphic.js.map +1 -1
  89. package/build/module/local/digest.d.ts +3 -3
  90. package/build/module/local/digest.js.map +1 -1
  91. package/build/module/local/generate.js +2 -0
  92. package/build/module/local/generate.js.map +1 -1
  93. package/build/module/local/index.d.ts +5 -1
  94. package/build/module/local/index.js +317 -7
  95. package/build/module/local/index.js.map +1 -1
  96. package/build/module/postgres-error.d.ts +3 -3
  97. package/build/module/postgres-error.js +4 -3
  98. package/build/module/postgres-error.js.map +1 -1
  99. package/build/module/query/listing/status.js +2 -6
  100. package/build/module/query/listing/status.js.map +1 -1
  101. package/build/module/query/tenant/status.d.ts +5 -8
  102. package/build/module/query/tenant/status.js +16 -20
  103. package/build/module/query/tenant/status.js.map +1 -1
  104. package/build/module/regional.d.ts +7 -1
  105. package/build/module/regional.js +14 -9
  106. package/build/module/regional.js.map +1 -1
  107. package/build/module/test/index.d.ts +25 -7
  108. package/build/module/test/index.js +35 -14
  109. package/build/module/test/index.js.map +1 -1
  110. package/build/module/transaction.d.ts +3 -3
  111. package/build/module/transaction.js.map +1 -1
  112. package/build/module/v1.generated.d.ts +559 -6
  113. package/build/module/v1.generated.js.map +1 -1
  114. package/package.json +3 -2
@@ -1,8 +1,9 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { PGlite } from '@electric-sql/pglite';
4
- import { FileMigrationProvider, Migrator } from 'kysely';
4
+ import { FileMigrationProvider, Migrator, sql } from 'kysely';
5
5
  import { PGliteDialect } from 'kysely-pglite-dialect';
6
+ import { withControlPlaneSchema } from '../control-plane';
6
7
  import { appMigrationEpoch } from '../migration';
7
8
  import { getKysely } from '../plugins';
8
9
  import { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';
@@ -10,6 +11,7 @@ export const root = path.join(__dirname, '../..');
10
11
  export const dumpPath = path.join(root, '.data.tar');
11
12
  async function migrateToLatest(kysely) {
12
13
  const migrator = new Migrator({
14
+ allowUnorderedMigrations: true,
13
15
  db: kysely,
14
16
  migrationTableSchema: appMigrationEpoch.tableSchema,
15
17
  migrationTableName: appMigrationEpoch.tableName,
@@ -25,21 +27,329 @@ async function migrateToLatest(kysely) {
25
27
  throw error;
26
28
  }
27
29
  }
30
+ // Every spec file used to replay this identical bootstrap - migrations, the
31
+ // schema surgery, and the control-plane seed copies - against a freshly loaded
32
+ // snapshot, which measured ~345ms per file against ~185ms for the snapshot load
33
+ // alone. None of it depends on the caller, so it runs once and is cached as a
34
+ // prepared snapshot keyed by everything that determines its content.
35
+ const preparedDumpPrefix = '.data.prepared.';
36
+ let preparedDumpPromise;
37
+ async function preparedDumpKey() {
38
+ const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([
39
+ fs.stat(dumpPath),
40
+ fs.readdir(path.join(root, appMigrationEpoch.folder)),
41
+ fs.readdir(path.join(root, 'control-plane-migrations')),
42
+ ]);
43
+ const hasher = new Bun.CryptoHasher('sha256');
44
+ hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);
45
+ hasher.update(appMigrations.sort().join(','));
46
+ hasher.update(controlPlaneMigrations.sort().join(','));
47
+ // Source of the bootstrap itself, so editing the surgery rebuilds the
48
+ // snapshot. Read through toString() rather than the file: this module is also
49
+ // published as CommonJS, where import.meta is a compile error.
50
+ for (const step of [
51
+ buildPreparedDump,
52
+ migrateToLatest,
53
+ ensureDigestFunction,
54
+ ensureGenRandomBytesFunction,
55
+ ]) {
56
+ hasher.update(step.toString());
57
+ }
58
+ return hasher.digest('hex').slice(0, 16);
59
+ }
60
+ async function resolvePreparedDump() {
61
+ const key = await preparedDumpKey();
62
+ const target = path.join(root, `${preparedDumpPrefix}${key}.tar`);
63
+ const cached = Bun.file(target);
64
+ if (await cached.exists()) {
65
+ return cached;
66
+ }
67
+ const content = await buildPreparedDump();
68
+ // Sibling workers build this concurrently on a cold cache; rename is atomic,
69
+ // so a reader never observes a half-written snapshot.
70
+ const staging = `${target}.${process.pid}.tmp`;
71
+ await Bun.write(staging, content);
72
+ await fs.rename(staging, target);
73
+ // Only finished snapshots: a sibling worker's staging file also carries the
74
+ // prefix, and removing it would break its rename.
75
+ const current = path.basename(target);
76
+ for (const entry of await fs.readdir(root)) {
77
+ if (entry.startsWith(preparedDumpPrefix) &&
78
+ entry.endsWith('.tar') &&
79
+ entry !== current) {
80
+ await fs.rm(path.join(root, entry), { force: true });
81
+ }
82
+ }
83
+ return content;
84
+ }
85
+ async function buildPreparedDump() {
86
+ const pglite = new PGlite({
87
+ loadDataDir: Bun.file(dumpPath),
88
+ });
89
+ const dialect = new PGliteDialect(pglite);
90
+ const kysely = getKysely(dialect, {
91
+ repositoryName: 'localTestingPrepare',
92
+ });
93
+ await ensureDigestFunction(kysely);
94
+ await ensureGenRandomBytesFunction(kysely);
95
+ await migrateToLatest(kysely);
96
+ await sql `alter schema public rename to regional_public`.execute(kysely);
97
+ await sql `alter schema core rename to regional_core`.execute(kysely);
98
+ await sql `create schema public`.execute(kysely);
99
+ await sql `create schema core`.execute(kysely);
100
+ const controlPlaneBootstrapKysely = getKysely(dialect, {
101
+ repositoryName: 'localTestingPrepare/control-plane-bootstrap',
102
+ });
103
+ const controlPlaneMigrator = new Migrator({
104
+ db: controlPlaneBootstrapKysely,
105
+ migrationTableSchema: 'public',
106
+ migrationTableName: 'control_plane_kysely_migration',
107
+ migrationLockTableName: 'control_plane_kysely_migration_lock',
108
+ provider: new FileMigrationProvider({
109
+ fs,
110
+ path,
111
+ migrationFolder: path.join(root, 'control-plane-migrations'),
112
+ }),
113
+ });
114
+ const { error: controlPlaneMigrationError } = await controlPlaneMigrator.migrateToLatest();
115
+ if (controlPlaneMigrationError) {
116
+ throw controlPlaneMigrationError;
117
+ }
118
+ await sql `alter table core.flow set schema public`.execute(controlPlaneBootstrapKysely);
119
+ await sql `alter table core.issue_message_overwrite set schema public`.execute(controlPlaneBootstrapKysely);
120
+ await sql `drop schema core`.execute(controlPlaneBootstrapKysely);
121
+ await sql `alter schema public rename to control_plane`.execute(controlPlaneBootstrapKysely);
122
+ await sql `alter schema regional_public rename to public`.execute(controlPlaneBootstrapKysely);
123
+ await sql `alter schema regional_core rename to core`.execute(controlPlaneBootstrapKysely);
124
+ await sql `
125
+ do $$
126
+ declare
127
+ definition text;
128
+ begin
129
+ select pg_get_functiondef(
130
+ 'control_plane.normalize_tenant_slug(text)'::regprocedure
131
+ ) into definition;
132
+ execute replace(definition, 'public.', 'control_plane.');
133
+
134
+ select pg_get_functiondef(
135
+ 'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure
136
+ ) into definition;
137
+ execute replace(definition, 'public.', 'control_plane.');
138
+
139
+ select pg_get_functiondef(
140
+ 'control_plane.refresh_operation_state(uuid)'::regprocedure
141
+ ) into definition;
142
+ execute replace(definition, 'public.', 'control_plane.');
143
+
144
+ select pg_get_functiondef(
145
+ 'control_plane.refresh_destructive_job_operation()'::regprocedure
146
+ ) into definition;
147
+ execute replace(definition, 'public.', 'control_plane.');
148
+ end;
149
+ $$;
150
+ `.execute(controlPlaneBootstrapKysely);
151
+ // The canonical VRPlatform tenant. Production code falls back to this exact id
152
+ // in getCalculatedBillingPartnerId, so specs need it to exist without each of
153
+ // them creating - and mutating - their own copy of a shared singleton.
154
+ await kysely
155
+ .insertInto('public.tenant')
156
+ .values({
157
+ id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',
158
+ name: 'VRPlatform',
159
+ type: 'partner',
160
+ status: 'active',
161
+ isActive: true,
162
+ isGeneralLedger: false,
163
+ isOnboarding: false,
164
+ partnerId: null,
165
+ billingPartnerId: null,
166
+ defaultCurrency: 'usd',
167
+ statementStartAt: new Date('2020-01-01T00:00:00Z'),
168
+ })
169
+ .onConflict((oc) => oc.column('id').doNothing())
170
+ .execute();
171
+ await sql `
172
+ insert into control_plane.app (
173
+ authentication,
174
+ category,
175
+ color,
176
+ created_at,
177
+ icon,
178
+ icon_round,
179
+ id,
180
+ info,
181
+ name,
182
+ type,
183
+ version
184
+ )
185
+ select
186
+ authentication,
187
+ category,
188
+ color,
189
+ created_at,
190
+ icon,
191
+ icon_round,
192
+ id,
193
+ info,
194
+ name,
195
+ type,
196
+ version
197
+ from public.app
198
+ on conflict (id) do nothing;
199
+ `.execute(controlPlaneBootstrapKysely);
200
+ await sql `
201
+ insert into control_plane.currency (name)
202
+ select name
203
+ from public.currency
204
+ on conflict (name) do nothing;
205
+ `.execute(controlPlaneBootstrapKysely);
206
+ await sql `
207
+ insert into control_plane.booking_channel (
208
+ channel_ref,
209
+ color,
210
+ created_at,
211
+ icon,
212
+ icon_provider,
213
+ id,
214
+ last_generate_run,
215
+ logo,
216
+ logo_provider,
217
+ selected_booking_channel_icon_candidate_id,
218
+ selected_booking_channel_logo_candidate_id,
219
+ unique_ref,
220
+ updated_at
221
+ )
222
+ select
223
+ channel_ref,
224
+ color,
225
+ created_at,
226
+ icon,
227
+ icon_provider,
228
+ id,
229
+ last_generate_run,
230
+ logo,
231
+ logo_provider,
232
+ selected_booking_channel_icon_candidate_id,
233
+ selected_booking_channel_logo_candidate_id,
234
+ unique_ref,
235
+ updated_at
236
+ from public.booking_channel
237
+ on conflict (id) do nothing;
238
+ `.execute(controlPlaneBootstrapKysely);
239
+ await sql `
240
+ insert into control_plane.booking_channel_icon_candidate (
241
+ booking_channel_id,
242
+ cloudflare_image_id,
243
+ color,
244
+ comment,
245
+ created_at,
246
+ external_icon,
247
+ height,
248
+ id,
249
+ provider,
250
+ source,
251
+ updated_at,
252
+ width
253
+ )
254
+ select
255
+ booking_channel_id,
256
+ cloudflare_image_id,
257
+ color,
258
+ comment,
259
+ created_at,
260
+ external_icon,
261
+ height,
262
+ id,
263
+ provider,
264
+ source,
265
+ updated_at,
266
+ width
267
+ from public.booking_channel_icon_candidate
268
+ on conflict (id) do nothing;
269
+ `.execute(controlPlaneBootstrapKysely);
270
+ await sql `
271
+ insert into control_plane.tenant (
272
+ billing_partner_id,
273
+ billing_plan,
274
+ created_at,
275
+ data_region,
276
+ id,
277
+ name,
278
+ partner_id,
279
+ slug,
280
+ status,
281
+ storage_realm,
282
+ type,
283
+ unique_ref,
284
+ updated_at
285
+ )
286
+ select
287
+ billing_partner_id,
288
+ billing_plan,
289
+ created_at,
290
+ data_region,
291
+ id,
292
+ name,
293
+ partner_id,
294
+ slug,
295
+ status,
296
+ storage_realm,
297
+ type,
298
+ unique_ref,
299
+ updated_at
300
+ from public.tenant
301
+ on conflict (id) do nothing;
302
+ `.execute(controlPlaneBootstrapKysely);
303
+ await sql `
304
+ insert into control_plane.token (
305
+ created_at,
306
+ expires_at,
307
+ id,
308
+ nano_id,
309
+ payload,
310
+ tenant_id,
311
+ type,
312
+ user_id
313
+ )
314
+ select
315
+ created_at,
316
+ expires_at,
317
+ id,
318
+ nano_id,
319
+ payload,
320
+ tenant_id,
321
+ type,
322
+ user_id
323
+ from public.token
324
+ on conflict (id) do nothing;
325
+ `.execute(controlPlaneBootstrapKysely);
326
+ const content = await pglite.dumpDataDir('none');
327
+ await kysely.destroy();
328
+ return content;
329
+ }
28
330
  export async function useLocalKysely(args = {}) {
29
331
  let isDestroyed = false;
30
- // const now = performance.now();
31
- const dump = Bun.file(dumpPath);
332
+ preparedDumpPromise ??= resolvePreparedDump();
32
333
  const pglite = new PGlite({
33
- loadDataDir: dump,
334
+ loadDataDir: await preparedDumpPromise,
34
335
  });
336
+ // The constructor is lazy. The bootstrap this replaced forced the snapshot to
337
+ // load before returning, so keep that contract: a returned handle is usable,
338
+ // and a bad snapshot fails here instead of inside an unrelated test.
339
+ await pglite.waitReady;
35
340
  const dialect = new PGliteDialect(pglite);
36
341
  const kysely = getKysely(dialect, {
37
342
  repositoryName: args?.repositoryName ?? 'localTesting',
38
343
  log: args?.log,
39
344
  });
40
- await ensureDigestFunction(kysely);
41
- await ensureGenRandomBytesFunction(kysely);
42
- await migrateToLatest(kysely);
345
+ const controlPlaneKysely = withControlPlaneSchema(getKysely(dialect, {
346
+ repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,
347
+ log: args.log,
348
+ }), 'control_plane', 'control_plane');
349
+ controlPlaneKysely.destroy = async () => { };
350
+ Object.defineProperty(kysely, 'controlPlaneKysely', {
351
+ value: controlPlaneKysely,
352
+ });
43
353
  const originalDestroy = kysely.destroy.bind(kysely);
44
354
  kysely.destroy = async () => {
45
355
  if (isDestroyed)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAkB,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAOrD,KAAK,UAAU,eAAe,CAAC,MAAmC;IAChE,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;QAC5B,EAAE,EAAE,MAAM;QACV,oBAAoB,EAAE,iBAAiB,CAAC,WAAW;QACnD,kBAAkB,EAAE,iBAAiB,CAAC,SAAS;QAC/C,sBAAsB,EAAE,iBAAiB,CAAC,aAAa;QACvD,QAAQ,EAAE,IAAI,qBAAqB,CAAC;YAClC,EAAE;YACF,IAAI;YACJ,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,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;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B,EAAE;IACnE,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,iCAAiC;IAEjC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE;QAChC,cAAc,EAAE,IAAI,EAAE,cAAc,IAAI,cAAc;QACtD,GAAG,EAAE,IAAI,EAAE,GAAG;KACf,CAAC,CAAC;IACH,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,4BAA4B,CAAC,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 from both production's postgres.js driver and
3
- * PGlite, which expose constraint names under different property names.
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: string;
7
+ constraint?: string;
8
8
  }): boolean;
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Matches PostgreSQL errors from both production's postgres.js driver and
3
- * PGlite, which expose constraint names under different property names.
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 function isPostgresError(error, expected) {
6
6
  if (!(error instanceof Error) ||
@@ -13,6 +13,7 @@ export function isPostgresError(error, expected) {
13
13
  : 'constraint_name' in error && typeof error.constraint_name === 'string'
14
14
  ? error.constraint_name
15
15
  : undefined;
16
- return error.code === expected.code && constraint === expected.constraint;
16
+ return (error.code === expected.code &&
17
+ (expected.constraint === undefined || constraint === expected.constraint));
17
18
  }
18
19
  //# sourceMappingURL=postgres-error.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-error.js","sourceRoot":"src/","sources":["postgres-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAc,EACd,QAA8C;IAE9C,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,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,IAAI,UAAU,KAAK,QAAQ,CAAC,UAAU,CAAC;AAC5E,CAAC","sourcesContent":["/**\n * Matches PostgreSQL errors from both production's postgres.js driver and\n * PGlite, which expose constraint names under different property names.\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 error.code === expected.code && constraint === expected.constraint;\n}\n"]}
1
+ {"version":3,"file":"postgres-error.js","sourceRoot":"src/","sources":["postgres-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,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"]}
@@ -1,16 +1,12 @@
1
1
  import { day } from '@vrplatform/utils';
2
2
  import { sql } from '../../isomorphic';
3
+ import { whereTenantActive } from '../tenant/status';
3
4
  function hasActiveListing(eb, today) {
4
5
  return eb.exists(eb
5
6
  .selectFrom('public.tenant as tenant')
6
- .leftJoin('public.tenant as billingPartner', 'billingPartner.id', 'tenant.calculatedBillingPartnerId')
7
7
  .select('tenant.id')
8
8
  .whereRef('tenant.id', '=', 'l.tenantId')
9
- .where('tenant.calculatedStatus', '=', 'active')
10
- .where((eb2) => eb2.or([
11
- eb2('tenant.calculatedBillingPartnerId', 'is', null),
12
- eb2('billingPartner.calculatedStatus', '=', 'active'),
13
- ]))
9
+ .where(whereTenantActive)
14
10
  .where((eb2) => eb2.or([
15
11
  eb2.and([
16
12
  eb2('tenant.isGeneralLedger', '=', false),
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/listing/status.ts"],"names":[],"mappings":"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","sourcesContent":["import { day } from '@vrplatform/utils';\nimport type { DB, ExpressionBuilder, PublicListing } from '../../isomorphic';\nimport { sql } from '../../isomorphic';\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 .leftJoin(\n 'public.tenant as billingPartner',\n 'billingPartner.id',\n 'tenant.calculatedBillingPartnerId'\n )\n .select('tenant.id')\n .whereRef('tenant.id', '=', 'l.tenantId')\n .where('tenant.calculatedStatus', '=', 'active')\n .where((eb2) =>\n eb2.or([\n eb2('tenant.calculatedBillingPartnerId', 'is', null),\n eb2('billingPartner.calculatedStatus', '=', 'active'),\n ])\n )\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
+ {"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/listing/status.ts"],"names":[],"mappings":"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","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 { DB, ExpressionBuilder, PublicTenant } from '../../isomorphic';
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", import("kysely/dist/cjs/util/type-utils").SqlBool>;
8
- export declare function whereTenantNotTestTeam(eb: TenantExpressionBuilder, testTeamId: string): import("kysely").ExpressionWrapper<DB & {
9
- tenant: PublicTenant;
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", import("kysely/dist/cjs/util/type-utils").SqlBool>;
13
+ }, "tenant", SqlBool>;
17
14
  export {};
@@ -1,36 +1,32 @@
1
- import { day } from '@vrplatform/utils';
1
+ import { sql, } from '../../isomorphic';
2
2
  import { getCalculatedBillingPartnerId } from './billing-partner';
3
3
  export function whereTenantActive(eb) {
4
4
  return eb.and([
5
5
  eb('tenant.calculatedStatus', '=', 'active'),
6
- eb.exists(eb
6
+ eb.not(eb.exists(eb
7
7
  .selectFrom('public.tenant as billingPartner')
8
8
  .select('billingPartner.id')
9
9
  .where('billingPartner.id', '=', eb.fn.coalesce('tenant.calculatedBillingPartnerId', eb.val(getCalculatedBillingPartnerId({}))))
10
- .where('billingPartner.calculatedStatus', '=', 'active')),
10
+ .where('billingPartner.calculatedStatus', 'is distinct from', 'active'))),
11
11
  ]);
12
12
  }
13
- export function whereTenantNotTestTeam(eb, testTeamId) {
14
- return eb.and([
15
- eb('tenant.id', '!=', testTeamId),
16
- eb.or([
17
- eb('tenant.partnerId', 'is', null),
18
- eb('tenant.partnerId', '!=', testTeamId),
19
- ]),
20
- eb.or([
21
- eb('tenant.billingPartnerId', 'is', null),
22
- eb('tenant.billingPartnerId', '!=', testTeamId),
23
- ]),
24
- ]);
13
+ export function whereTenantNotTestTeam(testTeamId) {
14
+ return sql `(
15
+ ${sql.ref('tenant.id')} != ${testTeamId}
16
+ and (
17
+ ${sql.ref('tenant.partnerId')} is null
18
+ or ${sql.ref('tenant.partnerId')} != ${testTeamId}
19
+ )
20
+ and (
21
+ ${sql.ref('tenant.billingPartnerId')} is null
22
+ or ${sql.ref('tenant.billingPartnerId')} != ${testTeamId}
23
+ )
24
+ )`;
25
25
  }
26
- export function whereTenantShouldBePaid(eb, { includePartnerTeams = false, today = day().yyyymmdd(), } = {}) {
26
+ export function whereTenantShouldBePaid(eb, { includePartnerTeams = false, } = {}) {
27
27
  return eb.and([
28
28
  whereTenantActive(eb),
29
29
  eb('tenant.isOnboarding', '=', false),
30
- eb.or([
31
- eb('tenant.trialUntil', '<', today),
32
- eb('tenant.trialUntil', 'is', null),
33
- ]),
34
30
  ...(includePartnerTeams
35
31
  ? []
36
32
  : [eb('tenant.calculatedIsBillable', '=', true)]),
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/tenant/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAOlE,MAAM,UAAU,iBAAiB,CAAC,EAA2B;IAC3D,OAAO,EAAE,CAAC,GAAG,CAAC;QACZ,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE,QAAQ,CAAC;QAC5C,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,6BAA6B,CAAC,EAAE,CAAC,CAAC,CAC1C,CACF;aACA,KAAK,CAAC,iCAAiC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAC3D;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,EAA2B,EAC3B,UAAkB;IAElB,OAAO,EAAE,CAAC,GAAG,CAAC;QACZ,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC;QACjC,EAAE,CAAC,EAAE,CAAC;YACJ,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC;YAClC,EAAE,CAAC,kBAAkB,EAAE,IAAI,EAAE,UAAU,CAAC;SACzC,CAAC;QACF,EAAE,CAAC,EAAE,CAAC;YACJ,EAAE,CAAC,yBAAyB,EAAE,IAAI,EAAE,IAAI,CAAC;YACzC,EAAE,CAAC,yBAAyB,EAAE,IAAI,EAAE,UAAU,CAAC;SAChD,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,EAA2B,EAC3B,EACE,mBAAmB,GAAG,KAAK,EAC3B,KAAK,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,MAItB,EAAE;IAEN,OAAO,EAAE,CAAC,GAAG,CAAC;QACZ,iBAAiB,CAAC,EAAE,CAAC;QACrB,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE,KAAK,CAAC;QACrC,EAAE,CAAC,EAAE,CAAC;YACJ,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE,KAAK,CAAC;YACnC,EAAE,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,CAAC;SACpC,CAAC;QACF,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 { day } from '@vrplatform/utils';\nimport type { DB, ExpressionBuilder, PublicTenant } 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.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('billingPartner.calculatedStatus', '=', 'active')\n ),\n ]);\n}\n\nexport function whereTenantNotTestTeam(\n eb: TenantExpressionBuilder,\n testTeamId: string\n) {\n return eb.and([\n eb('tenant.id', '!=', testTeamId),\n eb.or([\n eb('tenant.partnerId', 'is', null),\n eb('tenant.partnerId', '!=', testTeamId),\n ]),\n eb.or([\n eb('tenant.billingPartnerId', 'is', null),\n eb('tenant.billingPartnerId', '!=', testTeamId),\n ]),\n ]);\n}\n\nexport function whereTenantShouldBePaid(\n eb: TenantExpressionBuilder,\n {\n includePartnerTeams = false,\n today = day().yyyymmdd(),\n }: {\n includePartnerTeams?: boolean;\n today?: Date | string;\n } = {}\n) {\n return eb.and([\n whereTenantActive(eb),\n eb('tenant.isOnboarding', '=', false),\n eb.or([\n eb('tenant.trialUntil', '<', today),\n eb('tenant.trialUntil', 'is', null),\n ]),\n ...(includePartnerTeams\n ? []\n : [eb('tenant.calculatedIsBillable', '=', true)]),\n ]);\n}\n"]}
1
+ {"version":3,"file":"status.js","sourceRoot":"src/","sources":["query/tenant/status.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,GAKJ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAOlE,MAAM,UAAU,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,6BAA6B,CAAC,EAAE,CAAC,CAAC,CAC1C,CACF;aACA,KAAK,CACJ,iCAAiC,EACjC,kBAAkB,EAClB,QAAQ,CACT,CACJ,CACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACvD,OAAO,GAAG,CAAS;MACf,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,UAAU;;QAEnC,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC;WACxB,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,UAAU;;;QAG/C,GAAG,CAAC,GAAG,CAAC,yBAAyB,CAAC;WAC/B,GAAG,CAAC,GAAG,CAAC,yBAAyB,CAAC,OAAO,UAAU;;IAE1D,CAAC;AACL,CAAC;AAED,MAAM,UAAU,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"]}
@@ -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>;