@progus/connector 0.7.0 → 0.7.2

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.
@@ -20,6 +20,25 @@ function safeJsonParse(text) {
20
20
  }
21
21
 
22
22
  // src/crossSell.ts
23
+ function appendUtmSource(url, utmSource) {
24
+ const source = utmSource?.trim();
25
+ if (!source) return url;
26
+ try {
27
+ const parsed = new URL(url);
28
+ if (!parsed.searchParams.has("utm_source")) {
29
+ parsed.searchParams.set("utm_source", source);
30
+ }
31
+ return parsed.toString();
32
+ } catch {
33
+ return url;
34
+ }
35
+ }
36
+ function withSourceTracking(apps, utmSource) {
37
+ return apps.map((app) => ({
38
+ ...app,
39
+ url: appendUtmSource(app.url, utmSource)
40
+ }));
41
+ }
23
42
  function getCrossSellOffers(options = {}) {
24
43
  const appsCatalog = options.appsCatalog ?? [];
25
44
  const installedKeys = new Set(
@@ -79,7 +98,7 @@ function buildFallbackCatalog(options) {
79
98
  if (limit > 0) {
80
99
  items = items.slice(0, limit);
81
100
  }
82
- return items;
101
+ return withSourceTracking(items, appName);
83
102
  }
84
103
  async function fetchAppsCatalog(options = {}) {
85
104
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -105,7 +124,7 @@ async function fetchAppsCatalog(options = {}) {
105
124
  logger?.error?.("Failed to fetch apps catalog", { status: response.status });
106
125
  return buildFallbackCatalog(options);
107
126
  }
108
- return parsed;
127
+ return withSourceTracking(parsed, appName);
109
128
  } catch (error) {
110
129
  logger?.error?.("Failed to fetch apps catalog", {
111
130
  error: error instanceof Error ? error.message : String(error)
@@ -20,13 +20,20 @@ type ConnectorConfig = {
20
20
  logger?: Logger;
21
21
  enableIdempotency?: boolean;
22
22
  };
23
- type TrackEventName = "installation" | "uninstallation" | "subscription";
23
+ type TrackEventName = "installation" | "uninstallation" | "subscription" | "transaction";
24
+ type TransactionEventData = {
25
+ transactionId: string;
26
+ value: number;
27
+ currency?: string;
28
+ platform?: string;
29
+ };
24
30
  type TrackEventParams<TData = Record<string, unknown>> = {
25
31
  eventName: TrackEventName | (string & {});
26
32
  shopDomain: string;
27
33
  partnerId?: string | null;
28
34
  data?: TData;
29
35
  externalId?: string;
36
+ platform?: string;
30
37
  };
31
38
  type TrackResult<TData = Record<string, unknown>> = {
32
39
  success: boolean;
@@ -51,6 +58,7 @@ type SubscriptionEventData = {
51
58
  subscriptionId?: number | string;
52
59
  subscriptionPrice?: number | string;
53
60
  subscriptionPeriod?: string;
61
+ platform?: string;
54
62
  };
55
63
  type AppsCatalogEntry = {
56
64
  key: string;
@@ -83,4 +91,4 @@ declare function getCrossSellOffers(options?: CrossSellOptions): AppsCatalogEntr
83
91
  declare function fetchAppsCatalog(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
84
92
  declare function getCrossSellOffersFromApi(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
85
93
 
86
- export { type AssignPartnerIdWithSubscriptionInput 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 };
94
+ export { type AssignPartnerIdWithSubscriptionInput as A, type ConnectorConfig as C, type Logger as L, type SubscriptionEventData as S, type TrackEventParams as T, type TrackResult as a, type TransactionEventData as b, type CheckPartnerIdResult as c, type ShopifyAdminGraphQLClient as d, getCrossSellOffersFromApi as e, fetchAppsCatalog as f, getCrossSellOffers as g, type AppsCatalogEntry as h, type CrossSellFetchOptions as i, type CrossSellOptions as j, type TrackEventName as k };
@@ -20,13 +20,20 @@ type ConnectorConfig = {
20
20
  logger?: Logger;
21
21
  enableIdempotency?: boolean;
22
22
  };
23
- type TrackEventName = "installation" | "uninstallation" | "subscription";
23
+ type TrackEventName = "installation" | "uninstallation" | "subscription" | "transaction";
24
+ type TransactionEventData = {
25
+ transactionId: string;
26
+ value: number;
27
+ currency?: string;
28
+ platform?: string;
29
+ };
24
30
  type TrackEventParams<TData = Record<string, unknown>> = {
25
31
  eventName: TrackEventName | (string & {});
26
32
  shopDomain: string;
27
33
  partnerId?: string | null;
28
34
  data?: TData;
29
35
  externalId?: string;
36
+ platform?: string;
30
37
  };
31
38
  type TrackResult<TData = Record<string, unknown>> = {
32
39
  success: boolean;
@@ -51,6 +58,7 @@ type SubscriptionEventData = {
51
58
  subscriptionId?: number | string;
52
59
  subscriptionPrice?: number | string;
53
60
  subscriptionPeriod?: string;
61
+ platform?: string;
54
62
  };
55
63
  type AppsCatalogEntry = {
56
64
  key: string;
@@ -83,4 +91,4 @@ declare function getCrossSellOffers(options?: CrossSellOptions): AppsCatalogEntr
83
91
  declare function fetchAppsCatalog(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
84
92
  declare function getCrossSellOffersFromApi(options?: CrossSellFetchOptions): Promise<AppsCatalogEntry[]>;
85
93
 
86
- export { type AssignPartnerIdWithSubscriptionInput 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 };
94
+ export { type AssignPartnerIdWithSubscriptionInput as A, type ConnectorConfig as C, type Logger as L, type SubscriptionEventData as S, type TrackEventParams as T, type TrackResult as a, type TransactionEventData as b, type CheckPartnerIdResult as c, type ShopifyAdminGraphQLClient as d, getCrossSellOffersFromApi as e, fetchAppsCatalog as f, getCrossSellOffers as g, type AppsCatalogEntry as h, type CrossSellFetchOptions as i, type CrossSellOptions as j, type TrackEventName as k };
@@ -39,6 +39,25 @@ function safeJsonParse(text) {
39
39
  }
40
40
 
41
41
  // src/crossSell.ts
42
+ function appendUtmSource(url, utmSource) {
43
+ const source = utmSource?.trim();
44
+ if (!source) return url;
45
+ try {
46
+ const parsed = new URL(url);
47
+ if (!parsed.searchParams.has("utm_source")) {
48
+ parsed.searchParams.set("utm_source", source);
49
+ }
50
+ return parsed.toString();
51
+ } catch {
52
+ return url;
53
+ }
54
+ }
55
+ function withSourceTracking(apps, utmSource) {
56
+ return apps.map((app) => ({
57
+ ...app,
58
+ url: appendUtmSource(app.url, utmSource)
59
+ }));
60
+ }
42
61
  function getCrossSellOffers(options = {}) {
43
62
  const appsCatalog = options.appsCatalog ?? [];
44
63
  const installedKeys = new Set(
@@ -98,7 +117,7 @@ function buildFallbackCatalog(options) {
98
117
  if (limit > 0) {
99
118
  items = items.slice(0, limit);
100
119
  }
101
- return items;
120
+ return withSourceTracking(items, appName);
102
121
  }
103
122
  async function fetchAppsCatalog(options = {}) {
104
123
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -124,7 +143,7 @@ async function fetchAppsCatalog(options = {}) {
124
143
  logger?.error?.("Failed to fetch apps catalog", { status: response.status });
125
144
  return buildFallbackCatalog(options);
126
145
  }
127
- return parsed;
146
+ return withSourceTracking(parsed, appName);
128
147
  } catch (error) {
129
148
  logger?.error?.("Failed to fetch apps catalog", {
130
149
  error: error instanceof Error ? error.message : String(error)
@@ -1 +1 @@
1
- export { e as AppsCatalogEntry, h as CrossSellFetchOptions, i as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, d as getCrossSellOffersFromApi } from './crossSell-BdqPj2g7.cjs';
1
+ export { h as AppsCatalogEntry, i as CrossSellFetchOptions, j as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, e as getCrossSellOffersFromApi } from './crossSell-DGRqzhbh.cjs';
@@ -1 +1 @@
1
- export { e as AppsCatalogEntry, h as CrossSellFetchOptions, i as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, d as getCrossSellOffersFromApi } from './crossSell-BdqPj2g7.js';
1
+ export { h as AppsCatalogEntry, i as CrossSellFetchOptions, j as CrossSellOptions, f as fetchAppsCatalog, g as getCrossSellOffers, e as getCrossSellOffersFromApi } from './crossSell-DGRqzhbh.js';
package/dist/crossSell.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  fetchAppsCatalog,
3
3
  getCrossSellOffers,
4
4
  getCrossSellOffersFromApi
5
- } from "./chunk-WZ5FAA44.js";
5
+ } from "./chunk-77N7IXZB.js";
6
6
  export {
7
7
  fetchAppsCatalog,
8
8
  getCrossSellOffers,
package/dist/index.cjs CHANGED
@@ -211,6 +211,7 @@ function createProgusConnector(config) {
211
211
  trackSubscriptionPurchased: fail,
212
212
  trackSubscriptionUpdated: fail,
213
213
  trackSubscriptionCancelled: fail,
214
+ trackTransaction: fail,
214
215
  assignPartnerIdWithSubscription: fail,
215
216
  checkPartnerId: async () => ({ success: false, message, status: 500 })
216
217
  };
@@ -233,6 +234,9 @@ function createProgusConnector(config) {
233
234
  if (partnerId) {
234
235
  requestPayload.partnerId = partnerId;
235
236
  }
237
+ if (payload.platform !== void 0) {
238
+ requestPayload.platform = payload.platform;
239
+ }
236
240
  if (enableIdempotency) {
237
241
  const eventId = buildEventId(shopDomain, String(eventName), externalId);
238
242
  if (eventId) {
@@ -288,11 +292,27 @@ function createProgusConnector(config) {
288
292
  logger?.info?.("Partner event skipped: missing partnerId required for installation event");
289
293
  return { success: false, message: "Missing partnerId" };
290
294
  }
291
- return postEvent("installation", { shopDomain: payload.shopDomain, partnerId });
295
+ return postEvent("installation", {
296
+ shopDomain: payload.shopDomain,
297
+ partnerId,
298
+ platform: payload.platform
299
+ });
292
300
  }
293
301
  async function trackUninstall(payload) {
294
302
  return postEvent("uninstallation", { shopDomain: payload.shopDomain });
295
303
  }
304
+ async function trackTransaction(payload) {
305
+ const { transactionId, value } = payload.data;
306
+ if (!transactionId || typeof value !== "number" || !Number.isFinite(value)) {
307
+ logger?.info?.("Partner event skipped: transaction requires transactionId and numeric value");
308
+ return { success: false, message: "Invalid transaction data: transactionId and value required" };
309
+ }
310
+ return postEvent("transaction", {
311
+ shopDomain: payload.shopDomain,
312
+ data: payload.data,
313
+ externalId: transactionId
314
+ });
315
+ }
296
316
  async function trackSubscription(payload) {
297
317
  const normalized = normalizeSubscriptionData(payload.data);
298
318
  if (!normalized) {
@@ -397,12 +417,32 @@ function createProgusConnector(config) {
397
417
  trackSubscriptionPurchased: trackSubscription,
398
418
  trackSubscriptionUpdated: trackSubscription,
399
419
  trackSubscriptionCancelled: trackSubscription,
420
+ trackTransaction,
400
421
  assignPartnerIdWithSubscription,
401
422
  checkPartnerId
402
423
  };
403
424
  }
404
425
 
405
426
  // src/crossSell.ts
427
+ function appendUtmSource(url, utmSource) {
428
+ const source = utmSource?.trim();
429
+ if (!source) return url;
430
+ try {
431
+ const parsed = new URL(url);
432
+ if (!parsed.searchParams.has("utm_source")) {
433
+ parsed.searchParams.set("utm_source", source);
434
+ }
435
+ return parsed.toString();
436
+ } catch {
437
+ return url;
438
+ }
439
+ }
440
+ function withSourceTracking(apps, utmSource) {
441
+ return apps.map((app) => ({
442
+ ...app,
443
+ url: appendUtmSource(app.url, utmSource)
444
+ }));
445
+ }
406
446
  function getCrossSellOffers(options = {}) {
407
447
  const appsCatalog = options.appsCatalog ?? [];
408
448
  const installedKeys = new Set(
@@ -462,7 +502,7 @@ function buildFallbackCatalog(options) {
462
502
  if (limit > 0) {
463
503
  items = items.slice(0, limit);
464
504
  }
465
- return items;
505
+ return withSourceTracking(items, appName);
466
506
  }
467
507
  async function fetchAppsCatalog(options = {}) {
468
508
  const fetchImpl = options.fetch ?? globalThis.fetch;
@@ -488,7 +528,7 @@ async function fetchAppsCatalog(options = {}) {
488
528
  logger?.error?.("Failed to fetch apps catalog", { status: response.status });
489
529
  return buildFallbackCatalog(options);
490
530
  }
491
- return parsed;
531
+ return withSourceTracking(parsed, appName);
492
532
  } catch (error) {
493
533
  logger?.error?.("Failed to fetch apps catalog", {
494
534
  error: error instanceof Error ? error.message : String(error)
package/dist/index.d.cts CHANGED
@@ -1,11 +1,12 @@
1
- import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, A as AssignPartnerIdWithSubscriptionInput, b as CheckPartnerIdResult, c as ShopifyAdminGraphQLClient } from './crossSell-BdqPj2g7.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-BdqPj2g7.cjs';
1
+ import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, b as TransactionEventData, A as AssignPartnerIdWithSubscriptionInput, c as CheckPartnerIdResult, d as ShopifyAdminGraphQLClient } from './crossSell-DGRqzhbh.cjs';
2
+ export { h as AppsCatalogEntry, i as CrossSellFetchOptions, j as CrossSellOptions, L as Logger, k as TrackEventName, f as fetchAppsCatalog, g as getCrossSellOffers, e as getCrossSellOffersFromApi } from './crossSell-DGRqzhbh.cjs';
3
3
 
4
4
  type Connector = {
5
5
  track: (eventName: TrackEventParams["eventName"], payload: Omit<TrackEventParams, "eventName">) => Promise<TrackResult>;
6
6
  trackInstall: (payload: {
7
7
  shopDomain: string;
8
8
  partnerId?: string | null;
9
+ platform?: string;
9
10
  }) => Promise<TrackResult>;
10
11
  trackUninstall: (payload: {
11
12
  shopDomain: string;
@@ -22,6 +23,10 @@ type Connector = {
22
23
  shopDomain: string;
23
24
  data: SubscriptionEventData;
24
25
  }) => Promise<TrackResult>;
26
+ trackTransaction: (payload: {
27
+ shopDomain: string;
28
+ data: TransactionEventData;
29
+ }) => Promise<TrackResult>;
25
30
  assignPartnerIdWithSubscription: (payload: AssignPartnerIdWithSubscriptionInput) => Promise<TrackResult & {
26
31
  partnerId?: string;
27
32
  }>;
@@ -39,4 +44,4 @@ declare function signPayload(body: string, secret: string): string;
39
44
 
40
45
  declare function normalizePartnerId(value?: string | null): string | null;
41
46
 
42
- export { AssignPartnerIdWithSubscriptionInput, CheckPartnerIdResult, ConnectorConfig, ShopifyAdminGraphQLClient, SubscriptionEventData, TrackEventParams, TrackResult, createProgusConnector, fetchActiveSubscriptionEventData, normalizePartnerId, signPayload };
47
+ export { AssignPartnerIdWithSubscriptionInput, CheckPartnerIdResult, ConnectorConfig, ShopifyAdminGraphQLClient, SubscriptionEventData, TrackEventParams, TrackResult, TransactionEventData, createProgusConnector, fetchActiveSubscriptionEventData, normalizePartnerId, signPayload };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, A as AssignPartnerIdWithSubscriptionInput, b as CheckPartnerIdResult, c as ShopifyAdminGraphQLClient } from './crossSell-BdqPj2g7.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-BdqPj2g7.js';
1
+ import { C as ConnectorConfig, T as TrackEventParams, a as TrackResult, S as SubscriptionEventData, b as TransactionEventData, A as AssignPartnerIdWithSubscriptionInput, c as CheckPartnerIdResult, d as ShopifyAdminGraphQLClient } from './crossSell-DGRqzhbh.js';
2
+ export { h as AppsCatalogEntry, i as CrossSellFetchOptions, j as CrossSellOptions, L as Logger, k as TrackEventName, f as fetchAppsCatalog, g as getCrossSellOffers, e as getCrossSellOffersFromApi } from './crossSell-DGRqzhbh.js';
3
3
 
4
4
  type Connector = {
5
5
  track: (eventName: TrackEventParams["eventName"], payload: Omit<TrackEventParams, "eventName">) => Promise<TrackResult>;
6
6
  trackInstall: (payload: {
7
7
  shopDomain: string;
8
8
  partnerId?: string | null;
9
+ platform?: string;
9
10
  }) => Promise<TrackResult>;
10
11
  trackUninstall: (payload: {
11
12
  shopDomain: string;
@@ -22,6 +23,10 @@ type Connector = {
22
23
  shopDomain: string;
23
24
  data: SubscriptionEventData;
24
25
  }) => Promise<TrackResult>;
26
+ trackTransaction: (payload: {
27
+ shopDomain: string;
28
+ data: TransactionEventData;
29
+ }) => Promise<TrackResult>;
25
30
  assignPartnerIdWithSubscription: (payload: AssignPartnerIdWithSubscriptionInput) => Promise<TrackResult & {
26
31
  partnerId?: string;
27
32
  }>;
@@ -39,4 +44,4 @@ declare function signPayload(body: string, secret: string): string;
39
44
 
40
45
  declare function normalizePartnerId(value?: string | null): string | null;
41
46
 
42
- export { AssignPartnerIdWithSubscriptionInput, CheckPartnerIdResult, ConnectorConfig, ShopifyAdminGraphQLClient, SubscriptionEventData, TrackEventParams, TrackResult, createProgusConnector, fetchActiveSubscriptionEventData, normalizePartnerId, signPayload };
47
+ export { AssignPartnerIdWithSubscriptionInput, CheckPartnerIdResult, ConnectorConfig, ShopifyAdminGraphQLClient, SubscriptionEventData, TrackEventParams, TrackResult, TransactionEventData, createProgusConnector, fetchActiveSubscriptionEventData, normalizePartnerId, signPayload };
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  normalizePartnerId,
7
7
  safeJsonParse,
8
8
  stripTrailingSlash
9
- } from "./chunk-WZ5FAA44.js";
9
+ } from "./chunk-77N7IXZB.js";
10
10
 
11
11
  // src/subscription.ts
12
12
  var ACTIVE_SUBSCRIPTIONS_QUERY = `
@@ -168,6 +168,7 @@ function createProgusConnector(config) {
168
168
  trackSubscriptionPurchased: fail,
169
169
  trackSubscriptionUpdated: fail,
170
170
  trackSubscriptionCancelled: fail,
171
+ trackTransaction: fail,
171
172
  assignPartnerIdWithSubscription: fail,
172
173
  checkPartnerId: async () => ({ success: false, message, status: 500 })
173
174
  };
@@ -190,6 +191,9 @@ function createProgusConnector(config) {
190
191
  if (partnerId) {
191
192
  requestPayload.partnerId = partnerId;
192
193
  }
194
+ if (payload.platform !== void 0) {
195
+ requestPayload.platform = payload.platform;
196
+ }
193
197
  if (enableIdempotency) {
194
198
  const eventId = buildEventId(shopDomain, String(eventName), externalId);
195
199
  if (eventId) {
@@ -245,11 +249,27 @@ function createProgusConnector(config) {
245
249
  logger?.info?.("Partner event skipped: missing partnerId required for installation event");
246
250
  return { success: false, message: "Missing partnerId" };
247
251
  }
248
- return postEvent("installation", { shopDomain: payload.shopDomain, partnerId });
252
+ return postEvent("installation", {
253
+ shopDomain: payload.shopDomain,
254
+ partnerId,
255
+ platform: payload.platform
256
+ });
249
257
  }
250
258
  async function trackUninstall(payload) {
251
259
  return postEvent("uninstallation", { shopDomain: payload.shopDomain });
252
260
  }
261
+ async function trackTransaction(payload) {
262
+ const { transactionId, value } = payload.data;
263
+ if (!transactionId || typeof value !== "number" || !Number.isFinite(value)) {
264
+ logger?.info?.("Partner event skipped: transaction requires transactionId and numeric value");
265
+ return { success: false, message: "Invalid transaction data: transactionId and value required" };
266
+ }
267
+ return postEvent("transaction", {
268
+ shopDomain: payload.shopDomain,
269
+ data: payload.data,
270
+ externalId: transactionId
271
+ });
272
+ }
253
273
  async function trackSubscription(payload) {
254
274
  const normalized = normalizeSubscriptionData(payload.data);
255
275
  if (!normalized) {
@@ -354,6 +374,7 @@ function createProgusConnector(config) {
354
374
  trackSubscriptionPurchased: trackSubscription,
355
375
  trackSubscriptionUpdated: trackSubscription,
356
376
  trackSubscriptionCancelled: trackSubscription,
377
+ trackTransaction,
357
378
  assignPartnerIdWithSubscription,
358
379
  checkPartnerId
359
380
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progus/connector",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Progus partner/affiliate connector helpers",
5
5
  "license": "MIT",
6
6
  "type": "module",