@ophelio/sdk 0.5.0 → 0.5.1

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 CHANGED
@@ -30,9 +30,11 @@ if (result.admitted) {
30
30
  }
31
31
 
32
32
  // Offline gate cache
33
- const { members, generated_at } = await ophelio.members.sync()
33
+ const { members, generated_at } = await ophelio.members.sync({
34
+ targets: ['venue_a'], // roster for this gate; optional
35
+ })
34
36
  // later, incremental:
35
- await ophelio.members.sync({ since: generated_at })
37
+ await ophelio.members.sync({ since: generated_at, targets: ['venue_a'] })
36
38
  ```
37
39
 
38
40
  ## Authentication
@@ -160,7 +162,7 @@ Everything reachable with an API key is covered:
160
162
  | Namespace | Methods |
161
163
  | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162
164
  | `admit` | `check({ card, targets? })` |
163
- | `members` | `sync({ since? })`, `get(id)`, `listEntitlements(id, { type?, targets? })`, `update(id, ...)`, `remove(id)`, `setPrimary(id)`, `reissueCard(id, { note? })` |
165
+ | `members` | `sync({ since?, targets? })`, `get(id)`, `listEntitlements(id, { type?, targets? })`, `update(id, ...)`, `remove(id)`, `setPrimary(id)`, `reissueCard(id, { note? })` |
164
166
  | `memberships` | `list(params?)`, `get(id)`, `create(...)`, `update(id, ...)`, `cancel(id, ...)`, `uncancel(id)`, `renew(id, ...)`, `upgrade(id, ...)`, `downgrade(id, ...)`, `listMembers(id)`, `addMember(id, ...)`, `listScheduledChanges(id, params?)`, `cancelScheduledChange(id, changeId)`, `listTransactions(id, params?)`, `listTermTransactions(id, termId, params?)`, `createTransaction(id, ...)` |
165
167
  | `customers` | `list(params?)`, `get(id, params?)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listMemberships(id, params?)` — `list`/`get` accept `view: 'full'` to include `membership_summary` |
166
168
  | `entitlements` | `redeem(...)`, `recordUsage(...)`, `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
@@ -338,10 +340,11 @@ rejected, not registered for you.
338
340
  ### Target context
339
341
 
340
342
  A read can say where it is being made, and the entitlements it gets back are
341
- checked against the availability rows for that place. `admit.check` and
342
- `members.listEntitlements` take `targets` — a set of registered target codes,
343
- sent comma-separated on the wire — and `entitlements.recordUsage` takes a
344
- singular `target`, because one usage event happens at one place.
343
+ checked against the availability rows for that place. `admit.check`,
344
+ `members.listEntitlements` and `members.sync` take `targets` — a set of
345
+ registered target codes, sent comma-separated on the wire — and
346
+ `entitlements.recordUsage` takes a singular `target`, because one usage event
347
+ happens at one place.
345
348
 
346
349
  ```ts
347
350
  const result = await ophelio.admit.check({
@@ -357,8 +360,9 @@ for (const entitlement of result.entitlements) {
357
360
  }
358
361
  ```
359
362
 
360
- **Three cases, answered differently.** Omitting `targets` says nothing about
361
- where the request is: every target restriction is then treated as met, and
363
+ **Three cases, answered differently on `admit.check` and
364
+ `members.listEntitlements`.** Omitting `targets` says nothing about where the
365
+ request is: every target restriction is then treated as met, and
362
366
  `target_context_applied` comes back `false`. Passing `[]` says the caller names
363
367
  no targets, so only benefits valid everywhere come back. Passing codes means a
364
368
  benefit has to name one of them. Dates are checked in all three cases.
@@ -369,9 +373,20 @@ rather than dropped, so a typo cannot pass for a benefit that does not apply.
369
373
 
370
374
  **The parameter does a different job on each endpoint.** At the gate it is part
371
375
  of the admission decision; on `members.listEntitlements` it filters the list you
372
- get back. `members.sync` takes no targets at all — each member's entitlements
373
- are a snapshot taken at the moment of the sync, and the gate that caches them
374
- applies no rules of its own.
376
+ get back. On `members.sync` it is the scope of what one gate stores for later:
377
+ each member's entitlements are a snapshot taken at the moment of the sync, read
378
+ back during an outage without being checked again, so the targets you sync with
379
+ settle what that gate can grant while it is offline. The gate applies no rules
380
+ of its own.
381
+
382
+ **`members.sync` differs from the other two in two ways, both deliberate.** An
383
+ empty `targets` is refused with a 400 there. It is not read as naming no
384
+ targets, so it never returns only the benefits valid everywhere. And the
385
+ per-project setting below does not apply to it — a sync that omits `targets`
386
+ is always answered and returns the whole roster. The roster is the copy a gate
387
+ falls back on when it cannot reach us, so a quietly shortened or unfetchable
388
+ one would go unnoticed until the outage it exists for. Neither is an oversight
389
+ to be tidied up into consistency.
375
390
 
376
391
  `valid_on` and `valid_at` list only what an entitlement **matched**. `valid_on`
377
392
  is omitted when no date restricts it, and `valid_at` when no place does. What
@@ -380,10 +395,11 @@ benefit is valid, never which restrictions the member missed. Read the two
380
395
  lists separately — because an entitlement applies if any one row matches, a
381
396
  date in `valid_on` and a place in `valid_at` need not come from the same row.
382
397
 
383
- A project can require every read to say where it is. Once all of its gates send
384
- their own `targets`, an operator turns the setting on, and from then on a read
385
- that omits `targets` altogether is refused with a 400. Passing `[]` is not the
386
- same as omitting it: that read has said where it is and named no targets, so it
387
- is still answered, exactly as the three cases above describe. It is a
398
+ A project can require `admit.check` and `members.listEntitlements` to say where
399
+ they are. Once all of its gates send their own `targets`, an operator turns the
400
+ setting on, and from then on one of those reads that omits `targets` altogether
401
+ is refused with a 400. `members.sync` is exempt, as above. Passing `[]` is not
402
+ the same as omitting it: that read has said where it is and named no targets,
403
+ so it is still answered, exactly as the three cases above describe. It is a
388
404
  per-project setting rather than anything the client sends, so start sending
389
405
  `targets` before expecting it to be required.
package/dist/index.cjs CHANGED
@@ -687,12 +687,31 @@ var MembersResource = class extends APIResource {
687
687
  /**
688
688
  * Active-member list for offline gate caching. Pass the previous
689
689
  * response's `generated_at` as `since` to fetch incrementally.
690
+ *
691
+ * `targets` names the venue, zone, shop or gate this roster is for, and
692
+ * settles what the gate can grant while it is offline: each member's
693
+ * entitlements are stored as they stand at the moment of the sync and are
694
+ * read back during an outage without being checked again. Omit it for the
695
+ * whole roster. Codes are matched exactly, so send them back verbatim from
696
+ * `targetCodes.list()` — an unregistered one is refused with a 400.
697
+ *
698
+ * Two things work differently here than on `admit.check` and
699
+ * `members.listEntitlements`, both on purpose. An empty `targets` is
700
+ * refused with a 400. It is not read as naming no targets, so it never
701
+ * returns only the benefits valid everywhere. And a project that requires
702
+ * every read to say where it is still answers a sync that omits `targets`.
703
+ * The roster is what a gate falls back on when it cannot reach us, so a
704
+ * quietly shortened or unfetchable copy would only show up during the
705
+ * outage it was kept for.
690
706
  */
691
707
  sync(params = {}, options) {
692
708
  return this.transport.request({
693
709
  method: "GET",
694
710
  path: "/api/v1/members/sync",
695
- query: { since: params.since },
711
+ query: {
712
+ since: params.since,
713
+ targets: params.targets
714
+ },
696
715
  retryable: true,
697
716
  options
698
717
  });
package/dist/index.d.cts CHANGED
@@ -5888,9 +5888,26 @@ declare class MembersResource extends APIResource {
5888
5888
  /**
5889
5889
  * Active-member list for offline gate caching. Pass the previous
5890
5890
  * response's `generated_at` as `since` to fetch incrementally.
5891
+ *
5892
+ * `targets` names the venue, zone, shop or gate this roster is for, and
5893
+ * settles what the gate can grant while it is offline: each member's
5894
+ * entitlements are stored as they stand at the moment of the sync and are
5895
+ * read back during an outage without being checked again. Omit it for the
5896
+ * whole roster. Codes are matched exactly, so send them back verbatim from
5897
+ * `targetCodes.list()` — an unregistered one is refused with a 400.
5898
+ *
5899
+ * Two things work differently here than on `admit.check` and
5900
+ * `members.listEntitlements`, both on purpose. An empty `targets` is
5901
+ * refused with a 400. It is not read as naming no targets, so it never
5902
+ * returns only the benefits valid everywhere. And a project that requires
5903
+ * every read to say where it is still answers a sync that omits `targets`.
5904
+ * The roster is what a gate falls back on when it cannot reach us, so a
5905
+ * quietly shortened or unfetchable copy would only show up during the
5906
+ * outage it was kept for.
5891
5907
  */
5892
5908
  sync(params?: {
5893
5909
  since?: string;
5910
+ targets?: string[];
5894
5911
  }, options?: RequestOptions): Promise<MemberSyncResponse>;
5895
5912
  get(id: string, options?: RequestOptions): Promise<Member>;
5896
5913
  /**
package/dist/index.d.mts CHANGED
@@ -5888,9 +5888,26 @@ declare class MembersResource extends APIResource {
5888
5888
  /**
5889
5889
  * Active-member list for offline gate caching. Pass the previous
5890
5890
  * response's `generated_at` as `since` to fetch incrementally.
5891
+ *
5892
+ * `targets` names the venue, zone, shop or gate this roster is for, and
5893
+ * settles what the gate can grant while it is offline: each member's
5894
+ * entitlements are stored as they stand at the moment of the sync and are
5895
+ * read back during an outage without being checked again. Omit it for the
5896
+ * whole roster. Codes are matched exactly, so send them back verbatim from
5897
+ * `targetCodes.list()` — an unregistered one is refused with a 400.
5898
+ *
5899
+ * Two things work differently here than on `admit.check` and
5900
+ * `members.listEntitlements`, both on purpose. An empty `targets` is
5901
+ * refused with a 400. It is not read as naming no targets, so it never
5902
+ * returns only the benefits valid everywhere. And a project that requires
5903
+ * every read to say where it is still answers a sync that omits `targets`.
5904
+ * The roster is what a gate falls back on when it cannot reach us, so a
5905
+ * quietly shortened or unfetchable copy would only show up during the
5906
+ * outage it was kept for.
5891
5907
  */
5892
5908
  sync(params?: {
5893
5909
  since?: string;
5910
+ targets?: string[];
5894
5911
  }, options?: RequestOptions): Promise<MemberSyncResponse>;
5895
5912
  get(id: string, options?: RequestOptions): Promise<Member>;
5896
5913
  /**
package/dist/index.mjs CHANGED
@@ -686,12 +686,31 @@ var MembersResource = class extends APIResource {
686
686
  /**
687
687
  * Active-member list for offline gate caching. Pass the previous
688
688
  * response's `generated_at` as `since` to fetch incrementally.
689
+ *
690
+ * `targets` names the venue, zone, shop or gate this roster is for, and
691
+ * settles what the gate can grant while it is offline: each member's
692
+ * entitlements are stored as they stand at the moment of the sync and are
693
+ * read back during an outage without being checked again. Omit it for the
694
+ * whole roster. Codes are matched exactly, so send them back verbatim from
695
+ * `targetCodes.list()` — an unregistered one is refused with a 400.
696
+ *
697
+ * Two things work differently here than on `admit.check` and
698
+ * `members.listEntitlements`, both on purpose. An empty `targets` is
699
+ * refused with a 400. It is not read as naming no targets, so it never
700
+ * returns only the benefits valid everywhere. And a project that requires
701
+ * every read to say where it is still answers a sync that omits `targets`.
702
+ * The roster is what a gate falls back on when it cannot reach us, so a
703
+ * quietly shortened or unfetchable copy would only show up during the
704
+ * outage it was kept for.
689
705
  */
690
706
  sync(params = {}, options) {
691
707
  return this.transport.request({
692
708
  method: "GET",
693
709
  path: "/api/v1/members/sync",
694
- query: { since: params.since },
710
+ query: {
711
+ since: params.since,
712
+ targets: params.targets
713
+ },
695
714
  retryable: true,
696
715
  options
697
716
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ophelio/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Official JavaScript / TypeScript SDK for the Ophel.io membership & entitlement API.",
5
5
  "license": "MIT",
6
6
  "author": "Ophel.io",