passlet 0.2.0 → 0.2.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.
- package/README.md +72 -0
- package/dist/index.cjs +14 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/package.json +20 -16
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
[](https://www.npmjs.com/package/passlet)
|
|
9
|
+
[](https://www.npmjs.com/package/passlet)
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install passlet
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { Wallet, field } from "passlet";
|
|
21
|
+
|
|
22
|
+
const wallet = new Wallet({
|
|
23
|
+
apple: {
|
|
24
|
+
passTypeIdentifier: process.env.APPLE_PASS_TYPE_ID!,
|
|
25
|
+
teamId: process.env.APPLE_TEAM_ID!,
|
|
26
|
+
signerCert: process.env.APPLE_SIGNER_CERT!,
|
|
27
|
+
signerKey: process.env.APPLE_SIGNER_KEY!,
|
|
28
|
+
wwdr: process.env.APPLE_WWDR!,
|
|
29
|
+
},
|
|
30
|
+
google: {
|
|
31
|
+
issuerId: process.env.GOOGLE_ISSUER_ID!,
|
|
32
|
+
clientEmail: process.env.GOOGLE_CLIENT_EMAIL!,
|
|
33
|
+
privateKey: process.env.GOOGLE_PRIVATE_KEY!,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const pass = wallet.loyalty({
|
|
38
|
+
id: "my-rewards",
|
|
39
|
+
name: "Rewards Card",
|
|
40
|
+
fields: [
|
|
41
|
+
field.primary("points", "Points", "1250"),
|
|
42
|
+
field.secondary("tier", "Tier", "Gold"),
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const { apple, google } = await pass.create({ serialNumber: "user-123" });
|
|
47
|
+
// apple → Uint8Array (.pkpass file, serve with Content-Type: application/vnd.apple.pkpass)
|
|
48
|
+
// google → JWT string (save link: https://pay.google.com/gp/v/save/<jwt>)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Omit `apple` or `google` from the credentials to skip that provider.
|
|
52
|
+
|
|
53
|
+
## Pass types
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
wallet.loyalty(config);
|
|
57
|
+
wallet.event(config);
|
|
58
|
+
wallet.flight(config);
|
|
59
|
+
wallet.coupon(config);
|
|
60
|
+
wallet.giftCard(config);
|
|
61
|
+
wallet.generic(config);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Credentials
|
|
65
|
+
|
|
66
|
+
**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.
|
|
67
|
+
|
|
68
|
+
**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.
|
|
69
|
+
|
|
70
|
+
## License
|
|
71
|
+
|
|
72
|
+
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}): ${
|
|
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(
|