@ophelio/sdk 0.3.1 → 0.4.0
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.
- package/README.md +96 -23
- package/dist/index.cjs +158 -15
- package/dist/index.d.cts +732 -318
- package/dist/index.d.mts +732 -318
- package/dist/index.mjs +158 -15
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -125,6 +125,21 @@ const DEFAULT_MAX_RETRIES = 2;
|
|
|
125
125
|
function resolveIdempotencyKey(idempotencyKey) {
|
|
126
126
|
return idempotencyKey?.trim() || crypto.randomUUID();
|
|
127
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Serialises query parameters into a search string.
|
|
130
|
+
*
|
|
131
|
+
* `undefined` drops the parameter entirely. An empty array does not: it emits
|
|
132
|
+
* the bare key (`?status=`), because "filter by nothing" and "do not filter"
|
|
133
|
+
* are different requests and the API distinguishes them.
|
|
134
|
+
*/
|
|
135
|
+
function serialiseQuery(query) {
|
|
136
|
+
const search = new URLSearchParams();
|
|
137
|
+
for (const [key, value] of Object.entries(query ?? {})) {
|
|
138
|
+
if (value === void 0) continue;
|
|
139
|
+
search.set(key, Array.isArray(value) ? value.join(",") : value);
|
|
140
|
+
}
|
|
141
|
+
return search.toString();
|
|
142
|
+
}
|
|
128
143
|
var Transport = class {
|
|
129
144
|
apiKey;
|
|
130
145
|
baseUrl;
|
|
@@ -179,9 +194,7 @@ var Transport = class {
|
|
|
179
194
|
throw lastError;
|
|
180
195
|
}
|
|
181
196
|
buildUrl(params) {
|
|
182
|
-
const
|
|
183
|
-
for (const [key, value] of Object.entries(params.query ?? {})) if (value !== void 0) search.set(key, value);
|
|
184
|
-
const queryString = search.toString();
|
|
197
|
+
const queryString = serialiseQuery(params.query);
|
|
185
198
|
return `${this.baseUrl}${params.path}${queryString ? `?${queryString}` : ""}`;
|
|
186
199
|
}
|
|
187
200
|
buildHeaders(params) {
|
|
@@ -234,12 +247,30 @@ function pageQuery(params) {
|
|
|
234
247
|
//#endregion
|
|
235
248
|
//#region src/resources/admit.ts
|
|
236
249
|
var AdmitResource = class extends APIResource {
|
|
237
|
-
/**
|
|
250
|
+
/**
|
|
251
|
+
* Gate admission check: `GET /admit?card=<cardId>`.
|
|
252
|
+
*
|
|
253
|
+
* `targets` names the venue, zone, shop or gate the request is being made
|
|
254
|
+
* at, and is the context the entitlements are judged in — a benefit
|
|
255
|
+
* restricted to somewhere else drops out of `entitlements`. Three states,
|
|
256
|
+
* and they are answered differently: omit it and every target restriction
|
|
257
|
+
* is treated as satisfied; pass `[]` and only benefits valid anywhere
|
|
258
|
+
* survive; pass codes and a benefit needs one of them. Read
|
|
259
|
+
* `target_context_applied` on the result to tell the first apart from the
|
|
260
|
+
* other two.
|
|
261
|
+
*
|
|
262
|
+
* Codes are matched exactly, so send them back verbatim from
|
|
263
|
+
* `targetCodes.list()` — an unregistered or miscased code is refused with
|
|
264
|
+
* a 400 rather than quietly ignored.
|
|
265
|
+
*/
|
|
238
266
|
check(params, options) {
|
|
239
267
|
return this.transport.request({
|
|
240
268
|
method: "GET",
|
|
241
269
|
path: "/api/v1/admit",
|
|
242
|
-
query: {
|
|
270
|
+
query: {
|
|
271
|
+
card: params.card,
|
|
272
|
+
targets: params.targets
|
|
273
|
+
},
|
|
243
274
|
retryable: true,
|
|
244
275
|
options
|
|
245
276
|
});
|
|
@@ -315,7 +346,7 @@ var BillingOptionsResource = class extends APIResource {
|
|
|
315
346
|
//#endregion
|
|
316
347
|
//#region src/resources/calendar-rules.ts
|
|
317
348
|
/**
|
|
318
|
-
* A calendar rule is one row of a calendar's
|
|
349
|
+
* A calendar rule is one row of a calendar's set of dates. Conditions AND
|
|
319
350
|
* within a rule and rules OR across a calendar, so "weekends in August" is a
|
|
320
351
|
* single rule rather than two.
|
|
321
352
|
*
|
|
@@ -353,17 +384,24 @@ var CalendarRulesResource = class extends APIResource {
|
|
|
353
384
|
//#endregion
|
|
354
385
|
//#region src/resources/calendars.ts
|
|
355
386
|
/**
|
|
356
|
-
* Calendars are named, reusable
|
|
387
|
+
* Calendars are named, reusable sets of dates ("Peak 2026", "Weekends").
|
|
357
388
|
* The dates themselves live in the rules attached to them.
|
|
358
389
|
*
|
|
359
390
|
* A calendar containing no rules is valid for **all** dates, not none.
|
|
360
391
|
*/
|
|
361
392
|
var CalendarsResource = class extends APIResource {
|
|
393
|
+
/**
|
|
394
|
+
* Pass `view: 'full'` to include `plan_entitlement_count` on every
|
|
395
|
+
* calendar.
|
|
396
|
+
*/
|
|
362
397
|
async list(params, options) {
|
|
363
398
|
const response = await this.transport.request({
|
|
364
399
|
method: "GET",
|
|
365
400
|
path: "/api/v1/calendars",
|
|
366
|
-
query:
|
|
401
|
+
query: {
|
|
402
|
+
...pageQuery(params),
|
|
403
|
+
...params?.view ? { view: params.view } : {}
|
|
404
|
+
},
|
|
367
405
|
retryable: true,
|
|
368
406
|
options
|
|
369
407
|
});
|
|
@@ -373,10 +411,14 @@ var CalendarsResource = class extends APIResource {
|
|
|
373
411
|
total_size: response.total_size
|
|
374
412
|
};
|
|
375
413
|
}
|
|
376
|
-
|
|
414
|
+
/**
|
|
415
|
+
* Pass `view: 'full'` to include `plan_entitlement_count`.
|
|
416
|
+
*/
|
|
417
|
+
get(id, params = {}, options) {
|
|
377
418
|
return this.transport.request({
|
|
378
419
|
method: "GET",
|
|
379
420
|
path: `/api/v1/calendars/${encodeURIComponent(id)}`,
|
|
421
|
+
query: params.view ? { view: params.view } : void 0,
|
|
380
422
|
retryable: true,
|
|
381
423
|
options
|
|
382
424
|
});
|
|
@@ -529,6 +571,14 @@ var EntitlementsResource = class extends APIResource {
|
|
|
529
571
|
/**
|
|
530
572
|
* Fire-and-forget batch usage reporting (one row per member). Idempotent
|
|
531
573
|
* per (key, member). Returns the recorded usage rows.
|
|
574
|
+
*
|
|
575
|
+
* `target` is the single registered code for the venue, zone, shop or gate
|
|
576
|
+
* the usage happened at — one event, one place, which is why it is
|
|
577
|
+
* singular here where the reads take `targets`. It is both the context the
|
|
578
|
+
* entitlement is judged in and a column on the row that comes back, so it
|
|
579
|
+
* is queryable in a way the free-form `context` is not. It is part of the
|
|
580
|
+
* idempotency fingerprint: a replay of the same key at a different target
|
|
581
|
+
* is refused rather than silently returning the original row.
|
|
532
582
|
*/
|
|
533
583
|
async recordUsage(params, options = {}) {
|
|
534
584
|
const { idempotencyKey, ...requestOptions } = options;
|
|
@@ -654,11 +704,29 @@ var MembersResource = class extends APIResource {
|
|
|
654
704
|
options
|
|
655
705
|
});
|
|
656
706
|
}
|
|
707
|
+
/**
|
|
708
|
+
* The entitlements a member can use right now.
|
|
709
|
+
*
|
|
710
|
+
* `targets` filters the result down to the benefits valid at the venue,
|
|
711
|
+
* zone, shop or gate it names — the same codes `admit.check` takes, but
|
|
712
|
+
* read as a filter here rather than as the context a gate decision is made
|
|
713
|
+
* in. Three states: omit it and nothing is filtered by target; pass `[]`
|
|
714
|
+
* and only benefits valid anywhere come back; pass codes and a benefit
|
|
715
|
+
* needs one of them. Codes are matched exactly, so send them back verbatim
|
|
716
|
+
* from `targetCodes.list()` — an unregistered one is refused with a 400.
|
|
717
|
+
*
|
|
718
|
+
* Each entitlement carries `valid_on` and `valid_at` when something
|
|
719
|
+
* restricts it by date or by target; both list only what it matched, never
|
|
720
|
+
* what it failed.
|
|
721
|
+
*/
|
|
657
722
|
async listEntitlements(id, params = {}, options) {
|
|
658
723
|
return (await this.transport.request({
|
|
659
724
|
method: "GET",
|
|
660
725
|
path: `/api/v1/members/${encodeURIComponent(id)}/entitlements`,
|
|
661
|
-
query: {
|
|
726
|
+
query: {
|
|
727
|
+
type: params.type,
|
|
728
|
+
targets: params.targets
|
|
729
|
+
},
|
|
662
730
|
retryable: true,
|
|
663
731
|
options
|
|
664
732
|
})).entitlements;
|
|
@@ -917,6 +985,45 @@ var MembershipsResource = class extends APIResource {
|
|
|
917
985
|
}
|
|
918
986
|
};
|
|
919
987
|
//#endregion
|
|
988
|
+
//#region src/resources/plan-entitlement-availabilities.ts
|
|
989
|
+
/**
|
|
990
|
+
* An availability row says when and where one plan entitlement applies: a
|
|
991
|
+
* calendar (null = any date) and a set of registered target codes (empty =
|
|
992
|
+
* anywhere). Rows OR, and a plan entitlement with no rows at all is
|
|
993
|
+
* unrestricted.
|
|
994
|
+
*
|
|
995
|
+
* Rows are created and listed through their plan entitlement
|
|
996
|
+
* (`ophelio.planEntitlements.createAvailability` / `listAvailabilities`); this
|
|
997
|
+
* resource addresses an individual row.
|
|
998
|
+
*/
|
|
999
|
+
var PlanEntitlementAvailabilitiesResource = class extends APIResource {
|
|
1000
|
+
get(id, options) {
|
|
1001
|
+
return this.transport.request({
|
|
1002
|
+
method: "GET",
|
|
1003
|
+
path: `/api/v1/plan-entitlement-availabilities/${encodeURIComponent(id)}`,
|
|
1004
|
+
retryable: true,
|
|
1005
|
+
options
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
update(id, params, options) {
|
|
1009
|
+
return this.transport.request({
|
|
1010
|
+
method: "PATCH",
|
|
1011
|
+
path: `/api/v1/plan-entitlement-availabilities/${encodeURIComponent(id)}`,
|
|
1012
|
+
body: params,
|
|
1013
|
+
retryable: false,
|
|
1014
|
+
options
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
async delete(id, options) {
|
|
1018
|
+
await this.transport.request({
|
|
1019
|
+
method: "DELETE",
|
|
1020
|
+
path: `/api/v1/plan-entitlement-availabilities/${encodeURIComponent(id)}`,
|
|
1021
|
+
retryable: false,
|
|
1022
|
+
options
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
//#endregion
|
|
920
1027
|
//#region src/resources/plan-entitlements.ts
|
|
921
1028
|
var PlanEntitlementsResource = class extends APIResource {
|
|
922
1029
|
get(id, options) {
|
|
@@ -945,6 +1052,29 @@ var PlanEntitlementsResource = class extends APIResource {
|
|
|
945
1052
|
options
|
|
946
1053
|
});
|
|
947
1054
|
}
|
|
1055
|
+
async listAvailabilities(id, params, options) {
|
|
1056
|
+
const response = await this.transport.request({
|
|
1057
|
+
method: "GET",
|
|
1058
|
+
path: `/api/v1/plan-entitlements/${encodeURIComponent(id)}/availabilities`,
|
|
1059
|
+
query: pageQuery(params),
|
|
1060
|
+
retryable: true,
|
|
1061
|
+
options
|
|
1062
|
+
});
|
|
1063
|
+
return {
|
|
1064
|
+
items: response.availabilities,
|
|
1065
|
+
next_page_token: response.next_page_token,
|
|
1066
|
+
total_size: response.total_size
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
createAvailability(id, params, options) {
|
|
1070
|
+
return this.transport.request({
|
|
1071
|
+
method: "POST",
|
|
1072
|
+
path: `/api/v1/plan-entitlements/${encodeURIComponent(id)}/availabilities`,
|
|
1073
|
+
body: params,
|
|
1074
|
+
retryable: false,
|
|
1075
|
+
options
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
948
1078
|
};
|
|
949
1079
|
//#endregion
|
|
950
1080
|
//#region src/resources/plan-links.ts
|
|
@@ -1181,16 +1311,23 @@ var SalesChannelsResource = class extends APIResource {
|
|
|
1181
1311
|
//#endregion
|
|
1182
1312
|
//#region src/resources/target-codes.ts
|
|
1183
1313
|
/**
|
|
1184
|
-
* The registered
|
|
1185
|
-
* `coffee_shop`). Codes are matched exactly — list them and send
|
|
1186
|
-
* verbatim rather than constructing or case-folding them.
|
|
1314
|
+
* The registered code for each venue, zone, shop or gate a request can name
|
|
1315
|
+
* (`venue_a`, `coffee_shop`). Codes are matched exactly — list them and send
|
|
1316
|
+
* values back verbatim rather than constructing or case-folding them.
|
|
1187
1317
|
*/
|
|
1188
1318
|
var TargetCodesResource = class extends APIResource {
|
|
1319
|
+
/**
|
|
1320
|
+
* Pass `view: 'full'` to include `plan_entitlement_count` on every target
|
|
1321
|
+
* code.
|
|
1322
|
+
*/
|
|
1189
1323
|
async list(params, options) {
|
|
1190
1324
|
const response = await this.transport.request({
|
|
1191
1325
|
method: "GET",
|
|
1192
1326
|
path: "/api/v1/target-codes",
|
|
1193
|
-
query:
|
|
1327
|
+
query: {
|
|
1328
|
+
...pageQuery(params),
|
|
1329
|
+
...params?.view ? { view: params.view } : {}
|
|
1330
|
+
},
|
|
1194
1331
|
retryable: true,
|
|
1195
1332
|
options
|
|
1196
1333
|
});
|
|
@@ -1200,10 +1337,14 @@ var TargetCodesResource = class extends APIResource {
|
|
|
1200
1337
|
total_size: response.total_size
|
|
1201
1338
|
};
|
|
1202
1339
|
}
|
|
1203
|
-
|
|
1340
|
+
/**
|
|
1341
|
+
* Pass `view: 'full'` to include `plan_entitlement_count`.
|
|
1342
|
+
*/
|
|
1343
|
+
get(id, params = {}, options) {
|
|
1204
1344
|
return this.transport.request({
|
|
1205
1345
|
method: "GET",
|
|
1206
1346
|
path: `/api/v1/target-codes/${encodeURIComponent(id)}`,
|
|
1347
|
+
query: params.view ? { view: params.view } : void 0,
|
|
1207
1348
|
retryable: true,
|
|
1208
1349
|
options
|
|
1209
1350
|
});
|
|
@@ -1375,6 +1516,7 @@ var Ophelio = class Ophelio {
|
|
|
1375
1516
|
calendars;
|
|
1376
1517
|
calendarRules;
|
|
1377
1518
|
planEntitlements;
|
|
1519
|
+
planEntitlementAvailabilities;
|
|
1378
1520
|
planLinks;
|
|
1379
1521
|
planPricingGroupMappings;
|
|
1380
1522
|
billingOptionSalesChannels;
|
|
@@ -1401,6 +1543,7 @@ var Ophelio = class Ophelio {
|
|
|
1401
1543
|
this.calendars = new CalendarsResource(transport);
|
|
1402
1544
|
this.calendarRules = new CalendarRulesResource(transport);
|
|
1403
1545
|
this.planEntitlements = new PlanEntitlementsResource(transport);
|
|
1546
|
+
this.planEntitlementAvailabilities = new PlanEntitlementAvailabilitiesResource(transport);
|
|
1404
1547
|
this.planLinks = new PlanLinksResource(transport);
|
|
1405
1548
|
this.planPricingGroupMappings = new PlanPricingGroupMappingsResource(transport);
|
|
1406
1549
|
this.billingOptionSalesChannels = new BillingOptionSalesChannelsResource(transport);
|