@onesub/server 0.12.0 → 0.12.1

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 (120) hide show
  1. package/dist/__tests__/webhook-apple.test.d.ts +12 -0
  2. package/dist/__tests__/webhook-apple.test.d.ts.map +1 -0
  3. package/dist/__tests__/webhook-google.test.d.ts +13 -0
  4. package/dist/__tests__/webhook-google.test.d.ts.map +1 -0
  5. package/dist/index.cjs +258 -288
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.ts +0 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +259 -286
  10. package/dist/index.js.map +1 -1
  11. package/dist/providers/google.d.ts.map +1 -1
  12. package/dist/routes/webhook-apple.d.ts +6 -0
  13. package/dist/routes/webhook-apple.d.ts.map +1 -0
  14. package/dist/routes/webhook-google.d.ts +7 -0
  15. package/dist/routes/webhook-google.d.ts.map +1 -0
  16. package/dist/routes/webhook.d.ts +4 -17
  17. package/dist/routes/webhook.d.ts.map +1 -1
  18. package/package.json +2 -2
  19. package/dist/__tests__/admin-customer-detail.test.js +0 -146
  20. package/dist/__tests__/admin-customer-detail.test.js.map +0 -1
  21. package/dist/__tests__/admin-list-subscriptions.test.js +0 -192
  22. package/dist/__tests__/admin-list-subscriptions.test.js.map +0 -1
  23. package/dist/__tests__/admin-subscription-detail.test.js +0 -112
  24. package/dist/__tests__/admin-subscription-detail.test.js.map +0 -1
  25. package/dist/__tests__/apple-root-ca.test.js +0 -41
  26. package/dist/__tests__/apple-root-ca.test.js.map +0 -1
  27. package/dist/__tests__/apple-status-api.test.js +0 -345
  28. package/dist/__tests__/apple-status-api.test.js.map +0 -1
  29. package/dist/__tests__/cache.test.js +0 -34
  30. package/dist/__tests__/cache.test.js.map +0 -1
  31. package/dist/__tests__/entitlements.test.js +0 -268
  32. package/dist/__tests__/entitlements.test.js.map +0 -1
  33. package/dist/__tests__/error-codes.test.js +0 -168
  34. package/dist/__tests__/error-codes.test.js.map +0 -1
  35. package/dist/__tests__/fetch-hardening.test.js +0 -192
  36. package/dist/__tests__/fetch-hardening.test.js.map +0 -1
  37. package/dist/__tests__/google-paused.test.js +0 -126
  38. package/dist/__tests__/google-paused.test.js.map +0 -1
  39. package/dist/__tests__/google-price-change.test.js +0 -186
  40. package/dist/__tests__/google-price-change.test.js.map +0 -1
  41. package/dist/__tests__/google-subscriptions-v2.test.js +0 -206
  42. package/dist/__tests__/google-subscriptions-v2.test.js.map +0 -1
  43. package/dist/__tests__/lifecycle-scenarios.test.js +0 -579
  44. package/dist/__tests__/lifecycle-scenarios.test.js.map +0 -1
  45. package/dist/__tests__/lifecycle-states.test.js +0 -423
  46. package/dist/__tests__/lifecycle-states.test.js.map +0 -1
  47. package/dist/__tests__/linked-purchase-token.test.js +0 -227
  48. package/dist/__tests__/linked-purchase-token.test.js.map +0 -1
  49. package/dist/__tests__/metrics.test.js +0 -340
  50. package/dist/__tests__/metrics.test.js.map +0 -1
  51. package/dist/__tests__/mock-provider.test.js +0 -188
  52. package/dist/__tests__/mock-provider.test.js.map +0 -1
  53. package/dist/__tests__/openapi.test.js +0 -32
  54. package/dist/__tests__/openapi.test.js.map +0 -1
  55. package/dist/__tests__/paused-auto-resume.test.js +0 -162
  56. package/dist/__tests__/paused-auto-resume.test.js.map +0 -1
  57. package/dist/__tests__/providers.test.js +0 -321
  58. package/dist/__tests__/providers.test.js.map +0 -1
  59. package/dist/__tests__/redis-store.test.js +0 -117
  60. package/dist/__tests__/redis-store.test.js.map +0 -1
  61. package/dist/__tests__/refund-policy.test.js +0 -317
  62. package/dist/__tests__/refund-policy.test.js.map +0 -1
  63. package/dist/__tests__/schema.test.js +0 -46
  64. package/dist/__tests__/schema.test.js.map +0 -1
  65. package/dist/__tests__/store.test.js +0 -172
  66. package/dist/__tests__/store.test.js.map +0 -1
  67. package/dist/__tests__/test-utils.js +0 -30
  68. package/dist/__tests__/test-utils.js.map +0 -1
  69. package/dist/__tests__/webhook-events.test.js +0 -36
  70. package/dist/__tests__/webhook-events.test.js.map +0 -1
  71. package/dist/__tests__/webhook-queue.test.js +0 -26
  72. package/dist/__tests__/webhook-queue.test.js.map +0 -1
  73. package/dist/__tests__/webhook-refund.test.js +0 -313
  74. package/dist/__tests__/webhook-refund.test.js.map +0 -1
  75. package/dist/cache.js +0 -43
  76. package/dist/cache.js.map +0 -1
  77. package/dist/errors.js +0 -19
  78. package/dist/errors.js.map +0 -1
  79. package/dist/http.js +0 -36
  80. package/dist/http.js.map +0 -1
  81. package/dist/logger.js +0 -20
  82. package/dist/logger.js.map +0 -1
  83. package/dist/openapi.js +0 -196
  84. package/dist/openapi.js.map +0 -1
  85. package/dist/providers/apple-root-ca.js +0 -38
  86. package/dist/providers/apple-root-ca.js.map +0 -1
  87. package/dist/providers/apple.js +0 -510
  88. package/dist/providers/apple.js.map +0 -1
  89. package/dist/providers/google.js +0 -522
  90. package/dist/providers/google.js.map +0 -1
  91. package/dist/providers/mock.js +0 -93
  92. package/dist/providers/mock.js.map +0 -1
  93. package/dist/routes/admin.js +0 -287
  94. package/dist/routes/admin.js.map +0 -1
  95. package/dist/routes/entitlements.js +0 -130
  96. package/dist/routes/entitlements.js.map +0 -1
  97. package/dist/routes/metrics.js +0 -281
  98. package/dist/routes/metrics.js.map +0 -1
  99. package/dist/routes/purchase.js +0 -187
  100. package/dist/routes/purchase.js.map +0 -1
  101. package/dist/routes/status.js +0 -55
  102. package/dist/routes/status.js.map +0 -1
  103. package/dist/routes/validate.js +0 -70
  104. package/dist/routes/validate.js.map +0 -1
  105. package/dist/routes/webhook.js +0 -461
  106. package/dist/routes/webhook.js.map +0 -1
  107. package/dist/store.js +0 -145
  108. package/dist/store.js.map +0 -1
  109. package/dist/stores/postgres.js +0 -329
  110. package/dist/stores/postgres.js.map +0 -1
  111. package/dist/stores/redis.js +0 -255
  112. package/dist/stores/redis.js.map +0 -1
  113. package/dist/stores/schema.js +0 -67
  114. package/dist/stores/schema.js.map +0 -1
  115. package/dist/tracing.js +0 -74
  116. package/dist/tracing.js.map +0 -1
  117. package/dist/webhook-events.js +0 -57
  118. package/dist/webhook-events.js.map +0 -1
  119. package/dist/webhook-queue.js +0 -108
  120. package/dist/webhook-queue.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -85,5 +85,4 @@ export { validateAppleReceipt, fetchAppleSubscriptionStatus } from './providers/
85
85
  export { validateGoogleReceipt } from './providers/google.js';
86
86
  export { evaluateEntitlement } from './routes/entitlements.js';
87
87
  export { setLogger, log } from './logger.js';
88
- export default createOneSubMiddleware;
89
88
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AASnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE;;;OAGG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CA6C7E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAW7F;AAGD,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC9E,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACxF,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAI/E,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAI/D,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAG7C,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AASnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE;;;OAGG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;OAIG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CA6C7E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAW7F;AAGD,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC9E,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACxF,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAI/E,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAI/D,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -723,6 +723,7 @@ async function fetchProductPurchase(packageName, productId, purchaseToken, acces
723
723
  async function acknowledgeGoogleSubscription(purchaseToken, productId, config) {
724
724
  if (config.mockMode) return;
725
725
  if (!config.serviceAccountKey) return;
726
+ if (!config.packageName) return;
726
727
  let accessToken;
727
728
  try {
728
729
  accessToken = await getCachedAccessToken(config.serviceAccountKey);
@@ -748,6 +749,7 @@ async function acknowledgeGoogleSubscription(purchaseToken, productId, config) {
748
749
  async function acknowledgeGoogleProduct(purchaseToken, productId, config) {
749
750
  if (config.mockMode) return;
750
751
  if (!config.serviceAccountKey) return;
752
+ if (!config.packageName) return;
751
753
  let accessToken;
752
754
  try {
753
755
  accessToken = await getCachedAccessToken(config.serviceAccountKey);
@@ -772,6 +774,7 @@ async function acknowledgeGoogleProduct(purchaseToken, productId, config) {
772
774
  }
773
775
  async function consumeGoogleProductReceipt(purchaseToken, productId, config) {
774
776
  if (!config.serviceAccountKey) return;
777
+ if (!config.packageName) return;
775
778
  let accessToken;
776
779
  try {
777
780
  accessToken = await getCachedAccessToken(config.serviceAccountKey);
@@ -819,6 +822,10 @@ async function validateGoogleReceipt(receipt, productId, config) {
819
822
  log.warn("[onesub/google] No serviceAccountKey provided \u2014 cannot call Play API");
820
823
  return null;
821
824
  }
825
+ if (!config.packageName) {
826
+ log.warn("[onesub/google] No packageName provided \u2014 cannot call Play API");
827
+ return null;
828
+ }
822
829
  let purchase;
823
830
  try {
824
831
  const token = await getCachedAccessToken(config.serviceAccountKey);
@@ -871,6 +878,10 @@ async function validateGoogleProductReceipt(purchaseToken, productId, config, ty
871
878
  log.warn("[onesub/google] No serviceAccountKey \u2014 cannot validate product receipt");
872
879
  return null;
873
880
  }
881
+ if (!config.packageName) {
882
+ log.warn("[onesub/google] No packageName \u2014 cannot validate product receipt");
883
+ return null;
884
+ }
874
885
  let purchase;
875
886
  try {
876
887
  const token = await getCachedAccessToken(config.serviceAccountKey);
@@ -1063,41 +1074,9 @@ function createStatusRouter(store) {
1063
1074
  });
1064
1075
  return router;
1065
1076
  }
1066
- var GOOGLE_JWKS_URL = "https://www.googleapis.com/oauth2/v3/certs";
1067
- var googleJwks = null;
1068
- function getGoogleJwks() {
1069
- if (!googleJwks) {
1070
- googleJwks = createRemoteJWKSet(new URL(GOOGLE_JWKS_URL));
1071
- }
1072
- return googleJwks;
1073
- }
1074
- async function verifyGooglePushToken(req, expectedAudience) {
1075
- const authHeader = req.headers["authorization"];
1076
- if (typeof authHeader !== "string" || !authHeader.startsWith("Bearer ")) {
1077
- return false;
1078
- }
1079
- const token = authHeader.slice("Bearer ".length).trim();
1080
- try {
1081
- await jwtVerify(token, getGoogleJwks(), { audience: expectedAudience });
1082
- return true;
1083
- } catch {
1084
- return false;
1085
- }
1086
- }
1087
- var APPLE_ACTIVE_TYPES = /* @__PURE__ */ new Set([
1088
- "SUBSCRIBED",
1089
- "DID_RENEW",
1090
- "DID_RECOVER",
1091
- "OFFER_REDEEMED"
1092
- ]);
1093
- var APPLE_CANCELED_TYPES = /* @__PURE__ */ new Set([
1094
- "REVOKE",
1095
- "REFUND",
1096
- "CONSUMPTION_REQUEST"
1097
- ]);
1098
- var APPLE_EXPIRED_TYPES = /* @__PURE__ */ new Set([
1099
- "EXPIRED"
1100
- ]);
1077
+ var APPLE_ACTIVE_TYPES = /* @__PURE__ */ new Set(["SUBSCRIBED", "DID_RENEW", "DID_RECOVER", "OFFER_REDEEMED"]);
1078
+ var APPLE_CANCELED_TYPES = /* @__PURE__ */ new Set(["REVOKE", "REFUND", "CONSUMPTION_REQUEST"]);
1079
+ var APPLE_EXPIRED_TYPES = /* @__PURE__ */ new Set(["EXPIRED"]);
1101
1080
  function mapAppleNotificationStatus(notificationType, subtype) {
1102
1081
  if (notificationType === "DID_FAIL_TO_RENEW") {
1103
1082
  return subtype === "GRACE_PERIOD" ? SUBSCRIPTION_STATUS.GRACE_PERIOD : SUBSCRIPTION_STATUS.ON_HOLD;
@@ -1108,283 +1087,278 @@ function mapAppleNotificationStatus(notificationType, subtype) {
1108
1087
  if (APPLE_ACTIVE_TYPES.has(notificationType)) return SUBSCRIPTION_STATUS.ACTIVE;
1109
1088
  return null;
1110
1089
  }
1111
- function createWebhookRouter(config, store, purchaseStore, webhookEventStore) {
1112
- const router = Router();
1113
- router.post(ROUTES.WEBHOOK_APPLE, async (req, res) => {
1114
- const body = req.body;
1115
- if (!body.signedPayload) {
1116
- sendError(res, 400, ONESUB_ERROR_CODE.MISSING_SIGNED_PAYLOAD, "Missing signedPayload");
1117
- return;
1118
- }
1119
- let payload;
1120
- try {
1121
- payload = await decodeJws(
1122
- body.signedPayload,
1123
- config.apple?.skipJwsVerification
1124
- );
1125
- } catch (err) {
1126
- log.error("[onesub/webhook/apple] Failed to decode signedPayload:", err);
1127
- sendError(res, 400, ONESUB_ERROR_CODE.INVALID_SIGNED_PAYLOAD, "Invalid signedPayload");
1128
- return;
1129
- }
1130
- if (webhookEventStore && typeof payload.notificationUUID === "string") {
1131
- const fresh = await webhookEventStore.markIfNew("apple", payload.notificationUUID);
1132
- if (!fresh) {
1133
- log.info("[onesub/webhook/apple] dedupe: already processed", payload.notificationUUID);
1134
- res.status(200).json({ received: true, deduped: true });
1135
- return;
1136
- }
1137
- }
1138
- const decoded = await decodeAppleNotification(payload, config.apple?.skipJwsVerification);
1139
- if (!decoded) {
1140
- res.status(200).json({ received: true });
1090
+ async function handleAppleWebhook(req, res, config, store, purchaseStore, webhookEventStore) {
1091
+ const body = req.body;
1092
+ if (!body.signedPayload) {
1093
+ sendError(res, 400, ONESUB_ERROR_CODE.MISSING_SIGNED_PAYLOAD, "Missing signedPayload");
1094
+ return;
1095
+ }
1096
+ let payload;
1097
+ try {
1098
+ payload = await decodeJws(
1099
+ body.signedPayload,
1100
+ config.apple?.skipJwsVerification
1101
+ );
1102
+ } catch (err) {
1103
+ log.error("[onesub/webhook/apple] Failed to decode signedPayload:", err);
1104
+ sendError(res, 400, ONESUB_ERROR_CODE.INVALID_SIGNED_PAYLOAD, "Invalid signedPayload");
1105
+ return;
1106
+ }
1107
+ if (webhookEventStore && typeof payload.notificationUUID === "string") {
1108
+ const fresh = await webhookEventStore.markIfNew("apple", payload.notificationUUID);
1109
+ if (!fresh) {
1110
+ log.info("[onesub/webhook/apple] dedupe: already processed", payload.notificationUUID);
1111
+ res.status(200).json({ received: true, deduped: true });
1141
1112
  return;
1142
1113
  }
1143
- const {
1144
- originalTransactionId,
1145
- transactionId,
1146
- type,
1147
- productId,
1148
- bundleId,
1149
- environment,
1150
- status,
1151
- willRenew,
1152
- expiresAt
1153
- } = decoded;
1154
- const notificationType = payload.notificationType;
1155
- const subtype = payload.subtype;
1156
- const mapped = mapAppleNotificationStatus(notificationType, subtype);
1157
- const finalStatus = mapped ?? status;
1158
- if (notificationType === "CONSUMPTION_REQUEST" && config.apple?.consumptionInfoProvider && transactionId && productId) {
1159
- const provider = config.apple.consumptionInfoProvider;
1160
- const appleConfig = config.apple;
1161
- void (async () => {
1162
- try {
1163
- const info = await provider({
1164
- transactionId,
1165
- originalTransactionId,
1166
- productId,
1167
- bundleId: bundleId ?? appleConfig.bundleId,
1168
- environment
1114
+ }
1115
+ const decoded = await decodeAppleNotification(payload, config.apple?.skipJwsVerification);
1116
+ if (!decoded) {
1117
+ res.status(200).json({ received: true });
1118
+ return;
1119
+ }
1120
+ const {
1121
+ originalTransactionId,
1122
+ transactionId,
1123
+ type,
1124
+ productId,
1125
+ bundleId,
1126
+ environment,
1127
+ status,
1128
+ willRenew,
1129
+ expiresAt
1130
+ } = decoded;
1131
+ const notificationType = payload.notificationType;
1132
+ const subtype = payload.subtype;
1133
+ const mapped = mapAppleNotificationStatus(notificationType, subtype);
1134
+ const finalStatus = mapped ?? status;
1135
+ if (notificationType === "CONSUMPTION_REQUEST" && config.apple?.consumptionInfoProvider && transactionId && productId) {
1136
+ const provider = config.apple.consumptionInfoProvider;
1137
+ const appleConfig = config.apple;
1138
+ void (async () => {
1139
+ try {
1140
+ const info = await provider({
1141
+ transactionId,
1142
+ originalTransactionId,
1143
+ productId,
1144
+ bundleId: bundleId ?? appleConfig.bundleId,
1145
+ environment
1146
+ });
1147
+ if (info) {
1148
+ await sendAppleConsumptionResponse(transactionId, info, appleConfig, {
1149
+ sandbox: environment === "Sandbox"
1169
1150
  });
1170
- if (info) {
1171
- await sendAppleConsumptionResponse(transactionId, info, appleConfig, {
1172
- sandbox: environment === "Sandbox"
1173
- });
1174
- }
1175
- } catch (err) {
1176
- log.warn("[onesub/webhook/apple] consumptionInfoProvider failed:", err);
1177
1151
  }
1178
- })();
1179
- }
1180
- const isOneTimePurchase = type === "Consumable" || type === "Non-Consumable";
1181
- const isRefundOrRevoke = APPLE_CANCELED_TYPES.has(notificationType);
1182
- try {
1183
- if (isOneTimePurchase && isRefundOrRevoke) {
1184
- const lookupId = transactionId ?? originalTransactionId;
1185
- const removed = await purchaseStore.deletePurchaseByTransactionId(lookupId);
1186
- if (!removed) {
1187
- log.warn(
1188
- "[onesub/webhook/apple] IAP refund for unknown transaction:",
1189
- lookupId
1190
- );
1191
- }
1192
- res.status(200).json({ received: true });
1193
- return;
1152
+ } catch (err) {
1153
+ log.warn("[onesub/webhook/apple] consumptionInfoProvider failed:", err);
1194
1154
  }
1195
- const existing = await store.getByTransactionId(originalTransactionId);
1196
- if (existing) {
1197
- const isSubscriptionRefund = isRefundOrRevoke && !isOneTimePurchase && notificationType !== "CONSUMPTION_REQUEST";
1198
- const keepEntitlement = isSubscriptionRefund && config.refundPolicy === "until_expiry";
1199
- const updated = keepEntitlement ? { ...existing, willRenew: false } : {
1200
- ...existing,
1201
- status: finalStatus,
1202
- willRenew,
1203
- // expiresAt may be absent on non-subscription payloads — keep the
1204
- // previously-stored value rather than overwriting with null/empty.
1205
- expiresAt: expiresAt ?? existing.expiresAt
1206
- };
1207
- await store.save(updated);
1208
- } else if (config.apple?.issuerId && config.apple?.keyId && config.apple?.privateKey) {
1209
- const fresh = await fetchAppleSubscriptionStatus(originalTransactionId, config.apple, {
1210
- sandbox: environment === "Sandbox"
1211
- });
1212
- if (fresh) {
1213
- fresh.userId = originalTransactionId;
1214
- await store.save(fresh);
1215
- } else {
1216
- log.warn(
1217
- "[onesub/webhook/apple] Unknown transaction and Status API returned no record:",
1218
- originalTransactionId
1219
- );
1220
- }
1221
- } else {
1222
- log.warn(
1223
- "[onesub/webhook/apple] Received notification for unknown transaction (no API creds to recover):",
1224
- originalTransactionId
1225
- );
1155
+ })();
1156
+ }
1157
+ const isOneTimePurchase = type === "Consumable" || type === "Non-Consumable";
1158
+ const isRefundOrRevoke = APPLE_CANCELED_TYPES.has(notificationType);
1159
+ try {
1160
+ if (isOneTimePurchase && isRefundOrRevoke) {
1161
+ const lookupId = transactionId ?? originalTransactionId;
1162
+ const removed = await purchaseStore.deletePurchaseByTransactionId(lookupId);
1163
+ if (!removed) {
1164
+ log.warn("[onesub/webhook/apple] IAP refund for unknown transaction:", lookupId);
1226
1165
  }
1227
1166
  res.status(200).json({ received: true });
1228
- } catch (err) {
1229
- log.error("[onesub/webhook/apple] Store update error:", err);
1230
- sendError(res, 500, ONESUB_ERROR_CODE.WEBHOOK_PROCESSING_FAILED, "Failed to update subscription");
1231
- }
1232
- });
1233
- router.post(ROUTES.WEBHOOK_GOOGLE, async (req, res) => {
1234
- if (config.google?.pushAudience) {
1235
- const authenticated = await verifyGooglePushToken(req, config.google.pushAudience);
1236
- if (!authenticated) {
1237
- sendError(res, 401, ONESUB_ERROR_CODE.UNAUTHORIZED, "Unauthorized");
1238
- return;
1239
- }
1240
- }
1241
- const body = req.body;
1242
- if (!body.message?.data) {
1243
- sendError(res, 400, ONESUB_ERROR_CODE.MISSING_MESSAGE_DATA, "Missing message.data");
1244
1167
  return;
1245
1168
  }
1246
- if (webhookEventStore && typeof body.message.messageId === "string") {
1247
- const fresh = await webhookEventStore.markIfNew("google", body.message.messageId);
1248
- if (!fresh) {
1249
- log.info("[onesub/webhook/google] dedupe: already processed", body.message.messageId);
1250
- res.status(200).json({ received: true, deduped: true });
1251
- return;
1252
- }
1253
- }
1254
- const voided = decodeGoogleVoidedNotification(body);
1255
- if (voided) {
1256
- if (config.google?.packageName && voided.packageName !== config.google.packageName) {
1169
+ const existing = await store.getByTransactionId(originalTransactionId);
1170
+ if (existing) {
1171
+ const isSubscriptionRefund = isRefundOrRevoke && !isOneTimePurchase && notificationType !== "CONSUMPTION_REQUEST";
1172
+ const keepEntitlement = isSubscriptionRefund && config.refundPolicy === "until_expiry";
1173
+ const updated = keepEntitlement ? { ...existing, willRenew: false } : {
1174
+ ...existing,
1175
+ status: finalStatus,
1176
+ willRenew,
1177
+ expiresAt: expiresAt ?? existing.expiresAt
1178
+ };
1179
+ await store.save(updated);
1180
+ } else if (config.apple?.issuerId && config.apple?.keyId && config.apple?.privateKey) {
1181
+ const fresh = await fetchAppleSubscriptionStatus(originalTransactionId, config.apple, {
1182
+ sandbox: environment === "Sandbox"
1183
+ });
1184
+ if (fresh) {
1185
+ fresh.userId = originalTransactionId;
1186
+ await store.save(fresh);
1187
+ } else {
1257
1188
  log.warn(
1258
- "[onesub/webhook/google] voided package name mismatch:",
1259
- voided.packageName,
1260
- "!==",
1261
- config.google.packageName
1189
+ "[onesub/webhook/apple] Unknown transaction and Status API returned no record:",
1190
+ originalTransactionId
1262
1191
  );
1263
- sendError(res, 400, ONESUB_ERROR_CODE.PACKAGE_NAME_MISMATCH, "Package name mismatch");
1264
- return;
1265
- }
1266
- try {
1267
- if (voided.productType === 1) {
1268
- const existing = await store.getByTransactionId(voided.purchaseToken);
1269
- if (existing) {
1270
- const updated = config.refundPolicy === "until_expiry" ? { ...existing, willRenew: false } : { ...existing, status: SUBSCRIPTION_STATUS.CANCELED };
1271
- await store.save(updated);
1272
- } else {
1273
- log.warn(
1274
- "[onesub/webhook/google] voided subscription for unknown purchaseToken:",
1275
- voided.purchaseToken
1276
- );
1277
- }
1278
- } else {
1279
- const removed = await purchaseStore.deletePurchaseByTransactionId(voided.orderId);
1280
- if (!removed) {
1281
- log.warn(
1282
- "[onesub/webhook/google] voided IAP for unknown orderId:",
1283
- voided.orderId
1284
- );
1285
- }
1286
- }
1287
- res.status(200).json({ received: true });
1288
- } catch (err) {
1289
- log.error("[onesub/webhook/google] voided notification error:", err);
1290
- sendError(res, 500, ONESUB_ERROR_CODE.WEBHOOK_PROCESSING_FAILED, "Failed to process voided notification");
1291
1192
  }
1193
+ } else {
1194
+ log.warn(
1195
+ "[onesub/webhook/apple] Received notification for unknown transaction (no API creds to recover):",
1196
+ originalTransactionId
1197
+ );
1198
+ }
1199
+ res.status(200).json({ received: true });
1200
+ } catch (err) {
1201
+ log.error("[onesub/webhook/apple] Store update error:", err);
1202
+ sendError(res, 500, ONESUB_ERROR_CODE.WEBHOOK_PROCESSING_FAILED, "Failed to update subscription");
1203
+ }
1204
+ }
1205
+ var GOOGLE_JWKS_URL = "https://www.googleapis.com/oauth2/v3/certs";
1206
+ var googleJwks = null;
1207
+ function getGoogleJwks() {
1208
+ if (!googleJwks) googleJwks = createRemoteJWKSet(new URL(GOOGLE_JWKS_URL));
1209
+ return googleJwks;
1210
+ }
1211
+ async function verifyGooglePushToken(req, expectedAudience) {
1212
+ const authHeader = req.headers["authorization"];
1213
+ if (typeof authHeader !== "string" || !authHeader.startsWith("Bearer ")) return false;
1214
+ try {
1215
+ await jwtVerify(authHeader.slice("Bearer ".length).trim(), getGoogleJwks(), {
1216
+ audience: expectedAudience
1217
+ });
1218
+ return true;
1219
+ } catch {
1220
+ return false;
1221
+ }
1222
+ }
1223
+ async function handleGoogleWebhook(req, res, config, store, purchaseStore, webhookEventStore) {
1224
+ if (config.google?.pushAudience) {
1225
+ const authenticated = await verifyGooglePushToken(req, config.google.pushAudience);
1226
+ if (!authenticated) {
1227
+ sendError(res, 401, ONESUB_ERROR_CODE.UNAUTHORIZED, "Unauthorized");
1292
1228
  return;
1293
1229
  }
1294
- const notification = decodeGoogleNotification(body);
1295
- if (!notification) {
1296
- res.status(200).json({ received: true });
1230
+ }
1231
+ const body = req.body;
1232
+ if (!body.message?.data) {
1233
+ sendError(res, 400, ONESUB_ERROR_CODE.MISSING_MESSAGE_DATA, "Missing message.data");
1234
+ return;
1235
+ }
1236
+ if (webhookEventStore && typeof body.message.messageId === "string") {
1237
+ const fresh = await webhookEventStore.markIfNew("google", body.message.messageId);
1238
+ if (!fresh) {
1239
+ log.info("[onesub/webhook/google] dedupe: already processed", body.message.messageId);
1240
+ res.status(200).json({ received: true, deduped: true });
1297
1241
  return;
1298
1242
  }
1299
- const { notificationType, purchaseToken, subscriptionId, packageName } = notification;
1300
- if (config.google?.packageName && packageName !== config.google.packageName) {
1301
- log.warn(
1302
- "[onesub/webhook/google] Package name mismatch:",
1303
- packageName,
1304
- "!==",
1305
- config.google.packageName
1306
- );
1243
+ }
1244
+ const voided = decodeGoogleVoidedNotification(body);
1245
+ if (voided) {
1246
+ if (config.google?.packageName && voided.packageName !== config.google.packageName) {
1247
+ log.warn("[onesub/webhook/google] voided package name mismatch:", voided.packageName, "!==", config.google.packageName);
1307
1248
  sendError(res, 400, ONESUB_ERROR_CODE.PACKAGE_NAME_MISMATCH, "Package name mismatch");
1308
1249
  return;
1309
1250
  }
1310
1251
  try {
1311
- const existing = await store.getByTransactionId(purchaseToken);
1312
- let finalStatus;
1313
- if (isGoogleActiveNotification(notificationType)) {
1314
- finalStatus = SUBSCRIPTION_STATUS.ACTIVE;
1315
- } else if (isGoogleGracePeriodNotification(notificationType)) {
1316
- finalStatus = SUBSCRIPTION_STATUS.GRACE_PERIOD;
1317
- } else if (isGoogleOnHoldNotification(notificationType)) {
1318
- finalStatus = SUBSCRIPTION_STATUS.ON_HOLD;
1319
- } else if (isGooglePausedNotification(notificationType)) {
1320
- finalStatus = SUBSCRIPTION_STATUS.PAUSED;
1321
- } else if (isGooglePriceChangeConfirmedNotification(notificationType)) {
1322
- finalStatus = SUBSCRIPTION_STATUS.ACTIVE;
1323
- } else if (isGoogleCanceledNotification(notificationType)) {
1324
- finalStatus = SUBSCRIPTION_STATUS.CANCELED;
1325
- } else if (isGoogleExpiredNotification(notificationType)) {
1326
- finalStatus = SUBSCRIPTION_STATUS.EXPIRED;
1252
+ if (voided.productType === 1) {
1253
+ const existing = await store.getByTransactionId(voided.purchaseToken);
1254
+ if (existing) {
1255
+ const updated = config.refundPolicy === "until_expiry" ? { ...existing, willRenew: false } : { ...existing, status: SUBSCRIPTION_STATUS.CANCELED };
1256
+ await store.save(updated);
1257
+ } else {
1258
+ log.warn("[onesub/webhook/google] voided subscription for unknown purchaseToken:", voided.purchaseToken);
1259
+ }
1327
1260
  } else {
1328
- finalStatus = SUBSCRIPTION_STATUS.ACTIVE;
1329
- }
1330
- if (isGooglePriceChangeConfirmedNotification(notificationType) && config.google?.onPriceChangeConfirmed) {
1331
- const hook = config.google.onPriceChangeConfirmed;
1332
- void Promise.resolve().then(() => hook({ purchaseToken, subscriptionId, packageName })).catch((err) => log.warn("[onesub/webhook/google] onPriceChangeConfirmed hook failed:", err));
1261
+ const removed = await purchaseStore.deletePurchaseByTransactionId(voided.orderId);
1262
+ if (!removed) {
1263
+ log.warn("[onesub/webhook/google] voided IAP for unknown orderId:", voided.orderId);
1264
+ }
1333
1265
  }
1334
- if (existing) {
1335
- let updated = { ...existing, status: finalStatus };
1336
- if (config.google?.serviceAccountKey) {
1337
- const fresh = await validateGoogleReceipt(purchaseToken, subscriptionId, config.google);
1338
- if (fresh) {
1339
- const preserveNotificationStatus = finalStatus === SUBSCRIPTION_STATUS.GRACE_PERIOD || finalStatus === SUBSCRIPTION_STATUS.ON_HOLD;
1340
- updated = {
1341
- ...existing,
1342
- status: preserveNotificationStatus ? finalStatus : fresh.status,
1343
- expiresAt: fresh.expiresAt,
1344
- willRenew: fresh.willRenew,
1345
- // Propagate v2-only fields that fresh may have updated. Without
1346
- // these, paused→active transitions left autoResumeTime stale and
1347
- // upgrade chains lost their linkedPurchaseToken on subsequent
1348
- // notifications. Use ?? undefined so cleared values become undefined
1349
- // (e.g. resume from paused autoResumeTime should disappear).
1350
- autoResumeTime: fresh.autoResumeTime,
1351
- linkedPurchaseToken: fresh.linkedPurchaseToken ?? existing.linkedPurchaseToken
1352
- };
1353
- }
1266
+ res.status(200).json({ received: true });
1267
+ } catch (err) {
1268
+ log.error("[onesub/webhook/google] voided notification error:", err);
1269
+ sendError(res, 500, ONESUB_ERROR_CODE.WEBHOOK_PROCESSING_FAILED, "Failed to process voided notification");
1270
+ }
1271
+ return;
1272
+ }
1273
+ const notification = decodeGoogleNotification(body);
1274
+ if (!notification) {
1275
+ res.status(200).json({ received: true });
1276
+ return;
1277
+ }
1278
+ const { notificationType, purchaseToken, subscriptionId, packageName } = notification;
1279
+ if (config.google?.packageName && packageName !== config.google.packageName) {
1280
+ log.warn("[onesub/webhook/google] Package name mismatch:", packageName, "!==", config.google.packageName);
1281
+ sendError(res, 400, ONESUB_ERROR_CODE.PACKAGE_NAME_MISMATCH, "Package name mismatch");
1282
+ return;
1283
+ }
1284
+ try {
1285
+ const existing = await store.getByTransactionId(purchaseToken);
1286
+ let finalStatus;
1287
+ if (isGoogleActiveNotification(notificationType)) {
1288
+ finalStatus = SUBSCRIPTION_STATUS.ACTIVE;
1289
+ } else if (isGoogleGracePeriodNotification(notificationType)) {
1290
+ finalStatus = SUBSCRIPTION_STATUS.GRACE_PERIOD;
1291
+ } else if (isGoogleOnHoldNotification(notificationType)) {
1292
+ finalStatus = SUBSCRIPTION_STATUS.ON_HOLD;
1293
+ } else if (isGooglePausedNotification(notificationType)) {
1294
+ finalStatus = SUBSCRIPTION_STATUS.PAUSED;
1295
+ } else if (isGooglePriceChangeConfirmedNotification(notificationType)) {
1296
+ finalStatus = SUBSCRIPTION_STATUS.ACTIVE;
1297
+ } else if (isGoogleCanceledNotification(notificationType)) {
1298
+ finalStatus = SUBSCRIPTION_STATUS.CANCELED;
1299
+ } else if (isGoogleExpiredNotification(notificationType)) {
1300
+ finalStatus = SUBSCRIPTION_STATUS.EXPIRED;
1301
+ } else {
1302
+ finalStatus = SUBSCRIPTION_STATUS.ACTIVE;
1303
+ }
1304
+ if (isGooglePriceChangeConfirmedNotification(notificationType) && config.google?.onPriceChangeConfirmed) {
1305
+ const hook = config.google.onPriceChangeConfirmed;
1306
+ void Promise.resolve().then(() => hook({ purchaseToken, subscriptionId, packageName })).catch((err) => log.warn("[onesub/webhook/google] onPriceChangeConfirmed hook failed:", err));
1307
+ }
1308
+ if (existing) {
1309
+ let updated = { ...existing, status: finalStatus };
1310
+ if (config.google?.serviceAccountKey) {
1311
+ const fresh = await validateGoogleReceipt(purchaseToken, subscriptionId, config.google);
1312
+ if (fresh) {
1313
+ const preserveNotificationStatus = finalStatus === SUBSCRIPTION_STATUS.GRACE_PERIOD || finalStatus === SUBSCRIPTION_STATUS.ON_HOLD;
1314
+ updated = {
1315
+ ...existing,
1316
+ status: preserveNotificationStatus ? finalStatus : fresh.status,
1317
+ expiresAt: fresh.expiresAt,
1318
+ willRenew: fresh.willRenew,
1319
+ autoResumeTime: fresh.autoResumeTime,
1320
+ linkedPurchaseToken: fresh.linkedPurchaseToken ?? existing.linkedPurchaseToken
1321
+ };
1354
1322
  }
1355
- await store.save(updated);
1356
- } else {
1357
- if (config.google?.serviceAccountKey) {
1358
- const fresh = await validateGoogleReceipt(purchaseToken, subscriptionId, config.google);
1359
- if (fresh) {
1360
- if (fresh.linkedPurchaseToken) {
1361
- const previous = await store.getByTransactionId(fresh.linkedPurchaseToken);
1362
- if (previous) {
1363
- fresh.userId = previous.userId;
1364
- log.info(
1365
- `[onesub/webhook/google] inherited userId ${previous.userId} from linkedPurchaseToken ${fresh.linkedPurchaseToken} \u2192 new token ${purchaseToken}`
1366
- );
1367
- } else {
1368
- fresh.userId = purchaseToken;
1369
- }
1370
- } else {
1371
- fresh.userId = purchaseToken;
1323
+ }
1324
+ await store.save(updated);
1325
+ } else {
1326
+ if (config.google?.serviceAccountKey) {
1327
+ const fresh = await validateGoogleReceipt(purchaseToken, subscriptionId, config.google);
1328
+ if (fresh) {
1329
+ if (fresh.linkedPurchaseToken) {
1330
+ const previous = await store.getByTransactionId(fresh.linkedPurchaseToken);
1331
+ fresh.userId = previous ? previous.userId : purchaseToken;
1332
+ if (previous) {
1333
+ log.info(`[onesub/webhook/google] inherited userId ${previous.userId} from linkedPurchaseToken ${fresh.linkedPurchaseToken} \u2192 new token ${purchaseToken}`);
1372
1334
  }
1373
- await store.save(fresh);
1335
+ } else {
1336
+ fresh.userId = purchaseToken;
1374
1337
  }
1375
- } else {
1376
- log.warn(
1377
- "[onesub/webhook/google] Unknown purchase token and no serviceAccountKey to re-fetch:",
1378
- purchaseToken
1379
- );
1338
+ await store.save(fresh);
1380
1339
  }
1340
+ } else {
1341
+ log.warn("[onesub/webhook/google] Unknown purchase token and no serviceAccountKey to re-fetch:", purchaseToken);
1381
1342
  }
1382
- res.status(200).json({ received: true });
1383
- } catch (err) {
1384
- log.error("[onesub/webhook/google] Error handling notification:", err);
1385
- sendError(res, 500, ONESUB_ERROR_CODE.WEBHOOK_PROCESSING_FAILED, "Failed to process notification");
1386
1343
  }
1387
- });
1344
+ res.status(200).json({ received: true });
1345
+ } catch (err) {
1346
+ log.error("[onesub/webhook/google] Error handling notification:", err);
1347
+ sendError(res, 500, ONESUB_ERROR_CODE.WEBHOOK_PROCESSING_FAILED, "Failed to process notification");
1348
+ }
1349
+ }
1350
+
1351
+ // src/routes/webhook.ts
1352
+ function createWebhookRouter(config, store, purchaseStore, webhookEventStore) {
1353
+ const router = Router();
1354
+ router.post(
1355
+ ROUTES.WEBHOOK_APPLE,
1356
+ (req, res) => handleAppleWebhook(req, res, config, store, purchaseStore, webhookEventStore)
1357
+ );
1358
+ router.post(
1359
+ ROUTES.WEBHOOK_GOOGLE,
1360
+ (req, res) => handleGoogleWebhook(req, res, config, store, purchaseStore, webhookEventStore)
1361
+ );
1388
1362
  return router;
1389
1363
  }
1390
1364
  var NO_PURCHASE = { valid: false, purchase: null };
@@ -3048,7 +3022,6 @@ function createOneSubServer(config) {
3048
3022
  app.use(createOneSubMiddleware(config));
3049
3023
  return app;
3050
3024
  }
3051
- var index_default = createOneSubMiddleware;
3052
3025
  var isMain = typeof process !== "undefined" && process.argv[1] != null && new URL(import.meta.url).pathname.endsWith(process.argv[1].replace(/\\/g, "/"));
3053
3026
  if (isMain) {
3054
3027
  const config = {
@@ -3074,6 +3047,6 @@ if (isMain) {
3074
3047
  });
3075
3048
  }
3076
3049
 
3077
- export { BullMQWebhookQueue, CacheWebhookEventStore, InMemoryCacheAdapter, InMemoryPurchaseStore, InMemorySubscriptionStore, InMemoryWebhookEventStore, InProcessWebhookQueue, ONESUB_OPENAPI, PostgresPurchaseStore, PostgresSubscriptionStore, RedisCacheAdapter, RedisPurchaseStore, RedisSubscriptionStore, RedisWebhookEventStore, createOneSubMiddleware, createOneSubServer, index_default as default, evaluateEntitlement, fetchAppleSubscriptionStatus, getDefaultCache, log, openapiHandler, setDefaultCache, setLogger, validateAppleReceipt, validateGoogleReceipt, withSpan };
3050
+ export { BullMQWebhookQueue, CacheWebhookEventStore, InMemoryCacheAdapter, InMemoryPurchaseStore, InMemorySubscriptionStore, InMemoryWebhookEventStore, InProcessWebhookQueue, ONESUB_OPENAPI, PostgresPurchaseStore, PostgresSubscriptionStore, RedisCacheAdapter, RedisPurchaseStore, RedisSubscriptionStore, RedisWebhookEventStore, createOneSubMiddleware, createOneSubServer, evaluateEntitlement, fetchAppleSubscriptionStatus, getDefaultCache, log, openapiHandler, setDefaultCache, setLogger, validateAppleReceipt, validateGoogleReceipt, withSpan };
3078
3051
  //# sourceMappingURL=index.js.map
3079
3052
  //# sourceMappingURL=index.js.map