stripe-experiment-sync 1.0.12 → 1.0.15-beta.1766078819

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.
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/supabase/index.ts
@@ -48,13 +38,13 @@ module.exports = __toCommonJS(supabase_exports);
48
38
  var import_supabase_management_js = require("supabase-management-js");
49
39
 
50
40
  // raw-ts:/home/runner/work/sync-engine/sync-engine/packages/sync-engine/src/supabase/edge-functions/stripe-setup.ts
51
- var stripe_setup_default = "import { StripeSync, runMigrations, VERSION } from 'npm:stripe-experiment-sync'\nimport postgres from 'npm:postgres'\n\nDeno.serve(async (req) => {\n // Require authentication for both GET and POST\n const authHeader = req.headers.get('Authorization')\n if (!authHeader?.startsWith('Bearer ')) {\n return new Response('Unauthorized', { status: 401 })\n }\n\n // Handle GET requests for status\n if (req.method === 'GET') {\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n return new Response(JSON.stringify({ error: 'SUPABASE_DB_URL not set' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n let sql\n\n try {\n sql = postgres(dbUrl, { max: 1, prepare: false })\n\n // Query installation status from schema comment\n const commentResult = await sql`\n SELECT obj_description(oid, 'pg_namespace') as comment\n FROM pg_namespace\n WHERE nspname = 'stripe'\n `\n\n const comment = commentResult[0]?.comment || null\n let installationStatus = 'not_installed'\n\n if (comment && comment.includes('stripe-sync')) {\n // Parse installation status from comment\n if (comment.includes('installation:started')) {\n installationStatus = 'installing'\n } else if (comment.includes('installation:error')) {\n installationStatus = 'error'\n } else if (comment.includes('installed')) {\n installationStatus = 'installed'\n }\n }\n\n // Query sync runs (only if schema exists)\n let syncStatus = []\n if (comment) {\n try {\n syncStatus = await sql`\n SELECT DISTINCT ON (account_id)\n account_id, started_at, closed_at, status, error_message,\n total_processed, total_objects, complete_count, error_count,\n running_count, pending_count, triggered_by, max_concurrent\n FROM stripe.sync_runs\n ORDER BY account_id, started_at DESC\n `\n } catch (err) {\n // Ignore errors if sync_runs view doesn't exist yet\n console.warn('sync_runs query failed (may not exist yet):', err)\n }\n }\n\n return new Response(\n JSON.stringify({\n package_version: VERSION,\n installation_status: installationStatus,\n sync_status: syncStatus,\n }),\n {\n status: 200,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n },\n }\n )\n } catch (error) {\n console.error('Status query error:', error)\n return new Response(\n JSON.stringify({\n error: error.message,\n package_version: VERSION,\n installation_status: 'not_installed',\n }),\n {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n } finally {\n if (sql) await sql.end()\n }\n }\n\n // Handle POST requests for setup (existing logic)\n if (req.method !== 'POST') {\n return new Response('Method not allowed', { status: 405 })\n }\n\n let stripeSync = null\n try {\n // Get and validate database URL\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n throw new Error('SUPABASE_DB_URL environment variable is not set')\n }\n // Remove sslmode from connection string (not supported by pg in Deno)\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n\n await runMigrations({ databaseUrl: dbUrl })\n\n stripeSync = new StripeSync({\n poolConfig: { connectionString: dbUrl, max: 2 }, // Need 2 for advisory lock + queries\n stripeSecretKey: Deno.env.get('STRIPE_SECRET_KEY'),\n })\n\n // Release any stale advisory locks from previous timeouts\n await stripeSync.postgresClient.query('SELECT pg_advisory_unlock_all()')\n\n // Construct webhook URL from SUPABASE_URL (available in all Edge Functions)\n const supabaseUrl = Deno.env.get('SUPABASE_URL')\n if (!supabaseUrl) {\n throw new Error('SUPABASE_URL environment variable is not set')\n }\n const webhookUrl = supabaseUrl + '/functions/v1/stripe-webhook'\n\n const webhook = await stripeSync.findOrCreateManagedWebhook(webhookUrl)\n\n await stripeSync.postgresClient.pool.end()\n\n return new Response(\n JSON.stringify({\n success: true,\n message: 'Setup complete',\n webhookId: webhook.id,\n }),\n {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n } catch (error) {\n console.error('Setup error:', error)\n // Cleanup on error\n if (stripeSync) {\n try {\n await stripeSync.postgresClient.query('SELECT pg_advisory_unlock_all()')\n await stripeSync.postgresClient.pool.end()\n } catch (cleanupErr) {\n console.warn('Cleanup failed:', cleanupErr)\n }\n }\n return new Response(JSON.stringify({ success: false, error: error.message }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n})\n";
41
+ var stripe_setup_default = "import { StripeSync, runMigrations, VERSION } from 'npm:stripe-experiment-sync'\nimport postgres from 'npm:postgres'\n\n// Helper to validate accessToken against Management API\nasync function validateAccessToken(projectRef: string, accessToken: string): Promise<boolean> {\n // Try to fetch project details using the access token\n // This validates that the token is valid for the management API\n const url = `https://api.supabase.com/v1/projects/${projectRef}`\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n })\n\n // If we can successfully get the project, the token is valid\n return response.ok\n}\n\n// Helper to delete edge function via Management API\nasync function deleteEdgeFunction(\n projectRef: string,\n functionSlug: string,\n accessToken: string\n): Promise<void> {\n const url = `https://api.supabase.com/v1/projects/${projectRef}/functions/${functionSlug}`\n const response = await fetch(url, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.ok && response.status !== 404) {\n const text = await response.text()\n throw new Error(`Failed to delete function ${functionSlug}: ${response.status} ${text}`)\n }\n}\n\n// Helper to delete secrets via Management API\nasync function deleteSecret(\n projectRef: string,\n secretName: string,\n accessToken: string\n): Promise<void> {\n const url = `https://api.supabase.com/v1/projects/${projectRef}/secrets`\n const response = await fetch(url, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify([secretName]),\n })\n\n if (!response.ok && response.status !== 404) {\n const text = await response.text()\n console.warn(`Failed to delete secret ${secretName}: ${response.status} ${text}`)\n }\n}\n\nDeno.serve(async (req) => {\n // Extract project ref from SUPABASE_URL (format: https://{projectRef}.{base})\n const supabaseUrl = Deno.env.get('SUPABASE_URL')\n if (!supabaseUrl) {\n return new Response(JSON.stringify({ error: 'SUPABASE_URL not set' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n const projectRef = new URL(supabaseUrl).hostname.split('.')[0]\n\n // Validate access token for all requests\n const authHeader = req.headers.get('Authorization')\n if (!authHeader?.startsWith('Bearer ')) {\n return new Response('Unauthorized', { status: 401 })\n }\n\n const accessToken = authHeader.substring(7) // Remove 'Bearer '\n const isValid = await validateAccessToken(projectRef, accessToken)\n if (!isValid) {\n return new Response('Forbidden: Invalid access token for this project', { status: 403 })\n }\n\n // Handle GET requests for status\n if (req.method === 'GET') {\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n return new Response(JSON.stringify({ error: 'SUPABASE_DB_URL not set' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n let sql\n\n try {\n sql = postgres(dbUrl, { max: 1, prepare: false })\n\n // Query installation status from schema comment\n const commentResult = await sql`\n SELECT obj_description(oid, 'pg_namespace') as comment\n FROM pg_namespace\n WHERE nspname = 'stripe'\n `\n\n const comment = commentResult[0]?.comment || null\n let installationStatus = 'not_installed'\n\n if (comment && comment.includes('stripe-sync')) {\n // Parse installation status from comment\n if (comment.includes('installation:started')) {\n installationStatus = 'installing'\n } else if (comment.includes('installation:error')) {\n installationStatus = 'error'\n } else if (comment.includes('installed')) {\n installationStatus = 'installed'\n }\n }\n\n // Query sync runs (only if schema exists)\n let syncStatus = []\n if (comment) {\n try {\n syncStatus = await sql`\n SELECT DISTINCT ON (account_id)\n account_id, started_at, closed_at, status, error_message,\n total_processed, total_objects, complete_count, error_count,\n running_count, pending_count, triggered_by, max_concurrent\n FROM stripe.sync_runs\n ORDER BY account_id, started_at DESC\n `\n } catch (err) {\n // Ignore errors if sync_runs view doesn't exist yet\n console.warn('sync_runs query failed (may not exist yet):', err)\n }\n }\n\n return new Response(\n JSON.stringify({\n package_version: VERSION,\n installation_status: installationStatus,\n sync_status: syncStatus,\n }),\n {\n status: 200,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n },\n }\n )\n } catch (error) {\n console.error('Status query error:', error)\n return new Response(\n JSON.stringify({\n error: error.message,\n package_version: VERSION,\n installation_status: 'not_installed',\n }),\n {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n } finally {\n if (sql) await sql.end()\n }\n }\n\n // Handle DELETE requests for uninstall\n if (req.method === 'DELETE') {\n let stripeSync = null\n try {\n // Get and validate database URL\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n throw new Error('SUPABASE_DB_URL environment variable is not set')\n }\n // Remove sslmode from connection string (not supported by pg in Deno)\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n\n // Stripe key is required for uninstall to delete webhooks\n const stripeKey = Deno.env.get('STRIPE_SECRET_KEY')\n if (!stripeKey) {\n throw new Error('STRIPE_SECRET_KEY environment variable is required for uninstall')\n }\n\n // Step 1: Delete Stripe webhooks and clean up database\n stripeSync = new StripeSync({\n poolConfig: { connectionString: dbUrl, max: 2 },\n stripeSecretKey: stripeKey,\n })\n\n // Delete all managed webhooks\n const webhooks = await stripeSync.listManagedWebhooks()\n for (const webhook of webhooks) {\n try {\n await stripeSync.deleteManagedWebhook(webhook.id)\n console.log(`Deleted webhook: ${webhook.id}`)\n } catch (err) {\n console.warn(`Could not delete webhook ${webhook.id}:`, err)\n }\n }\n\n // Unschedule pg_cron job\n try {\n await stripeSync.postgresClient.query(`\n DO $$\n BEGIN\n IF EXISTS (SELECT 1 FROM cron.job WHERE jobname = 'stripe-sync-worker') THEN\n PERFORM cron.unschedule('stripe-sync-worker');\n END IF;\n END $$;\n `)\n } catch (err) {\n console.warn('Could not unschedule pg_cron job:', err)\n }\n\n // Delete vault secret\n try {\n await stripeSync.postgresClient.query(`\n DELETE FROM vault.secrets\n WHERE name = 'stripe_sync_worker_secret'\n `)\n } catch (err) {\n console.warn('Could not delete vault secret:', err)\n }\n\n // Terminate connections holding locks on stripe schema\n try {\n await stripeSync.postgresClient.query(`\n SELECT pg_terminate_backend(pid)\n FROM pg_locks l\n JOIN pg_class c ON l.relation = c.oid\n JOIN pg_namespace n ON c.relnamespace = n.oid\n WHERE n.nspname = 'stripe'\n AND l.pid != pg_backend_pid()\n `)\n } catch (err) {\n console.warn('Could not terminate connections:', err)\n }\n\n // Drop schema with retry\n let dropAttempts = 0\n const maxAttempts = 3\n while (dropAttempts < maxAttempts) {\n try {\n await stripeSync.postgresClient.query('DROP SCHEMA IF EXISTS stripe CASCADE')\n break // Success, exit loop\n } catch (err) {\n dropAttempts++\n if (dropAttempts >= maxAttempts) {\n throw new Error(\n `Failed to drop schema after ${maxAttempts} attempts. ` +\n `There may be active connections or locks on the stripe schema. ` +\n `Error: ${err.message}`\n )\n }\n // Wait 1 second before retrying\n await new Promise((resolve) => setTimeout(resolve, 1000))\n }\n }\n\n await stripeSync.postgresClient.pool.end()\n\n // Step 2: Delete Supabase secrets\n try {\n await deleteSecret(projectRef, 'STRIPE_SECRET_KEY', accessToken)\n } catch (err) {\n console.warn('Could not delete STRIPE_SECRET_KEY secret:', err)\n }\n\n // Step 3: Delete Edge Functions\n try {\n await deleteEdgeFunction(projectRef, 'stripe-setup', accessToken)\n } catch (err) {\n console.warn('Could not delete stripe-setup function:', err)\n }\n\n try {\n await deleteEdgeFunction(projectRef, 'stripe-webhook', accessToken)\n } catch (err) {\n console.warn('Could not delete stripe-webhook function:', err)\n }\n\n try {\n await deleteEdgeFunction(projectRef, 'stripe-worker', accessToken)\n } catch (err) {\n console.warn('Could not delete stripe-worker function:', err)\n }\n\n return new Response(\n JSON.stringify({\n success: true,\n message: 'Uninstall complete',\n }),\n {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n } catch (error) {\n console.error('Uninstall error:', error)\n // Cleanup on error\n if (stripeSync) {\n try {\n await stripeSync.postgresClient.pool.end()\n } catch (cleanupErr) {\n console.warn('Cleanup failed:', cleanupErr)\n }\n }\n return new Response(JSON.stringify({ success: false, error: error.message }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n }\n\n // Handle POST requests for install\n if (req.method !== 'POST') {\n return new Response('Method not allowed', { status: 405 })\n }\n\n let stripeSync = null\n try {\n // Get and validate database URL\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n throw new Error('SUPABASE_DB_URL environment variable is not set')\n }\n // Remove sslmode from connection string (not supported by pg in Deno)\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n\n await runMigrations({ databaseUrl: dbUrl })\n\n stripeSync = new StripeSync({\n poolConfig: { connectionString: dbUrl, max: 2 }, // Need 2 for advisory lock + queries\n stripeSecretKey: Deno.env.get('STRIPE_SECRET_KEY'),\n })\n\n // Release any stale advisory locks from previous timeouts\n await stripeSync.postgresClient.query('SELECT pg_advisory_unlock_all()')\n\n // Construct webhook URL from SUPABASE_URL (available in all Edge Functions)\n const supabaseUrl = Deno.env.get('SUPABASE_URL')\n if (!supabaseUrl) {\n throw new Error('SUPABASE_URL environment variable is not set')\n }\n const webhookUrl = supabaseUrl + '/functions/v1/stripe-webhook'\n\n const webhook = await stripeSync.findOrCreateManagedWebhook(webhookUrl)\n\n await stripeSync.postgresClient.pool.end()\n\n return new Response(\n JSON.stringify({\n success: true,\n message: 'Setup complete',\n webhookId: webhook.id,\n }),\n {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n } catch (error) {\n console.error('Setup error:', error)\n // Cleanup on error\n if (stripeSync) {\n try {\n await stripeSync.postgresClient.query('SELECT pg_advisory_unlock_all()')\n await stripeSync.postgresClient.pool.end()\n } catch (cleanupErr) {\n console.warn('Cleanup failed:', cleanupErr)\n }\n }\n return new Response(JSON.stringify({ success: false, error: error.message }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n})\n";
52
42
 
53
43
  // raw-ts:/home/runner/work/sync-engine/sync-engine/packages/sync-engine/src/supabase/edge-functions/stripe-webhook.ts
54
44
  var stripe_webhook_default = "import { StripeSync } from 'npm:stripe-experiment-sync'\n\nDeno.serve(async (req) => {\n if (req.method !== 'POST') {\n return new Response('Method not allowed', { status: 405 })\n }\n\n const sig = req.headers.get('stripe-signature')\n if (!sig) {\n return new Response('Missing stripe-signature header', { status: 400 })\n }\n\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n return new Response(JSON.stringify({ error: 'SUPABASE_DB_URL not set' }), { status: 500 })\n }\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n\n const stripeSync = new StripeSync({\n poolConfig: { connectionString: dbUrl, max: 1 },\n stripeSecretKey: Deno.env.get('STRIPE_SECRET_KEY')!,\n })\n\n try {\n const rawBody = new Uint8Array(await req.arrayBuffer())\n await stripeSync.processWebhook(rawBody, sig)\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n })\n } catch (error) {\n console.error('Webhook processing error:', error)\n const isSignatureError =\n error.message?.includes('signature') || error.type === 'StripeSignatureVerificationError'\n const status = isSignatureError ? 400 : 500\n return new Response(JSON.stringify({ error: error.message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n })\n } finally {\n await stripeSync.postgresClient.pool.end()\n }\n})\n";
55
45
 
56
46
  // raw-ts:/home/runner/work/sync-engine/sync-engine/packages/sync-engine/src/supabase/edge-functions/stripe-worker.ts
57
- var stripe_worker_default = "/**\n * Stripe Sync Worker\n *\n * Triggered by pg_cron at a configurable interval (default: 60 seconds). Uses pgmq for durable work queue.\n *\n * Flow:\n * 1. Read batch of messages from pgmq (qty=10, vt=60s)\n * 2. If queue empty: enqueue all objects (continuous sync)\n * 3. Process messages in parallel (Promise.all):\n * - processNext(object)\n * - Delete message on success\n * - Re-enqueue if hasMore\n * 4. Return results summary\n *\n * Concurrency:\n * - Multiple workers can run concurrently via overlapping pg_cron triggers.\n * - Each worker processes its batch of messages in parallel (Promise.all).\n * - pgmq visibility timeout prevents duplicate message reads across workers.\n * - processNext() is idempotent (uses internal cursor tracking), so duplicate\n * processing on timeout/crash is safe.\n */\n\nimport { StripeSync } from 'npm:stripe-experiment-sync'\nimport postgres from 'npm:postgres'\n\nconst QUEUE_NAME = 'stripe_sync_work'\nconst VISIBILITY_TIMEOUT = 60 // seconds\nconst BATCH_SIZE = 10\n\nDeno.serve(async (req) => {\n const authHeader = req.headers.get('Authorization')\n if (!authHeader?.startsWith('Bearer ')) {\n return new Response('Unauthorized', { status: 401 })\n }\n\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n return new Response(JSON.stringify({ error: 'SUPABASE_DB_URL not set' }), { status: 500 })\n }\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n\n let sql\n let stripeSync\n\n try {\n sql = postgres(dbUrl, { max: 1, prepare: false })\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: 'Failed to create postgres connection',\n details: error.message,\n stack: error.stack,\n }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n )\n }\n\n try {\n stripeSync = new StripeSync({\n poolConfig: { connectionString: dbUrl, max: 1 },\n stripeSecretKey: Deno.env.get('STRIPE_SECRET_KEY')!,\n })\n } catch (error) {\n await sql.end()\n return new Response(\n JSON.stringify({\n error: 'Failed to create StripeSync',\n details: error.message,\n stack: error.stack,\n }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n )\n }\n\n try {\n // Read batch of messages from queue\n const messages = await sql`\n SELECT * FROM pgmq.read(${QUEUE_NAME}::text, ${VISIBILITY_TIMEOUT}::int, ${BATCH_SIZE}::int)\n `\n\n // If queue empty, enqueue all objects for continuous sync\n if (messages.length === 0) {\n // Create sync run to make enqueued work visible (status='pending')\n const { objects } = await stripeSync.joinOrCreateSyncRun('worker')\n const msgs = objects.map((object) => JSON.stringify({ object }))\n\n await sql`\n SELECT pgmq.send_batch(\n ${QUEUE_NAME}::text,\n ${sql.array(msgs)}::jsonb[]\n )\n `\n\n return new Response(JSON.stringify({ enqueued: objects.length, objects }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n // Process messages in parallel\n const results = await Promise.all(\n messages.map(async (msg) => {\n const { object } = msg.message as { object: string }\n\n try {\n const result = await stripeSync.processNext(object)\n\n // Delete message on success (cast to bigint to disambiguate overloaded function)\n await sql`SELECT pgmq.delete(${QUEUE_NAME}::text, ${msg.msg_id}::bigint)`\n\n // Re-enqueue if more pages\n if (result.hasMore) {\n await sql`SELECT pgmq.send(${QUEUE_NAME}::text, ${sql.json({ object })}::jsonb)`\n }\n\n return { object, ...result }\n } catch (error) {\n // Log error but continue to next message\n // Message will become visible again after visibility timeout\n console.error(`Error processing ${object}:`, error)\n return {\n object,\n processed: 0,\n hasMore: false,\n error: error.message,\n stack: error.stack,\n }\n }\n })\n )\n\n return new Response(JSON.stringify({ results }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n })\n } catch (error) {\n console.error('Worker error:', error)\n return new Response(JSON.stringify({ error: error.message, stack: error.stack }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n } finally {\n if (sql) await sql.end()\n if (stripeSync) await stripeSync.postgresClient.pool.end()\n }\n})\n";
47
+ var stripe_worker_default = "/**\n * Stripe Sync Worker\n *\n * Triggered by pg_cron at a configurable interval (default: 60 seconds). Uses pgmq for durable work queue.\n *\n * Flow:\n * 1. Read batch of messages from pgmq (qty=10, vt=60s)\n * 2. If queue empty: enqueue all objects (continuous sync)\n * 3. Process messages in parallel (Promise.all):\n * - processNext(object)\n * - Delete message on success\n * - Re-enqueue if hasMore\n * 4. Return results summary\n *\n * Concurrency:\n * - Multiple workers can run concurrently via overlapping pg_cron triggers.\n * - Each worker processes its batch of messages in parallel (Promise.all).\n * - pgmq visibility timeout prevents duplicate message reads across workers.\n * - processNext() is idempotent (uses internal cursor tracking), so duplicate\n * processing on timeout/crash is safe.\n */\n\nimport { StripeSync } from 'npm:stripe-experiment-sync'\nimport postgres from 'npm:postgres'\n\nconst QUEUE_NAME = 'stripe_sync_work'\nconst VISIBILITY_TIMEOUT = 60 // seconds\nconst BATCH_SIZE = 10\n\nDeno.serve(async (req) => {\n const authHeader = req.headers.get('Authorization')\n if (!authHeader?.startsWith('Bearer ')) {\n return new Response('Unauthorized', { status: 401 })\n }\n\n const token = authHeader.substring(7) // Remove 'Bearer '\n\n const rawDbUrl = Deno.env.get('SUPABASE_DB_URL')\n if (!rawDbUrl) {\n return new Response(JSON.stringify({ error: 'SUPABASE_DB_URL not set' }), { status: 500 })\n }\n const dbUrl = rawDbUrl.replace(/[?&]sslmode=[^&]*/g, '').replace(/[?&]$/, '')\n\n let sql\n let stripeSync\n\n try {\n sql = postgres(dbUrl, { max: 1, prepare: false })\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: 'Failed to create postgres connection',\n details: error.message,\n stack: error.stack,\n }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n )\n }\n\n try {\n // Validate that the token matches the unique worker secret stored in vault\n const vaultResult = await sql`\n SELECT decrypted_secret\n FROM vault.decrypted_secrets\n WHERE name = 'stripe_sync_worker_secret'\n `\n\n if (vaultResult.length === 0) {\n await sql.end()\n return new Response('Worker secret not configured in vault', { status: 500 })\n }\n\n const storedSecret = vaultResult[0].decrypted_secret\n if (token !== storedSecret) {\n await sql.end()\n return new Response('Forbidden: Invalid worker secret', { status: 403 })\n }\n\n stripeSync = new StripeSync({\n poolConfig: { connectionString: dbUrl, max: 1 },\n stripeSecretKey: Deno.env.get('STRIPE_SECRET_KEY')!,\n enableSigma: (Deno.env.get('ENABLE_SIGMA') ?? 'false') === 'true',\n })\n } catch (error) {\n await sql.end()\n return new Response(\n JSON.stringify({\n error: 'Failed to create StripeSync',\n details: error.message,\n stack: error.stack,\n }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n )\n }\n\n try {\n // Read batch of messages from queue\n const messages = await sql`\n SELECT * FROM pgmq.read(${QUEUE_NAME}::text, ${VISIBILITY_TIMEOUT}::int, ${BATCH_SIZE}::int)\n `\n\n // If queue empty, enqueue all objects for continuous sync\n if (messages.length === 0) {\n // Create sync run to make enqueued work visible (status='pending')\n const { objects } = await stripeSync.joinOrCreateSyncRun('worker')\n const msgs = objects.map((object) => JSON.stringify({ object }))\n\n await sql`\n SELECT pgmq.send_batch(\n ${QUEUE_NAME}::text,\n ${sql.array(msgs)}::jsonb[]\n )\n `\n\n return new Response(JSON.stringify({ enqueued: objects.length, objects }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n // Process messages in parallel\n const results = await Promise.all(\n messages.map(async (msg) => {\n const { object } = msg.message as { object: string }\n\n try {\n const result = await stripeSync.processNext(object)\n\n // Delete message on success (cast to bigint to disambiguate overloaded function)\n await sql`SELECT pgmq.delete(${QUEUE_NAME}::text, ${msg.msg_id}::bigint)`\n\n // Re-enqueue if more pages\n if (result.hasMore) {\n await sql`SELECT pgmq.send(${QUEUE_NAME}::text, ${sql.json({ object })}::jsonb)`\n }\n\n return { object, ...result }\n } catch (error) {\n // Log error but continue to next message\n // Message will become visible again after visibility timeout\n console.error(`Error processing ${object}:`, error)\n return {\n object,\n processed: 0,\n hasMore: false,\n error: error.message,\n stack: error.stack,\n }\n }\n })\n )\n\n return new Response(JSON.stringify({ results }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n })\n } catch (error) {\n console.error('Worker error:', error)\n return new Response(JSON.stringify({ error: error.message, stack: error.stack }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n } finally {\n if (sql) await sql.end()\n if (stripeSync) await stripeSync.postgresClient.pool.end()\n }\n})\n";
58
48
 
59
49
  // src/supabase/edge-function-code.ts
60
50
  var setupFunctionCode = stripe_setup_default;
@@ -64,7 +54,7 @@ var workerFunctionCode = stripe_worker_default;
64
54
  // package.json
65
55
  var package_default = {
66
56
  name: "stripe-experiment-sync",
67
- version: "1.0.12",
57
+ version: "1.0.15-beta.1766078819",
68
58
  private: false,
69
59
  description: "Stripe Sync Engine to sync Stripe data to Postgres",
70
60
  type: "module",
@@ -104,6 +94,7 @@ var package_default = {
104
94
  dotenv: "^16.4.7",
105
95
  express: "^4.18.2",
106
96
  inquirer: "^12.3.0",
97
+ papaparse: "5.4.1",
107
98
  pg: "^8.16.3",
108
99
  "pg-node-migrations": "0.0.8",
109
100
  stripe: "^17.7.0",
@@ -115,6 +106,7 @@ var package_default = {
115
106
  "@types/express": "^4.17.21",
116
107
  "@types/inquirer": "^9.0.7",
117
108
  "@types/node": "^24.10.1",
109
+ "@types/papaparse": "5.3.16",
118
110
  "@types/pg": "^8.15.5",
119
111
  "@types/ws": "^8.5.13",
120
112
  "@types/yesql": "^4.1.4",
@@ -144,7 +136,6 @@ var package_default = {
144
136
  };
145
137
 
146
138
  // src/supabase/supabase.ts
147
- var import_stripe = __toESM(require("stripe"), 1);
148
139
  var STRIPE_SCHEMA_COMMENT_PREFIX = "stripe-sync";
149
140
  var INSTALLATION_STARTED_SUFFIX = "installation:started";
150
141
  var INSTALLATION_ERROR_SUFFIX = "installation:error";
@@ -153,6 +144,7 @@ var SupabaseSetupClient = class {
153
144
  api;
154
145
  projectRef;
155
146
  projectBaseUrl;
147
+ accessToken;
156
148
  constructor(options) {
157
149
  this.api = new import_supabase_management_js.SupabaseManagementAPI({
158
150
  accessToken: options.accessToken,
@@ -160,6 +152,7 @@ var SupabaseSetupClient = class {
160
152
  });
161
153
  this.projectRef = options.projectRef;
162
154
  this.projectBaseUrl = options.projectBaseUrl || process.env.SUPABASE_BASE_URL || "supabase.co";
155
+ this.accessToken = options.accessToken;
163
156
  }
164
157
  /**
165
158
  * Validate that the project exists and we have access
@@ -179,20 +172,20 @@ var SupabaseSetupClient = class {
179
172
  /**
180
173
  * Deploy an Edge Function
181
174
  */
182
- async deployFunction(name, code) {
175
+ async deployFunction(name, code, verifyJwt = false) {
183
176
  const functions = await this.api.listFunctions(this.projectRef);
184
177
  const exists = functions?.some((f) => f.slug === name);
185
178
  if (exists) {
186
179
  await this.api.updateFunction(this.projectRef, name, {
187
180
  body: code,
188
- verify_jwt: false
181
+ verify_jwt: verifyJwt
189
182
  });
190
183
  } else {
191
184
  await this.api.createFunction(this.projectRef, {
192
185
  slug: name,
193
186
  name,
194
187
  body: code,
195
- verify_jwt: false
188
+ verify_jwt: verifyJwt
196
189
  });
197
190
  }
198
191
  }
@@ -233,8 +226,8 @@ var SupabaseSetupClient = class {
233
226
  `Invalid interval: ${intervalSeconds}. Must be either 1-59 seconds or a multiple of 60 (e.g., 60, 120, 180).`
234
227
  );
235
228
  }
236
- const serviceRoleKey = await this.getServiceRoleKey();
237
- const escapedServiceRoleKey = serviceRoleKey.replace(/'/g, "''");
229
+ const workerSecret = crypto.randomUUID();
230
+ const escapedWorkerSecret = workerSecret.replace(/'/g, "''");
238
231
  const sql = `
239
232
  -- Enable extensions
240
233
  CREATE EXTENSION IF NOT EXISTS pg_cron;
@@ -247,10 +240,10 @@ var SupabaseSetupClient = class {
247
240
  SELECT 1 FROM pgmq.list_queues() WHERE queue_name = 'stripe_sync_work'
248
241
  );
249
242
 
250
- -- Store service role key in vault for pg_cron to use
243
+ -- Store unique worker secret in vault for pg_cron to use
251
244
  -- Delete existing secret if it exists, then create new one
252
- DELETE FROM vault.secrets WHERE name = 'stripe_sync_service_role_key';
253
- SELECT vault.create_secret('${escapedServiceRoleKey}', 'stripe_sync_service_role_key');
245
+ DELETE FROM vault.secrets WHERE name = 'stripe_sync_worker_secret';
246
+ SELECT vault.create_secret('${escapedWorkerSecret}', 'stripe_sync_worker_secret');
254
247
 
255
248
  -- Delete existing jobs if they exist
256
249
  SELECT cron.unschedule('stripe-sync-worker') WHERE EXISTS (
@@ -269,7 +262,7 @@ var SupabaseSetupClient = class {
269
262
  SELECT net.http_post(
270
263
  url := 'https://${this.projectRef}.${this.projectBaseUrl}/functions/v1/stripe-worker',
271
264
  headers := jsonb_build_object(
272
- 'Authorization', 'Bearer ' || (SELECT decrypted_secret FROM vault.decrypted_secrets WHERE name = 'stripe_sync_service_role_key')
265
+ 'Authorization', 'Bearer ' || (SELECT decrypted_secret FROM vault.decrypted_secrets WHERE name = 'stripe_sync_worker_secret')
273
266
  )
274
267
  )
275
268
  $$
@@ -283,17 +276,6 @@ var SupabaseSetupClient = class {
283
276
  getWebhookUrl() {
284
277
  return `https://${this.projectRef}.${this.projectBaseUrl}/functions/v1/stripe-webhook`;
285
278
  }
286
- /**
287
- * Get the service role key for this project (needed to invoke Edge Functions)
288
- */
289
- async getServiceRoleKey() {
290
- const apiKeys = await this.api.getProjectApiKeys(this.projectRef);
291
- const serviceRoleKey = apiKeys?.find((k) => k.name === "service_role");
292
- if (!serviceRoleKey) {
293
- throw new Error("Could not find service_role API key");
294
- }
295
- return serviceRoleKey.api_key;
296
- }
297
279
  /**
298
280
  * Get the anon key for this project (needed for Realtime subscriptions)
299
281
  */
@@ -314,12 +296,12 @@ var SupabaseSetupClient = class {
314
296
  /**
315
297
  * Invoke an Edge Function
316
298
  */
317
- async invokeFunction(name, serviceRoleKey) {
299
+ async invokeFunction(name, bearerToken) {
318
300
  const url = `https://${this.projectRef}.${this.projectBaseUrl}/functions/v1/${name}`;
319
301
  const response = await fetch(url, {
320
302
  method: "POST",
321
303
  headers: {
322
- Authorization: `Bearer ${serviceRoleKey}`,
304
+ Authorization: `Bearer ${bearerToken}`,
323
305
  "Content-Type": "application/json"
324
306
  }
325
307
  });
@@ -422,77 +404,25 @@ var SupabaseSetupClient = class {
422
404
  }
423
405
  /**
424
406
  * Uninstall stripe-sync from a Supabase project
425
- * Removes all Edge Functions, secrets, database resources, and Stripe webhooks
407
+ * Invokes the stripe-setup edge function's DELETE endpoint which handles cleanup
426
408
  */
427
- async uninstall(stripeSecretKey) {
428
- const stripe = stripeSecretKey ? new import_stripe.default(stripeSecretKey, { apiVersion: "2025-02-24.acacia" }) : null;
409
+ async uninstall() {
429
410
  try {
430
- try {
431
- const webhookResult = await this.runSQL(`
432
- SELECT id FROM stripe._managed_webhooks WHERE id IS NOT NULL
433
- `);
434
- const webhookIds = webhookResult[0]?.rows?.map((r) => r.id) || [];
435
- for (const webhookId of webhookIds) {
436
- try {
437
- await stripe?.webhookEndpoints.del(webhookId);
438
- } catch (err) {
439
- console.warn(`Could not delete Stripe webhook ${webhookId}:`, err);
440
- }
411
+ const url = `https://${this.projectRef}.${this.projectBaseUrl}/functions/v1/stripe-setup`;
412
+ const response = await fetch(url, {
413
+ method: "DELETE",
414
+ headers: {
415
+ Authorization: `Bearer ${this.accessToken}`,
416
+ "Content-Type": "application/json"
441
417
  }
442
- } catch (err) {
443
- console.warn("Could not query/delete webhooks:", err);
444
- }
445
- await this.deleteFunction("stripe-setup");
446
- await this.deleteFunction("stripe-webhook");
447
- await this.deleteFunction("stripe-worker");
448
- await this.deleteSecret("STRIPE_SECRET_KEY");
449
- try {
450
- await this.runSQL(`
451
- DO $$
452
- BEGIN
453
- IF EXISTS (SELECT 1 FROM cron.job WHERE jobname = 'stripe-sync-worker') THEN
454
- PERFORM cron.unschedule('stripe-sync-worker');
455
- END IF;
456
- END $$;
457
- `);
458
- } catch (err) {
459
- console.warn("Could not unschedule pg_cron job:", err);
460
- }
461
- try {
462
- await this.runSQL(`
463
- DELETE FROM vault.secrets
464
- WHERE name = 'stripe_sync_service_role_key'
465
- `);
466
- } catch (err) {
467
- console.warn("Could not delete vault secret:", err);
468
- }
469
- try {
470
- await this.runSQL(`
471
- SELECT pg_terminate_backend(pid)
472
- FROM pg_locks l
473
- JOIN pg_class c ON l.relation = c.oid
474
- JOIN pg_namespace n ON c.relnamespace = n.oid
475
- WHERE n.nspname = 'stripe'
476
- AND l.pid != pg_backend_pid()
477
- `);
478
- } catch (err) {
479
- console.warn("Could not terminate connections:", err);
418
+ });
419
+ if (!response.ok) {
420
+ const text = await response.text();
421
+ throw new Error(`Uninstall failed: ${response.status} ${text}`);
480
422
  }
481
- let dropAttempts = 0;
482
- const maxAttempts = 3;
483
- while (dropAttempts < maxAttempts) {
484
- try {
485
- await this.runSQL(`DROP SCHEMA IF EXISTS stripe CASCADE`);
486
- break;
487
- } catch (err) {
488
- dropAttempts++;
489
- if (dropAttempts >= maxAttempts) {
490
- throw new Error(
491
- `Failed to drop schema after ${maxAttempts} attempts. There may be active connections or locks on the stripe schema. Error: ${err instanceof Error ? err.message : String(err)}`
492
- );
493
- }
494
- await new Promise((resolve) => setTimeout(resolve, 1e3));
495
- }
423
+ const result = await response.json();
424
+ if (result.success === false) {
425
+ throw new Error(`Uninstall failed: ${result.error}`);
496
426
  }
497
427
  } catch (error) {
498
428
  throw new Error(`Uninstall failed: ${error instanceof Error ? error.message : String(error)}`);
@@ -525,12 +455,11 @@ var SupabaseSetupClient = class {
525
455
  const versionedSetup = this.injectPackageVersion(setupFunctionCode, version);
526
456
  const versionedWebhook = this.injectPackageVersion(webhookFunctionCode, version);
527
457
  const versionedWorker = this.injectPackageVersion(workerFunctionCode, version);
528
- await this.deployFunction("stripe-setup", versionedSetup);
529
- await this.deployFunction("stripe-webhook", versionedWebhook);
530
- await this.deployFunction("stripe-worker", versionedWorker);
458
+ await this.deployFunction("stripe-setup", versionedSetup, false);
459
+ await this.deployFunction("stripe-webhook", versionedWebhook, false);
460
+ await this.deployFunction("stripe-worker", versionedWorker, false);
531
461
  await this.setSecrets([{ name: "STRIPE_SECRET_KEY", value: trimmedStripeKey }]);
532
- const serviceRoleKey = await this.getServiceRoleKey();
533
- const setupResult = await this.invokeFunction("stripe-setup", serviceRoleKey);
462
+ const setupResult = await this.invokeFunction("stripe-setup", this.accessToken);
534
463
  if (!setupResult.success) {
535
464
  throw new Error(`Setup failed: ${setupResult.error}`);
536
465
  }
@@ -563,18 +492,14 @@ async function install(params) {
563
492
  await client.install(stripeKey, packageVersion, workerIntervalSeconds);
564
493
  }
565
494
  async function uninstall(params) {
566
- const { supabaseAccessToken, supabaseProjectRef, stripeKey } = params;
567
- const trimmedStripeKey = stripeKey && stripeKey.trim();
568
- if (trimmedStripeKey && !trimmedStripeKey.startsWith("sk_") && !trimmedStripeKey.startsWith("rk_")) {
569
- throw new Error('Stripe key should start with "sk_" or "rk_"');
570
- }
495
+ const { supabaseAccessToken, supabaseProjectRef } = params;
571
496
  const client = new SupabaseSetupClient({
572
497
  accessToken: supabaseAccessToken,
573
498
  projectRef: supabaseProjectRef,
574
499
  projectBaseUrl: params.baseProjectUrl,
575
- managementApiBaseUrl: params.baseManagementApiUrl
500
+ managementApiBaseUrl: params.baseManagementApiBaseUrl
576
501
  });
577
- await client.uninstall(trimmedStripeKey);
502
+ await client.uninstall();
578
503
  }
579
504
  // Annotate the CommonJS export names for ESM import in node:
580
505
  0 && (module.exports = {
@@ -17,6 +17,7 @@ declare class SupabaseSetupClient {
17
17
  private api;
18
18
  private projectRef;
19
19
  private projectBaseUrl;
20
+ private accessToken;
20
21
  constructor(options: DeployClientOptions);
21
22
  /**
22
23
  * Validate that the project exists and we have access
@@ -25,7 +26,7 @@ declare class SupabaseSetupClient {
25
26
  /**
26
27
  * Deploy an Edge Function
27
28
  */
28
- deployFunction(name: string, code: string): Promise<void>;
29
+ deployFunction(name: string, code: string, verifyJwt?: boolean): Promise<void>;
29
30
  /**
30
31
  * Set secrets for Edge Functions
31
32
  */
@@ -46,10 +47,6 @@ declare class SupabaseSetupClient {
46
47
  * Get the webhook URL for this project
47
48
  */
48
49
  getWebhookUrl(): string;
49
- /**
50
- * Get the service role key for this project (needed to invoke Edge Functions)
51
- */
52
- getServiceRoleKey(): Promise<string>;
53
50
  /**
54
51
  * Get the anon key for this project (needed for Realtime subscriptions)
55
52
  */
@@ -61,7 +58,7 @@ declare class SupabaseSetupClient {
61
58
  /**
62
59
  * Invoke an Edge Function
63
60
  */
64
- invokeFunction(name: string, serviceRoleKey: string): Promise<{
61
+ invokeFunction(name: string, bearerToken: string): Promise<{
65
62
  success: boolean;
66
63
  error?: string;
67
64
  }>;
@@ -91,9 +88,9 @@ declare class SupabaseSetupClient {
91
88
  deleteSecret(name: string): Promise<void>;
92
89
  /**
93
90
  * Uninstall stripe-sync from a Supabase project
94
- * Removes all Edge Functions, secrets, database resources, and Stripe webhooks
91
+ * Invokes the stripe-setup edge function's DELETE endpoint which handles cleanup
95
92
  */
96
- uninstall(stripeSecretKey?: string): Promise<void>;
93
+ uninstall(): Promise<void>;
97
94
  /**
98
95
  * Inject package version into Edge Function code
99
96
  */
@@ -112,9 +109,8 @@ declare function install(params: {
112
109
  declare function uninstall(params: {
113
110
  supabaseAccessToken: string;
114
111
  supabaseProjectRef: string;
115
- stripeKey?: string;
116
112
  baseProjectUrl?: string;
117
- baseManagementApiUrl?: string;
113
+ baseManagementApiBaseUrl?: string;
118
114
  }): Promise<void>;
119
115
 
120
116
  declare const setupFunctionCode: string;
@@ -17,6 +17,7 @@ declare class SupabaseSetupClient {
17
17
  private api;
18
18
  private projectRef;
19
19
  private projectBaseUrl;
20
+ private accessToken;
20
21
  constructor(options: DeployClientOptions);
21
22
  /**
22
23
  * Validate that the project exists and we have access
@@ -25,7 +26,7 @@ declare class SupabaseSetupClient {
25
26
  /**
26
27
  * Deploy an Edge Function
27
28
  */
28
- deployFunction(name: string, code: string): Promise<void>;
29
+ deployFunction(name: string, code: string, verifyJwt?: boolean): Promise<void>;
29
30
  /**
30
31
  * Set secrets for Edge Functions
31
32
  */
@@ -46,10 +47,6 @@ declare class SupabaseSetupClient {
46
47
  * Get the webhook URL for this project
47
48
  */
48
49
  getWebhookUrl(): string;
49
- /**
50
- * Get the service role key for this project (needed to invoke Edge Functions)
51
- */
52
- getServiceRoleKey(): Promise<string>;
53
50
  /**
54
51
  * Get the anon key for this project (needed for Realtime subscriptions)
55
52
  */
@@ -61,7 +58,7 @@ declare class SupabaseSetupClient {
61
58
  /**
62
59
  * Invoke an Edge Function
63
60
  */
64
- invokeFunction(name: string, serviceRoleKey: string): Promise<{
61
+ invokeFunction(name: string, bearerToken: string): Promise<{
65
62
  success: boolean;
66
63
  error?: string;
67
64
  }>;
@@ -91,9 +88,9 @@ declare class SupabaseSetupClient {
91
88
  deleteSecret(name: string): Promise<void>;
92
89
  /**
93
90
  * Uninstall stripe-sync from a Supabase project
94
- * Removes all Edge Functions, secrets, database resources, and Stripe webhooks
91
+ * Invokes the stripe-setup edge function's DELETE endpoint which handles cleanup
95
92
  */
96
- uninstall(stripeSecretKey?: string): Promise<void>;
93
+ uninstall(): Promise<void>;
97
94
  /**
98
95
  * Inject package version into Edge Function code
99
96
  */
@@ -112,9 +109,8 @@ declare function install(params: {
112
109
  declare function uninstall(params: {
113
110
  supabaseAccessToken: string;
114
111
  supabaseProjectRef: string;
115
- stripeKey?: string;
116
112
  baseProjectUrl?: string;
117
- baseManagementApiUrl?: string;
113
+ baseManagementApiBaseUrl?: string;
118
114
  }): Promise<void>;
119
115
 
120
116
  declare const setupFunctionCode: string;
@@ -9,8 +9,8 @@ import {
9
9
  uninstall,
10
10
  webhookFunctionCode,
11
11
  workerFunctionCode
12
- } from "../chunk-RAM7OG7J.js";
13
- import "../chunk-IO2EEPFD.js";
12
+ } from "../chunk-5J4LJ44K.js";
13
+ import "../chunk-TPFENIK3.js";
14
14
  export {
15
15
  INSTALLATION_ERROR_SUFFIX,
16
16
  INSTALLATION_INSTALLED_SUFFIX,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stripe-experiment-sync",
3
- "version": "1.0.12",
3
+ "version": "1.0.15-beta.1766078819",
4
4
  "private": false,
5
5
  "description": "Stripe Sync Engine to sync Stripe data to Postgres",
6
6
  "type": "module",
@@ -40,6 +40,7 @@
40
40
  "dotenv": "^16.4.7",
41
41
  "express": "^4.18.2",
42
42
  "inquirer": "^12.3.0",
43
+ "papaparse": "5.4.1",
43
44
  "pg": "^8.16.3",
44
45
  "pg-node-migrations": "0.0.8",
45
46
  "stripe": "^17.7.0",
@@ -51,6 +52,7 @@
51
52
  "@types/express": "^4.17.21",
52
53
  "@types/inquirer": "^9.0.7",
53
54
  "@types/node": "^24.10.1",
55
+ "@types/papaparse": "5.3.16",
54
56
  "@types/pg": "^8.15.5",
55
57
  "@types/ws": "^8.5.13",
56
58
  "@types/yesql": "^4.1.4",