passlet 0.2.0 → 0.2.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 ADDED
@@ -0,0 +1,74 @@
1
+ <picture>
2
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/oscartrevio/passlet/main/.github/assets/header-dark.svg">
3
+ <img src="https://raw.githubusercontent.com/oscartrevio/passlet/main/.github/assets/header.svg" alt="Passlet" width="100%">
4
+ </picture>
5
+
6
+ **[Passlet](https://github.com/oscartrevio/passlet)** is a library for generating Apple Wallet and Google Wallet passes from a single TypeScript API.
7
+
8
+ [![npm version](https://img.shields.io/npm/v/passlet)](https://www.npmjs.com/package/passlet)
9
+ [![downloads](https://img.shields.io/npm/dm/passlet)](https://www.npmjs.com/package/passlet)
10
+ [![license](https://img.shields.io/npm/l/passlet)](https://www.npmjs.com/package/passlet)
11
+ [![GitHub stars](https://img.shields.io/github/stars/oscartrevio/passlet)](https://github.com/oscartrevio/passlet/stargazers)
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install passlet
17
+ ```
18
+
19
+ ## Quickstart
20
+
21
+ ```ts
22
+ import { Wallet, field } from "passlet";
23
+
24
+ const wallet = new Wallet({
25
+ apple: {
26
+ passTypeIdentifier: process.env.APPLE_PASS_TYPE_ID!,
27
+ teamId: process.env.APPLE_TEAM_ID!,
28
+ signerCert: process.env.APPLE_SIGNER_CERT!,
29
+ signerKey: process.env.APPLE_SIGNER_KEY!,
30
+ wwdr: process.env.APPLE_WWDR!,
31
+ },
32
+ google: {
33
+ issuerId: process.env.GOOGLE_ISSUER_ID!,
34
+ clientEmail: process.env.GOOGLE_CLIENT_EMAIL!,
35
+ privateKey: process.env.GOOGLE_PRIVATE_KEY!,
36
+ },
37
+ });
38
+
39
+ const pass = wallet.loyalty({
40
+ id: "my-rewards",
41
+ name: "Rewards Card",
42
+ fields: [
43
+ field.primary("points", "Points", "1250"),
44
+ field.secondary("tier", "Tier", "Gold"),
45
+ ],
46
+ });
47
+
48
+ const { apple, google } = await pass.create({ serialNumber: "user-123" });
49
+ // apple → Uint8Array (.pkpass file, serve with Content-Type: application/vnd.apple.pkpass)
50
+ // google → JWT string (save link: https://pay.google.com/gp/v/save/<jwt>)
51
+ ```
52
+
53
+ Omit `apple` or `google` from the credentials to skip that provider.
54
+
55
+ ## Pass types
56
+
57
+ ```ts
58
+ wallet.loyalty(config);
59
+ wallet.event(config);
60
+ wallet.flight(config);
61
+ wallet.coupon(config);
62
+ wallet.giftCard(config);
63
+ wallet.generic(config);
64
+ ```
65
+
66
+ ## Credentials
67
+
68
+ **Apple** — requires an Apple Developer account with a Pass Type ID. [Create one in the Developer portal](https://developer.apple.com/account/resources/identifiers/list/passTypeId), then download your signing certificate and convert it to PEM.
69
+
70
+ **Google** — requires a Google Wallet issuer account. [Set one up in the Pay & Wallet Console](https://pay.google.com/business/console), create a service account, and download the JSON key.
71
+
72
+ ## License
73
+
74
+ MIT
package/dist/index.cjs CHANGED
@@ -439,7 +439,7 @@ async function getAccessToken(credentials, privateKey) {
439
439
  const text = await response.text();
440
440
  throw new WalletError(
441
441
  "GOOGLE_API_ERROR",
442
- `Failed to obtain access token (${response.status}): ${text}`
442
+ `Failed to obtain access token (${response.status}): ${extractGoogleDetail(text)}`
443
443
  );
444
444
  }
445
445
  const data = await response.json();
@@ -460,12 +460,23 @@ async function walletRequest(method, path, credentials, privateKey, body) {
460
460
  body: body === void 0 ? void 0 : JSON.stringify(body)
461
461
  });
462
462
  }
463
+ function extractGoogleDetail(text) {
464
+ try {
465
+ const body = JSON.parse(text);
466
+ if (body.error?.message) {
467
+ return body.error.message;
468
+ }
469
+ } catch {
470
+ }
471
+ return text;
472
+ }
463
473
  async function assertOk(response) {
464
474
  if (!response.ok) {
465
475
  const text = await response.text();
476
+ const detail = extractGoogleDetail(text);
466
477
  throw new WalletError(
467
478
  "GOOGLE_API_ERROR",
468
- `Google Wallet API error (${response.status}): ${text}`
479
+ `Google Wallet API error (${response.status}): ${detail}`
469
480
  );
470
481
  }
471
482
  }
@@ -484,7 +495,7 @@ async function ensureClass(classType, classId, classBody, credentials, privateKe
484
495
  const text = await existing.text();
485
496
  throw new WalletError(
486
497
  "GOOGLE_API_ERROR",
487
- `Google Wallet API error (${existing.status}): ${text}`
498
+ `Google Wallet API error (${existing.status}): ${extractGoogleDetail(text)}`
488
499
  );
489
500
  }
490
501
  await assertOk(