@sudobility/subscription_service 1.0.11 → 1.0.12

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.
@@ -5,13 +5,13 @@
5
5
  * to fetch user entitlements and subscription information. Handles sandbox
6
6
  * filtering via the `testMode` parameter.
7
7
  */
8
- import type { SubscriptionInfo } from "../types/subscription";
8
+ import type { RevenueCatApiKeys, SubscriptionInfo } from "../types/subscription";
9
9
  /**
10
10
  * Configuration for SubscriptionHelper.
11
11
  */
12
12
  export interface SubscriptionHelperConfig {
13
- /** RevenueCat secret API key (for server-side use) */
14
- revenueCatApiKey: string;
13
+ /** RevenueCat secret API keys per platform */
14
+ revenueCatApiKeys: RevenueCatApiKeys;
15
15
  /** Base URL for RevenueCat API. Defaults to https://api.revenuecat.com/v1 */
16
16
  baseUrl?: string;
17
17
  /** Request timeout in milliseconds. Defaults to 10000 (10 seconds). */
@@ -23,15 +23,16 @@ export interface SubscriptionHelperConfig {
23
23
  *
24
24
  * Uses the RevenueCat REST API v1 endpoint `GET /subscribers/{user_id}` to
25
25
  * fetch subscriber data, then filters entitlements by expiration and sandbox status.
26
+ * Queries each configured platform API key and merges the results.
26
27
  */
27
28
  export declare class SubscriptionHelper {
28
- private readonly apiKey;
29
+ private readonly apiKeys;
29
30
  private readonly baseUrl;
30
31
  private readonly timeoutMs;
31
32
  /**
32
33
  * Creates a new SubscriptionHelper instance.
33
34
  *
34
- * @param config - Configuration containing the RevenueCat API key and optional base URL.
35
+ * @param config - Configuration containing the RevenueCat API keys and optional base URL.
35
36
  */
36
37
  constructor(config: SubscriptionHelperConfig);
37
38
  /**
@@ -46,17 +47,28 @@ export declare class SubscriptionHelper {
46
47
  */
47
48
  getEntitlements(userId: string, testMode?: boolean): Promise<string[]>;
48
49
  /**
49
- * Get full subscription info including entitlements and subscription start date.
50
+ * Get full subscription info including entitlements, subscription start date,
51
+ * and platform.
50
52
  *
51
- * Fetches the subscriber data from RevenueCat, filters out expired entitlements
53
+ * Queries each configured platform API key, filters out expired entitlements
52
54
  * and (optionally) sandbox purchases, and returns the active entitlement names
53
- * along with the earliest purchase date.
55
+ * along with the earliest purchase date and the platform it came from.
54
56
  *
55
57
  * @param userId - The RevenueCat user identifier.
56
58
  * @param testMode - When true, includes sandbox purchases. Defaults to false.
57
- * @returns Subscription info with active entitlements and earliest purchase date.
59
+ * @returns Subscription info with active entitlements, earliest purchase date, and platform.
58
60
  * @throws Error if the RevenueCat API returns a non-404, non-OK response.
59
61
  */
60
62
  getSubscriptionInfo(userId: string, testMode?: boolean): Promise<SubscriptionInfo>;
63
+ /**
64
+ * Fetch subscriber info from RevenueCat for a single API key.
65
+ *
66
+ * For web/webSandbox keys, sandbox filtering is handled by key selection
67
+ * in getSubscriptionInfo. For ios/android/macos keys, sandbox filtering
68
+ * is done by checking the subscription's `environment` field.
69
+ *
70
+ * @returns Active entitlement names and earliest purchase date for this key.
71
+ */
72
+ private fetchSubscriberInfo;
61
73
  }
62
74
  //# sourceMappingURL=SubscriptionHelper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionHelper.d.ts","sourceRoot":"","sources":["../../src/helpers/SubscriptionHelper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC;;;;OAIG;gBACS,MAAM,EAAE,wBAAwB;IAM5C;;;;;;;;;OASG;IACG,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB;;;;;;;;;;;OAWG;IACG,mBAAmB,CACvB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,gBAAgB,CAAC;CA6E7B"}
1
+ {"version":3,"file":"SubscriptionHelper.d.ts","sourceRoot":"","sources":["../../src/helpers/SubscriptionHelper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,8CAA8C;IAC9C,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC;;;;OAIG;gBACS,MAAM,EAAE,wBAAwB;IAM5C;;;;;;;;;OASG;IACG,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC;IASpB;;;;;;;;;;;;OAYG;IACG,mBAAmB,CACvB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAsD5B;;;;;;;;OAQG;YACW,mBAAmB;CAsElC"}
@@ -5,22 +5,31 @@
5
5
  * to fetch user entitlements and subscription information. Handles sandbox
6
6
  * filtering via the `testMode` parameter.
7
7
  */
8
- import { NONE_ENTITLEMENT } from "@sudobility/types";
8
+ import { NONE_ENTITLEMENT, SubscriptionPlatform } from "@sudobility/types";
9
+ /** Maps RevenueCatApiKeys fields to SubscriptionPlatform values. */
10
+ const API_KEY_PLATFORM_MAP = [
11
+ { key: "web", platform: SubscriptionPlatform.Web },
12
+ { key: "webSandbox", platform: SubscriptionPlatform.Web },
13
+ { key: "ios", platform: SubscriptionPlatform.iOS },
14
+ { key: "android", platform: SubscriptionPlatform.Android },
15
+ { key: "macos", platform: SubscriptionPlatform.macOS },
16
+ ];
9
17
  /**
10
18
  * Helper class for interacting with RevenueCat API to get user entitlements
11
19
  * and subscription information.
12
20
  *
13
21
  * Uses the RevenueCat REST API v1 endpoint `GET /subscribers/{user_id}` to
14
22
  * fetch subscriber data, then filters entitlements by expiration and sandbox status.
23
+ * Queries each configured platform API key and merges the results.
15
24
  */
16
25
  export class SubscriptionHelper {
17
26
  /**
18
27
  * Creates a new SubscriptionHelper instance.
19
28
  *
20
- * @param config - Configuration containing the RevenueCat API key and optional base URL.
29
+ * @param config - Configuration containing the RevenueCat API keys and optional base URL.
21
30
  */
22
31
  constructor(config) {
23
- this.apiKey = config.revenueCatApiKey;
32
+ this.apiKeys = config.revenueCatApiKeys;
24
33
  this.baseUrl = config.baseUrl ?? "https://api.revenuecat.com/v1";
25
34
  this.timeoutMs = config.timeoutMs ?? 10000;
26
35
  }
@@ -42,21 +51,71 @@ export class SubscriptionHelper {
42
51
  return info.entitlements;
43
52
  }
44
53
  /**
45
- * Get full subscription info including entitlements and subscription start date.
54
+ * Get full subscription info including entitlements, subscription start date,
55
+ * and platform.
46
56
  *
47
- * Fetches the subscriber data from RevenueCat, filters out expired entitlements
57
+ * Queries each configured platform API key, filters out expired entitlements
48
58
  * and (optionally) sandbox purchases, and returns the active entitlement names
49
- * along with the earliest purchase date.
59
+ * along with the earliest purchase date and the platform it came from.
50
60
  *
51
61
  * @param userId - The RevenueCat user identifier.
52
62
  * @param testMode - When true, includes sandbox purchases. Defaults to false.
53
- * @returns Subscription info with active entitlements and earliest purchase date.
63
+ * @returns Subscription info with active entitlements, earliest purchase date, and platform.
54
64
  * @throws Error if the RevenueCat API returns a non-404, non-OK response.
55
65
  */
56
66
  async getSubscriptionInfo(userId, testMode = false) {
57
67
  if (!userId || typeof userId !== "string") {
58
68
  throw new Error("userId must be a non-empty string");
59
69
  }
70
+ const allEntitlements = [];
71
+ let earliestPurchaseDate = null;
72
+ let resultPlatform = null;
73
+ for (const { key, platform } of API_KEY_PLATFORM_MAP) {
74
+ const apiKey = this.apiKeys[key];
75
+ if (!apiKey)
76
+ continue;
77
+ // In production mode, skip webSandbox key
78
+ if (!testMode && key === "webSandbox")
79
+ continue;
80
+ // In test mode, skip web key (use webSandbox instead)
81
+ if (testMode && key === "web" && this.apiKeys.webSandbox)
82
+ continue;
83
+ const result = await this.fetchSubscriberInfo(userId, apiKey, key, testMode);
84
+ for (const name of result.entitlements) {
85
+ if (!allEntitlements.includes(name)) {
86
+ allEntitlements.push(name);
87
+ }
88
+ }
89
+ if (result.purchaseDate) {
90
+ if (!earliestPurchaseDate || result.purchaseDate < earliestPurchaseDate) {
91
+ earliestPurchaseDate = result.purchaseDate;
92
+ resultPlatform = platform;
93
+ }
94
+ }
95
+ }
96
+ if (allEntitlements.length === 0) {
97
+ return {
98
+ entitlements: [NONE_ENTITLEMENT],
99
+ subscriptionStartedAt: null,
100
+ platform: null,
101
+ };
102
+ }
103
+ return {
104
+ entitlements: allEntitlements,
105
+ subscriptionStartedAt: earliestPurchaseDate,
106
+ platform: resultPlatform,
107
+ };
108
+ }
109
+ /**
110
+ * Fetch subscriber info from RevenueCat for a single API key.
111
+ *
112
+ * For web/webSandbox keys, sandbox filtering is handled by key selection
113
+ * in getSubscriptionInfo. For ios/android/macos keys, sandbox filtering
114
+ * is done by checking the subscription's `environment` field.
115
+ *
116
+ * @returns Active entitlement names and earliest purchase date for this key.
117
+ */
118
+ async fetchSubscriberInfo(userId, apiKey, keyName, testMode) {
60
119
  const url = `${this.baseUrl}/subscribers/${encodeURIComponent(userId)}`;
61
120
  const controller = new AbortController();
62
121
  const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
@@ -65,7 +124,7 @@ export class SubscriptionHelper {
65
124
  response = await fetch(url, {
66
125
  method: "GET",
67
126
  headers: {
68
- Authorization: `Bearer ${this.apiKey}`,
127
+ Authorization: `Bearer ${apiKey}`,
69
128
  "Content-Type": "application/json",
70
129
  },
71
130
  signal: controller.signal,
@@ -75,10 +134,7 @@ export class SubscriptionHelper {
75
134
  clearTimeout(timeoutId);
76
135
  }
77
136
  if (response.status === 404) {
78
- return {
79
- entitlements: [NONE_ENTITLEMENT],
80
- subscriptionStartedAt: null,
81
- };
137
+ return { entitlements: [], purchaseDate: null };
82
138
  }
83
139
  if (!response.ok) {
84
140
  throw new Error(`RevenueCat API error: ${response.status} ${response.statusText}`);
@@ -89,13 +145,15 @@ export class SubscriptionHelper {
89
145
  const now = new Date();
90
146
  const activeEntitlements = [];
91
147
  let earliestPurchaseDate = null;
148
+ // For ios/android/macos, filter by environment field
149
+ const checkEnvironment = keyName === "ios" || keyName === "android" || keyName === "macos";
92
150
  for (const [name, entitlement] of Object.entries(entitlements)) {
93
151
  const isActive = !entitlement.expires_date || new Date(entitlement.expires_date) > now;
94
152
  if (!isActive) {
95
153
  continue;
96
154
  }
97
155
  const subscription = subscriptions[entitlement.product_identifier];
98
- if (!testMode && subscription?.sandbox === true) {
156
+ if (checkEnvironment && !testMode && subscription?.environment === "sandbox") {
99
157
  continue;
100
158
  }
101
159
  activeEntitlements.push(name);
@@ -104,16 +162,7 @@ export class SubscriptionHelper {
104
162
  earliestPurchaseDate = purchaseDate;
105
163
  }
106
164
  }
107
- if (activeEntitlements.length === 0) {
108
- return {
109
- entitlements: [NONE_ENTITLEMENT],
110
- subscriptionStartedAt: null,
111
- };
112
- }
113
- return {
114
- entitlements: activeEntitlements,
115
- subscriptionStartedAt: earliestPurchaseDate,
116
- };
165
+ return { entitlements: activeEntitlements, purchaseDate: earliestPurchaseDate };
117
166
  }
118
167
  }
119
168
  //# sourceMappingURL=SubscriptionHelper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionHelper.js","sourceRoot":"","sources":["../../src/helpers/SubscriptionHelper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubscriptionHelper.js","sourceRoot":"","sources":["../../src/helpers/SubscriptionHelper.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Re-exports all types and the SubscriptionHelper class for server-side
5
5
  * subscription management via RevenueCat.
6
6
  */
7
- export { type RevenueCatEntitlement, type RevenueCatSubscription, type RevenueCatSubscriberResponse, type SubscriptionInfo, } from "./types";
7
+ export { type RevenueCatApiKeys, type RevenueCatEntitlement, type RevenueCatSubscription, type RevenueCatSubscriberResponse, type SubscriptionInfo, } from "./types";
8
8
  export { NONE_ENTITLEMENT } from "@sudobility/types";
9
9
  export { SubscriptionHelper, type SubscriptionHelperConfig, } from "./helpers";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,GACtB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EACL,kBAAkB,EAClB,KAAK,wBAAwB,GAC9B,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,GACtB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EACL,kBAAkB,EAClB,KAAK,wBAAwB,GAC9B,MAAM,WAAW,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,oCAAoC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,UAAU;AACV,OAAO,EACL,kBAAkB,GAEnB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,oCAAoC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,UAAU;AACV,OAAO,EACL,kBAAkB,GAEnB,MAAM,WAAW,CAAC"}
@@ -29,6 +29,8 @@ export interface RevenueCatSubscription {
29
29
  sandbox: boolean;
30
30
  /** Store where the purchase was made */
31
31
  store: string;
32
+ /** Environment: "sandbox" or "production" (present on iOS/Android/macOS subscriptions) */
33
+ environment?: string;
32
34
  }
33
35
  /**
34
36
  * Response shape from RevenueCat's GET /subscribers/{user_id} endpoint.
@@ -1 +1 @@
1
- {"version":3,"file":"entitlements.d.ts","sourceRoot":"","sources":["../../src/types/entitlements.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mCAAmC;IACnC,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE;QACV,YAAY,EAAE;YACZ,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAAC;SACtC,CAAC;QACF,aAAa,EAAE;YACb,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,CAAC;SACvC,CAAC;KACH,CAAC;CACH"}
1
+ {"version":3,"file":"entitlements.d.ts","sourceRoot":"","sources":["../../src/types/entitlements.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mCAAmC;IACnC,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE;QACV,YAAY,EAAE;YACZ,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAAC;SACtC,CAAC;QACF,aAAa,EAAE;YACb,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,CAAC;SACvC,CAAC;KACH,CAAC;CACH"}
@@ -2,5 +2,5 @@
2
2
  * @fileoverview Type re-exports for subscription_service.
3
3
  */
4
4
  export { type RevenueCatEntitlement, type RevenueCatSubscription, type RevenueCatSubscriberResponse, } from "./entitlements";
5
- export { type SubscriptionInfo } from "./subscription";
5
+ export { type RevenueCatApiKeys, type SubscriptionInfo } from "./subscription";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,GAClC,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,GAClC,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,6 +1,23 @@
1
1
  /**
2
2
  * @fileoverview Domain types for subscription information returned by SubscriptionHelper.
3
3
  */
4
+ import { SubscriptionPlatform } from "@sudobility/types";
5
+ /**
6
+ * RevenueCat API keys per platform. All fields are optional —
7
+ * only platforms the app supports need to be provided.
8
+ */
9
+ export interface RevenueCatApiKeys {
10
+ /** RevenueCat secret API key for web (Stripe) */
11
+ web?: string;
12
+ /** RevenueCat secret API key for web sandbox */
13
+ webSandbox?: string;
14
+ /** RevenueCat secret API key for iOS (App Store) */
15
+ ios?: string;
16
+ /** RevenueCat secret API key for Android (Play Store) */
17
+ android?: string;
18
+ /** RevenueCat secret API key for macOS (Mac App Store) */
19
+ macos?: string;
20
+ }
4
21
  /**
5
22
  * Subscription information returned by SubscriptionHelper.
6
23
  */
@@ -9,5 +26,7 @@ export interface SubscriptionInfo {
9
26
  entitlements: string[];
10
27
  /** When the subscription started (earliest purchase date), or null if no subscription */
11
28
  subscriptionStartedAt: Date | null;
29
+ /** Platform where the subscription was purchased, or null if no subscription */
30
+ platform: SubscriptionPlatform | null;
12
31
  }
13
32
  //# sourceMappingURL=subscription.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/types/subscription.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yFAAyF;IACzF,qBAAqB,EAAE,IAAI,GAAG,IAAI,CAAC;CACpC"}
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/types/subscription.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yFAAyF;IACzF,qBAAqB,EAAE,IAAI,GAAG,IAAI,CAAC;IACnC,gFAAgF;IAChF,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACvC"}
package/package.json CHANGED
@@ -1,16 +1,41 @@
1
1
  {
2
2
  "name": "@sudobility/subscription_service",
3
- "version": "1.0.11",
4
- "description": "Shared subscription management library using RevenueCat for entitlements",
5
- "type": "module",
3
+ "version": "1.0.12",
4
+ "author": "Sudobility",
6
5
  "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
6
+ "devDependencies": {
7
+ "@sudobility/types": "^1.9.59",
8
+ "@types/bun": "latest",
9
+ "@types/node": "^24.0.0",
10
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
11
+ "@typescript-eslint/parser": "^8.50.0",
12
+ "eslint": "^9.39.0",
13
+ "eslint-plugin-import": "^2.32.0",
14
+ "prettier": "^3.7.0",
15
+ "typescript": "^5.9.0",
16
+ "vitest": "^4.0.4"
17
+ },
8
18
  "exports": {
9
19
  ".": {
10
20
  "import": "./dist/index.js",
11
21
  "types": "./dist/index.d.ts"
12
22
  }
13
23
  },
24
+ "description": "Shared subscription management library using RevenueCat for entitlements",
25
+ "files": [
26
+ "dist/**/*",
27
+ "CLAUDE.md"
28
+ ],
29
+ "keywords": [
30
+ "subscription",
31
+ "revenuecat",
32
+ "entitlements",
33
+ "in-app-purchase"
34
+ ],
35
+ "license": "BUSL-1.1",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
14
39
  "scripts": {
15
40
  "build": "tsc -p tsconfig.esm.json",
16
41
  "clean": "rm -rf dist",
@@ -25,33 +50,6 @@
25
50
  "verify": "bun run typecheck && bun run lint && bun run test && bun run build",
26
51
  "prepublishOnly": "bun run clean && bun run verify"
27
52
  },
28
- "files": [
29
- "dist/**/*",
30
- "CLAUDE.md"
31
- ],
32
- "keywords": [
33
- "subscription",
34
- "revenuecat",
35
- "entitlements",
36
- "in-app-purchase"
37
- ],
38
- "author": "Sudobility",
39
- "license": "BUSL-1.1",
40
- "peerDependencies": {
41
- "@sudobility/types": "^1.9.59"
42
- },
43
- "devDependencies": {
44
- "vitest": "^4.0.4",
45
- "@types/bun": "latest",
46
- "@types/node": "^24.0.0",
47
- "@typescript-eslint/eslint-plugin": "^8.50.0",
48
- "@typescript-eslint/parser": "^8.50.0",
49
- "eslint": "^9.39.0",
50
- "eslint-plugin-import": "^2.32.0",
51
- "prettier": "^3.7.0",
52
- "typescript": "^5.9.0"
53
- },
54
- "publishConfig": {
55
- "access": "public"
56
- }
53
+ "type": "module",
54
+ "types": "./dist/index.d.ts"
57
55
  }