@progus/connector 0.6.1 → 0.6.3

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 { 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 { 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,79 @@ 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 subscriptionPrice = parsePrice(pricingDetails?.price?.amount);
411
+ const subscriptionPeriod = normalizeInterval(pricingDetails?.interval, active?.name);
412
+ if (!subscriptionPeriod || subscriptionPrice === null) return null;
413
+ return {
414
+ subscriptionStatus: active?.status ?? "ACTIVE",
415
+ subscriptionName: active?.name,
416
+ subscriptionId,
417
+ subscriptionPrice,
418
+ subscriptionPeriod
419
+ };
420
+ }
351
421
  // Annotate the CommonJS export names for ESM import in node:
352
422
  0 && (module.exports = {
353
423
  createProgusConnector,
424
+ fetchActiveSubscriptionEventData,
354
425
  fetchAppsCatalog,
355
426
  getCrossSellOffers,
356
427
  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,78 @@ 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 subscriptionPrice = parsePrice(pricingDetails?.price?.amount);
269
+ const subscriptionPeriod = normalizeInterval(pricingDetails?.interval, active?.name);
270
+ if (!subscriptionPeriod || subscriptionPrice === null) return null;
271
+ return {
272
+ subscriptionStatus: active?.status ?? "ACTIVE",
273
+ subscriptionName: active?.name,
274
+ subscriptionId,
275
+ subscriptionPrice,
276
+ subscriptionPeriod
277
+ };
278
+ }
210
279
  export {
211
280
  createProgusConnector,
281
+ fetchActiveSubscriptionEventData,
212
282
  fetchAppsCatalog,
213
283
  getCrossSellOffers,
214
284
  getCrossSellOffersFromApi,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progus/connector",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Progus partner/affiliate connector helpers",
5
5
  "license": "MIT",
6
6
  "type": "module",