stripe-experiment-sync 0.0.1 → 0.0.2

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/dist/index.cjs CHANGED
@@ -891,7 +891,8 @@ var StripeAutoSync = class {
891
891
  webhookPath: options.webhookPath || "/stripe-webhooks",
892
892
  stripeApiVersion: options.stripeApiVersion || "2020-08-27",
893
893
  autoExpandLists: options.autoExpandLists !== void 0 ? options.autoExpandLists : false,
894
- backfillRelatedEntities: options.backfillRelatedEntities !== void 0 ? options.backfillRelatedEntities : true
894
+ backfillRelatedEntities: options.backfillRelatedEntities !== void 0 ? options.backfillRelatedEntities : true,
895
+ keepWebhooksOnShutdown: options.keepWebhooksOnShutdown !== void 0 ? options.keepWebhooksOnShutdown : true
895
896
  };
896
897
  }
897
898
  /**
@@ -926,7 +927,7 @@ var StripeAutoSync = class {
926
927
  poolConfig
927
928
  });
928
929
  const baseUrl = this.options.baseUrl();
929
- const { webhook, uuid } = await this.stripeSync.createManagedWebhook(
930
+ const { webhook, uuid } = await this.stripeSync.findOrCreateManagedWebhook(
930
931
  `${baseUrl}${this.options.webhookPath}`,
931
932
  {
932
933
  enabled_events: ["*"],
@@ -936,6 +937,10 @@ var StripeAutoSync = class {
936
937
  );
937
938
  this.webhookId = webhook.id;
938
939
  this.webhookUuid = uuid;
940
+ console.log("Starting initial backfill of all Stripe data...");
941
+ const backfillResult = await this.stripeSync.syncBackfill({ object: "all" });
942
+ const totalSynced = Object.values(backfillResult).reduce((sum, result) => sum + (result?.synced || 0), 0);
943
+ console.log(`\u2713 Backfill complete: ${totalSynced} objects synced`);
939
944
  this.mountWebhook(app);
940
945
  app.use(this.getBodyParserMiddleware());
941
946
  return {
@@ -956,10 +961,10 @@ var StripeAutoSync = class {
956
961
  }
957
962
  /**
958
963
  * Stops all services and cleans up resources:
959
- * 1. Deletes Stripe webhook endpoint from Stripe and database
964
+ * 1. Optionally deletes Stripe webhook endpoint from Stripe and database (based on keepWebhooksOnShutdown)
960
965
  */
961
966
  async stop() {
962
- if (this.webhookId && this.stripeSync) {
967
+ if (this.webhookId && this.stripeSync && !this.options.keepWebhooksOnShutdown) {
963
968
  try {
964
969
  await this.stripeSync.deleteManagedWebhook(this.webhookId);
965
970
  } catch (error) {
@@ -1058,7 +1063,7 @@ var StripeSync = class {
1058
1063
  postgresClient;
1059
1064
  async processWebhook(payload, signature, uuid) {
1060
1065
  const result = await this.postgresClient.query(
1061
- `SELECT secret FROM "${this.config.schema || DEFAULT_SCHEMA}"."managed_webhooks" WHERE uuid = $1`,
1066
+ `SELECT secret FROM "${this.config.schema || DEFAULT_SCHEMA}"."_managed_webhooks" WHERE uuid = $1`,
1062
1067
  [uuid]
1063
1068
  );
1064
1069
  if (result.rows.length === 0) {
@@ -2275,16 +2280,38 @@ var StripeSync = class {
2275
2280
  await this.upsertManagedWebhooks([webhookWithUuid]);
2276
2281
  return { webhook, uuid };
2277
2282
  }
2283
+ async findOrCreateManagedWebhook(baseUrl, params) {
2284
+ const existingWebhooks = await this.listManagedWebhooks();
2285
+ for (const existingWebhook of existingWebhooks) {
2286
+ const existingBaseUrl = existingWebhook.url.replace(/\/[^/]+$/, "");
2287
+ if (existingBaseUrl === baseUrl) {
2288
+ try {
2289
+ const stripeWebhook = await this.stripe.webhookEndpoints.retrieve(
2290
+ existingWebhook.id
2291
+ );
2292
+ if (stripeWebhook.status === "enabled") {
2293
+ return {
2294
+ webhook: stripeWebhook,
2295
+ uuid: existingWebhook.uuid
2296
+ };
2297
+ }
2298
+ } catch (error) {
2299
+ continue;
2300
+ }
2301
+ }
2302
+ }
2303
+ return this.createManagedWebhook(baseUrl, params);
2304
+ }
2278
2305
  async getManagedWebhook(id) {
2279
2306
  const result = await this.postgresClient.query(
2280
- `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."managed_webhooks" WHERE id = $1`,
2307
+ `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."_managed_webhooks" WHERE id = $1`,
2281
2308
  [id]
2282
2309
  );
2283
2310
  return result.rows.length > 0 ? result.rows[0] : null;
2284
2311
  }
2285
2312
  async listManagedWebhooks() {
2286
2313
  const result = await this.postgresClient.query(
2287
- `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."managed_webhooks" ORDER BY created DESC`
2314
+ `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."_managed_webhooks" ORDER BY created DESC`
2288
2315
  );
2289
2316
  return result.rows;
2290
2317
  }
@@ -2297,12 +2324,12 @@ var StripeSync = class {
2297
2324
  }
2298
2325
  async deleteManagedWebhook(id) {
2299
2326
  await this.stripe.webhookEndpoints.del(id);
2300
- return this.postgresClient.delete("managed_webhooks", id);
2327
+ return this.postgresClient.delete("_managed_webhooks", id);
2301
2328
  }
2302
2329
  async upsertManagedWebhooks(webhooks, syncTimestamp) {
2303
2330
  return this.postgresClient.upsertManyWithTimestampProtection(
2304
2331
  webhooks,
2305
- "managed_webhooks",
2332
+ "_managed_webhooks",
2306
2333
  managedWebhookSchema,
2307
2334
  syncTimestamp
2308
2335
  );
package/dist/index.d.cts CHANGED
@@ -12,6 +12,7 @@ interface StripeAutoSyncOptions {
12
12
  stripeApiVersion?: string;
13
13
  autoExpandLists?: boolean;
14
14
  backfillRelatedEntities?: boolean;
15
+ keepWebhooksOnShutdown?: boolean;
15
16
  }
16
17
  interface StripeAutoSyncInfo {
17
18
  baseUrl: string;
@@ -44,7 +45,7 @@ declare class StripeAutoSync {
44
45
  start(app: Express): Promise<StripeAutoSyncInfo>;
45
46
  /**
46
47
  * Stops all services and cleans up resources:
47
- * 1. Deletes Stripe webhook endpoint from Stripe and database
48
+ * 1. Optionally deletes Stripe webhook endpoint from Stripe and database (based on keepWebhooksOnShutdown)
48
49
  */
49
50
  stop(): Promise<void>;
50
51
  /**
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ interface StripeAutoSyncOptions {
12
12
  stripeApiVersion?: string;
13
13
  autoExpandLists?: boolean;
14
14
  backfillRelatedEntities?: boolean;
15
+ keepWebhooksOnShutdown?: boolean;
15
16
  }
16
17
  interface StripeAutoSyncInfo {
17
18
  baseUrl: string;
@@ -44,7 +45,7 @@ declare class StripeAutoSync {
44
45
  start(app: Express): Promise<StripeAutoSyncInfo>;
45
46
  /**
46
47
  * Stops all services and cleans up resources:
47
- * 1. Deletes Stripe webhook endpoint from Stripe and database
48
+ * 1. Optionally deletes Stripe webhook endpoint from Stripe and database (based on keepWebhooksOnShutdown)
48
49
  */
49
50
  stop(): Promise<void>;
50
51
  /**
package/dist/index.js CHANGED
@@ -850,7 +850,8 @@ var StripeAutoSync = class {
850
850
  webhookPath: options.webhookPath || "/stripe-webhooks",
851
851
  stripeApiVersion: options.stripeApiVersion || "2020-08-27",
852
852
  autoExpandLists: options.autoExpandLists !== void 0 ? options.autoExpandLists : false,
853
- backfillRelatedEntities: options.backfillRelatedEntities !== void 0 ? options.backfillRelatedEntities : true
853
+ backfillRelatedEntities: options.backfillRelatedEntities !== void 0 ? options.backfillRelatedEntities : true,
854
+ keepWebhooksOnShutdown: options.keepWebhooksOnShutdown !== void 0 ? options.keepWebhooksOnShutdown : true
854
855
  };
855
856
  }
856
857
  /**
@@ -885,7 +886,7 @@ var StripeAutoSync = class {
885
886
  poolConfig
886
887
  });
887
888
  const baseUrl = this.options.baseUrl();
888
- const { webhook, uuid } = await this.stripeSync.createManagedWebhook(
889
+ const { webhook, uuid } = await this.stripeSync.findOrCreateManagedWebhook(
889
890
  `${baseUrl}${this.options.webhookPath}`,
890
891
  {
891
892
  enabled_events: ["*"],
@@ -895,6 +896,10 @@ var StripeAutoSync = class {
895
896
  );
896
897
  this.webhookId = webhook.id;
897
898
  this.webhookUuid = uuid;
899
+ console.log("Starting initial backfill of all Stripe data...");
900
+ const backfillResult = await this.stripeSync.syncBackfill({ object: "all" });
901
+ const totalSynced = Object.values(backfillResult).reduce((sum, result) => sum + (result?.synced || 0), 0);
902
+ console.log(`\u2713 Backfill complete: ${totalSynced} objects synced`);
898
903
  this.mountWebhook(app);
899
904
  app.use(this.getBodyParserMiddleware());
900
905
  return {
@@ -915,10 +920,10 @@ var StripeAutoSync = class {
915
920
  }
916
921
  /**
917
922
  * Stops all services and cleans up resources:
918
- * 1. Deletes Stripe webhook endpoint from Stripe and database
923
+ * 1. Optionally deletes Stripe webhook endpoint from Stripe and database (based on keepWebhooksOnShutdown)
919
924
  */
920
925
  async stop() {
921
- if (this.webhookId && this.stripeSync) {
926
+ if (this.webhookId && this.stripeSync && !this.options.keepWebhooksOnShutdown) {
922
927
  try {
923
928
  await this.stripeSync.deleteManagedWebhook(this.webhookId);
924
929
  } catch (error) {
@@ -1017,7 +1022,7 @@ var StripeSync = class {
1017
1022
  postgresClient;
1018
1023
  async processWebhook(payload, signature, uuid) {
1019
1024
  const result = await this.postgresClient.query(
1020
- `SELECT secret FROM "${this.config.schema || DEFAULT_SCHEMA}"."managed_webhooks" WHERE uuid = $1`,
1025
+ `SELECT secret FROM "${this.config.schema || DEFAULT_SCHEMA}"."_managed_webhooks" WHERE uuid = $1`,
1021
1026
  [uuid]
1022
1027
  );
1023
1028
  if (result.rows.length === 0) {
@@ -2234,16 +2239,38 @@ var StripeSync = class {
2234
2239
  await this.upsertManagedWebhooks([webhookWithUuid]);
2235
2240
  return { webhook, uuid };
2236
2241
  }
2242
+ async findOrCreateManagedWebhook(baseUrl, params) {
2243
+ const existingWebhooks = await this.listManagedWebhooks();
2244
+ for (const existingWebhook of existingWebhooks) {
2245
+ const existingBaseUrl = existingWebhook.url.replace(/\/[^/]+$/, "");
2246
+ if (existingBaseUrl === baseUrl) {
2247
+ try {
2248
+ const stripeWebhook = await this.stripe.webhookEndpoints.retrieve(
2249
+ existingWebhook.id
2250
+ );
2251
+ if (stripeWebhook.status === "enabled") {
2252
+ return {
2253
+ webhook: stripeWebhook,
2254
+ uuid: existingWebhook.uuid
2255
+ };
2256
+ }
2257
+ } catch (error) {
2258
+ continue;
2259
+ }
2260
+ }
2261
+ }
2262
+ return this.createManagedWebhook(baseUrl, params);
2263
+ }
2237
2264
  async getManagedWebhook(id) {
2238
2265
  const result = await this.postgresClient.query(
2239
- `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."managed_webhooks" WHERE id = $1`,
2266
+ `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."_managed_webhooks" WHERE id = $1`,
2240
2267
  [id]
2241
2268
  );
2242
2269
  return result.rows.length > 0 ? result.rows[0] : null;
2243
2270
  }
2244
2271
  async listManagedWebhooks() {
2245
2272
  const result = await this.postgresClient.query(
2246
- `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."managed_webhooks" ORDER BY created DESC`
2273
+ `SELECT * FROM "${this.config.schema || DEFAULT_SCHEMA}"."_managed_webhooks" ORDER BY created DESC`
2247
2274
  );
2248
2275
  return result.rows;
2249
2276
  }
@@ -2256,12 +2283,12 @@ var StripeSync = class {
2256
2283
  }
2257
2284
  async deleteManagedWebhook(id) {
2258
2285
  await this.stripe.webhookEndpoints.del(id);
2259
- return this.postgresClient.delete("managed_webhooks", id);
2286
+ return this.postgresClient.delete("_managed_webhooks", id);
2260
2287
  }
2261
2288
  async upsertManagedWebhooks(webhooks, syncTimestamp) {
2262
2289
  return this.postgresClient.upsertManyWithTimestampProtection(
2263
2290
  webhooks,
2264
- "managed_webhooks",
2291
+ "_managed_webhooks",
2265
2292
  managedWebhookSchema,
2266
2293
  syncTimestamp
2267
2294
  );
@@ -0,0 +1,2 @@
1
+ -- Rename managed_webhooks table to _managed_webhooks
2
+ alter table if exists "stripe"."managed_webhooks" rename to "_managed_webhooks";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stripe-experiment-sync",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "private": false,
5
5
  "description": "Stripe Sync Engine to sync Stripe data based on webhooks to Postgres",
6
6
  "type": "module",