@hubbyesim/sdk 2.1.0 → 2.2.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/dist/index.js CHANGED
@@ -1012,6 +1012,15 @@ var partnerApiV1EsimsShow = (options) => (options.client ?? client).get({
1012
1012
  url: "/v1/esims/{iccid}",
1013
1013
  ...options
1014
1014
  });
1015
+ var partnerApiV1EsimsUsage = (options) => (options.client ?? client).get({
1016
+ security: [
1017
+ { name: "X-Api-Key", type: "apiKey" },
1018
+ { name: "X-Signature", type: "apiKey" },
1019
+ { name: "X-Timestamp", type: "apiKey" }
1020
+ ],
1021
+ url: "/v1/esims/{iccid}/usage",
1022
+ ...options
1023
+ });
1015
1024
  var partnerApiV1EsimsInstructions = (options) => (options.client ?? client).get({
1016
1025
  security: [
1017
1026
  { name: "X-Api-Key", type: "apiKey" },
@@ -1121,8 +1130,8 @@ async function signRequest(secret, request) {
1121
1130
  }
1122
1131
 
1123
1132
  // lib/version.ts
1124
- var SUPPORTED_API_VERSION = "5.13.0";
1125
- var SDK_VERSION = "2.1.0";
1133
+ var SUPPORTED_API_VERSION = "5.14.0";
1134
+ var SDK_VERSION = "2.2.0";
1126
1135
 
1127
1136
  // lib/transport.ts
1128
1137
  var DEFAULT_RETRY = {
@@ -1368,7 +1377,22 @@ var Hubby = class {
1368
1377
  client: this.#client,
1369
1378
  ...options,
1370
1379
  path: { iccid },
1371
- query: input.refresh === void 0 ? void 0 : { refresh: `${input.refresh}` }
1380
+ query: refreshQuery(input)
1381
+ })
1382
+ );
1383
+ }
1384
+ /**
1385
+ * `GET /v1/esims/{iccid}/usage`: what the traveller can still use on the
1386
+ * eSIM, one entry per destination, newest first. `refresh: true` reads
1387
+ * the network now; it shares `getEsim`'s per-Partner rate limit.
1388
+ */
1389
+ async getEsimUsage(iccid, input = {}, options = {}) {
1390
+ return unwrap(
1391
+ await partnerApiV1EsimsUsage({
1392
+ client: this.#client,
1393
+ ...options,
1394
+ path: { iccid },
1395
+ query: refreshQuery(input)
1372
1396
  })
1373
1397
  );
1374
1398
  }
@@ -1550,6 +1574,9 @@ function unwrap(result) {
1550
1574
  }
1551
1575
  return result.data;
1552
1576
  }
1577
+ function refreshQuery(input) {
1578
+ return input.refresh === void 0 ? void 0 : { refresh: `${input.refresh}` };
1579
+ }
1553
1580
 
1554
1581
  // lib/webhooks.ts
1555
1582
  var WebhookVerificationError = class extends Error {
package/llms.txt CHANGED
@@ -38,10 +38,12 @@ const issued = await hubby.issuePackage('ORDER-4471', item.id, {
38
38
  });
39
39
  // A key replays its first answer for 24 hours (Idempotent-Replayed: true); after a terminate it answers 409 idempotency_key_spent: issue again with a new key.
40
40
  // state 'redeemed': show issued.data.esim.install_links, or issued.data.esim.lpa as a QR code.
41
+ // state and every other response enum is its known values or any other string (a minor can add one): switch with a default branch.
41
42
  // issued.data (also getPackage): id (the id in getEsim's packages), state, bundle_id, issued_at, installed_at, activated_at, expires_at, terminated_at, esim { iccid, installed_at, install_links { ios, android }, lpa, smdp_address, matching_id }.
42
43
 
43
44
  await hubby.terminatePackage('ORDER-4471', item.id, { reason: 'changed_plans' }); // resolves undefined (204)
44
45
  const esim = await hubby.getEsim(issued.data.esim.iccid, { refresh: true });
46
+ // Each of esim.data.packages carries its destination { id, name, type, iso2, iso3 }.
45
47
  // issued.data and each of esim.data.packages carry valid_until: when the data stops working, null until activation. expires_at is only the latest moment the package can still be activated.
46
48
  ```
47
49
 
@@ -55,12 +57,23 @@ const { countries, regions } = await hubby.getDestinations();
55
57
  const plans = await hubby.getDestinationBundles('ES');
56
58
  ```
57
59
 
58
- Add a package to a traveller's eSIM: each traveller has one Universal eSIM. Book again for the same `external_user_id`, then issue. The answer is `installed` once the eSIM is on the phone, so skip the install screen. There is no `topUp()` call; this is it. The Hubby apps offer a top-up only for a destination the traveller already holds, and any other destination is a purchase from the shop; the Partner API does not enforce this, so your app must. `getEsim` names only each package's `bundle_id` and `booking_id`: take a package's destination from its booking's item, or from your own record of what you sold.
60
+ Show usage: `getEsimUsage(iccid)` answers `data`, one entry per destination, newest first; show one card per entry, with the figures the Hubby apps show. Days left: from `remaining_seconds`, set even before a date is known. Add "until <date>" when `valid_until` is set; null does not mean unused, because an older package in the entry can already be in use. `remaining_bytes === 0`: used up. Anything else: `remaining_bytes` of `total_bytes` left. On `is_unlimited`, `total_bytes` and `remaining_bytes` are null and `used_bytes` is still set. A destination can appear twice (one data entry, one unlimited entry), and packages the traveller bought in the Hubby app count too. `refresh: true` shares `getEsim`'s rate limit.
59
61
 
60
62
  ```ts
63
+ const usage = await hubby.getEsimUsage(iccid);
64
+ // Each entry: destination { id, name, type, iso2, iso3 }, is_unlimited, total_bytes, used_bytes, remaining_bytes, valid_until, remaining_seconds, package_ids (ids in getEsim's packages), synced_at.
65
+ // total_bytes is always used_bytes + remaining_bytes: data an ended package did not use counts as used.
66
+ const daysLeft = Math.ceil(usage.data[0].remaining_seconds / 86_400);
67
+ ```
68
+
69
+ Add a package to a traveller's eSIM: each traveller has one Universal eSIM. Book again for the same `external_user_id`, then issue. The answer is `installed` once the eSIM is on the phone, so skip the install screen. There is no `topUp()` call; this is it. The Hubby apps offer a top-up only for a destination the traveller already holds, and any other destination is a purchase from the shop; the Partner API does not enforce this, so your app must. To top up a usage entry, take the destination from the entry. Each of `getEsim`'s `packages` also carries its `destination`, the same object.
70
+
71
+ ```ts
72
+ const plans = await hubby.getDestinationBundles(entry.destination.id); // entry: from getEsimUsage
61
73
  const topUp = await hubby.createBooking({
62
74
  external_reference: 'ORDER-5120',
63
- package_specifications: [{ destination: 'ES', package_type: 'data-limited', size: '3GB', external_user_id: 'user-88213' }],
75
+ package_specifications: [{ bundle_id: plans.data[0].id, external_user_id: 'user-88213' }],
76
+ // With a package_strategy (no bundle_id): { destination: entry.destination.iso2 ?? entry.destination.name, ... }; a region has no iso2.
64
77
  });
65
78
  const added = await hubby.issuePackage('ORDER-5120', topUp.data.items![0].id, {
66
79
  idempotencyKey: crypto.randomUUID(), // stored with your purchase record first
@@ -71,7 +84,7 @@ const added = await hubby.issuePackage('ORDER-5120', topUp.data.items![0].id, {
71
84
 
72
85
  ## Docs
73
86
 
74
- - [README](https://www.npmjs.com/package/@hubbyesim/sdk): client options, retries, the full book, issue, install, terminate and read flow, what to show per state, every method, errors, per-call options, webhook verification, signing without the client
87
+ - [README](https://www.npmjs.com/package/@hubbyesim/sdk): client options, retries, the full book, issue, install, terminate and read flow, what to show per state, show usage, every method, errors, per-call options, webhook verification, signing without the client
75
88
  - [Partner API guide](https://docs.hubbyesim.com/guides/native-api): every call, field, refusal code and webhook event
76
89
 
77
90
  ## Optional
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubbyesim/sdk",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Official TypeScript SDK for the Hubby Partner API: signed requests, idempotent retries, webhook verification and typed operations.",
5
5
  "keywords": [
6
6
  "hubby",