stripe-experiment-sync 1.0.21 → 1.0.23

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/README.md CHANGED
@@ -39,7 +39,7 @@ const sync = new StripeSync({
39
39
  })
40
40
 
41
41
  // Create a managed webhook - no additional processing needed!
42
- const webhook = await sync.findOrCreateManagedWebhook('https://example.com/stripe-webhooks')
42
+ const webhook = await sync.webhook.findOrCreateManagedWebhook('https://example.com/stripe-webhooks')
43
43
 
44
44
  // Cleanup when done (closes PostgreSQL connection pool)
45
45
  await sync.close()
@@ -54,7 +54,7 @@ The Stripe Sync Engine automatically manages webhook endpoints and their process
54
54
  ```typescript
55
55
  // Create or reuse an existing webhook endpoint
56
56
  // This webhook will automatically sync all Stripe events to your database
57
- const webhook = await sync.findOrCreateManagedWebhook('https://example.com/stripe-webhooks')
57
+ const webhook = await sync.webhook.findOrCreateManagedWebhook('https://example.com/stripe-webhooks')
58
58
 
59
59
  // Create a webhook for specific events
60
60
  const webhook = await sync.createManagedWebhook('https://example.com/stripe-webhooks', {
@@ -71,7 +71,7 @@ console.log(webhook.secret) // whsec_xxx
71
71
 
72
72
  ```typescript
73
73
  // List all managed webhooks
74
- const webhooks = await sync.listManagedWebhooks()
74
+ const webhooks = await sync.webhook.listManagedWebhooks()
75
75
 
76
76
  // Get a specific webhook
77
77
  const webhook = await sync.getManagedWebhook('we_xxx')
@@ -104,7 +104,7 @@ app.post('/stripe-webhooks', async (req, res) => {
104
104
  const payload = req.body
105
105
 
106
106
  try {
107
- await sync.processWebhook(payload, signature)
107
+ await sync.webhook.processWebhook(payload, signature)
108
108
  res.status(200).send({ received: true })
109
109
  } catch (error) {
110
110
  res.status(400).send({ error: error.message })
@@ -132,9 +132,6 @@ await sync.close()
132
132
  | `autoExpandLists` | boolean | Fetch all list items from Stripe (not just the default 10) |
133
133
  | `backfillRelatedEntities` | boolean | Ensure related entities exist for foreign key integrity |
134
134
  | `revalidateObjectsViaStripeApi` | Array | Always fetch latest data from Stripe instead of trusting webhook payload. Possible values: charge, credit_note, customer, dispute, invoice, payment_intent, payment_method, plan, price, product, refund, review, radar.early_fraud_warning, setup_intent, subscription, subscription_schedule, tax_id |
135
- | `maxRetries` | number | Maximum retry attempts for 429 rate limits. Default: 5 |
136
- | `initialRetryDelayMs` | number | Initial retry delay in milliseconds. Default: 1000 |
137
- | `maxRetryDelayMs` | number | Maximum retry delay in milliseconds. Default: 60000 |
138
135
  | `logger` | Logger | Logger instance (pino-compatible) |
139
136
 
140
137
  ## Database Schema
@@ -185,17 +182,14 @@ await sync.syncSingleEntity('prod_xyz')
185
182
  ### Backfill Historical Data
186
183
 
187
184
  ```ts
188
- // Sync all products created after a date
189
- await sync.processUntilDone({
190
- object: 'product',
191
- created: { gte: 1643872333 }, // Unix timestamp
192
- })
185
+ // Sync all products
186
+ await sync.fullSync(['product'])
193
187
 
194
188
  // Sync all customers
195
- await sync.processUntilDone({ object: 'customer' })
189
+ await sync.fullSync(['customer'])
196
190
 
197
191
  // Sync everything
198
- await sync.processUntilDone({ object: 'all' })
192
+ await sync.fullSync()
199
193
  ```
200
194
 
201
195
  Supported objects: `all`, `charge`, `checkout_sessions`, `credit_note`, `customer`, `customer_with_entitlements`, `dispute`, `early_fraud_warning`, `invoice`, `payment_intent`, `payment_method`, `plan`, `price`, `product`, `refund`, `setup_intent`, `subscription`, `subscription_schedules`, `tax_id`.
@@ -277,6 +271,21 @@ The install command will:
277
271
  3. Create a managed Stripe webhook pointing to your Supabase project
278
272
  4. Set up a pg_cron job for automatic background syncing
279
273
 
274
+ ### Required Permissions
275
+
276
+ The Supabase access token must have the following Management API permissions:
277
+
278
+ | Permission | Used For |
279
+ | ------------------------------ | ------------------------------------------------------------ |
280
+ | `projects_read` | Validate project access and existence |
281
+ | `edge_functions_write` | Deploy Edge Functions (setup, webhook, worker, sigma-worker) |
282
+ | `edge_functions_secrets_write` | Set Stripe API key and configuration secrets |
283
+ | `database_write` | Execute database migrations and schema setup |
284
+ | `database_read` | Check schema existence and verify installation |
285
+ | `api_gateway_keys_read` | Retrieve project's anon API key |
286
+
287
+ **Note:** When generating a personal access token or using OAuth2, ensure these permissions are granted. For OAuth2 tokens, these correspond to the fine-grained token permissions on the Management API.
288
+
280
289
  ## CLI Commands
281
290
 
282
291
  ```bash
@@ -3,11 +3,11 @@ import {
3
3
  StripeSync,
4
4
  createStripeWebSocketClient,
5
5
  runMigrations
6
- } from "./chunk-ECLPGCY6.js";
6
+ } from "./chunk-K22YTC4W.js";
7
7
  import {
8
8
  install,
9
9
  uninstall
10
- } from "./chunk-3KTFUZTY.js";
10
+ } from "./chunk-H7FT5PGN.js";
11
11
 
12
12
  // src/cli/config.ts
13
13
  import dotenv from "dotenv";
@@ -111,6 +111,73 @@ Creating ngrok tunnel for port ${port}...`));
111
111
  import chalk3 from "chalk";
112
112
  import express from "express";
113
113
  import dotenv2 from "dotenv";
114
+ async function monitorCommand(options) {
115
+ try {
116
+ dotenv2.config();
117
+ let databaseUrl = options.databaseUrl || process.env.DATABASE_URL || "";
118
+ if (!databaseUrl) {
119
+ const inquirer2 = (await import("inquirer")).default;
120
+ const answers = await inquirer2.prompt([
121
+ {
122
+ type: "password",
123
+ name: "databaseUrl",
124
+ message: "Enter your Postgres DATABASE_URL:",
125
+ mask: "*",
126
+ validate: (input) => {
127
+ if (!input || input.trim() === "") return "DATABASE_URL is required";
128
+ if (!input.startsWith("postgres://") && !input.startsWith("postgresql://"))
129
+ return 'DATABASE_URL should start with "postgres://" or "postgresql://"';
130
+ return true;
131
+ }
132
+ }
133
+ ]);
134
+ databaseUrl = answers.databaseUrl;
135
+ }
136
+ const poolConfig = {
137
+ max: 1,
138
+ connectionString: databaseUrl,
139
+ keepAlive: true
140
+ };
141
+ const stripeSync = await StripeSync.create({
142
+ databaseUrl,
143
+ stripeSecretKey: options.stripeKey || process.env.STRIPE_API_KEY || process.env.STRIPE_SECRET_KEY || "sk_placeholder",
144
+ poolConfig
145
+ });
146
+ console.log(chalk3.blue("Monitoring table row counts (Ctrl-C to stop)...\n"));
147
+ const activeRun = await stripeSync.postgresClient.getActiveSyncRun(stripeSync.accountId);
148
+ if (!activeRun) {
149
+ const lastCompleted = await stripeSync.postgresClient.getCompletedRun(
150
+ stripeSync.accountId,
151
+ Infinity
152
+ );
153
+ if (lastCompleted) {
154
+ console.log(
155
+ chalk3.green(
156
+ `No active sync run. Last completed at ${lastCompleted.runStartedAt.toISOString()}`
157
+ )
158
+ );
159
+ } else {
160
+ console.log(chalk3.yellow("No active or completed sync runs found."));
161
+ }
162
+ await stripeSync.close();
163
+ return;
164
+ }
165
+ const interval = stripeSync.startTableMonitor(2e3, activeRun);
166
+ const cleanup = () => {
167
+ clearInterval(interval);
168
+ stripeSync.close().finally(() => process.exit(0));
169
+ };
170
+ process.on("SIGINT", cleanup);
171
+ process.on("SIGTERM", cleanup);
172
+ await new Promise(() => {
173
+ });
174
+ } catch (error) {
175
+ if (error instanceof Error) {
176
+ console.error(chalk3.red(error.message));
177
+ }
178
+ process.exit(1);
179
+ }
180
+ }
114
181
  var VALID_SYNC_OBJECTS = [
115
182
  "all",
116
183
  "customer",
@@ -219,7 +286,7 @@ async function backfillCommand(options, entityName) {
219
286
  connectionString: config.databaseUrl,
220
287
  keepAlive: true
221
288
  };
222
- stripeSync = new StripeSync({
289
+ stripeSync = await StripeSync.create({
223
290
  databaseUrl: config.databaseUrl,
224
291
  stripeSecretKey: config.stripeApiKey,
225
292
  enableSigma,
@@ -229,12 +296,7 @@ async function backfillCommand(options, entityName) {
229
296
  poolConfig
230
297
  });
231
298
  if (entityName === "all") {
232
- const backfill = await stripeSync.processUntilDoneParallel({
233
- object: "all",
234
- triggeredBy: "cli-backfill",
235
- maxParallel: 10,
236
- skipInaccessibleSigmaTables: true
237
- });
299
+ const backfill = await stripeSync.fullSync();
238
300
  const objectCount = Object.keys(backfill.totals).length;
239
301
  console.log(
240
302
  chalk3.green(
@@ -255,14 +317,19 @@ async function backfillCommand(options, entityName) {
255
317
  }
256
318
  }
257
319
  } else {
258
- const result = await stripeSync.processUntilDone({ object: entityName });
259
- const totalSynced = Object.values(result).reduce(
260
- (sum, syncResult) => sum + (syncResult?.synced || 0),
320
+ const result = await stripeSync.fullSync(
321
+ [entityName],
322
+ true,
323
+ 20,
324
+ 10,
325
+ true,
261
326
  0
262
327
  );
263
328
  const tableType = isSigmaTable ? "(sigma)" : "";
264
329
  console.log(
265
- chalk3.green(`\u2713 Backfill complete: ${totalSynced} ${entityName} ${tableType} rows synced`)
330
+ chalk3.green(
331
+ `\u2713 Full sync complete: ${result.totalSynced} ${entityName} ${tableType} rows synced`
332
+ )
266
333
  );
267
334
  }
268
335
  await stripeSync.close();
@@ -337,7 +404,7 @@ async function migrateCommand(options) {
337
404
  }
338
405
  }
339
406
  async function syncCommand(options) {
340
- let stripeSync = null;
407
+ let stripeSync;
341
408
  let tunnel = null;
342
409
  let server = null;
343
410
  let webhookId = null;
@@ -357,7 +424,7 @@ Cleaning up... (signal: ${signal || "manual"})`));
357
424
  const keepWebhooksOnShutdown = process.env.KEEP_WEBHOOKS_ON_SHUTDOWN === "true";
358
425
  if (webhookId && stripeSync && !keepWebhooksOnShutdown) {
359
426
  try {
360
- await stripeSync.deleteManagedWebhook(webhookId);
427
+ await stripeSync.webhook.deleteManagedWebhook(webhookId);
361
428
  console.log(chalk3.green("\u2713 Webhook cleanup complete"));
362
429
  } catch {
363
430
  console.log(chalk3.yellow("\u26A0 Could not delete webhook"));
@@ -420,7 +487,7 @@ Mode: ${modeLabel}`));
420
487
  connectionString: config.databaseUrl,
421
488
  keepAlive: true
422
489
  };
423
- stripeSync = new StripeSync({
490
+ stripeSync = await StripeSync.create({
424
491
  databaseUrl: config.databaseUrl,
425
492
  stripeSecretKey: config.stripeApiKey,
426
493
  enableSigma: config.enableSigma,
@@ -439,7 +506,7 @@ Mode: ${modeLabel}`));
439
506
  const payload = JSON.parse(event.event_payload);
440
507
  console.log(chalk3.cyan(`\u2190 ${payload.type}`) + chalk3.gray(` (${payload.id})`));
441
508
  if (stripeSync) {
442
- await stripeSync.processEvent(payload);
509
+ await stripeSync.webhook.processEvent(payload);
443
510
  return {
444
511
  status: 200,
445
512
  event_type: payload.type,
@@ -473,7 +540,9 @@ Mode: ${modeLabel}`));
473
540
  tunnel = await createTunnel(port, config.ngrokAuthToken);
474
541
  const webhookPath = process.env.WEBHOOK_PATH || "/stripe-webhooks";
475
542
  console.log(chalk3.blue("\nCreating Stripe webhook endpoint..."));
476
- const webhook = await stripeSync.findOrCreateManagedWebhook(`${tunnel.url}${webhookPath}`);
543
+ const webhook = await stripeSync.webhook.findOrCreateManagedWebhook(
544
+ `${tunnel.url}${webhookPath}`
545
+ );
477
546
  webhookId = webhook.id;
478
547
  const eventCount = webhook.enabled_events?.length || 0;
479
548
  console.log(chalk3.green(`\u2713 Webhook created: ${webhook.id}`));
@@ -494,7 +563,7 @@ Mode: ${modeLabel}`));
494
563
  return res.status(400).send({ error: "Missing raw body for signature verification" });
495
564
  }
496
565
  try {
497
- await stripeSync.processWebhook(rawBody, sig);
566
+ await stripeSync.webhook.processWebhook(rawBody, sig);
498
567
  return res.status(200).send({ received: true });
499
568
  } catch (error) {
500
569
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
@@ -518,11 +587,7 @@ Starting server on port ${port}...`));
518
587
  throw new Error("StripeSync not initialized.");
519
588
  }
520
589
  console.log(chalk3.blue("\nStarting historical backfill (parallel sweep)..."));
521
- const backfill = await stripeSync.processUntilDoneParallel({
522
- triggeredBy: "cli-historical-backfill",
523
- maxParallel: 10,
524
- skipInaccessibleSigmaTables: true
525
- });
590
+ const backfill = await stripeSync.fullSync();
526
591
  const objectCount = Object.keys(backfill.totals).length;
527
592
  console.log(
528
593
  chalk3.green(
@@ -543,9 +608,6 @@ Starting server on port ${port}...`));
543
608
  )
544
609
  );
545
610
  }
546
- console.log(chalk3.blue("\nStarting incremental backfill..."));
547
- await stripeSync.processUntilDone();
548
- console.log(chalk3.green("\u2713 Incremental backfill complete"));
549
611
  } else {
550
612
  console.log(chalk3.yellow("\n\u23ED\uFE0F Skipping initial sync (SKIP_BACKFILL=true)"));
551
613
  }
@@ -562,6 +624,145 @@ Starting server on port ${port}...`));
562
624
  process.exit(1);
563
625
  }
564
626
  }
627
+ async function fullSyncCommand(options) {
628
+ let stripeSync = null;
629
+ try {
630
+ dotenv2.config();
631
+ const enableSigma = options.enableSigma ?? process.env.ENABLE_SIGMA === "true";
632
+ const intervalSeconds = options.interval ?? 86400;
633
+ let stripeApiKey = options.stripeKey || process.env.STRIPE_API_KEY || process.env.STRIPE_SECRET_KEY || "";
634
+ let databaseUrl = options.databaseUrl || process.env.DATABASE_URL || "";
635
+ if (!stripeApiKey || !databaseUrl) {
636
+ const inquirer2 = (await import("inquirer")).default;
637
+ const questions = [];
638
+ if (!stripeApiKey) {
639
+ questions.push({
640
+ type: "password",
641
+ name: "stripeApiKey",
642
+ message: "Enter your Stripe API key:",
643
+ mask: "*",
644
+ validate: (input) => {
645
+ if (!input || input.trim() === "") {
646
+ return "Stripe API key is required";
647
+ }
648
+ if (!input.startsWith("sk_") && !input.startsWith("rk_")) {
649
+ return 'Stripe API key should start with "sk_" or "rk_"';
650
+ }
651
+ return true;
652
+ }
653
+ });
654
+ }
655
+ if (!databaseUrl) {
656
+ questions.push({
657
+ type: "password",
658
+ name: "databaseUrl",
659
+ message: "Enter your Postgres DATABASE_URL:",
660
+ mask: "*",
661
+ validate: (input) => {
662
+ if (!input || input.trim() === "") {
663
+ return "DATABASE_URL is required";
664
+ }
665
+ if (!input.startsWith("postgres://") && !input.startsWith("postgresql://")) {
666
+ return 'DATABASE_URL should start with "postgres://" or "postgresql://"';
667
+ }
668
+ return true;
669
+ }
670
+ });
671
+ }
672
+ if (questions.length > 0) {
673
+ console.log(chalk3.yellow("\nMissing required configuration. Please provide:"));
674
+ const answers = await inquirer2.prompt(questions);
675
+ if (answers.stripeApiKey) stripeApiKey = answers.stripeApiKey;
676
+ if (answers.databaseUrl) databaseUrl = answers.databaseUrl;
677
+ }
678
+ }
679
+ const config = {
680
+ stripeApiKey,
681
+ databaseUrl
682
+ };
683
+ console.log(chalk3.blue("\nPerforming full resync of all Stripe data..."));
684
+ console.log(chalk3.gray(`Database: ${config.databaseUrl.replace(/:[^:@]+@/, ":****@")}`));
685
+ console.log(chalk3.gray(`Reconciliation interval: ${intervalSeconds}s`));
686
+ try {
687
+ await runMigrations({
688
+ databaseUrl: config.databaseUrl,
689
+ enableSigma
690
+ });
691
+ } catch (migrationError) {
692
+ console.error(chalk3.red("Failed to run migrations:"));
693
+ console.error(
694
+ migrationError instanceof Error ? migrationError.message : String(migrationError)
695
+ );
696
+ throw migrationError;
697
+ }
698
+ const poolConfig = {
699
+ max: 10,
700
+ connectionString: config.databaseUrl,
701
+ keepAlive: true
702
+ };
703
+ stripeSync = await StripeSync.create({
704
+ databaseUrl: config.databaseUrl,
705
+ stripeSecretKey: config.stripeApiKey,
706
+ enableSigma,
707
+ stripeApiVersion: process.env.STRIPE_API_VERSION || "2020-08-27",
708
+ autoExpandLists: process.env.AUTO_EXPAND_LISTS === "true",
709
+ backfillRelatedEntities: process.env.BACKFILL_RELATED_ENTITIES !== "false",
710
+ poolConfig
711
+ });
712
+ const completedRun = await stripeSync.postgresClient.getCompletedRun(
713
+ stripeSync.accountId,
714
+ intervalSeconds
715
+ );
716
+ if (completedRun) {
717
+ console.log(
718
+ chalk3.green(
719
+ `\u2713 Skipping resync \u2014 a successful run completed at ${completedRun.runStartedAt.toISOString()} (within ${intervalSeconds}s window)`
720
+ )
721
+ );
722
+ await stripeSync.close();
723
+ return;
724
+ }
725
+ const startTime = Date.now();
726
+ const result = await stripeSync.fullSync(
727
+ void 0,
728
+ void 0,
729
+ options.workerCount,
730
+ options.rateLimit
731
+ );
732
+ const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
733
+ const objectCount = Object.keys(result.totals).length;
734
+ console.log(
735
+ chalk3.green(
736
+ `\u2713 Full resync complete: ${result.totalSynced} rows synced across ${objectCount} objects in ${elapsed}s`
737
+ )
738
+ );
739
+ if (result.skipped.length > 0) {
740
+ console.log(
741
+ chalk3.yellow(
742
+ `Skipped ${result.skipped.length} Sigma tables without access: ${result.skipped.join(", ")}`
743
+ )
744
+ );
745
+ }
746
+ if (result.errors.length > 0) {
747
+ console.log(chalk3.red(`Full resync finished with ${result.errors.length} errors:`));
748
+ for (const err of result.errors) {
749
+ console.log(chalk3.red(` - ${err.object}: ${err.message}`));
750
+ }
751
+ }
752
+ await stripeSync.close();
753
+ } catch (error) {
754
+ if (error instanceof Error) {
755
+ console.error(chalk3.red(error.message));
756
+ }
757
+ if (stripeSync) {
758
+ try {
759
+ await stripeSync.close();
760
+ } catch {
761
+ }
762
+ }
763
+ process.exit(1);
764
+ }
765
+ }
565
766
  async function installCommand(options) {
566
767
  try {
567
768
  dotenv2.config();
@@ -611,6 +812,14 @@ async function installCommand(options) {
611
812
  }
612
813
  }
613
814
  console.log(chalk3.blue("\n\u{1F680} Installing Stripe Sync to Supabase Edge Functions...\n"));
815
+ const tokenSource = options.supabaseAccessToken ? "CLI" : process.env.SUPABASE_ACCESS_TOKEN ? "env" : "prompt";
816
+ const projectSource = options.supabaseProjectRef ? "CLI" : process.env.SUPABASE_PROJECT_REF ? "env" : "prompt";
817
+ console.log(
818
+ chalk3.gray(
819
+ `Access token source: ${tokenSource} (${accessToken.slice(0, 8)}...${accessToken.slice(-4)})`
820
+ )
821
+ );
822
+ console.log(chalk3.gray(`Project ref source: ${projectSource} (${projectRef})`));
614
823
  const supabaseManagementUrl = options.supabaseManagementUrl || process.env.SUPABASE_MANAGEMENT_URL;
615
824
  console.log(chalk3.gray("Validating project access..."));
616
825
  await install({
@@ -619,8 +828,10 @@ async function installCommand(options) {
619
828
  stripeKey,
620
829
  packageVersion: options.packageVersion,
621
830
  workerIntervalSeconds: options.workerInterval,
831
+ syncIntervalSeconds: options.syncInterval,
622
832
  supabaseManagementUrl,
623
- enableSigma: options.enableSigma
833
+ enableSigma: options.enableSigma,
834
+ rateLimit: options.rateLimit
624
835
  });
625
836
  console.log(chalk3.cyan("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
626
837
  console.log(chalk3.cyan.bold(" Installation Complete!"));
@@ -699,9 +910,11 @@ async function uninstallCommand(options) {
699
910
  export {
700
911
  loadConfig,
701
912
  createTunnel,
913
+ monitorCommand,
702
914
  backfillCommand,
703
915
  migrateCommand,
704
916
  syncCommand,
917
+ fullSyncCommand,
705
918
  installCommand,
706
919
  uninstallCommand
707
920
  };
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "stripe-experiment-sync",
4
- version: "1.0.21",
4
+ version: "1.0.23",
5
5
  private: false,
6
6
  description: "Stripe Sync Engine to sync Stripe data to Postgres",
7
7
  type: "module",
@@ -26,12 +26,15 @@ var package_default = {
26
26
  },
27
27
  scripts: {
28
28
  clean: "rimraf dist",
29
- prebuild: "npm run clean",
29
+ prebuild: "npm run clean && npm run build:functions",
30
+ "build:functions": "tsx scripts/build-functions.ts",
30
31
  build: "tsup src/index.ts src/supabase/index.ts src/cli/index.ts src/cli/lib.ts --format esm,cjs --dts --shims && cp -r src/database/migrations dist/migrations",
31
32
  lint: "eslint src --ext .ts",
32
33
  test: "vitest",
33
34
  "test:integration": "TEST_POSTGRES_DB_URL=${TEST_POSTGRES_DB_URL:-postgresql://postgres:postgres@localhost:55432/postgres} vitest run src/stripeSync*integration.test.ts",
34
35
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
36
+ start: "pnpm run build && node dist/cli/index.js backfill",
37
+ "full-sync": "pnpm run build && node dist/cli/index.js full-sync",
35
38
  "generate:sigma-schema": "tsx src/sigma/schema/fetch-schema.ts"
36
39
  },
37
40
  files: [
@@ -42,13 +45,14 @@ var package_default = {
42
45
  chalk: "^5.3.0",
43
46
  commander: "^12.1.0",
44
47
  dotenv: "^16.4.7",
48
+ esbuild: "^0.27.3",
45
49
  express: "^4.18.2",
46
50
  inquirer: "^12.3.0",
47
51
  papaparse: "5.4.1",
48
52
  pg: "^8.16.3",
49
53
  "pg-node-migrations": "0.0.8",
50
54
  stripe: "^17.7.0",
51
- "supabase-management-js": "^0.1.6",
55
+ "supabase-management-js": "^2.0.2",
52
56
  ws: "^8.18.0",
53
57
  yesql: "^7.0.0"
54
58
  },
@@ -61,6 +65,7 @@ var package_default = {
61
65
  "@types/ws": "^8.5.13",
62
66
  "@types/yesql": "^4.1.4",
63
67
  "@vitest/ui": "^4.0.9",
68
+ esbuild: "^0.27.2",
64
69
  tsx: "^4.19.2",
65
70
  vitest: "^3.2.4"
66
71
  },