@drawbridge/drawbridge-stripe 0.1.20 → 0.1.22

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.js CHANGED
@@ -951,17 +951,12 @@ var require_subscription = __commonJS({
951
951
  },
952
952
  // Consume a deactivatableItems list. Each artifact is deactivated with an
953
953
  // artifact-id idempotency key (`<type>.deactivate:<id>`) so re-running a
954
- // delete is a safe no-op. Runs concurrently via Promise.allSettled;
955
- // rejections are logged through the injected logger and never rethrown,
956
- // so a single Stripe failure cannot block org-doc deletion. The logger is
957
- // injected because drawbridge-stripe stays a pure SDK wrapper — telemetry
958
- // remains the single Sentry owner.
954
+ // delete is a safe no-op. Promise.allSettled means a single Stripe failure
955
+ // never rejects the caller inspects the settled results. No logging here:
956
+ // drawbridge-stripe stays a pure SDK wrapper, so the consumer (which owns
957
+ // telemetry) logs the outcome.
959
958
  deactivate: async ({
960
- items = [],
961
- logger = { info() {
962
- }, warn() {
963
- }, error() {
964
- } }
959
+ items = []
965
960
  }) => {
966
961
  const deactivateOne = ({ type, id }) => {
967
962
  const options = idem(type + ".deactivate", id);
@@ -978,13 +973,61 @@ var require_subscription = __commonJS({
978
973
  }
979
974
  ;
980
975
  };
981
- return Promise.allSettled(
982
- items.map((item) => Promise.resolve(deactivateOne(item)).catch((error) => {
983
- logger.error(
984
- "Stripe deactivate failed for " + (item == null ? void 0 : item.type) + " " + (item == null ? void 0 : item.id) + ": " + (error == null ? void 0 : error.message)
985
- );
986
- }))
987
- );
976
+ return Promise.allSettled(items.map(deactivateOne));
977
+ },
978
+ // Pure read. Stripe-side safety-net discovery that complements the
979
+ // structural deactivatableItems() pass: walks Stripe by
980
+ // metadata.organization (prices/products via Search) and event_name
981
+ // prefix (meters via list + client-side filter, since the Billing
982
+ // Meters API has no Search endpoint and accepts no metadata). Returns
983
+ // a grouped { prices, products, meters } object with id-only arrays
984
+ // — caller logs the grouped object directly and flattens to feed the
985
+ // existing deactivate({items}) path. Per-type try/catch keeps a
986
+ // single-type Stripe outage from blocking the rest; the structured
987
+ // pass already ran before this so the org-delete is never gated on
988
+ // the sweep.
989
+ findOrphanedItems: async ({
990
+ organization
991
+ }) => {
992
+ var _a;
993
+ const orphaned = {
994
+ prices: [],
995
+ products: [],
996
+ meters: []
997
+ };
998
+ try {
999
+ for await (const price of stripe2.prices.search({
1000
+ query: "metadata['organization']:'" + organization + "' AND active:'true'"
1001
+ })) {
1002
+ orphaned.prices.push(price.id);
1003
+ }
1004
+ ;
1005
+ } catch {
1006
+ }
1007
+ ;
1008
+ try {
1009
+ for await (const product of stripe2.products.search({
1010
+ query: "metadata['organization']:'" + organization + "' AND active:'true'"
1011
+ })) {
1012
+ orphaned.products.push(product.id);
1013
+ }
1014
+ ;
1015
+ } catch {
1016
+ }
1017
+ ;
1018
+ try {
1019
+ const prefix = organization + "_usage_";
1020
+ for await (const meter of stripe2.billing.meters.list({ status: "active" })) {
1021
+ if ((_a = meter == null ? void 0 : meter.event_name) == null ? void 0 : _a.startsWith(prefix)) {
1022
+ orphaned.meters.push(meter.id);
1023
+ }
1024
+ ;
1025
+ }
1026
+ ;
1027
+ } catch {
1028
+ }
1029
+ ;
1030
+ return orphaned;
988
1031
  }
989
1032
  };
990
1033
  };
package/dist/index.mjs CHANGED
@@ -957,17 +957,12 @@ var require_subscription = __commonJS({
957
957
  },
958
958
  // Consume a deactivatableItems list. Each artifact is deactivated with an
959
959
  // artifact-id idempotency key (`<type>.deactivate:<id>`) so re-running a
960
- // delete is a safe no-op. Runs concurrently via Promise.allSettled;
961
- // rejections are logged through the injected logger and never rethrown,
962
- // so a single Stripe failure cannot block org-doc deletion. The logger is
963
- // injected because drawbridge-stripe stays a pure SDK wrapper — telemetry
964
- // remains the single Sentry owner.
960
+ // delete is a safe no-op. Promise.allSettled means a single Stripe failure
961
+ // never rejects the caller inspects the settled results. No logging here:
962
+ // drawbridge-stripe stays a pure SDK wrapper, so the consumer (which owns
963
+ // telemetry) logs the outcome.
965
964
  deactivate: async ({
966
- items = [],
967
- logger = { info() {
968
- }, warn() {
969
- }, error() {
970
- } }
965
+ items = []
971
966
  }) => {
972
967
  const deactivateOne = ({ type, id }) => {
973
968
  const options = idem(type + ".deactivate", id);
@@ -984,13 +979,61 @@ var require_subscription = __commonJS({
984
979
  }
985
980
  ;
986
981
  };
987
- return Promise.allSettled(
988
- items.map((item) => Promise.resolve(deactivateOne(item)).catch((error) => {
989
- logger.error(
990
- "Stripe deactivate failed for " + (item == null ? void 0 : item.type) + " " + (item == null ? void 0 : item.id) + ": " + (error == null ? void 0 : error.message)
991
- );
992
- }))
993
- );
982
+ return Promise.allSettled(items.map(deactivateOne));
983
+ },
984
+ // Pure read. Stripe-side safety-net discovery that complements the
985
+ // structural deactivatableItems() pass: walks Stripe by
986
+ // metadata.organization (prices/products via Search) and event_name
987
+ // prefix (meters via list + client-side filter, since the Billing
988
+ // Meters API has no Search endpoint and accepts no metadata). Returns
989
+ // a grouped { prices, products, meters } object with id-only arrays
990
+ // — caller logs the grouped object directly and flattens to feed the
991
+ // existing deactivate({items}) path. Per-type try/catch keeps a
992
+ // single-type Stripe outage from blocking the rest; the structured
993
+ // pass already ran before this so the org-delete is never gated on
994
+ // the sweep.
995
+ findOrphanedItems: async ({
996
+ organization
997
+ }) => {
998
+ var _a;
999
+ const orphaned = {
1000
+ prices: [],
1001
+ products: [],
1002
+ meters: []
1003
+ };
1004
+ try {
1005
+ for await (const price of stripe.prices.search({
1006
+ query: "metadata['organization']:'" + organization + "' AND active:'true'"
1007
+ })) {
1008
+ orphaned.prices.push(price.id);
1009
+ }
1010
+ ;
1011
+ } catch {
1012
+ }
1013
+ ;
1014
+ try {
1015
+ for await (const product of stripe.products.search({
1016
+ query: "metadata['organization']:'" + organization + "' AND active:'true'"
1017
+ })) {
1018
+ orphaned.products.push(product.id);
1019
+ }
1020
+ ;
1021
+ } catch {
1022
+ }
1023
+ ;
1024
+ try {
1025
+ const prefix = organization + "_usage_";
1026
+ for await (const meter of stripe.billing.meters.list({ status: "active" })) {
1027
+ if ((_a = meter == null ? void 0 : meter.event_name) == null ? void 0 : _a.startsWith(prefix)) {
1028
+ orphaned.meters.push(meter.id);
1029
+ }
1030
+ ;
1031
+ }
1032
+ ;
1033
+ } catch {
1034
+ }
1035
+ ;
1036
+ return orphaned;
994
1037
  }
995
1038
  };
996
1039
  };
package/package.json CHANGED
@@ -26,5 +26,5 @@
26
26
  "build": "tsup ./index.js && npm publish"
27
27
  },
28
28
  "types": "dist/index.d.ts",
29
- "version": "0.1.20"
29
+ "version": "0.1.22"
30
30
  }