@progus/connector 0.6.2 → 0.6.4

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.
@@ -4,6 +4,13 @@ type Logger = {
4
4
  error?: (message: string, meta?: Record<string, unknown>) => void;
5
5
  };
6
6
  type FetchLike = typeof fetch;
7
+ type ShopifyAdminGraphQLClient = {
8
+ graphql: (query: string, options?: {
9
+ variables?: Record<string, unknown>;
10
+ }) => Promise<{
11
+ json: () => Promise<unknown>;
12
+ }>;
13
+ };
7
14
  type ConnectorConfig = {
8
15
  appKey: string;
9
16
  apiBaseUrl: string;
@@ -75,4 +82,4 @@ declare function getCrossSellOffers(options?: CrossSellOptions): AppsCatalogEntr
75
82
  declare function fetchAppsCatalog(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
76
83
  declare function getCrossSellOffersFromApi(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
77
84
 
78
- export { type AssignPartnerIdInput as A, type ConnectorConfig as C, type Logger as L, type SubscriptionEventData as S, type TrackEventParams as T, type TrackResult as a, type CheckPartnerIdResult as b, getCrossSellOffersFromApi as c, type AppsCatalogEntry as d, type CrossSellFetchOptions as e, fetchAppsCatalog as f, getCrossSellOffers as g, type CrossSellOptions as h, type TrackEventName as i };
85
+ export { type AssignPartnerIdInput as A, type ConnectorConfig as C, type Logger as L, type SubscriptionEventData as S, type TrackEventParams as T, type TrackResult as a, type CheckPartnerIdResult as b, type ShopifyAdminGraphQLClient as c, getCrossSellOffersFromApi as d, type AppsCatalogEntry as e, fetchAppsCatalog as f, getCrossSellOffers as g, type CrossSellFetchOptions as h, type CrossSellOptions as i, type TrackEventName as j };
@@ -4,6 +4,13 @@ type Logger = {
4
4
  error?: (message: string, meta?: Record<string, unknown>) => void;
5
5
  };
6
6
  type FetchLike = typeof fetch;
7
+ type ShopifyAdminGraphQLClient = {
8
+ graphql: (query: string, options?: {
9
+ variables?: Record<string, unknown>;
10
+ }) => Promise<{
11
+ json: () => Promise<unknown>;
12
+ }>;
13
+ };
7
14
  type ConnectorConfig = {
8
15
  appKey: string;
9
16
  apiBaseUrl: string;
@@ -75,4 +82,4 @@ declare function getCrossSellOffers(options?: CrossSellOptions): AppsCatalogEntr
75
82
  declare function fetchAppsCatalog(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
76
83
  declare function getCrossSellOffersFromApi(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
77
84
 
78
- export { type AssignPartnerIdInput as A, type ConnectorConfig as C, type Logger as L, type SubscriptionEventData as S, type TrackEventParams as T, type TrackResult as a, type CheckPartnerIdResult as b, getCrossSellOffersFromApi as c, type AppsCatalogEntry as d, type CrossSellFetchOptions as e, fetchAppsCatalog as f, getCrossSellOffers as g, type CrossSellOptions as h, type TrackEventName as i };
85
+ export { type AssignPartnerIdInput as A, type ConnectorConfig as C, type Logger as L, type SubscriptionEventData as S, type TrackEventParams as T, type TrackResult as a, type CheckPartnerIdResult as b, type ShopifyAdminGraphQLClient as c, getCrossSellOffersFromApi as d, type AppsCatalogEntry as e, fetchAppsCatalog as f, getCrossSellOffers as g, type CrossSellFetchOptions as h, type CrossSellOptions as i, type TrackEventName as j };
@@ -1 +1 @@
1
- export { d as AppsCatalogEntry, e as CrossSellFetchOptions, h as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, c as getCrossSellOffersFromApi } from './crossSell-BFz9e72n.cjs';
1
+ export { e as AppsCatalogEntry, h as CrossSellFetchOptions, i as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, d as getCrossSellOffersFromApi } from './crossSell-Bs_6xA6f.cjs';
@@ -1 +1 @@
1
- export { d as AppsCatalogEntry, e as CrossSellFetchOptions, h as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, c as getCrossSellOffersFromApi } from './crossSell-BFz9e72n.js';
1
+ export { e as AppsCatalogEntry, h as CrossSellFetchOptions, i as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, d as getCrossSellOffersFromApi } from './crossSell-Bs_6xA6f.js';
package/dist/index.cjs CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  createProgusConnector: () => createProgusConnector,
24
+ fetchActiveSubscriptionEventData: () => fetchActiveSubscriptionEventData,
24
25
  fetchAppsCatalog: () => fetchAppsCatalog,
25
26
  getCrossSellOffers: () => getCrossSellOffers,
26
27
  getCrossSellOffersFromApi: () => getCrossSellOffersFromApi,
@@ -348,9 +349,80 @@ async function getCrossSellOffersFromApi(options = {}) {
348
349
  const appsCatalog = options.appsCatalog ?? await fetchAppsCatalog(options);
349
350
  return getCrossSellOffers({ ...options, appsCatalog });
350
351
  }
352
+
353
+ // src/subscription.ts
354
+ var ACTIVE_SUBSCRIPTIONS_QUERY = `
355
+ query {
356
+ currentAppInstallation {
357
+ activeSubscriptions {
358
+ id
359
+ name
360
+ status
361
+ lineItems {
362
+ plan {
363
+ pricingDetails {
364
+ __typename
365
+ ... on AppRecurringPricing {
366
+ interval
367
+ price {
368
+ amount
369
+ }
370
+ }
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
377
+ `;
378
+ function normalizeInterval(intervalRaw, nameHint) {
379
+ const interval = intervalRaw ? String(intervalRaw).toUpperCase() : "";
380
+ if (interval === "ANNUAL" || interval === "EVERY_30_DAYS") return interval;
381
+ if (interval === "MONTHLY" || interval === "EVERY_30DAYS") return "EVERY_30_DAYS";
382
+ const name = (nameHint ?? "").toLowerCase();
383
+ if (name.includes("annual") || name.includes("year")) return "ANNUAL";
384
+ if (name) return "EVERY_30_DAYS";
385
+ return "";
386
+ }
387
+ function parseSubscriptionId(rawId) {
388
+ if (!rawId) return null;
389
+ return rawId.match(/\d+$/)?.[0] ?? rawId.split("/").pop() ?? rawId;
390
+ }
391
+ function parsePrice(rawPrice) {
392
+ if (typeof rawPrice === "number") return rawPrice;
393
+ if (typeof rawPrice === "string") {
394
+ const parsed = Number(rawPrice);
395
+ return Number.isFinite(parsed) ? parsed : null;
396
+ }
397
+ return null;
398
+ }
399
+ async function fetchActiveSubscriptionEventData(admin, logger = console) {
400
+ const response = await admin.graphql(ACTIVE_SUBSCRIPTIONS_QUERY);
401
+ const result = await response.json();
402
+ if (result.errors?.length) {
403
+ logger.error?.("Partner subscription query errors", { errors: result.errors });
404
+ }
405
+ const subscriptions = result.data?.currentAppInstallation?.activeSubscriptions ?? [];
406
+ const active = subscriptions.find((sub) => String(sub.status ?? "").toUpperCase() === "ACTIVE") ?? subscriptions[0];
407
+ const subscriptionId = parseSubscriptionId(active?.id);
408
+ if (!subscriptionId) return null;
409
+ const pricingDetails = active?.lineItems?.[0]?.plan?.pricingDetails;
410
+ const rawPrice = pricingDetails?.price?.amount ?? pricingDetails?.cappedAmount?.amount;
411
+ const subscriptionPrice = parsePrice(rawPrice);
412
+ const subscriptionPeriod = normalizeInterval(pricingDetails?.interval, active?.name);
413
+ if (!subscriptionPeriod || subscriptionPrice === null) return null;
414
+ return {
415
+ subscriptionStatus: active?.status ?? "ACTIVE",
416
+ subscriptionName: active?.name,
417
+ subscriptionId,
418
+ subscriptionPrice,
419
+ subscriptionPeriod
420
+ };
421
+ }
351
422
  // Annotate the CommonJS export names for ESM import in node:
352
423
  0 && (module.exports = {
353
424
  createProgusConnector,
425
+ fetchActiveSubscriptionEventData,
354
426
  fetchAppsCatalog,
355
427
  getCrossSellOffers,
356
428
  getCrossSellOffersFromApi,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, A as AssignPartnerIdInput, b as CheckPartnerIdResult } from './crossSell-BFz9e72n.cjs';
2
- export { d as AppsCatalogEntry, e as CrossSellFetchOptions, h as CrossSellOptions, L as Logger, i as TrackEventName, f as fetchAppsCatalog, g as getCrossSellOffers, c as getCrossSellOffersFromApi } from './crossSell-BFz9e72n.cjs';
1
+ import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, A as AssignPartnerIdInput, b as CheckPartnerIdResult, c as ShopifyAdminGraphQLClient } from './crossSell-Bs_6xA6f.cjs';
2
+ export { e as AppsCatalogEntry, h as CrossSellFetchOptions, i as CrossSellOptions, L as Logger, j as TrackEventName, f as fetchAppsCatalog, g as getCrossSellOffers, d as getCrossSellOffersFromApi } from './crossSell-Bs_6xA6f.cjs';
3
3
 
4
4
  type Connector = {
5
5
  track: (eventName: TrackEventParams["eventName"], payload: Omit<TrackEventParams, "eventName">) => Promise<TrackResult>;
@@ -31,8 +31,12 @@ type Connector = {
31
31
  };
32
32
  declare function createProgusConnector(config: ConnectorConfig): Connector;
33
33
 
34
+ declare function fetchActiveSubscriptionEventData(admin: ShopifyAdminGraphQLClient, logger?: {
35
+ error?: (message: string, meta?: Record<string, unknown>) => void;
36
+ }): Promise<SubscriptionEventData | null>;
37
+
34
38
  declare function signPayload(body: string, secret: string): string;
35
39
 
36
40
  declare function normalizePartnerId(value?: string | null): string | null;
37
41
 
38
- export { AssignPartnerIdInput, CheckPartnerIdResult, ConnectorConfig, SubscriptionEventData, TrackEventParams, TrackResult, createProgusConnector, normalizePartnerId, signPayload };
42
+ export { AssignPartnerIdInput, CheckPartnerIdResult, ConnectorConfig, ShopifyAdminGraphQLClient, SubscriptionEventData, TrackEventParams, TrackResult, createProgusConnector, fetchActiveSubscriptionEventData, normalizePartnerId, signPayload };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, A as AssignPartnerIdInput, b as CheckPartnerIdResult } from './crossSell-BFz9e72n.js';
2
- export { d as AppsCatalogEntry, e as CrossSellFetchOptions, h as CrossSellOptions, L as Logger, i as TrackEventName, f as fetchAppsCatalog, g as getCrossSellOffers, c as getCrossSellOffersFromApi } from './crossSell-BFz9e72n.js';
1
+ import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, A as AssignPartnerIdInput, b as CheckPartnerIdResult, c as ShopifyAdminGraphQLClient } from './crossSell-Bs_6xA6f.js';
2
+ export { e as AppsCatalogEntry, h as CrossSellFetchOptions, i as CrossSellOptions, L as Logger, j as TrackEventName, f as fetchAppsCatalog, g as getCrossSellOffers, d as getCrossSellOffersFromApi } from './crossSell-Bs_6xA6f.js';
3
3
 
4
4
  type Connector = {
5
5
  track: (eventName: TrackEventParams["eventName"], payload: Omit<TrackEventParams, "eventName">) => Promise<TrackResult>;
@@ -31,8 +31,12 @@ type Connector = {
31
31
  };
32
32
  declare function createProgusConnector(config: ConnectorConfig): Connector;
33
33
 
34
+ declare function fetchActiveSubscriptionEventData(admin: ShopifyAdminGraphQLClient, logger?: {
35
+ error?: (message: string, meta?: Record<string, unknown>) => void;
36
+ }): Promise<SubscriptionEventData | null>;
37
+
34
38
  declare function signPayload(body: string, secret: string): string;
35
39
 
36
40
  declare function normalizePartnerId(value?: string | null): string | null;
37
41
 
38
- export { AssignPartnerIdInput, CheckPartnerIdResult, ConnectorConfig, SubscriptionEventData, TrackEventParams, TrackResult, createProgusConnector, normalizePartnerId, signPayload };
42
+ export { AssignPartnerIdInput, CheckPartnerIdResult, ConnectorConfig, ShopifyAdminGraphQLClient, SubscriptionEventData, TrackEventParams, TrackResult, createProgusConnector, fetchActiveSubscriptionEventData, normalizePartnerId, signPayload };
package/dist/index.js CHANGED
@@ -207,8 +207,79 @@ function createProgusConnector(config) {
207
207
  checkPartnerId
208
208
  };
209
209
  }
210
+
211
+ // src/subscription.ts
212
+ var ACTIVE_SUBSCRIPTIONS_QUERY = `
213
+ query {
214
+ currentAppInstallation {
215
+ activeSubscriptions {
216
+ id
217
+ name
218
+ status
219
+ lineItems {
220
+ plan {
221
+ pricingDetails {
222
+ __typename
223
+ ... on AppRecurringPricing {
224
+ interval
225
+ price {
226
+ amount
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+ }
235
+ `;
236
+ function normalizeInterval(intervalRaw, nameHint) {
237
+ const interval = intervalRaw ? String(intervalRaw).toUpperCase() : "";
238
+ if (interval === "ANNUAL" || interval === "EVERY_30_DAYS") return interval;
239
+ if (interval === "MONTHLY" || interval === "EVERY_30DAYS") return "EVERY_30_DAYS";
240
+ const name = (nameHint ?? "").toLowerCase();
241
+ if (name.includes("annual") || name.includes("year")) return "ANNUAL";
242
+ if (name) return "EVERY_30_DAYS";
243
+ return "";
244
+ }
245
+ function parseSubscriptionId(rawId) {
246
+ if (!rawId) return null;
247
+ return rawId.match(/\d+$/)?.[0] ?? rawId.split("/").pop() ?? rawId;
248
+ }
249
+ function parsePrice(rawPrice) {
250
+ if (typeof rawPrice === "number") return rawPrice;
251
+ if (typeof rawPrice === "string") {
252
+ const parsed = Number(rawPrice);
253
+ return Number.isFinite(parsed) ? parsed : null;
254
+ }
255
+ return null;
256
+ }
257
+ async function fetchActiveSubscriptionEventData(admin, logger = console) {
258
+ const response = await admin.graphql(ACTIVE_SUBSCRIPTIONS_QUERY);
259
+ const result = await response.json();
260
+ if (result.errors?.length) {
261
+ logger.error?.("Partner subscription query errors", { errors: result.errors });
262
+ }
263
+ const subscriptions = result.data?.currentAppInstallation?.activeSubscriptions ?? [];
264
+ const active = subscriptions.find((sub) => String(sub.status ?? "").toUpperCase() === "ACTIVE") ?? subscriptions[0];
265
+ const subscriptionId = parseSubscriptionId(active?.id);
266
+ if (!subscriptionId) return null;
267
+ const pricingDetails = active?.lineItems?.[0]?.plan?.pricingDetails;
268
+ const rawPrice = pricingDetails?.price?.amount ?? pricingDetails?.cappedAmount?.amount;
269
+ const subscriptionPrice = parsePrice(rawPrice);
270
+ const subscriptionPeriod = normalizeInterval(pricingDetails?.interval, active?.name);
271
+ if (!subscriptionPeriod || subscriptionPrice === null) return null;
272
+ return {
273
+ subscriptionStatus: active?.status ?? "ACTIVE",
274
+ subscriptionName: active?.name,
275
+ subscriptionId,
276
+ subscriptionPrice,
277
+ subscriptionPeriod
278
+ };
279
+ }
210
280
  export {
211
281
  createProgusConnector,
282
+ fetchActiveSubscriptionEventData,
212
283
  fetchAppsCatalog,
213
284
  getCrossSellOffers,
214
285
  getCrossSellOffersFromApi,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progus/connector",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "Progus partner/affiliate connector helpers",
5
5
  "license": "MIT",
6
6
  "type": "module",