diff --git a/.gitignore b/.gitignore
index 695d4b8..afc002c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,8 @@ node_modules
passModels/
certificates/
*.code-workspace
-.vscode/
+.vscode/*
+!.vscode/settings.json
*.js
lib/
examples/build
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..c2dd81d
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "bracketSpacing": true,
+ "trailingComma": "all",
+ "tabWidth": 4,
+ "useTabs": true
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..2e8a291
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "editor.tabSize": 4,
+ "editor.formatOnSave": true,
+ "editor.insertSpaces": false,
+ "editor.smoothScrolling": true,
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+}
diff --git a/examples/README.md b/examples/README.md
index 9c6d87a..e18c4bb 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -2,7 +2,7 @@
This is examples folder. These examples are used to test new features and as sample showcases.
-Each example is linked to webserver.js, which *requires* express.js to run.
+Each example is linked to webserver.js, which _requires_ express.js to run.
Express.js has been inserted as "example package" dipendency.
```sh
@@ -18,6 +18,7 @@ To make them work, you'll have to edit both certificates and model path.
Visit [http://localhost:8080/gen/examplePass](http://localhost:8080/gen/examplePass) to get the pass. Replace "examplePass" with the pass name in models folder.
Please note that `field.js` example will force you to download `exampleBooking.pass`, no matter what.
-___
+
+---
Every contribution is really appreciated. ❤️ Thank you!
diff --git a/examples/abstractModel.ts b/examples/abstractModel.ts
index 0ce9ee2..5eb3c7a 100644
--- a/examples/abstractModel.ts
+++ b/examples/abstractModel.ts
@@ -1,5 +1,9 @@
import genRoute, { app } from "./webserver";
-import { createPass, createAbstractModel, AbstractModel } from "passkit-generator";
+import {
+ createPass,
+ createAbstractModel,
+ AbstractModel,
+} from "passkit-generator";
let abstractModel: AbstractModel;
@@ -11,148 +15,182 @@ let abstractModel: AbstractModel;
signerCert: "../certificates/signerCert.pem",
signerKey: {
keyFile: "../certificates/signerKey.pem",
- passphrase: "123456"
- }
+ passphrase: "123456",
+ },
},
// overrides: request.body || request.params || request.query,
});
})();
genRoute.all(async function manageRequest(request, response) {
- const passName = request.params.modelName + "_" + (new Date()).toISOString().split('T')[0].replace(/-/ig, "");
+ const passName =
+ request.params.modelName +
+ "_" +
+ new Date().toISOString().split("T")[0].replace(/-/gi, "");
try {
const pass = await createPass(abstractModel);
pass.transitType = "PKTransitTypeAir";
- pass.headerFields.push({
- "key": "header1",
- "label": "Data",
- "value": "25 mag",
- "textAlignment": "PKTextAlignmentCenter"
- }, {
- "key": "header2",
- "label": "Volo",
- "value": "EZY997",
- "textAlignment": "PKTextAlignmentCenter"
- });
+ pass.headerFields.push(
+ {
+ key: "header1",
+ label: "Data",
+ value: "25 mag",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "header2",
+ label: "Volo",
+ value: "EZY997",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ );
- pass.primaryFields.push({
- key: "IATA-source",
- value: "NAP",
- label: "Napoli",
- textAlignment: "PKTextAlignmentLeft"
- }, {
- key: "IATA-destination",
- value: "VCE",
- label: "Venezia Marco Polo",
- textAlignment: "PKTextAlignmentRight"
- });
+ pass.primaryFields.push(
+ {
+ key: "IATA-source",
+ value: "NAP",
+ label: "Napoli",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "IATA-destination",
+ value: "VCE",
+ label: "Venezia Marco Polo",
+ textAlignment: "PKTextAlignmentRight",
+ },
+ );
- pass.secondaryFields.push({
- "key": "secondary1",
- "label": "Imbarco chiuso",
- "value": "18:40",
- "textAlignment": "PKTextAlignmentCenter",
- }, {
- "key": "sec2",
- "label": "Partenze",
- "value": "19:10",
- "textAlignment": "PKTextAlignmentCenter"
- }, {
- "key": "sec3",
- "label": "SB",
- "value": "Sì",
- "textAlignment": "PKTextAlignmentCenter"
- }, {
- "key": "sec4",
- "label": "Imbarco",
- "value": "Anteriore",
- "textAlignment": "PKTextAlignmentCenter"
- });
+ pass.secondaryFields.push(
+ {
+ key: "secondary1",
+ label: "Imbarco chiuso",
+ value: "18:40",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "sec2",
+ label: "Partenze",
+ value: "19:10",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "sec3",
+ label: "SB",
+ value: "Sì",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "sec4",
+ label: "Imbarco",
+ value: "Anteriore",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ );
- pass.auxiliaryFields.push({
- "key": "aux1",
- "label": "Passeggero",
- "value": "MR. WHO KNOWS",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "aux2",
- "label": "Posto",
- "value": "1A*",
- "textAlignment": "PKTextAlignmentCenter"
- });
+ pass.auxiliaryFields.push(
+ {
+ key: "aux1",
+ label: "Passeggero",
+ value: "MR. WHO KNOWS",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "aux2",
+ label: "Posto",
+ value: "1A*",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ );
- pass.backFields.push({
- "key": "document number",
- "label": "Numero documento:",
- "value": "- -",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "You're checked in, what next",
- "label": "Hai effettuato il check-in, Quali sono le prospettive",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Check In",
- "label": "1. check-in✓",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "checkIn",
- "label": "",
- "value": "Le uscite d'imbarco chiudono 30 minuti prima della partenza, quindi sii puntuale. In questo aeroporto puoi utilizzare la corsia Fast Track ai varchi di sicurezza.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "2. Bags",
- "label": "2. Bagaglio",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Require special assistance",
- "label": "Assistenza speciale",
- "value": "Se hai richiesto assistenza speciale, presentati a un membro del personale nell'area di Consegna bagagli almeno 90 minuti prima del volo.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "3. Departures",
- "label": "3. Partenze",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "photoId",
- "label": "Un documento d’identità corredato di fotografia",
- "value": "è obbligatorio su TUTTI i voli. Per un viaggio internazionale è necessario un passaporto valido o, dove consentita, una carta d’identità.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "yourSeat",
- "label": "Il tuo posto:",
- "value": "verifica il tuo numero di posto nella parte superiore. Durante l’imbarco utilizza le scale anteriori e posteriori: per le file 1-10 imbarcati dalla parte anteriore; per le file 11-31 imbarcati dalla parte posteriore. Colloca le borse di dimensioni ridotte sotto il sedile davanti a te.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Pack safely",
- "label": "Bagaglio sicuro",
- "value": "Fai clic http://easyjet.com/it/articoli-pericolosi per maggiori informazioni sulle merci pericolose oppure visita il sito CAA http://www.caa.co.uk/default.aspx?catid=2200",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Thank you for travelling easyJet",
- "label": "Grazie per aver viaggiato con easyJet",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- });
+ pass.backFields.push(
+ {
+ key: "document number",
+ label: "Numero documento:",
+ value: "- -",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "You're checked in, what next",
+ label: "Hai effettuato il check-in, Quali sono le prospettive",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Check In",
+ label: "1. check-in✓",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "checkIn",
+ label: "",
+ value:
+ "Le uscite d'imbarco chiudono 30 minuti prima della partenza, quindi sii puntuale. In questo aeroporto puoi utilizzare la corsia Fast Track ai varchi di sicurezza.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "2. Bags",
+ label: "2. Bagaglio",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Require special assistance",
+ label: "Assistenza speciale",
+ value:
+ "Se hai richiesto assistenza speciale, presentati a un membro del personale nell'area di Consegna bagagli almeno 90 minuti prima del volo.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "3. Departures",
+ label: "3. Partenze",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "photoId",
+ label: "Un documento d’identità corredato di fotografia",
+ value:
+ "è obbligatorio su TUTTI i voli. Per un viaggio internazionale è necessario un passaporto valido o, dove consentita, una carta d’identità.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "yourSeat",
+ label: "Il tuo posto:",
+ value:
+ "verifica il tuo numero di posto nella parte superiore. Durante l’imbarco utilizza le scale anteriori e posteriori: per le file 1-10 imbarcati dalla parte anteriore; per le file 11-31 imbarcati dalla parte posteriore. Colloca le borse di dimensioni ridotte sotto il sedile davanti a te.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Pack safely",
+ label: "Bagaglio sicuro",
+ value:
+ "Fai clic http://easyjet.com/it/articoli-pericolosi per maggiori informazioni sulle merci pericolose oppure visita il sito CAA http://www.caa.co.uk/default.aspx?catid=2200",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Thank you for travelling easyJet",
+ label: "Grazie per aver viaggiato con easyJet",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ );
const stream = pass.generate();
response.set({
"Content-type": "application/vnd.apple.pkpass",
- "Content-disposition": `attachment; filename=${passName}.pkpass`
+ "Content-disposition": `attachment; filename=${passName}.pkpass`,
});
stream.pipe(response);
- } catch(err) {
+ } catch (err) {
console.log(err);
response.set({
- "Content-type": "text/html"
+ "Content-type": "text/html",
});
response.send(err.message);
diff --git a/examples/additionalBuffers.ts b/examples/additionalBuffers.ts
index 8d6c750..1f30f38 100644
--- a/examples/additionalBuffers.ts
+++ b/examples/additionalBuffers.ts
@@ -11,12 +11,14 @@ import fetch from "node-fetch";
import { createPass } from "passkit-generator";
app.all(async function manageRequest(request, response) {
- let passName = request.params.modelName + "_" + (new Date()).toISOString().split('T')[0].replace(/-/ig, "");
+ let passName =
+ request.params.modelName +
+ "_" +
+ new Date().toISOString().split("T")[0].replace(/-/gi, "");
- const avatar = await (
- fetch("https://s.gravatar.com/avatar/83cd11399b7ea79977bc302f3931ee52?size=32&default=retro")
- .then(res => res.buffer())
- );
+ const avatar = await fetch(
+ "https://s.gravatar.com/avatar/83cd11399b7ea79977bc302f3931ee52?size=32&default=retro",
+ ).then((res) => res.buffer());
const passConfig = {
model: `./models/${request.params.modelName}`,
@@ -25,8 +27,8 @@ app.all(async function manageRequest(request, response) {
signerCert: "../certificates/signerCert.pem",
signerKey: {
keyFile: "../certificates/signerKey.pem",
- passphrase: "123456"
- }
+ passphrase: "123456",
+ },
},
overrides: request.body || request.params || request.query,
};
@@ -44,7 +46,7 @@ app.all(async function manageRequest(request, response) {
response.set({
"Content-type": "application/vnd.apple.pkpass",
- "Content-disposition": `attachment; filename=${passName}.pkpass`
+ "Content-disposition": `attachment; filename=${passName}.pkpass`,
});
stream.pipe(response);
diff --git a/examples/barcode.ts b/examples/barcode.ts
index 1d3f59f..17302bb 100644
--- a/examples/barcode.ts
+++ b/examples/barcode.ts
@@ -12,7 +12,10 @@ import app from "./webserver";
import { createPass } from "passkit-generator";
app.all(async function manageRequest(request, response) {
- const passName = request.params.modelName + "_" + (new Date()).toISOString().split('T')[0].replace(/-/ig, "");
+ const passName =
+ request.params.modelName +
+ "_" +
+ new Date().toISOString().split("T")[0].replace(/-/gi, "");
try {
const pass = await createPass({
@@ -22,8 +25,8 @@ app.all(async function manageRequest(request, response) {
signerCert: "../certificates/signerCert.pem",
signerKey: {
keyFile: "../certificates/signerKey.pem",
- passphrase: "123456"
- }
+ passphrase: "123456",
+ },
},
overrides: request.body || request.params || request.query,
});
@@ -37,17 +40,21 @@ app.all(async function manageRequest(request, response) {
// After this, pass.props["barcodes"] will have support for just two of three
// of the passed format (the valid ones);
- pass.barcodes({
- message: "Thank you for using this package <3",
- format: "PKBarcodeFormatCode128"
- }, {
- message: "Thank you for using this package <3",
- format: "PKBarcodeFormatPDF417"
- }, {
- message: "Thank you for using this package <3",
- // @ts-expect-error
- format: "PKBarcodeFormatMock44617"
- });
+ pass.barcodes(
+ {
+ message: "Thank you for using this package <3",
+ format: "PKBarcodeFormatCode128",
+ },
+ {
+ message: "Thank you for using this package <3",
+ format: "PKBarcodeFormatPDF417",
+ },
+ {
+ message: "Thank you for using this package <3",
+ // @ts-expect-error
+ format: "PKBarcodeFormatMock44617",
+ },
+ );
}
// You can change the format chosen for barcode prop support by calling .barcode()
@@ -57,12 +64,15 @@ app.all(async function manageRequest(request, response) {
pass.barcode("PKBarcodeFormatPDF417");
console.log("Barcode property is now:", pass.props["barcode"]);
- console.log("Barcodes support is autocompleted:", pass.props["barcodes"]);
+ console.log(
+ "Barcodes support is autocompleted:",
+ pass.props["barcodes"],
+ );
const stream = pass.generate();
response.set({
"Content-type": "application/vnd.apple.pkpass",
- "Content-disposition": `attachment; filename=${passName}.pkpass`
+ "Content-disposition": `attachment; filename=${passName}.pkpass`,
});
stream.pipe(response);
diff --git a/examples/expiration.ts b/examples/expiration.ts
index ca650a7..76ac077 100644
--- a/examples/expiration.ts
+++ b/examples/expiration.ts
@@ -13,11 +13,16 @@ import { createPass } from "passkit-generator";
app.all(async function manageRequest(request, response) {
if (!request.query.fn) {
- response.send("Generate a voided pass.
Generate a pass with expiration date");
+ response.send(
+ "Generate a voided pass.
Generate a pass with expiration date",
+ );
return;
}
- let passName = request.params.modelName + "_" + (new Date()).toISOString().split('T')[0].replace(/-/ig, "");
+ let passName =
+ request.params.modelName +
+ "_" +
+ new Date().toISOString().split("T")[0].replace(/-/gi, "");
try {
let pass = await createPass({
@@ -27,8 +32,8 @@ app.all(async function manageRequest(request, response) {
signerCert: "../certificates/signerCert.pem",
signerKey: {
keyFile: "../certificates/signerKey.pem",
- passphrase: "123456"
- }
+ passphrase: "123456",
+ },
},
overrides: request.body || request.params || request.query,
});
@@ -47,7 +52,7 @@ app.all(async function manageRequest(request, response) {
const stream = pass.generate();
response.set({
"Content-type": "application/vnd.apple.pkpass",
- "Content-disposition": `attachment; filename=${passName}.pkpass`
+ "Content-disposition": `attachment; filename=${passName}.pkpass`,
});
stream.pipe(response);
diff --git a/examples/fields.ts b/examples/fields.ts
index 241b552..98fce6e 100644
--- a/examples/fields.ts
+++ b/examples/fields.ts
@@ -13,7 +13,10 @@ import app from "./webserver";
import { createPass } from "passkit-generator";
app.all(async function manageRequest(request, response) {
- let passName = "exampleBooking" + "_" + (new Date()).toISOString().split('T')[0].replace(/-/ig, "");
+ let passName =
+ "exampleBooking" +
+ "_" +
+ new Date().toISOString().split("T")[0].replace(/-/gi, "");
try {
let pass = await createPass({
model: `./models/exampleBooking`,
@@ -22,133 +25,164 @@ app.all(async function manageRequest(request, response) {
signerCert: "../certificates/signerCert.pem",
signerKey: {
keyFile: "../certificates/signerKey.pem",
- passphrase: "123456"
- }
+ passphrase: "123456",
+ },
},
overrides: request.body || request.params || request.query,
});
pass.transitType = "PKTransitTypeAir";
- pass.headerFields.push({
- "key": "header1",
- "label": "Data",
- "value": "25 mag",
- "textAlignment": "PKTextAlignmentCenter"
- }, {
- "key": "header2",
- "label": "Volo",
- "value": "EZY997",
- "textAlignment": "PKTextAlignmentCenter"
- });
+ pass.headerFields.push(
+ {
+ key: "header1",
+ label: "Data",
+ value: "25 mag",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "header2",
+ label: "Volo",
+ value: "EZY997",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ );
- pass.primaryFields.push({
- key: "IATA-source",
- value: "NAP",
- label: "Napoli",
- textAlignment: "PKTextAlignmentLeft"
- }, {
- key: "IATA-destination",
- value: "VCE",
- label: "Venezia Marco Polo",
- textAlignment: "PKTextAlignmentRight"
- });
+ pass.primaryFields.push(
+ {
+ key: "IATA-source",
+ value: "NAP",
+ label: "Napoli",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "IATA-destination",
+ value: "VCE",
+ label: "Venezia Marco Polo",
+ textAlignment: "PKTextAlignmentRight",
+ },
+ );
- pass.secondaryFields.push({
- "key": "secondary1",
- "label": "Imbarco chiuso",
- "value": "18:40",
- "textAlignment": "PKTextAlignmentCenter",
- }, {
- "key": "sec2",
- "label": "Partenze",
- "value": "19:10",
- "textAlignment": "PKTextAlignmentCenter"
- }, {
- "key": "sec3",
- "label": "SB",
- "value": "Sì",
- "textAlignment": "PKTextAlignmentCenter"
- }, {
- "key": "sec4",
- "label": "Imbarco",
- "value": "Anteriore",
- "textAlignment": "PKTextAlignmentCenter"
- });
+ pass.secondaryFields.push(
+ {
+ key: "secondary1",
+ label: "Imbarco chiuso",
+ value: "18:40",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "sec2",
+ label: "Partenze",
+ value: "19:10",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "sec3",
+ label: "SB",
+ value: "Sì",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ {
+ key: "sec4",
+ label: "Imbarco",
+ value: "Anteriore",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ );
- pass.auxiliaryFields.push({
- "key": "aux1",
- "label": "Passeggero",
- "value": "MR. WHO KNOWS",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "aux2",
- "label": "Posto",
- "value": "1A*",
- "textAlignment": "PKTextAlignmentCenter"
- });
+ pass.auxiliaryFields.push(
+ {
+ key: "aux1",
+ label: "Passeggero",
+ value: "MR. WHO KNOWS",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "aux2",
+ label: "Posto",
+ value: "1A*",
+ textAlignment: "PKTextAlignmentCenter",
+ },
+ );
- pass.backFields.push({
- "key": "document number",
- "label": "Numero documento:",
- "value": "- -",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "You're checked in, what next",
- "label": "Hai effettuato il check-in, Quali sono le prospettive",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Check In",
- "label": "1. check-in✓",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "checkIn",
- "label": "",
- "value": "Le uscite d'imbarco chiudono 30 minuti prima della partenza, quindi sii puntuale. In questo aeroporto puoi utilizzare la corsia Fast Track ai varchi di sicurezza.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "2. Bags",
- "label": "2. Bagaglio",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Require special assistance",
- "label": "Assistenza speciale",
- "value": "Se hai richiesto assistenza speciale, presentati a un membro del personale nell'area di Consegna bagagli almeno 90 minuti prima del volo.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "3. Departures",
- "label": "3. Partenze",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "photoId",
- "label": "Un documento d’identità corredato di fotografia",
- "value": "è obbligatorio su TUTTI i voli. Per un viaggio internazionale è necessario un passaporto valido o, dove consentita, una carta d’identità.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "yourSeat",
- "label": "Il tuo posto:",
- "value": "verifica il tuo numero di posto nella parte superiore. Durante l’imbarco utilizza le scale anteriori e posteriori: per le file 1-10 imbarcati dalla parte anteriore; per le file 11-31 imbarcati dalla parte posteriore. Colloca le borse di dimensioni ridotte sotto il sedile davanti a te.",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Pack safely",
- "label": "Bagaglio sicuro",
- "value": "Fai clic http://easyjet.com/it/articoli-pericolosi per maggiori informazioni sulle merci pericolose oppure visita il sito CAA http://www.caa.co.uk/default.aspx?catid=2200",
- "textAlignment": "PKTextAlignmentLeft"
- }, {
- "key": "Thank you for travelling easyJet",
- "label": "Grazie per aver viaggiato con easyJet",
- "value": "",
- "textAlignment": "PKTextAlignmentLeft"
- });
+ pass.backFields.push(
+ {
+ key: "document number",
+ label: "Numero documento:",
+ value: "- -",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "You're checked in, what next",
+ label: "Hai effettuato il check-in, Quali sono le prospettive",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Check In",
+ label: "1. check-in✓",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "checkIn",
+ label: "",
+ value:
+ "Le uscite d'imbarco chiudono 30 minuti prima della partenza, quindi sii puntuale. In questo aeroporto puoi utilizzare la corsia Fast Track ai varchi di sicurezza.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "2. Bags",
+ label: "2. Bagaglio",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Require special assistance",
+ label: "Assistenza speciale",
+ value:
+ "Se hai richiesto assistenza speciale, presentati a un membro del personale nell'area di Consegna bagagli almeno 90 minuti prima del volo.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "3. Departures",
+ label: "3. Partenze",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "photoId",
+ label: "Un documento d’identità corredato di fotografia",
+ value:
+ "è obbligatorio su TUTTI i voli. Per un viaggio internazionale è necessario un passaporto valido o, dove consentita, una carta d’identità.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "yourSeat",
+ label: "Il tuo posto:",
+ value:
+ "verifica il tuo numero di posto nella parte superiore. Durante l’imbarco utilizza le scale anteriori e posteriori: per le file 1-10 imbarcati dalla parte anteriore; per le file 11-31 imbarcati dalla parte posteriore. Colloca le borse di dimensioni ridotte sotto il sedile davanti a te.",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Pack safely",
+ label: "Bagaglio sicuro",
+ value:
+ "Fai clic http://easyjet.com/it/articoli-pericolosi per maggiori informazioni sulle merci pericolose oppure visita il sito CAA http://www.caa.co.uk/default.aspx?catid=2200",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ {
+ key: "Thank you for travelling easyJet",
+ label: "Grazie per aver viaggiato con easyJet",
+ value: "",
+ textAlignment: "PKTextAlignmentLeft",
+ },
+ );
const stream = pass.generate();
response.set({
"Content-type": "application/vnd.apple.pkpass",
- "Content-disposition": `attachment; filename=${passName}.pkpass`
+ "Content-disposition": `attachment; filename=${passName}.pkpass`,
});
stream.pipe(response);
@@ -156,7 +190,7 @@ app.all(async function manageRequest(request, response) {
console.log(err);
response.set({
- "Content-type": "text/html"
+ "Content-type": "text/html",
});
response.send(err.message);
diff --git a/examples/localization.ts b/examples/localization.ts
index 55cf44e..0723bfb 100644
--- a/examples/localization.ts
+++ b/examples/localization.ts
@@ -8,7 +8,10 @@ import app from "./webserver";
import { createPass } from "passkit-generator";
app.all(async function manageRequest(request, response) {
- const passName = request.params.modelName + "_" + (new Date()).toISOString().split('T')[0].replace(/-/ig, "");
+ const passName =
+ request.params.modelName +
+ "_" +
+ new Date().toISOString().split("T")[0].replace(/-/gi, "");
try {
const pass = await createPass({
@@ -18,10 +21,10 @@ app.all(async function manageRequest(request, response) {
signerCert: "../certificates/signerCert.pem",
signerKey: {
keyFile: "../certificates/signerKey.pem",
- passphrase: "123456"
- }
+ passphrase: "123456",
+ },
},
- overrides: request.body || request.params || request.query
+ overrides: request.body || request.params || request.query,
});
// For each language you include, an .lproj folder in pass bundle
@@ -38,30 +41,33 @@ app.all(async function manageRequest(request, response) {
// Italian, already has an .lproj which gets included
pass.localize("it", {
- "EVENT": "Evento",
- "LOCATION": "Dove"
+ EVENT: "Evento",
+ LOCATION: "Dove",
});
// German, doesn't, so is created
pass.localize("de", {
- "EVENT": "Ereignis",
- "LOCATION": "Ort"
+ EVENT: "Ereignis",
+ LOCATION: "Ort",
});
// This language does not exist but is still added as .lproj folder
pass.localize("zu", {});
// @ts-ignore - ignoring for logging purposes. Do not replicate
- console.log("Added languages", Object.keys(pass.l10nTranslations).join(", "))
+ console.log(
+ "Added languages",
+ Object.keys(pass.l10nTranslations).join(", "),
+ );
const stream = pass.generate();
response.set({
"Content-type": "application/vnd.apple.pkpass",
- "Content-disposition": `attachment; filename=${passName}.pkpass`
+ "Content-disposition": `attachment; filename=${passName}.pkpass`,
});
stream.pipe(response);
- } catch(err) {
+ } catch (err) {
console.log(err);
response.set({
diff --git a/examples/models/examplePass.pass/pass.json b/examples/models/examplePass.pass/pass.json
index 673f4fb..6b2f743 100644
--- a/examples/models/examplePass.pass/pass.json
+++ b/examples/models/examplePass.pass/pass.json
@@ -1,49 +1,51 @@
{
- "formatVersion": 1,
- "passTypeIdentifier": "pass.com.example.myapp",
- "serialNumber": "nmyuxofgna",
- "teamIdentifier": "F53WB8AE67",
- "webServiceURL": "https://192.168.1.254:80/",
- "authenticationToken": "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc",
- "relevantDate": "2011-12-08T13:00-08:00",
- "locations": [
- {
- "longitude": -122.3748889,
- "latitude": 37.6189722
- },
- {
- "longitude": -122.03118,
- "latitude": 37.33182
- }
- ],
- "barcodes": [{
- "message": "123456789",
- "format": "PKBarcodeFormatQR",
- "messageEncoding": "iso-8859-1"
- }],
- "barcode": {
- "message": "123456789",
- "format": "PKBarcodeFormatQR",
- "messageEncoding": "iso-8859-1"
- },
- "organizationName": "Apple Inc.",
- "description": "Apple Event Ticket",
- "foregroundColor": "rgb(255, 255, 255)",
- "backgroundColor": "rgb(60, 65, 76)",
- "eventTicket": {
- "primaryFields": [
- {
- "key": "event",
- "label": "EVENT",
- "value": "The Beat Goes On"
- }
- ],
- "secondaryFields": [
- {
- "key": "loc",
- "label": "LOCATION",
- "value": "Moscone West"
- }
- ]
- }
+ "formatVersion": 1,
+ "passTypeIdentifier": "pass.com.example.myapp",
+ "serialNumber": "nmyuxofgna",
+ "teamIdentifier": "F53WB8AE67",
+ "webServiceURL": "https://192.168.1.254:80/",
+ "authenticationToken": "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc",
+ "relevantDate": "2011-12-08T13:00-08:00",
+ "locations": [
+ {
+ "longitude": -122.3748889,
+ "latitude": 37.6189722
+ },
+ {
+ "longitude": -122.03118,
+ "latitude": 37.33182
+ }
+ ],
+ "barcodes": [
+ {
+ "message": "123456789",
+ "format": "PKBarcodeFormatQR",
+ "messageEncoding": "iso-8859-1"
+ }
+ ],
+ "barcode": {
+ "message": "123456789",
+ "format": "PKBarcodeFormatQR",
+ "messageEncoding": "iso-8859-1"
+ },
+ "organizationName": "Apple Inc.",
+ "description": "Apple Event Ticket",
+ "foregroundColor": "rgb(255, 255, 255)",
+ "backgroundColor": "rgb(60, 65, 76)",
+ "eventTicket": {
+ "primaryFields": [
+ {
+ "key": "event",
+ "label": "EVENT",
+ "value": "The Beat Goes On"
+ }
+ ],
+ "secondaryFields": [
+ {
+ "key": "loc",
+ "label": "LOCATION",
+ "value": "Moscone West"
+ }
+ ]
+ }
}
diff --git a/examples/package-lock.json b/examples/package-lock.json
index 8332f33..160d7f7 100644
--- a/examples/package-lock.json
+++ b/examples/package-lock.json
@@ -1,560 +1,560 @@
{
- "name": "examples",
- "version": "0.0.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@hapi/hoek": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz",
- "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw=="
- },
- "@hapi/topo": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
- "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@sideway/address": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.0.tgz",
- "integrity": "sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@sideway/formula": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
- "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg=="
- },
- "@sideway/pinpoint": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
- "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
- },
- "@types/body-parser": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz",
- "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==",
- "dev": true,
- "requires": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "@types/connect": {
- "version": "3.4.32",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
- "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
- "dev": true,
- "requires": {
- "@types/node": "*"
- }
- },
- "@types/express": {
- "version": "4.17.0",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.0.tgz",
- "integrity": "sha512-CjaMu57cjgjuZbh9DpkloeGxV45CnMGlVd+XpG7Gm9QgVrd7KFq+X4HY0vM+2v0bczS48Wg7bvnMY5TN+Xmcfw==",
- "dev": true,
- "requires": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "*",
- "@types/serve-static": "*"
- }
- },
- "@types/express-serve-static-core": {
- "version": "4.16.7",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.7.tgz",
- "integrity": "sha512-847KvL8Q1y3TtFLRTXcVakErLJQgdpFSaq+k043xefz9raEf0C7HalpSY7OW5PyjCnY8P7bPW5t/Co9qqp+USg==",
- "dev": true,
- "requires": {
- "@types/node": "*",
- "@types/range-parser": "*"
- }
- },
- "@types/mime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
- "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==",
- "dev": true
- },
- "@types/node": {
- "version": "12.6.8",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
- "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==",
- "dev": true
- },
- "@types/node-fetch": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.0.tgz",
- "integrity": "sha512-TLFRywthBgL68auWj+ziWu+vnmmcHCDFC/sqCOQf1xTz4hRq8cu79z8CtHU9lncExGBsB8fXA4TiLDLt6xvMzw==",
- "dev": true,
- "requires": {
- "@types/node": "*"
- }
- },
- "@types/range-parser": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
- "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
- "dev": true
- },
- "@types/serve-static": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz",
- "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==",
- "dev": true,
- "requires": {
- "@types/express-serve-static-core": "*",
- "@types/mime": "*"
- }
- },
- "accepts": {
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
- "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
- "requires": {
- "mime-types": "~2.1.24",
- "negotiator": "0.6.2"
- }
- },
- "array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
- },
- "body-parser": {
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
- "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
- "requires": {
- "bytes": "3.1.0",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "http-errors": "1.7.2",
- "iconv-lite": "0.4.24",
- "on-finished": "~2.3.0",
- "qs": "6.7.0",
- "raw-body": "2.4.0",
- "type-is": "~1.6.17"
- }
- },
- "buffer-crc32": {
- "version": "0.2.13",
- "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
- },
- "bytes": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
- "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
- },
- "content-disposition": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
- "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
- "requires": {
- "safe-buffer": "5.1.2"
- }
- },
- "content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
- },
- "cookie": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
- "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "depd": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
- "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
- },
- "destroy": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
- },
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
- },
- "express": {
- "version": "4.17.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
- "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
- "requires": {
- "accepts": "~1.3.7",
- "array-flatten": "1.1.1",
- "body-parser": "1.19.0",
- "content-disposition": "0.5.3",
- "content-type": "~1.0.4",
- "cookie": "0.4.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "~1.1.2",
- "fresh": "0.5.2",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.5",
- "qs": "6.7.0",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.1.2",
- "send": "0.17.1",
- "serve-static": "1.14.1",
- "setprototypeof": "1.1.1",
- "statuses": "~1.5.0",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- }
- },
- "finalhandler": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
- "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "~2.3.0",
- "parseurl": "~1.3.3",
- "statuses": "~1.5.0",
- "unpipe": "~1.0.0"
- }
- },
- "forwarded": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
- "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
- },
- "http-errors": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
- "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
- "requires": {
- "depd": "~1.1.2",
- "inherits": "2.0.3",
- "setprototypeof": "1.1.1",
- "statuses": ">= 1.5.0 < 2",
- "toidentifier": "1.0.0"
- }
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "ipaddr.js": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
- "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
- },
- "joi": {
- "version": "17.3.0",
- "resolved": "https://registry.npmjs.org/joi/-/joi-17.3.0.tgz",
- "integrity": "sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg==",
- "requires": {
- "@hapi/hoek": "^9.0.0",
- "@hapi/topo": "^5.0.0",
- "@sideway/address": "^4.1.0",
- "@sideway/formula": "^3.0.0",
- "@sideway/pinpoint": "^2.0.0"
- }
- },
- "media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
- },
- "merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
- },
- "methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
- },
- "mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
- },
- "mime-db": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
- "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
- },
- "mime-types": {
- "version": "2.1.24",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
- "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
- "requires": {
- "mime-db": "1.40.0"
- }
- },
- "moment": {
- "version": "2.29.1",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
- "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "negotiator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
- "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
- },
- "node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
- },
- "node-forge": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.2.tgz",
- "integrity": "sha512-naKSScof4Wn+aoHU6HBsifh92Zeicm1GDQKd1vp3Y/kOi8ub0DozCa9KpvYNCXslFHYRmLNiqRopGdTGwNLpNw=="
- },
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
- },
- "passkit-generator": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/passkit-generator/-/passkit-generator-2.0.5.tgz",
- "integrity": "sha512-qcCc82IFfzRChQPDrm/KMhuoaO5hcnnz2M2XuI4nTad3h+RcRn/gZ0H2Zqmfta3CNutr0SHKuYzUxstyTttwGA==",
- "requires": {
- "debug": "^4.1.1",
- "joi": "^17.2.1",
- "moment": "^2.27.0",
- "node-forge": "^0.9.2",
- "yazl": "^2.5.1"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
- }
- },
- "path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
- },
- "proxy-addr": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
- "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
- "requires": {
- "forwarded": "~0.1.2",
- "ipaddr.js": "1.9.0"
- }
- },
- "qs": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
- "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
- },
- "range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
- },
- "raw-body": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
- "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
- "requires": {
- "bytes": "3.1.0",
- "http-errors": "1.7.2",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "send": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
- "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
- "requires": {
- "debug": "2.6.9",
- "depd": "~1.1.2",
- "destroy": "~1.0.4",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "~1.7.2",
- "mime": "1.6.0",
- "ms": "2.1.1",
- "on-finished": "~2.3.0",
- "range-parser": "~1.2.1",
- "statuses": "~1.5.0"
- },
- "dependencies": {
- "ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
- }
- }
- },
- "serve-static": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
- "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.17.1"
- }
- },
- "setprototypeof": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
- "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
- },
- "statuses": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
- },
- "toidentifier": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
- "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
- },
- "tslib": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
- "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
- },
- "type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "requires": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- }
- },
- "typescript": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
- "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
- "dev": true
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
- },
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
- },
- "yazl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
- "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
- "requires": {
- "buffer-crc32": "~0.2.3"
- }
- }
- }
+ "name": "examples",
+ "version": "0.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@hapi/hoek": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz",
+ "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw=="
+ },
+ "@hapi/topo": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
+ "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/address": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.0.tgz",
+ "integrity": "sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA==",
+ "requires": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "@sideway/formula": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
+ "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg=="
+ },
+ "@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
+ },
+ "@types/body-parser": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz",
+ "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==",
+ "dev": true,
+ "requires": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/connect": {
+ "version": "3.4.32",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
+ "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/express": {
+ "version": "4.17.0",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.0.tgz",
+ "integrity": "sha512-CjaMu57cjgjuZbh9DpkloeGxV45CnMGlVd+XpG7Gm9QgVrd7KFq+X4HY0vM+2v0bczS48Wg7bvnMY5TN+Xmcfw==",
+ "dev": true,
+ "requires": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "@types/express-serve-static-core": {
+ "version": "4.16.7",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.7.tgz",
+ "integrity": "sha512-847KvL8Q1y3TtFLRTXcVakErLJQgdpFSaq+k043xefz9raEf0C7HalpSY7OW5PyjCnY8P7bPW5t/Co9qqp+USg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/range-parser": "*"
+ }
+ },
+ "@types/mime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
+ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "12.6.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
+ "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==",
+ "dev": true
+ },
+ "@types/node-fetch": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.0.tgz",
+ "integrity": "sha512-TLFRywthBgL68auWj+ziWu+vnmmcHCDFC/sqCOQf1xTz4hRq8cu79z8CtHU9lncExGBsB8fXA4TiLDLt6xvMzw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/range-parser": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+ "dev": true
+ },
+ "@types/serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==",
+ "dev": true,
+ "requires": {
+ "@types/express-serve-static-core": "*",
+ "@types/mime": "*"
+ }
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ }
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ipaddr.js": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
+ "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
+ },
+ "joi": {
+ "version": "17.3.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.3.0.tgz",
+ "integrity": "sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg==",
+ "requires": {
+ "@hapi/hoek": "^9.0.0",
+ "@hapi/topo": "^5.0.0",
+ "@sideway/address": "^4.1.0",
+ "@sideway/formula": "^3.0.0",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "moment": {
+ "version": "2.29.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+ },
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ },
+ "node-forge": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.2.tgz",
+ "integrity": "sha512-naKSScof4Wn+aoHU6HBsifh92Zeicm1GDQKd1vp3Y/kOi8ub0DozCa9KpvYNCXslFHYRmLNiqRopGdTGwNLpNw=="
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "passkit-generator": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/passkit-generator/-/passkit-generator-2.0.5.tgz",
+ "integrity": "sha512-qcCc82IFfzRChQPDrm/KMhuoaO5hcnnz2M2XuI4nTad3h+RcRn/gZ0H2Zqmfta3CNutr0SHKuYzUxstyTttwGA==",
+ "requires": {
+ "debug": "^4.1.1",
+ "joi": "^17.2.1",
+ "moment": "^2.27.0",
+ "node-forge": "^0.9.2",
+ "yazl": "^2.5.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "proxy-addr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
+ "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.0"
+ }
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+ },
+ "tslib": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
+ "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "typescript": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
+ "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "yazl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+ "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+ "requires": {
+ "buffer-crc32": "~0.2.3"
+ }
+ }
+ }
}
diff --git a/examples/tsconfig.json b/examples/tsconfig.json
index c6c7a01..d32b4a5 100644
--- a/examples/tsconfig.json
+++ b/examples/tsconfig.json
@@ -3,7 +3,5 @@
"compilerOptions": {
"outDir": "build"
},
- "exclude": [
- "node_modules"
- ]
+ "exclude": ["node_modules"]
}
diff --git a/examples/webserver.ts b/examples/webserver.ts
index 01141b9..5a4788c 100644
--- a/examples/webserver.ts
+++ b/examples/webserver.ts
@@ -9,7 +9,7 @@ export const app = express();
app.use(express.json());
-app.listen(8080, "0.0.0.0", function(request, response) {
+app.listen(8080, "0.0.0.0", function (request, response) {
console.log("Webserver started.");
});
@@ -17,10 +17,11 @@ app.all("/", function (request, response) {
response.redirect("/gen/");
});
-app.route("/gen")
- .all((req, res) => {
- res.set("Content-Type", "text/html");
- res.send("Cannot generate a pass. Specify a modelName in the url to continue.
Usage: /gen/modelName")
- });
+app.route("/gen").all((req, res) => {
+ res.set("Content-Type", "text/html");
+ res.send(
+ "Cannot generate a pass. Specify a modelName in the url to continue.
Usage: /gen/modelName",
+ );
+});
export default app.route("/gen/:modelName");
diff --git a/package-lock.json b/package-lock.json
index 79c14db..7ad48ed 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -209,6 +209,12 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
+ "prettier": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
+ "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
+ "dev": true
+ },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
diff --git a/package.json b/package.json
index 4fa667d..96026e0 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
"@types/node-forge": "^0.9.7",
"@types/yazl": "^2.4.2",
"jasmine": "^3.6.4",
+ "prettier": "^2.2.1",
"rimraf": "^3.0.2",
"typescript": "^4.1.3"
},
diff --git a/spec/factory.ts b/spec/factory.ts
index 070d853..b41a07f 100644
--- a/spec/factory.ts
+++ b/spec/factory.ts
@@ -6,7 +6,7 @@ import * as path from "path";
describe("createPass", () => {
it("should throw if first argument is not provided", async () => {
await expectAsync(createPass(undefined)).toBeRejectedWithError(
- formatMessage("CP_NO_OPTS")
+ formatMessage("CP_NO_OPTS"),
);
});
@@ -27,71 +27,144 @@ describe("createPass", () => {
if (certificatesPath) {
it("should return a pass instance", async () => {
- await expectAsync(createPass({
- model: path.resolve(__dirname, "../examples/models/exampleBooking.pass"),
- certificates: {
- signerCert: path.resolve(__dirname, certificatesPath, "./signerCert.pem"),
- signerKey: {
- keyFile: path.resolve(__dirname, certificatesPath, "./signerKey.pem"),
- passphrase: "password1234"
+ await expectAsync(
+ createPass({
+ model: path.resolve(
+ __dirname,
+ "../examples/models/exampleBooking.pass",
+ ),
+ certificates: {
+ signerCert: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerCert.pem",
+ ),
+ signerKey: {
+ keyFile: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerKey.pem",
+ ),
+ passphrase: "password1234",
+ },
+ wwdr: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./WWDR.pem",
+ ),
},
- wwdr: path.resolve(__dirname, certificatesPath, "./WWDR.pem"),
- }
- })).toBeResolved();
+ }),
+ ).toBeResolved();
});
describe("Model validation", () => {
it("Should reject with non valid model", async () => {
- await expectAsync(createPass({
- // @ts-expect-error
- model: 0,
- certificates: {
- signerCert: path.resolve(__dirname, certificatesPath, "./signerCert.pem"),
- signerKey: {
- keyFile: path.resolve(__dirname, certificatesPath, "./signerKey.pem"),
- passphrase: "password1234"
+ await expectAsync(
+ createPass({
+ // @ts-expect-error
+ model: 0,
+ certificates: {
+ signerCert: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerCert.pem",
+ ),
+ signerKey: {
+ keyFile: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerKey.pem",
+ ),
+ passphrase: "password1234",
+ },
+ wwdr: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./WWDR.pem",
+ ),
},
- wwdr: path.resolve(__dirname, certificatesPath, "./WWDR.pem"),
- }
- })).toBeRejected();
+ }),
+ ).toBeRejected();
- await expectAsync(createPass({
- model: undefined,
- certificates: {
- signerCert: path.resolve(__dirname, certificatesPath, "./signerCert.pem"),
- signerKey: {
- keyFile: path.resolve(__dirname, certificatesPath, "./signerKey.pem"),
- passphrase: "password1234"
+ await expectAsync(
+ createPass({
+ model: undefined,
+ certificates: {
+ signerCert: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerCert.pem",
+ ),
+ signerKey: {
+ keyFile: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerKey.pem",
+ ),
+ passphrase: "password1234",
+ },
+ wwdr: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./WWDR.pem",
+ ),
},
- wwdr: path.resolve(__dirname, certificatesPath, "./WWDR.pem"),
- }
- })).toBeRejected();
+ }),
+ ).toBeRejected();
- await expectAsync(createPass({
- model: null,
- certificates: {
- signerCert: path.resolve(__dirname, certificatesPath, "./signerCert.pem"),
- signerKey: {
- keyFile: path.resolve(__dirname, certificatesPath, "./signerKey.pem"),
- passphrase: "password1234"
+ await expectAsync(
+ createPass({
+ model: null,
+ certificates: {
+ signerCert: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerCert.pem",
+ ),
+ signerKey: {
+ keyFile: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerKey.pem",
+ ),
+ passphrase: "password1234",
+ },
+ wwdr: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./WWDR.pem",
+ ),
},
- wwdr: path.resolve(__dirname, certificatesPath, "./WWDR.pem"),
- }
- })).toBeRejected();
+ }),
+ ).toBeRejected();
- await expectAsync(createPass({
- model: {},
- certificates: {
- signerCert: path.resolve(__dirname, certificatesPath, "./signerCert.pem"),
- signerKey: {
- keyFile: path.resolve(__dirname, certificatesPath, "./signerKey.pem"),
- passphrase: "password1234"
+ await expectAsync(
+ createPass({
+ model: {},
+ certificates: {
+ signerCert: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerCert.pem",
+ ),
+ signerKey: {
+ keyFile: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./signerKey.pem",
+ ),
+ passphrase: "password1234",
+ },
+ wwdr: path.resolve(
+ __dirname,
+ certificatesPath,
+ "./WWDR.pem",
+ ),
},
- wwdr: path.resolve(__dirname, certificatesPath, "./WWDR.pem"),
- }
- })).toBeRejected();
+ }),
+ ).toBeRejected();
});
});
}
- } catch (err) { }
+ } catch (err) {}
});
diff --git a/spec/index.ts b/spec/index.ts
index a69b319..3c952b7 100644
--- a/spec/index.ts
+++ b/spec/index.ts
@@ -9,16 +9,25 @@ describe("Passkit-generator", function () {
let pass: Pass;
beforeEach(async () => {
pass = await createPass({
- model: path.resolve(__dirname, "../examples/models/examplePass.pass"),
+ model: path.resolve(
+ __dirname,
+ "../examples/models/examplePass.pass",
+ ),
certificates: {
wwdr: path.resolve(__dirname, "../certificates/WWDR.pem"),
- signerCert: path.resolve(__dirname, "../certificates/signerCert.pem"),
+ signerCert: path.resolve(
+ __dirname,
+ "../certificates/signerCert.pem",
+ ),
signerKey: {
- keyFile: path.resolve(__dirname, "../certificates/signerKey.pem"),
- passphrase: "123456"
- }
+ keyFile: path.resolve(
+ __dirname,
+ "../certificates/signerKey.pem",
+ ),
+ passphrase: "123456",
+ },
},
- overrides: {}
+ overrides: {},
});
});
@@ -48,7 +57,7 @@ describe("Passkit-generator", function () {
it("Will apply changes if a second object argument with translations is passed", () => {
pass.localize("it", {
- "Test": "Prova"
+ Test: "Prova",
});
expect(typeof pass["l10nTranslations"]["it"]).toBe("object");
@@ -99,16 +108,21 @@ describe("Passkit-generator", function () {
describe("locations()", () => {
it("Won't apply changes if invalid location objects are passed", () => {
const props = pass.props["locations"] || [];
- const oldAmountOfLocations = props && props.length || 0;
+ const oldAmountOfLocations = (props && props.length) || 0;
- pass.locations({
- // @ts-expect-error
- "ibrupofene": "no",
- "longitude": 0.00000000
- }, ...props);
+ pass.locations(
+ {
+ // @ts-expect-error
+ ibrupofene: "no",
+ longitude: 0.0,
+ },
+ ...props,
+ );
if (oldAmountOfLocations) {
- expect(pass.props["locations"].length).toBe(oldAmountOfLocations);
+ expect(pass.props["locations"].length).toBe(
+ oldAmountOfLocations,
+ );
} else {
expect(pass.props["locations"]).toBe(undefined);
}
@@ -116,33 +130,42 @@ describe("Passkit-generator", function () {
it("Will filter out invalid location objects", () => {
const props = pass.props["locations"] || [];
- const oldAmountOfLocations = props && props.length || 0;
+ const oldAmountOfLocations = (props && props.length) || 0;
- pass.locations({
- // @ts-expect-error
- "ibrupofene": "no",
- "longitude": 0.00000000
- }, {
- "longitude": 4.42634523,
- "latitude": 5.344233323352
- }, ...(pass.props["locations"] || []));
+ pass.locations(
+ {
+ // @ts-expect-error
+ ibrupofene: "no",
+ longitude: 0.0,
+ },
+ {
+ longitude: 4.42634523,
+ latitude: 5.344233323352,
+ },
+ ...(pass.props["locations"] || []),
+ );
- expect(pass.props["locations"].length).toBe((oldAmountOfLocations || 0) + 1);
+ expect(pass.props["locations"].length).toBe(
+ (oldAmountOfLocations || 0) + 1,
+ );
});
});
describe("Beacons()", () => {
it("Won't apply changes if invalid beacon objects are passed", () => {
const props = pass.props["beacons"] || [];
- const oldAmountOfBeacons = props && props.length || 0;
+ const oldAmountOfBeacons = (props && props.length) || 0;
- pass.beacons({
- // @ts-expect-error
- "ibrupofene": "no",
- "major": 55,
- "minor": 0,
- "proximityUUID": "2707c5f4-deb9-48ff-b760-671bc885b6a7"
- }, ...props);
+ pass.beacons(
+ {
+ // @ts-expect-error
+ ibrupofene: "no",
+ major: 55,
+ minor: 0,
+ proximityUUID: "2707c5f4-deb9-48ff-b760-671bc885b6a7",
+ },
+ ...props,
+ );
if (oldAmountOfBeacons) {
expect(pass.props["beacons"].length).toBe(oldAmountOfBeacons);
@@ -153,20 +176,23 @@ describe("Passkit-generator", function () {
it("Will filter out invalid beacons objects", () => {
const props = pass.props["beacons"] || [];
- const oldAmountOfBeacons = props && props.length || 0;
-
- pass.beacons({
- "major": 55,
- "minor": 0,
- "proximityUUID": "59da0f96-3fb5-43aa-9028-2bc796c3d0c5"
- }, {
- "major": 55,
- "minor": 0,
- "proximityUUID": "fdcbbf48-a4ae-4ffb-9200-f8a373c5c18e",
- // @ts-expect-error
- "animal": "Monkey"
- }, ...props);
+ const oldAmountOfBeacons = (props && props.length) || 0;
+ pass.beacons(
+ {
+ major: 55,
+ minor: 0,
+ proximityUUID: "59da0f96-3fb5-43aa-9028-2bc796c3d0c5",
+ },
+ {
+ major: 55,
+ minor: 0,
+ proximityUUID: "fdcbbf48-a4ae-4ffb-9200-f8a373c5c18e",
+ // @ts-expect-error
+ animal: "Monkey",
+ },
+ ...props,
+ );
expect(pass.props["beacons"].length).toBe(oldAmountOfBeacons + 1);
});
@@ -175,7 +201,7 @@ describe("Passkit-generator", function () {
describe("barcodes()", () => {
it("Won't apply changes if no data is passed", () => {
const props = pass.props["barcodes"] || [];
- const oldAmountOfBarcodes = props && props.length || 0;
+ const oldAmountOfBarcodes = (props && props.length) || 0;
pass.barcodes();
expect(pass.props["barcodes"].length).toBe(oldAmountOfBarcodes);
@@ -183,7 +209,7 @@ describe("Passkit-generator", function () {
it("Will ignore boolean parameter", () => {
const props = pass.props["barcodes"] || [];
- const oldAmountOfBarcodes = props && props.length || 0;
+ const oldAmountOfBarcodes = (props && props.length) || 0;
// @ts-expect-error
pass.barcode(true);
@@ -192,7 +218,7 @@ describe("Passkit-generator", function () {
it("Will ignore numeric parameter", () => {
const props = pass.props["barcodes"] || [];
- const oldAmountOfBarcodes = props && props.length || 0;
+ const oldAmountOfBarcodes = (props && props.length) || 0;
// @ts-expect-error
pass.barcodes(42);
@@ -208,7 +234,7 @@ describe("Passkit-generator", function () {
pass.barcodes({
message: "28363516282",
format: "PKBarcodeFormatPDF417",
- messageEncoding: "utf8"
+ messageEncoding: "utf8",
});
expect(pass.props["barcodes"].length).toBe(1);
@@ -220,12 +246,14 @@ describe("Passkit-generator", function () {
format: "PKBarcodeFormatPDF417",
});
- expect(pass.props["barcodes"][0].messageEncoding).toBe("iso-8859-1");
+ expect(pass.props["barcodes"][0].messageEncoding).toBe(
+ "iso-8859-1",
+ );
});
it("Will ignore objects without message property", () => {
const props = pass.props["barcodes"] || [];
- const oldAmountOfBarcodes = props && props.length || 0;
+ const oldAmountOfBarcodes = (props && props.length) || 0;
// @ts-expect-error
pass.barcodes({
@@ -237,12 +265,19 @@ describe("Passkit-generator", function () {
it("Will ignore non-Barcodes schema compliant objects", () => {
// @ts-expect-error
- pass.barcodes(5, 10, 15, {
- message: "28363516282",
- format: "PKBarcodeFormatPDF417"
- }, 7, 1);
+ pass.barcodes(
+ 5,
+ 10,
+ 15,
+ {
+ message: "28363516282",
+ format: "PKBarcodeFormatPDF417",
+ },
+ 7,
+ 1,
+ );
- expect(pass.props["barcodes"].length).toBe(1)
+ expect(pass.props["barcodes"].length).toBe(1);
});
it("Will reset barcodes content if parameter is null", () => {
@@ -255,18 +290,18 @@ describe("Passkit-generator", function () {
it("Will ignore non string or null arguments", function () {
const oldBarcode = pass.props["barcode"] || undefined;
- pass
- .barcodes("Message-22645272183")
+ pass.barcodes("Message-22645272183")
// @ts-expect-error
- .barcode(55)
+ .barcode(55);
// unchanged
expect(pass.props["barcode"]).toEqual(oldBarcode);
});
it("Will reset backward value on null", () => {
- pass.barcodes("Message-22645272183")
- .barcode("PKBarcodeFormatAztec");
+ pass.barcodes("Message-22645272183").barcode(
+ "PKBarcodeFormatAztec",
+ );
expect(pass.props["barcode"].format).toBe("PKBarcodeFormatAztec");
@@ -277,8 +312,7 @@ describe("Passkit-generator", function () {
it("Won't apply changes if unknown format is passed", () => {
const oldBarcode = pass.props["barcode"] || undefined;
- pass
- .barcodes("Message-22645272183")
+ pass.barcodes("Message-22645272183")
// @ts-expect-error
.barcode("PKBingoBongoFormat");
diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json
index 58037b5..99dd35e 100644
--- a/spec/support/jasmine.json
+++ b/spec/support/jasmine.json
@@ -1,8 +1,6 @@
{
"spec_dir": "spec",
- "spec_files": [
- "**/*.js"
- ],
+ "spec_files": ["**/*.js"],
"stopSpecOnExpectationFailure": false,
"random": true
}
diff --git a/spec/utils.ts b/spec/utils.ts
index 5d3266c..3343d08 100644
--- a/spec/utils.ts
+++ b/spec/utils.ts
@@ -9,7 +9,7 @@ describe("splitBufferBundle", () => {
"de.lproj/background@2x.png": zeroBuffer,
"it.lproj/thumbnail@2x.png": zeroBuffer,
"thumbnail@2x.png": zeroBuffer,
- "background.png": zeroBuffer
+ "background.png": zeroBuffer,
};
const result = splitBufferBundle(payload);
@@ -25,11 +25,11 @@ describe("splitBufferBundle", () => {
},
"it.lproj": {
"thumbnail@2x.png": zeroBuffer,
- }
+ },
});
expect(result[1]).toEqual({
"thumbnail@2x.png": zeroBuffer,
- "background.png": zeroBuffer
+ "background.png": zeroBuffer,
});
});
diff --git a/src/abstract.ts b/src/abstract.ts
index 4e36163..3235d55 100644
--- a/src/abstract.ts
+++ b/src/abstract.ts
@@ -1,68 +1,75 @@
-import { Certificates, FinalCertificates, PartitionedBundle, OverridesSupportedOptions, FactoryOptions } from "./schema";
-import { getModelContents, readCertificatesFromOptions } from "./parser";
-import formatMessage from "./messages";
-
-const abmCertificates = Symbol("certificates");
-const abmModel = Symbol("model");
-const abmOverrides = Symbol("overrides");
-
-export interface AbstractFactoryOptions extends Omit {
- certificates?: Certificates;
-}
-
-interface AbstractModelOptions {
- bundle: PartitionedBundle;
- certificates: FinalCertificates;
- overrides?: OverridesSupportedOptions;
-}
-
-/**
- * Creates an abstract model to keep data
- * in memory for future passes creation
- * @param options
- */
-
-export async function createAbstractModel(options: AbstractFactoryOptions) {
- if (!(options && Object.keys(options).length)) {
- throw new Error(formatMessage("CP_NO_OPTS"));
- }
-
- try {
- const [bundle, certificates] = await Promise.all([
- getModelContents(options.model),
- readCertificatesFromOptions(options.certificates)
- ]);
-
- return new AbstractModel({
- bundle,
- certificates,
- overrides: options.overrides
- });
- } catch (err) {
- throw new Error(formatMessage("CP_INIT_ERROR", "abstract model", err));
- }
-}
-
-export class AbstractModel {
- private [abmCertificates]: FinalCertificates;
- private [abmModel]: PartitionedBundle;
- private [abmOverrides]: OverridesSupportedOptions;
-
- constructor(options: AbstractModelOptions) {
- this[abmModel] = options.bundle;
- this[abmCertificates] = options.certificates;
- this[abmOverrides] = options.overrides
- }
-
- get certificates(): FinalCertificates {
- return this[abmCertificates];
- }
-
- get bundle(): PartitionedBundle {
- return this[abmModel];
- }
-
- get overrides(): OverridesSupportedOptions {
- return this[abmOverrides];
- }
-}
+import {
+ Certificates,
+ FinalCertificates,
+ PartitionedBundle,
+ OverridesSupportedOptions,
+ FactoryOptions,
+} from "./schema";
+import { getModelContents, readCertificatesFromOptions } from "./parser";
+import formatMessage from "./messages";
+
+const abmCertificates = Symbol("certificates");
+const abmModel = Symbol("model");
+const abmOverrides = Symbol("overrides");
+
+export interface AbstractFactoryOptions
+ extends Omit {
+ certificates?: Certificates;
+}
+
+interface AbstractModelOptions {
+ bundle: PartitionedBundle;
+ certificates: FinalCertificates;
+ overrides?: OverridesSupportedOptions;
+}
+
+/**
+ * Creates an abstract model to keep data
+ * in memory for future passes creation
+ * @param options
+ */
+
+export async function createAbstractModel(options: AbstractFactoryOptions) {
+ if (!(options && Object.keys(options).length)) {
+ throw new Error(formatMessage("CP_NO_OPTS"));
+ }
+
+ try {
+ const [bundle, certificates] = await Promise.all([
+ getModelContents(options.model),
+ readCertificatesFromOptions(options.certificates),
+ ]);
+
+ return new AbstractModel({
+ bundle,
+ certificates,
+ overrides: options.overrides,
+ });
+ } catch (err) {
+ throw new Error(formatMessage("CP_INIT_ERROR", "abstract model", err));
+ }
+}
+
+export class AbstractModel {
+ private [abmCertificates]: FinalCertificates;
+ private [abmModel]: PartitionedBundle;
+ private [abmOverrides]: OverridesSupportedOptions;
+
+ constructor(options: AbstractModelOptions) {
+ this[abmModel] = options.bundle;
+ this[abmCertificates] = options.certificates;
+ this[abmOverrides] = options.overrides;
+ }
+
+ get certificates(): FinalCertificates {
+ return this[abmCertificates];
+ }
+
+ get bundle(): PartitionedBundle {
+ return this[abmModel];
+ }
+
+ get overrides(): OverridesSupportedOptions {
+ return this[abmOverrides];
+ }
+}
diff --git a/src/factory.ts b/src/factory.ts
index fa9a5fc..52e185e 100644
--- a/src/factory.ts
+++ b/src/factory.ts
@@ -1,5 +1,11 @@
import { Pass } from "./pass";
-import { FactoryOptions, BundleUnit, FinalCertificates, PartitionedBundle, OverridesSupportedOptions } from "./schema";
+import {
+ FactoryOptions,
+ BundleUnit,
+ FinalCertificates,
+ PartitionedBundle,
+ OverridesSupportedOptions,
+} from "./schema";
import formatMessage from "./messages";
import { getModelContents, readCertificatesFromOptions } from "./parser";
import { splitBufferBundle } from "./utils";
@@ -16,9 +22,14 @@ import { AbstractModel, AbstractFactoryOptions } from "./abstract";
export async function createPass(
options: FactoryOptions | InstanceType,
additionalBuffers?: BundleUnit,
- abstractMissingData?: Omit
+ abstractMissingData?: Omit,
): Promise {
- if (!(options && (options instanceof AbstractModel || Object.keys(options).length))) {
+ if (
+ !(
+ options &&
+ (options instanceof AbstractModel || Object.keys(options).length)
+ )
+ ) {
throw new Error(formatMessage("CP_NO_OPTS"));
}
@@ -27,35 +38,62 @@ export async function createPass(
let certificates: FinalCertificates;
let overrides: OverridesSupportedOptions = {
...(options.overrides || {}),
- ...(abstractMissingData && abstractMissingData.overrides || {})
+ ...((abstractMissingData && abstractMissingData.overrides) ||
+ {}),
};
- if (!(options.certificates && options.certificates.signerCert && options.certificates.signerKey) && abstractMissingData.certificates) {
+ if (
+ !(
+ options.certificates &&
+ options.certificates.signerCert &&
+ options.certificates.signerKey
+ ) &&
+ abstractMissingData.certificates
+ ) {
certificates = Object.assign(
options.certificates,
- await readCertificatesFromOptions(abstractMissingData.certificates)
+ await readCertificatesFromOptions(
+ abstractMissingData.certificates,
+ ),
);
} else {
certificates = options.certificates;
}
- return createPassInstance(options.bundle, certificates, overrides, additionalBuffers);
+ return createPassInstance(
+ options.bundle,
+ certificates,
+ overrides,
+ additionalBuffers,
+ );
} else {
const [bundle, certificates] = await Promise.all([
getModelContents(options.model),
- readCertificatesFromOptions(options.certificates)
+ readCertificatesFromOptions(options.certificates),
]);
- return createPassInstance(bundle, certificates, options.overrides, additionalBuffers);
+ return createPassInstance(
+ bundle,
+ certificates,
+ options.overrides,
+ additionalBuffers,
+ );
}
} catch (err) {
throw new Error(formatMessage("CP_INIT_ERROR", "pass", err));
}
}
-function createPassInstance(model: PartitionedBundle, certificates: FinalCertificates, overrides: OverridesSupportedOptions, additionalBuffers?: BundleUnit) {
+function createPassInstance(
+ model: PartitionedBundle,
+ certificates: FinalCertificates,
+ overrides: OverridesSupportedOptions,
+ additionalBuffers?: BundleUnit,
+) {
if (additionalBuffers) {
- const [additionalL10n, additionalBundle] = splitBufferBundle(additionalBuffers);
+ const [additionalL10n, additionalBundle] = splitBufferBundle(
+ additionalBuffers,
+ );
Object.assign(model["l10nBundle"], additionalL10n);
Object.assign(model["bundle"], additionalBundle);
}
@@ -63,6 +101,6 @@ function createPassInstance(model: PartitionedBundle, certificates: FinalCertifi
return new Pass({
model,
certificates,
- overrides
+ overrides,
});
}
diff --git a/src/fieldsArray.ts b/src/fieldsArray.ts
index 0e79aa6..b2543bf 100644
--- a/src/fieldsArray.ts
+++ b/src/fieldsArray.ts
@@ -24,20 +24,28 @@ export default class FieldsArray extends Array {
*/
push(...fieldsData: schema.Field[]): number {
- const validFields = fieldsData.reduce((acc: schema.Field[], current: schema.Field) => {
- if (!(typeof current === "object") || !schema.isValid(current, "field")) {
+ const validFields = fieldsData.reduce(
+ (acc: schema.Field[], current: schema.Field) => {
+ if (
+ !(typeof current === "object") ||
+ !schema.isValid(current, "field")
+ ) {
+ return acc;
+ }
+
+ if (this[poolSymbol].has(current.key)) {
+ fieldsDebug(
+ `Field with key "${current.key}" discarded: fields must be unique in pass scope.`,
+ );
+ } else {
+ this[poolSymbol].add(current.key);
+ acc.push(current);
+ }
+
return acc;
- }
-
- if (this[poolSymbol].has(current.key)) {
- fieldsDebug(`Field with key "${current.key}" discarded: fields must be unique in pass scope.`);
- } else {
- this[poolSymbol].add(current.key);
- acc.push(current);
- }
-
- return acc;
- }, []);
+ },
+ [],
+ );
return Array.prototype.push.call(this, ...validFields);
}
@@ -58,9 +66,13 @@ export default class FieldsArray extends Array {
* also uniqueKeys set
*/
- splice(start: number, deleteCount: number, ...items: schema.Field[]): schema.Field[] {
+ splice(
+ start: number,
+ deleteCount: number,
+ ...items: schema.Field[]
+ ): schema.Field[] {
const removeList = this.slice(start, deleteCount + start);
- removeList.forEach(item => this[poolSymbol].delete(item.key));
+ removeList.forEach((item) => this[poolSymbol].delete(item.key));
return Array.prototype.splice.call(this, start, deleteCount, items);
}
diff --git a/src/index.ts b/src/index.ts
index 29d0dd1..7df70e5 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,5 +3,5 @@ import { AbstractModel as AbstractModelClass } from "./abstract";
export { createPass } from "./factory";
export { createAbstractModel } from "./abstract";
-export type Pass = InstanceType
-export type AbstractModel = InstanceType
+export type Pass = InstanceType;
+export type AbstractModel = InstanceType;
diff --git a/src/messages.ts b/src/messages.ts
index 94f9cf0..7d0d227 100644
--- a/src/messages.ts
+++ b/src/messages.ts
@@ -1,31 +1,51 @@
const errors = {
- CP_INIT_ERROR: "Something went really bad in the %s initialization! Look at the log below this message. It should contain all the infos about the problem: \n%s",
- CP_NO_OPTS: "Cannot initialize the pass or abstract model creation: no options were passed.",
- CP_NO_CERTS: "Cannot initialize the pass creation: no valid certificates were passed.",
- PASSFILE_VALIDATION_FAILED: "Validation of pass type failed. Pass file is not a valid buffer or (more probably) does not respect the schema.\nRefer to https://apple.co/2Nvshvn to build a correct pass.",
- REQUIR_VALID_FAILED: "The options passed to Pass constructor does not meet the requirements.\nRefer to the documentation to compile them correctly.",
- MODEL_UNINITIALIZED: "Provided model ( %s ) matched but unitialized or may not contain icon or a valid pass.json.\nRefer to https://apple.co/2IhJr0Q, https://apple.co/2Nvshvn and documentation to fill the model correctly.",
- MODEL_NOT_VALID: "A model must be provided in form of path (string) or object { 'fileName': Buffer } in order to continue.",
+ CP_INIT_ERROR:
+ "Something went really bad in the %s initialization! Look at the log below this message. It should contain all the infos about the problem: \n%s",
+ CP_NO_OPTS:
+ "Cannot initialize the pass or abstract model creation: no options were passed.",
+ CP_NO_CERTS:
+ "Cannot initialize the pass creation: no valid certificates were passed.",
+ PASSFILE_VALIDATION_FAILED:
+ "Validation of pass type failed. Pass file is not a valid buffer or (more probably) does not respect the schema.\nRefer to https://apple.co/2Nvshvn to build a correct pass.",
+ REQUIR_VALID_FAILED:
+ "The options passed to Pass constructor does not meet the requirements.\nRefer to the documentation to compile them correctly.",
+ MODEL_UNINITIALIZED:
+ "Provided model ( %s ) matched but unitialized or may not contain icon or a valid pass.json.\nRefer to https://apple.co/2IhJr0Q, https://apple.co/2Nvshvn and documentation to fill the model correctly.",
+ MODEL_NOT_VALID:
+ "A model must be provided in form of path (string) or object { 'fileName': Buffer } in order to continue.",
MODELF_NOT_FOUND: "Model %s not found. Provide a valid one to continue.",
MODELF_FILE_NOT_FOUND: "File %s not found.",
- INVALID_CERTS: "Invalid certificate(s) loaded: %s. Please provide valid WWDR certificates and developer signer certificate and key (with passphrase).\nRefer to docs to obtain them.",
+ INVALID_CERTS:
+ "Invalid certificate(s) loaded: %s. Please provide valid WWDR certificates and developer signer certificate and key (with passphrase).\nRefer to docs to obtain them.",
INVALID_CERT_PATH: "Invalid certificate loaded. %s does not exist.",
- TRSTYPE_REQUIRED: "Cannot proceed with pass creation. transitType field is required for boardingPasses.",
- OVV_KEYS_BADFORMAT: "Cannot proceed with pass creation due to bad keys format in overrides.",
- NO_PASS_TYPE: "Cannot proceed with pass creation. Model definition (pass.json) has no valid type in it.\nRefer to https://apple.co/2wzyL5J to choose a valid pass type."
+ TRSTYPE_REQUIRED:
+ "Cannot proceed with pass creation. transitType field is required for boardingPasses.",
+ OVV_KEYS_BADFORMAT:
+ "Cannot proceed with pass creation due to bad keys format in overrides.",
+ NO_PASS_TYPE:
+ "Cannot proceed with pass creation. Model definition (pass.json) has no valid type in it.\nRefer to https://apple.co/2wzyL5J to choose a valid pass type.",
};
const debugMessages = {
- TRSTYPE_NOT_VALID: "Transit type changing rejected as not compliant with Apple Specifications. Transit type would become \"%s\" but should be in [PKTransitTypeAir, PKTransitTypeBoat, PKTransitTypeBus, PKTransitTypeGeneric, PKTransitTypeTrain]",
- BRC_NOT_SUPPORTED: "Format not found among barcodes. Cannot set backward compatibility.",
- BRC_FORMATTYPE_UNMATCH: "Format must be a string or null. Cannot set backward compatibility.",
- BRC_AUTC_MISSING_DATA: "Unable to autogenerate barcodes. Data is not a string.",
- BRC_BW_FORMAT_UNSUPPORTED: "This format is not supported (by Apple) for backward support. Please choose another one.",
- BRC_NO_POOL: "Cannot set barcode: no barcodes found. Please set barcodes first. Barcode is for retrocompatibility only.",
+ TRSTYPE_NOT_VALID:
+ 'Transit type changing rejected as not compliant with Apple Specifications. Transit type would become "%s" but should be in [PKTransitTypeAir, PKTransitTypeBoat, PKTransitTypeBus, PKTransitTypeGeneric, PKTransitTypeTrain]',
+ BRC_NOT_SUPPORTED:
+ "Format not found among barcodes. Cannot set backward compatibility.",
+ BRC_FORMATTYPE_UNMATCH:
+ "Format must be a string or null. Cannot set backward compatibility.",
+ BRC_AUTC_MISSING_DATA:
+ "Unable to autogenerate barcodes. Data is not a string.",
+ BRC_BW_FORMAT_UNSUPPORTED:
+ "This format is not supported (by Apple) for backward support. Please choose another one.",
+ BRC_NO_POOL:
+ "Cannot set barcode: no barcodes found. Please set barcodes first. Barcode is for retrocompatibility only.",
DATE_FORMAT_UNMATCH: "%s was not set due to incorrect date format.",
- NFC_INVALID: "Unable to set NFC properties: data not compliant with schema.",
- PRS_INVALID: "Unable to parse Personalization.json. File is not a valid JSON. Error: %s",
- PRS_REMOVED: "Personalization has been removed as it requires an NFC-enabled pass to work."
+ NFC_INVALID:
+ "Unable to set NFC properties: data not compliant with schema.",
+ PRS_INVALID:
+ "Unable to parse Personalization.json. File is not a valid JSON. Error: %s",
+ PRS_REMOVED:
+ "Personalization has been removed as it requires an NFC-enabled pass to work.",
};
type AllMessages = keyof (typeof debugMessages & typeof errors);
diff --git a/src/parser.ts b/src/parser.ts
index 49bad8f..08c69ab 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -1,8 +1,21 @@
import * as path from "path";
import forge from "node-forge";
import formatMessage from "./messages";
-import { FactoryOptions, PartitionedBundle, BundleUnit, Certificates, FinalCertificates, isValid } from "./schema";
-import { removeHidden, splitBufferBundle, getAllFilesWithName, hasFilesWithName, deletePersonalization } from "./utils";
+import {
+ FactoryOptions,
+ PartitionedBundle,
+ BundleUnit,
+ Certificates,
+ FinalCertificates,
+ isValid,
+} from "./schema";
+import {
+ removeHidden,
+ splitBufferBundle,
+ getAllFilesWithName,
+ hasFilesWithName,
+ deletePersonalization,
+} from "./utils";
import fs from "fs";
import debug from "debug";
@@ -27,10 +40,9 @@ export async function getModelContents(model: FactoryOptions["model"]) {
}
const modelFiles = Object.keys(modelContents.bundle);
- const isModelInitialized = (
+ const isModelInitialized =
modelFiles.includes("pass.json") &&
- hasFilesWithName("icon", modelFiles, "startsWith")
- );
+ hasFilesWithName("icon", modelFiles, "startsWith");
if (!isModelInitialized) {
throw new Error(formatMessage("MODEL_UNINITIALIZED", "parse result"));
@@ -46,19 +58,34 @@ export async function getModelContents(model: FactoryOptions["model"]) {
return modelContents;
}
- const logoFullNames = getAllFilesWithName("personalizationLogo", modelFiles, "startsWith");
- if (!(logoFullNames.length && modelContents.bundle[personalizationJsonFile].length)) {
+ const logoFullNames = getAllFilesWithName(
+ "personalizationLogo",
+ modelFiles,
+ "startsWith",
+ );
+ if (
+ !(
+ logoFullNames.length &&
+ modelContents.bundle[personalizationJsonFile].length
+ )
+ ) {
deletePersonalization(modelContents.bundle, logoFullNames);
return modelContents;
}
try {
- const parsedPersonalization = JSON.parse(modelContents.bundle[personalizationJsonFile].toString("utf8"));
- const isPersonalizationValid = isValid(parsedPersonalization, "personalizationDict");
+ const parsedPersonalization = JSON.parse(
+ modelContents.bundle[personalizationJsonFile].toString("utf8"),
+ );
+ const isPersonalizationValid = isValid(
+ parsedPersonalization,
+ "personalizationDict",
+ );
if (!isPersonalizationValid) {
- [...logoFullNames, personalizationJsonFile]
- .forEach(file => delete modelContents.bundle[file]);
+ [...logoFullNames, personalizationJsonFile].forEach(
+ (file) => delete modelContents.bundle[file],
+ );
return modelContents;
}
@@ -76,55 +103,70 @@ export async function getModelContents(model: FactoryOptions["model"]) {
* @param model
*/
-export async function getModelFolderContents(model: string): Promise {
+export async function getModelFolderContents(
+ model: string,
+): Promise {
try {
- const modelPath = `${model}${!path.extname(model) && ".pass" || ""}`;
+ const modelPath = `${model}${(!path.extname(model) && ".pass") || ""}`;
const modelFilesList = await readDir(modelPath);
// No dot-starting files, manifest and signature
- const filteredFiles = removeHidden(modelFilesList)
- .filter(f => !/(manifest|signature)/i.test(f) && /.+$/.test(path.parse(f).ext));
-
- const isModelInitialized = (
- filteredFiles.length &&
- hasFilesWithName("icon", filteredFiles, "startsWith")
+ const filteredFiles = removeHidden(modelFilesList).filter(
+ (f) =>
+ !/(manifest|signature)/i.test(f) &&
+ /.+$/.test(path.parse(f).ext),
);
+ const isModelInitialized =
+ filteredFiles.length &&
+ hasFilesWithName("icon", filteredFiles, "startsWith");
+
// Icon is required to proceed
if (!isModelInitialized) {
- throw new Error(formatMessage(
- "MODEL_UNINITIALIZED",
- path.parse(model).name
- ));
+ throw new Error(
+ formatMessage("MODEL_UNINITIALIZED", path.parse(model).name),
+ );
}
// Splitting files from localization folders
- const rawBundleFiles = filteredFiles.filter(entry => !entry.includes(".lproj"));
- const l10nFolders = filteredFiles.filter(entry => entry.includes(".lproj"));
-
- const rawBundleBuffers = await Promise.all(
- rawBundleFiles.map(file => readFile(path.resolve(modelPath, file)))
+ const rawBundleFiles = filteredFiles.filter(
+ (entry) => !entry.includes(".lproj"),
+ );
+ const l10nFolders = filteredFiles.filter((entry) =>
+ entry.includes(".lproj"),
);
- const bundle: BundleUnit = Object.assign({},
- ...rawBundleFiles.map((fileName, index) => ({ [fileName]: rawBundleBuffers[index] }))
+ const rawBundleBuffers = await Promise.all(
+ rawBundleFiles.map((file) =>
+ readFile(path.resolve(modelPath, file)),
+ ),
+ );
+
+ const bundle: BundleUnit = Object.assign(
+ {},
+ ...rawBundleFiles.map((fileName, index) => ({
+ [fileName]: rawBundleBuffers[index],
+ })),
);
// Reading concurrently localizations folder
// and their files and their buffers
const L10N_FilesListByFolder: Array = await Promise.all(
- l10nFolders.map(async folderPath => {
+ l10nFolders.map(async (folderPath) => {
// Reading current folder
const currentLangPath = path.join(modelPath, folderPath);
const files = await readDir(currentLangPath);
// Transforming files path to a model-relative path
- const validFiles = removeHidden(files)
- .map(file => path.join(currentLangPath, file));
+ const validFiles = removeHidden(files).map((file) =>
+ path.join(currentLangPath, file),
+ );
// Getting all the buffers from file paths
const buffers = await Promise.all(
- validFiles.map(file => readFile(file).catch(() => Buffer.alloc(0)))
+ validFiles.map((file) =>
+ readFile(file).catch(() => Buffer.alloc(0)),
+ ),
);
// Assigning each file path to its buffer
@@ -140,34 +182,37 @@ export async function getModelFolderContents(model: string): Promise ({ [l10nFolders[index]]: folder }))
+ ...L10N_FilesListByFolder.map((folder, index) => ({
+ [l10nFolders[index]]: folder,
+ })),
);
return {
bundle,
- l10nBundle
+ l10nBundle,
};
} catch (err) {
if (err?.code === "ENOENT") {
if (err.syscall === "open") {
// file opening failed
- throw new Error(formatMessage("MODELF_NOT_FOUND", err.path))
+ throw new Error(formatMessage("MODELF_NOT_FOUND", err.path));
} else if (err.syscall === "scandir") {
// directory reading failed
const pathContents = (err.path as string).split(/(\/|\\\?)/);
- throw new Error(formatMessage(
- "MODELF_FILE_NOT_FOUND",
- pathContents[pathContents.length - 1]
- ))
+ throw new Error(
+ formatMessage(
+ "MODELF_FILE_NOT_FOUND",
+ pathContents[pathContents.length - 1],
+ ),
+ );
}
}
@@ -182,27 +227,28 @@ export async function getModelFolderContents(model: string): Promise((acc, current) => {
- // Checking if current file is one of the autogenerated ones or if its
- // content is not available
+ const rawBundle = removeHidden(Object.keys(model)).reduce(
+ (acc, current) => {
+ // Checking if current file is one of the autogenerated ones or if its
+ // content is not available
- if (/(manifest|signature)/.test(current) || !model[current]) {
- return acc;
- }
+ if (/(manifest|signature)/.test(current) || !model[current]) {
+ return acc;
+ }
- return { ...acc, [current]: model[current] };
- }, {});
+ return { ...acc, [current]: model[current] };
+ },
+ {},
+ );
const bundleKeys = Object.keys(rawBundle);
- const isModelInitialized = (
- bundleKeys.length &&
- hasFilesWithName("icon", bundleKeys, "startsWith")
- );
+ const isModelInitialized =
+ bundleKeys.length && hasFilesWithName("icon", bundleKeys, "startsWith");
// Icon is required to proceed
if (!isModelInitialized) {
- throw new Error(formatMessage("MODEL_UNINITIALIZED", "Buffers"))
+ throw new Error(formatMessage("MODEL_UNINITIALIZED", "Buffers"));
}
// separing localization folders from bundle files
@@ -210,7 +256,7 @@ export function getModelBufferContents(model: BundleUnit): PartitionedBundle {
return {
bundle,
- l10nBundle
+ l10nBundle,
};
}
@@ -224,8 +270,16 @@ type flatCertificates = Omit & {
signerKey: string;
};
-export async function readCertificatesFromOptions(options: Certificates): Promise {
- if (!(options && Object.keys(options).length && isValid(options, "certificatesSchema"))) {
+export async function readCertificatesFromOptions(
+ options: Certificates,
+): Promise {
+ if (
+ !(
+ options &&
+ Object.keys(options).length &&
+ isValid(options, "certificatesSchema")
+ )
+ ) {
throw new Error(formatMessage("CP_NO_CERTS"));
}
@@ -239,30 +293,31 @@ export async function readCertificatesFromOptions(options: Certificates): Promis
// if the signerKey is an object, we want to get
// all the real contents and don't care of passphrase
- const flattenedDocs = Object.assign({}, options, { signerKey }) as flatCertificates;
+ const flattenedDocs = Object.assign({}, options, {
+ signerKey,
+ }) as flatCertificates;
// We read the contents
- const rawContentsPromises = Object.keys(flattenedDocs)
- .map(key => {
- const content = flattenedDocs[key];
+ const rawContentsPromises = Object.keys(flattenedDocs).map((key) => {
+ const content = flattenedDocs[key];
- if (!!path.parse(content).ext) {
- // The content is a path to the document
- return readFile(path.resolve(content), { encoding: "utf8" });
- } else {
- // Content is the real document content
- return Promise.resolve(content);
- }
- });
+ if (!!path.parse(content).ext) {
+ // The content is a path to the document
+ return readFile(path.resolve(content), { encoding: "utf8" });
+ } else {
+ // Content is the real document content
+ return Promise.resolve(content);
+ }
+ });
try {
const parsedContents = await Promise.all(rawContentsPromises);
const pemParsedContents = parsedContents.map((file, index) => {
const certName = Object.keys(options)[index];
- const passphrase = (
- typeof options.signerKey === "object" &&
- options.signerKey?.passphrase
- ) || undefined;
+ const passphrase =
+ (typeof options.signerKey === "object" &&
+ options.signerKey?.passphrase) ||
+ undefined;
const pem = parsePEM(certName, file, passphrase);
@@ -279,7 +334,9 @@ export async function readCertificatesFromOptions(options: Certificates): Promis
throw err;
}
- throw new Error(formatMessage("INVALID_CERT_PATH", path.parse(err.path).base));
+ throw new Error(
+ formatMessage("INVALID_CERT_PATH", path.parse(err.path).base),
+ );
}
}
diff --git a/src/pass.ts b/src/pass.ts
index 03ca452..15dd629 100644
--- a/src/pass.ts
+++ b/src/pass.ts
@@ -7,7 +7,13 @@ import { ZipFile } from "yazl";
import * as schema from "./schema";
import formatMessage from "./messages";
import FieldsArray from "./fieldsArray";
-import { generateStringFile, dateToW3CString, isValidRGB, deletePersonalization, getAllFilesWithName } from "./utils";
+import {
+ generateStringFile,
+ dateToW3CString,
+ isValidRGB,
+ deletePersonalization,
+ getAllFilesWithName,
+} from "./utils";
const barcodeDebug = debug("passkit:barcode");
const genericDebug = debug("passkit:generic");
@@ -20,7 +26,7 @@ const propsSchemaMap = new Map([
["barcode", "barcode"],
["beacons", "beaconsDict"],
["locations", "locationsDict"],
- ["nfc", "nfcDict"]
+ ["nfc", "nfcDict"],
]);
export class Pass {
@@ -42,7 +48,9 @@ export class Pass {
private Certificates: schema.FinalCertificates;
private [transitType]: string = "";
- private l10nTranslations: { [languageCode: string]: { [placeholder: string]: string } } = {};
+ private l10nTranslations: {
+ [languageCode: string]: { [placeholder: string]: string };
+ } = {};
constructor(options: schema.PassInstance) {
if (!schema.isValid(options, "instance")) {
@@ -54,77 +62,101 @@ export class Pass {
this.bundle = { ...options.model.bundle };
try {
- this.passCore = JSON.parse(this.bundle["pass.json"].toString("utf8"));
+ this.passCore = JSON.parse(
+ this.bundle["pass.json"].toString("utf8"),
+ );
} catch (err) {
throw new Error(formatMessage("PASSFILE_VALIDATION_FAILED"));
}
// Parsing the options and extracting only the valid ones.
- const validOverrides = schema.getValidated(options.overrides || {}, "supportedOptions") as schema.OverridesSupportedOptions;
+ const validOverrides = schema.getValidated(
+ options.overrides || {},
+ "supportedOptions",
+ ) as schema.OverridesSupportedOptions;
if (validOverrides === null) {
- throw new Error(formatMessage("OVV_KEYS_BADFORMAT"))
+ throw new Error(formatMessage("OVV_KEYS_BADFORMAT"));
}
- this.type = Object.keys(this.passCore)
- .find(key => /(boardingPass|eventTicket|coupon|generic|storeCard)/.test(key)) as keyof schema.ValidPassType;
+ this.type = Object.keys(this.passCore).find((key) =>
+ /(boardingPass|eventTicket|coupon|generic|storeCard)/.test(key),
+ ) as keyof schema.ValidPassType;
if (!this.type) {
throw new Error(formatMessage("NO_PASS_TYPE"));
}
// Parsing and validating pass.json keys
- const passCoreKeys = Object.keys(this.passCore) as (keyof schema.ValidPass)[];
- const validatedPassKeys = passCoreKeys.reduce((acc, current) => {
- if (this.type === current) {
- // We want to exclude type keys (eventTicket,
- // boardingPass, ecc.) and their content
- return acc;
- }
+ const passCoreKeys = Object.keys(
+ this.passCore,
+ ) as (keyof schema.ValidPass)[];
+ const validatedPassKeys = passCoreKeys.reduce(
+ (acc, current) => {
+ if (this.type === current) {
+ // We want to exclude type keys (eventTicket,
+ // boardingPass, ecc.) and their content
+ return acc;
+ }
- if (!propsSchemaMap.has(current)) {
- // If the property is unknown (we don't care if
- // it is valid or not for Wallet), we return
- // directly the content
- return { ...acc, [current]: this.passCore[current] };
- }
+ if (!propsSchemaMap.has(current)) {
+ // If the property is unknown (we don't care if
+ // it is valid or not for Wallet), we return
+ // directly the content
+ return { ...acc, [current]: this.passCore[current] };
+ }
- const currentSchema = propsSchemaMap.get(current)!;
+ const currentSchema = propsSchemaMap.get(current)!;
- if (Array.isArray(this.passCore[current])) {
- const valid = getValidInArray(
- currentSchema,
- this.passCore[current] as schema.ArrayPassSchema[]
- );
- return { ...acc, [current]: valid };
- } else {
- return {
- ...acc,
- [current]: schema.isValid(
- this.passCore[current],
- currentSchema
- ) && this.passCore[current] || undefined
- };
- }
- }, {});
+ if (Array.isArray(this.passCore[current])) {
+ const valid = getValidInArray(
+ currentSchema,
+ this.passCore[current] as schema.ArrayPassSchema[],
+ );
+ return { ...acc, [current]: valid };
+ } else {
+ return {
+ ...acc,
+ [current]:
+ (schema.isValid(
+ this.passCore[current],
+ currentSchema,
+ ) &&
+ this.passCore[current]) ||
+ undefined,
+ };
+ }
+ },
+ {},
+ );
this[passProps] = {
...(validatedPassKeys || {}),
- ...(validOverrides || {})
+ ...(validOverrides || {}),
};
- if (this.type === "boardingPass" && this.passCore[this.type]["transitType"]) {
+ if (
+ this.type === "boardingPass" &&
+ this.passCore[this.type]["transitType"]
+ ) {
// We might want to generate a boarding pass without setting manually
// in the code the transit type but right in the model;
this[transitType] = this.passCore[this.type]["transitType"];
}
- this._fields = ["primaryFields", "secondaryFields", "auxiliaryFields", "backFields", "headerFields"];
- this._fields.forEach(fieldName => {
+ this._fields = [
+ "primaryFields",
+ "secondaryFields",
+ "auxiliaryFields",
+ "backFields",
+ "headerFields",
+ ];
+ this._fields.forEach((fieldName) => {
this[fieldName] = new FieldsArray(
this.fieldsKeys,
- ...(this.passCore[this.type][fieldName] || [])
- .filter(field => schema.isValid(field, "field"))
+ ...(this.passCore[this.type][fieldName] || []).filter((field) =>
+ schema.isValid(field, "field"),
+ ),
);
});
}
@@ -146,13 +178,19 @@ export class Pass {
*/
const currentBundleFiles = Object.keys(this.bundle);
- if (!this[passProps].nfc && currentBundleFiles.includes("personalization.json")) {
+ if (
+ !this[passProps].nfc &&
+ currentBundleFiles.includes("personalization.json")
+ ) {
genericDebug(formatMessage("PRS_REMOVED"));
- deletePersonalization(this.bundle, getAllFilesWithName(
- "personalizationLogo",
- currentBundleFiles,
- "startsWith"
- ));
+ deletePersonalization(
+ this.bundle,
+ getAllFilesWithName(
+ "personalizationLogo",
+ currentBundleFiles,
+ "startsWith",
+ ),
+ );
}
const finalBundle = { ...this.bundle } as schema.BundleUnit;
@@ -161,7 +199,7 @@ export class Pass {
* Iterating through languages and generating pass.string file
*/
- Object.keys(this.l10nTranslations).forEach(lang => {
+ Object.keys(this.l10nTranslations).forEach((lang) => {
const strings = generateStringFile(this.l10nTranslations[lang]);
const langInBundles = `${lang}.lproj`;
@@ -176,13 +214,21 @@ export class Pass {
this.l10nBundles[langInBundles] = {};
}
- this.l10nBundles[langInBundles]["pass.strings"] = Buffer.concat([
- this.l10nBundles[langInBundles]["pass.strings"] || Buffer.alloc(0),
- strings
+ this.l10nBundles[langInBundles][
+ "pass.strings"
+ ] = Buffer.concat([
+ this.l10nBundles[langInBundles]["pass.strings"] ||
+ Buffer.alloc(0),
+ strings,
]);
}
- if (!(this.l10nBundles[langInBundles] && Object.keys(this.l10nBundles[langInBundles]).length)) {
+ if (
+ !(
+ this.l10nBundles[langInBundles] &&
+ Object.keys(this.l10nBundles[langInBundles]).length
+ )
+ ) {
return;
}
@@ -194,33 +240,48 @@ export class Pass {
* composition.
*/
- Object.assign(finalBundle, ...Object.keys(this.l10nBundles[langInBundles])
- .map(fileName => {
- const fullPath = path.join(langInBundles, fileName).replace(/\\/, "/");
- return { [fullPath]: this.l10nBundles[langInBundles][fileName] };
- })
+ Object.assign(
+ finalBundle,
+ ...Object.keys(this.l10nBundles[langInBundles]).map(
+ (fileName) => {
+ const fullPath = path
+ .join(langInBundles, fileName)
+ .replace(/\\/, "/");
+ return {
+ [fullPath]: this.l10nBundles[langInBundles][
+ fileName
+ ],
+ };
+ },
+ ),
);
});
/*
- * Parsing the buffers, pushing them into the archive
- * and returning the compiled manifest
- */
+ * Parsing the buffers, pushing them into the archive
+ * and returning the compiled manifest
+ */
const archive = new ZipFile();
- const manifest = Object.keys(finalBundle).reduce((acc, current) => {
- let hashFlow = forge.md.sha1.create();
+ const manifest = Object.keys(finalBundle).reduce(
+ (acc, current) => {
+ let hashFlow = forge.md.sha1.create();
- hashFlow.update(finalBundle[current].toString("binary"));
- archive.addBuffer(finalBundle[current], current);
- acc[current] = hashFlow.digest().toHex();
+ hashFlow.update(finalBundle[current].toString("binary"));
+ archive.addBuffer(finalBundle[current], current);
+ acc[current] = hashFlow.digest().toHex();
- return acc;
- }, {});
+ return acc;
+ },
+ {},
+ );
const signatureBuffer = this._sign(manifest);
archive.addBuffer(signatureBuffer, "signature");
- archive.addBuffer(Buffer.from(JSON.stringify(manifest)), "manifest.json");
+ archive.addBuffer(
+ Buffer.from(JSON.stringify(manifest)),
+ "manifest.json",
+ );
const passStream = new Stream.PassThrough();
archive.outputStream.pipe(passStream);
@@ -242,8 +303,15 @@ export class Pass {
* @see https://apple.co/2KOv0OW - Passes support localization
*/
- localize(lang: string, translations?: { [placeholder: string]: string }): this {
- if (lang && typeof lang === "string" && (typeof translations === "object" || translations === undefined)) {
+ localize(
+ lang: string,
+ translations?: { [placeholder: string]: string },
+ ): this {
+ if (
+ lang &&
+ typeof lang === "string" &&
+ (typeof translations === "object" || translations === undefined)
+ ) {
this.l10nTranslations[lang] = translations || {};
}
@@ -292,7 +360,7 @@ export class Pass {
*/
beacons(resetFlag: null): this;
- beacons(...data: schema.Beacon[]): this
+ beacons(...data: schema.Beacon[]): this;
beacons(...data: (schema.Beacon | null)[]): this {
if (data[0] === null) {
delete this[passProps]["beacons"];
@@ -322,7 +390,10 @@ export class Pass {
return this;
}
- const valid = processRelevancySet("locations", data as schema.Location[]);
+ const valid = processRelevancySet(
+ "locations",
+ data as schema.Location[],
+ );
if (valid.length) {
this[passProps]["locations"] = valid;
@@ -390,19 +461,28 @@ export class Pass {
* Validation assign default value to missing parameters (if any).
*/
- const validBarcodes = data.reduce((acc, current) => {
- if (!(current && current instanceof Object)) {
- return acc;
- }
+ const validBarcodes = data.reduce(
+ (acc, current) => {
+ if (!(current && current instanceof Object)) {
+ return acc;
+ }
- const validated = schema.getValidated(current, "barcode");
+ const validated = schema.getValidated(current, "barcode");
- if (!(validated && validated instanceof Object && Object.keys(validated).length)) {
- return acc;
- }
+ if (
+ !(
+ validated &&
+ validated instanceof Object &&
+ Object.keys(validated).length
+ )
+ ) {
+ return acc;
+ }
- return [...acc, validated] as schema.Barcode[];
- }, []);
+ return [...acc, validated] as schema.Barcode[];
+ },
+ [],
+ );
if (validBarcodes.length) {
this[passProps]["barcodes"] = validBarcodes;
@@ -446,7 +526,9 @@ export class Pass {
}
// Checking which object among barcodes has the same format of the specified one.
- const index = barcodes.findIndex(b => b.format.toLowerCase().includes(chosenFormat.toLowerCase()));
+ const index = barcodes.findIndex((b) =>
+ b.format.toLowerCase().includes(chosenFormat.toLowerCase()),
+ );
if (index === -1) {
barcodeDebug(formatMessage("BRC_NOT_SUPPORTED"));
@@ -472,7 +554,14 @@ export class Pass {
return this;
}
- if (!(data && typeof data === "object" && !Array.isArray(data) && schema.isValid(data, "nfcDict"))) {
+ if (
+ !(
+ data &&
+ typeof data === "object" &&
+ !Array.isArray(data) &&
+ schema.isValid(data, "nfcDict")
+ )
+ ) {
genericDebug(formatMessage("NFC_INVALID"));
return this;
}
@@ -505,7 +594,10 @@ export class Pass {
private _sign(manifest: schema.Manifest): Buffer {
const signature = forge.pkcs7.createSignedData();
- signature.content = forge.util.createBuffer(JSON.stringify(manifest), "utf8");
+ signature.content = forge.util.createBuffer(
+ JSON.stringify(manifest),
+ "utf8",
+ );
signature.addCertificate(this.Certificates.wwdr);
signature.addCertificate(this.Certificates.signerCert);
@@ -523,14 +615,18 @@ export class Pass {
key: this.Certificates.signerKey,
certificate: this.Certificates.signerCert,
digestAlgorithm: forge.pki.oids.sha1,
- authenticatedAttributes: [{
- type: forge.pki.oids.contentType,
- value: forge.pki.oids.data
- }, {
- type: forge.pki.oids.messageDigest,
- }, {
- type: forge.pki.oids.signingTime,
- }]
+ authenticatedAttributes: [
+ {
+ type: forge.pki.oids.contentType,
+ value: forge.pki.oids.data,
+ },
+ {
+ type: forge.pki.oids.messageDigest,
+ },
+ {
+ type: forge.pki.oids.signingTime,
+ },
+ ],
});
/**
@@ -554,7 +650,10 @@ export class Pass {
* of beautiful things. ¯\_(ツ)_/¯
*/
- return Buffer.from(forge.asn1.toDer(signature.toAsn1()).getBytes(), "binary");
+ return Buffer.from(
+ forge.asn1.toDer(signature.toAsn1()).getBytes(),
+ "binary",
+ );
}
/**
@@ -566,7 +665,9 @@ export class Pass {
*/
private _patch(passCoreBuffer: Buffer): Buffer {
- const passFile = JSON.parse(passCoreBuffer.toString()) as schema.ValidPass;
+ const passFile = JSON.parse(
+ passCoreBuffer.toString(),
+ ) as schema.ValidPass;
if (Object.keys(this[passProps]).length) {
/*
@@ -575,14 +676,22 @@ export class Pass {
* and then delete it from the passFile.
*/
- const passColors = ["backgroundColor", "foregroundColor", "labelColor"] as Array;
- passColors.filter(v => this[passProps][v] && !isValidRGB(this[passProps][v]))
- .forEach(v => delete this[passProps][v]);
+ const passColors = [
+ "backgroundColor",
+ "foregroundColor",
+ "labelColor",
+ ] as Array;
+ passColors
+ .filter(
+ (v) =>
+ this[passProps][v] && !isValidRGB(this[passProps][v]),
+ )
+ .forEach((v) => delete this[passProps][v]);
Object.assign(passFile, this[passProps]);
}
- this._fields.forEach(field => {
+ this._fields.forEach((field) => {
passFile[this.type][field] = this[field];
});
@@ -627,8 +736,14 @@ function barcodesFromUncompleteData(message: string): schema.Barcode[] {
"PKBarcodeFormatQR",
"PKBarcodeFormatPDF417",
"PKBarcodeFormatAztec",
- "PKBarcodeFormatCode128"
- ].map(format => schema.getValidated({ format, message }, "barcode") as schema.Barcode);
+ "PKBarcodeFormatCode128",
+ ].map(
+ (format) =>
+ schema.getValidated(
+ { format, message },
+ "barcode",
+ ) as schema.Barcode,
+ );
}
function processRelevancySet(key: string, data: T[]): T[] {
@@ -636,7 +751,10 @@ function processRelevancySet(key: string, data: T[]): T[] {
}
function getValidInArray(schemaName: schema.Schema, contents: T[]): T[] {
- return contents.filter(current => Object.keys(current).length && schema.isValid(current, schemaName));
+ return contents.filter(
+ (current) =>
+ Object.keys(current).length && schema.isValid(current, schemaName),
+ );
}
function processDate(key: string, date: Date): string | null {
diff --git a/src/schema.ts b/src/schema.ts
index 51399ed..413c0ec 100644
--- a/src/schema.ts
+++ b/src/schema.ts
@@ -10,10 +10,12 @@ export interface Manifest {
export interface Certificates {
wwdr?: string;
signerCert?: string;
- signerKey?: {
- keyFile: string;
- passphrase?: string;
- } | string;
+ signerKey?:
+ | {
+ keyFile: string;
+ passphrase?: string;
+ }
+ | string;
}
export interface FactoryOptions {
@@ -29,7 +31,7 @@ export interface BundleUnit {
export interface PartitionedBundle {
bundle: BundleUnit;
l10nBundle: {
- [key: string]: BundleUnit
+ [key: string]: BundleUnit;
};
}
@@ -49,17 +51,24 @@ export interface PassInstance {
// * JOI Schemas + Related Interfaces * //
// ************************************ //
-const certificatesSchema = Joi.object().keys({
- wwdr: Joi.alternatives(Joi.binary(), Joi.string()).required(),
- signerCert: Joi.alternatives(Joi.binary(), Joi.string()).required(),
- signerKey: Joi.alternatives().try(
- Joi.object().keys({
- keyFile: Joi.alternatives(Joi.binary(), Joi.string()).required(),
- passphrase: Joi.string().required(),
- }),
- Joi.alternatives(Joi.binary(), Joi.string())
- ).required()
-}).required();
+const certificatesSchema = Joi.object()
+ .keys({
+ wwdr: Joi.alternatives(Joi.binary(), Joi.string()).required(),
+ signerCert: Joi.alternatives(Joi.binary(), Joi.string()).required(),
+ signerKey: Joi.alternatives()
+ .try(
+ Joi.object().keys({
+ keyFile: Joi.alternatives(
+ Joi.binary(),
+ Joi.string(),
+ ).required(),
+ passphrase: Joi.string().required(),
+ }),
+ Joi.alternatives(Joi.binary(), Joi.string()),
+ )
+ .required(),
+ })
+ .required();
const instance = Joi.object().keys({
model: Joi.alternatives(Joi.object(), Joi.string()).required(),
@@ -88,28 +97,31 @@ export interface OverridesSupportedOptions {
maxDistance?: number;
}
-const supportedOptions = Joi.object().keys({
- serialNumber: Joi.string(),
- description: Joi.string(),
- organizationName: Joi.string(),
- passTypeIdentifier: Joi.string(),
- teamIdentifier: Joi.string(),
- appLaunchURL: Joi.string(),
- associatedStoreIdentifiers: Joi.array().items(Joi.number()),
- userInfo: Joi.alternatives(Joi.object().unknown(), Joi.array()),
- // parsing url as set of words and nums followed by dots, optional port and any possible path after
- webServiceURL: Joi.string().regex(/https?:\/\/(?:[a-z0-9]+\.?)+(?::\d{2,})?(?:\/[\S]+)*/),
- authenticationToken: Joi.string().min(16),
- sharingProhibited: Joi.boolean(),
- backgroundColor: Joi.string().min(10).max(16),
- foregroundColor: Joi.string().min(10).max(16),
- labelColor: Joi.string().min(10).max(16),
- groupingIdentifier: Joi.string(),
- suppressStripShine: Joi.boolean(),
- logoText: Joi.string(),
- maxDistance: Joi.number().positive(),
-}).with("webServiceURL", "authenticationToken");
-
+const supportedOptions = Joi.object()
+ .keys({
+ serialNumber: Joi.string(),
+ description: Joi.string(),
+ organizationName: Joi.string(),
+ passTypeIdentifier: Joi.string(),
+ teamIdentifier: Joi.string(),
+ appLaunchURL: Joi.string(),
+ associatedStoreIdentifiers: Joi.array().items(Joi.number()),
+ userInfo: Joi.alternatives(Joi.object().unknown(), Joi.array()),
+ // parsing url as set of words and nums followed by dots, optional port and any possible path after
+ webServiceURL: Joi.string().regex(
+ /https?:\/\/(?:[a-z0-9]+\.?)+(?::\d{2,})?(?:\/[\S]+)*/,
+ ),
+ authenticationToken: Joi.string().min(16),
+ sharingProhibited: Joi.boolean(),
+ backgroundColor: Joi.string().min(10).max(16),
+ foregroundColor: Joi.string().min(10).max(16),
+ labelColor: Joi.string().min(10).max(16),
+ groupingIdentifier: Joi.string(),
+ suppressStripShine: Joi.boolean(),
+ logoText: Joi.string(),
+ maxDistance: Joi.number().positive(),
+ })
+ .with("webServiceURL", "authenticationToken");
/* For a correct usage of semantics, please refer to https://apple.co/2I66Phk */
@@ -130,7 +142,7 @@ interface PersonNameComponent {
const personNameComponents = Joi.object().keys({
givenName: Joi.string().required(),
- familyName: Joi.string().required()
+ familyName: Joi.string().required(),
});
interface Seat {
@@ -148,12 +160,12 @@ const seat = Joi.object().keys({
seatNumber: Joi.string(),
seatIdentifier: Joi.string(),
seatType: Joi.string(),
- seatDescription: Joi.string()
+ seatDescription: Joi.string(),
});
const location = Joi.object().keys({
latitude: Joi.number().required(),
- longitude: Joi.number().required()
+ longitude: Joi.number().required(),
});
interface Semantics {
@@ -201,7 +213,15 @@ interface Semantics {
venueEntrance?: string;
venuePhoneNumber?: string;
venueRoom?: string;
- eventType?: "PKEventTypeGeneric" | "PKEventTypeLivePerformance" | "PKEventTypeMovie" | "PKEventTypeSports" | "PKEventTypeConference" | "PKEventTypeConvention" | "PKEventTypeWorkshop" | "PKEventTypeSocialGathering";
+ eventType?:
+ | "PKEventTypeGeneric"
+ | "PKEventTypeLivePerformance"
+ | "PKEventTypeMovie"
+ | "PKEventTypeSports"
+ | "PKEventTypeConference"
+ | "PKEventTypeConvention"
+ | "PKEventTypeWorkshop"
+ | "PKEventTypeSocialGathering";
eventStartDate?: string;
eventEndDate?: string;
artistIDs?: string;
@@ -270,7 +290,9 @@ const semantics = Joi.object().keys({
venueEntrance: Joi.string(),
venuePhoneNumber: Joi.string(),
venueRoom: Joi.string(),
- eventType: Joi.string().regex(/(PKEventTypeGeneric|PKEventTypeLivePerformance|PKEventTypeMovie|PKEventTypeSports|PKEventTypeConference|PKEventTypeConvention|PKEventTypeWorkshop|PKEventTypeSocialGathering)/),
+ eventType: Joi.string().regex(
+ /(PKEventTypeGeneric|PKEventTypeLivePerformance|PKEventTypeMovie|PKEventTypeSports|PKEventTypeConference|PKEventTypeConvention|PKEventTypeWorkshop|PKEventTypeSocialGathering)/,
+ ),
eventStartDate: Joi.string(),
eventEndDate: Joi.string(),
artistIDs: Joi.string(),
@@ -287,7 +309,7 @@ const semantics = Joi.object().keys({
awayTeamAbbreviation: Joi.string(),
sportName: Joi.string(),
// Store Card Passes
- balance: currencyAmount
+ balance: currencyAmount,
});
export interface ValidPassType {
@@ -310,11 +332,16 @@ interface PassInterfacesProps {
voided?: boolean;
}
-type AllPassProps = PassInterfacesProps & ValidPassType & OverridesSupportedOptions;
+type AllPassProps = PassInterfacesProps &
+ ValidPassType &
+ OverridesSupportedOptions;
export type ValidPass = {
[K in keyof AllPassProps]: AllPassProps[K];
};
-export type PassColors = Pick;
+export type PassColors = Pick<
+ OverridesSupportedOptions,
+ "backgroundColor" | "foregroundColor" | "labelColor"
+>;
export interface Barcode {
altText?: string;
@@ -323,13 +350,22 @@ export interface Barcode {
message: string;
}
-export type BarcodeFormat = "PKBarcodeFormatQR" | "PKBarcodeFormatPDF417" | "PKBarcodeFormatAztec" | "PKBarcodeFormatCode128";
+export type BarcodeFormat =
+ | "PKBarcodeFormatQR"
+ | "PKBarcodeFormatPDF417"
+ | "PKBarcodeFormatAztec"
+ | "PKBarcodeFormatCode128";
const barcode = Joi.object().keys({
altText: Joi.string(),
messageEncoding: Joi.string().default("iso-8859-1"),
- format: Joi.string().required().regex(/(PKBarcodeFormatQR|PKBarcodeFormatPDF417|PKBarcodeFormatAztec|PKBarcodeFormatCode128)/, "barcodeType"),
- message: Joi.string().required()
+ format: Joi.string()
+ .required()
+ .regex(
+ /(PKBarcodeFormatQR|PKBarcodeFormatPDF417|PKBarcodeFormatAztec|PKBarcodeFormatCode128)/,
+ "barcodeType",
+ ),
+ message: Joi.string().required(),
});
export interface Field {
@@ -350,30 +386,53 @@ export interface Field {
}
const field = Joi.object().keys({
- attributedValue: Joi.alternatives(Joi.string().allow(""), Joi.number(), Joi.date().iso()),
+ attributedValue: Joi.alternatives(
+ Joi.string().allow(""),
+ Joi.number(),
+ Joi.date().iso(),
+ ),
changeMessage: Joi.string(),
- dataDetectorType: Joi.array().items(Joi.string().regex(/(PKDataDetectorTypePhoneNumber|PKDataDetectorTypeLink|PKDataDetectorTypeAddress|PKDataDetectorTypeCalendarEvent)/, "dataDetectorType")),
+ dataDetectorType: Joi.array().items(
+ Joi.string().regex(
+ /(PKDataDetectorTypePhoneNumber|PKDataDetectorTypeLink|PKDataDetectorTypeAddress|PKDataDetectorTypeCalendarEvent)/,
+ "dataDetectorType",
+ ),
+ ),
label: Joi.string().allow(""),
- textAlignment: Joi.string().regex(/(PKTextAlignmentLeft|PKTextAlignmentCenter|PKTextAlignmentRight|PKTextAlignmentNatural)/, "graphic-alignment"),
+ textAlignment: Joi.string().regex(
+ /(PKTextAlignmentLeft|PKTextAlignmentCenter|PKTextAlignmentRight|PKTextAlignmentNatural)/,
+ "graphic-alignment",
+ ),
key: Joi.string().required(),
- value: Joi.alternatives(Joi.string().allow(""), Joi.number(), Joi.date().iso()).required(),
+ value: Joi.alternatives(
+ Joi.string().allow(""),
+ Joi.number(),
+ Joi.date().iso(),
+ ).required(),
semantics,
// date fields formatters, all optionals
- dateStyle: Joi.string().regex(/(PKDateStyleNone|PKDateStyleShort|PKDateStyleMedium|PKDateStyleLong|PKDateStyleFull)/, "date style"),
+ dateStyle: Joi.string().regex(
+ /(PKDateStyleNone|PKDateStyleShort|PKDateStyleMedium|PKDateStyleLong|PKDateStyleFull)/,
+ "date style",
+ ),
ignoreTimeZone: Joi.boolean(),
isRelative: Joi.boolean(),
- timeStyle: Joi.string().regex(/(PKDateStyleNone|PKDateStyleShort|PKDateStyleMedium|PKDateStyleLong|PKDateStyleFull)/, "date style"),
+ timeStyle: Joi.string().regex(
+ /(PKDateStyleNone|PKDateStyleShort|PKDateStyleMedium|PKDateStyleLong|PKDateStyleFull)/,
+ "date style",
+ ),
// number fields formatters, all optionals
- currencyCode: Joi.string()
- .when("value", {
- is: Joi.number(),
- otherwise: Joi.string().forbidden()
- }),
+ currencyCode: Joi.string().when("value", {
+ is: Joi.number(),
+ otherwise: Joi.string().forbidden(),
+ }),
numberStyle: Joi.string()
- .regex(/(PKNumberStyleDecimal|PKNumberStylePercent|PKNumberStyleScientific|PKNumberStyleSpellOut)/)
+ .regex(
+ /(PKNumberStyleDecimal|PKNumberStylePercent|PKNumberStyleScientific|PKNumberStyleSpellOut)/,
+ )
.when("value", {
is: Joi.number(),
- otherwise: Joi.string().forbidden()
+ otherwise: Joi.string().forbidden(),
}),
});
@@ -385,10 +444,14 @@ export interface Beacon {
}
const beaconsDict = Joi.object().keys({
- major: Joi.number().integer().positive().max(65535).greater(Joi.ref("minor")),
+ major: Joi.number()
+ .integer()
+ .positive()
+ .max(65535)
+ .greater(Joi.ref("minor")),
minor: Joi.number().integer().min(0).max(65535),
proximityUUID: Joi.string().required(),
- relevantText: Joi.string()
+ relevantText: Joi.string(),
});
export interface Location {
@@ -402,7 +465,7 @@ const locationsDict = Joi.object().keys({
altitude: Joi.number(),
latitude: Joi.number().required(),
longitude: Joi.number().required(),
- relevantText: Joi.string()
+ relevantText: Joi.string(),
});
export interface PassFields {
@@ -414,18 +477,29 @@ export interface PassFields {
}
const passDict = Joi.object().keys({
- auxiliaryFields: Joi.array().items(Joi.object().keys({
- row: Joi.number().max(1).min(0)
- }).concat(field)),
+ auxiliaryFields: Joi.array().items(
+ Joi.object()
+ .keys({
+ row: Joi.number().max(1).min(0),
+ })
+ .concat(field),
+ ),
backFields: Joi.array().items(field),
headerFields: Joi.array().items(field),
primaryFields: Joi.array().items(field),
- secondaryFields: Joi.array().items(field)
+ secondaryFields: Joi.array().items(field),
});
-export type TransitType = "PKTransitTypeAir" | "PKTransitTypeBoat" | "PKTransitTypeBus" | "PKTransitTypeGeneric" | "PKTransitTypeTrain";
+export type TransitType =
+ | "PKTransitTypeAir"
+ | "PKTransitTypeBoat"
+ | "PKTransitTypeBus"
+ | "PKTransitTypeGeneric"
+ | "PKTransitTypeTrain";
-const transitType = Joi.string().regex(/(PKTransitTypeAir|PKTransitTypeBoat|PKTransitTypeBus|PKTransitTypeGeneric|PKTransitTypeTrain)/);
+const transitType = Joi.string().regex(
+ /(PKTransitTypeAir|PKTransitTypeBoat|PKTransitTypeBus|PKTransitTypeGeneric|PKTransitTypeTrain)/,
+);
export interface NFC {
message: string;
@@ -434,7 +508,7 @@ export interface NFC {
const nfcDict = Joi.object().keys({
message: Joi.string().required().max(64),
- encryptionPublicKey: Joi.string()
+ encryptionPublicKey: Joi.string(),
});
// ************************************* //
@@ -447,11 +521,20 @@ export interface Personalization {
termsAndConditions?: string;
}
-type PRSField = "PKPassPersonalizationFieldName" | "PKPassPersonalizationFieldPostalCode" | "PKPassPersonalizationFieldEmailAddress" | "PKPassPersonalizationFieldPhoneNumber";
+type PRSField =
+ | "PKPassPersonalizationFieldName"
+ | "PKPassPersonalizationFieldPostalCode"
+ | "PKPassPersonalizationFieldEmailAddress"
+ | "PKPassPersonalizationFieldPhoneNumber";
const personalizationDict = Joi.object().keys({
requiredPersonalizationFields: Joi.array()
- .items("PKPassPersonalizationFieldName", "PKPassPersonalizationFieldPostalCode", "PKPassPersonalizationFieldEmailAddress", "PKPassPersonalizationFieldPhoneNumber")
+ .items(
+ "PKPassPersonalizationFieldName",
+ "PKPassPersonalizationFieldPostalCode",
+ "PKPassPersonalizationFieldEmailAddress",
+ "PKPassPersonalizationFieldPhoneNumber",
+ )
.required(),
description: Joi.string().required(),
termsAndConditions: Joi.string(),
@@ -470,7 +553,7 @@ const schemas = {
transitType,
nfcDict,
supportedOptions,
- personalizationDict
+ personalizationDict,
};
export type Schema = keyof typeof schemas;
@@ -491,14 +574,18 @@ export function isValid(opts: any, schemaName: Schema): boolean {
const resolvedSchema = resolveSchemaName(schemaName);
if (!resolvedSchema) {
- schemaDebug(`validation failed due to missing or mispelled schema name`);
+ schemaDebug(
+ `validation failed due to missing or mispelled schema name`,
+ );
return false;
}
const validation = resolvedSchema.validate(opts);
if (validation.error) {
- schemaDebug(`validation failed due to error: ${validation.error.message}`);
+ schemaDebug(
+ `validation failed due to error: ${validation.error.message}`,
+ );
}
return !validation.error;
@@ -511,18 +598,25 @@ export function isValid(opts: any, schemaName: Schema): boolean {
* @returns {object} the filtered value or empty object
*/
-export function getValidated(opts: any, schemaName: Schema): T | null {
+export function getValidated(
+ opts: any,
+ schemaName: Schema,
+): T | null {
const resolvedSchema = resolveSchemaName(schemaName);
if (!resolvedSchema) {
- schemaDebug(`validation failed due to missing or mispelled schema name`);
+ schemaDebug(
+ `validation failed due to missing or mispelled schema name`,
+ );
return null;
}
const validation = resolvedSchema.validate(opts, { stripUnknown: true });
if (validation.error) {
- schemaDebug(`Validation failed in getValidated due to error: ${validation.error.message}`);
+ schemaDebug(
+ `Validation failed in getValidated due to error: ${validation.error.message}`,
+ );
return null;
}
diff --git a/src/utils.ts b/src/utils.ts
index 0fb9fdb..19912e9 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -16,13 +16,15 @@ export function isValidRGB(value?: string): boolean {
return false;
}
- const rgb = value.match(/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
+ const rgb = value.match(
+ /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/,
+ );
if (!rgb) {
return false;
}
- return rgb.slice(1, 4).every(v => Math.abs(Number(v)) <= 255);
+ return rgb.slice(1, 4).every((v) => Math.abs(Number(v)) <= 255);
}
/**
@@ -57,7 +59,7 @@ export function dateToW3CString(date: Date) {
*/
export function removeHidden(from: Array): Array {
- return from.filter(e => e.charAt(0) !== ".");
+ return from.filter((e) => e.charAt(0) !== ".");
}
/**
@@ -77,8 +79,9 @@ export function generateStringFile(lang: { [index: string]: string }): Buffer {
// Pass.strings format is the following one for each row:
// "key" = "value";
- const strings = Object.keys(lang)
- .map(key => `"${key}" = "${lang[key].replace(/"/g, '\"')}";`);
+ const strings = Object.keys(lang).map(
+ (key) => `"${key}" = "${lang[key].replace(/"/g, '"')}";`,
+ );
return Buffer.from(strings.join(EOL), "utf8");
}
@@ -89,47 +92,73 @@ export function generateStringFile(lang: { [index: string]: string }): Buffer {
* @param origin
*/
-type PartitionedBundleElements = [PartitionedBundle["l10nBundle"], PartitionedBundle["bundle"]];
+type PartitionedBundleElements = [
+ PartitionedBundle["l10nBundle"],
+ PartitionedBundle["bundle"],
+];
-export function splitBufferBundle(origin: BundleUnit): PartitionedBundleElements {
+export function splitBufferBundle(
+ origin: BundleUnit,
+): PartitionedBundleElements {
const initialValue: PartitionedBundleElements = [{}, {}];
if (!origin) {
return initialValue;
}
- return Object.entries(origin).reduce(([l10n, bundle], [key, buffer]) => {
- if (!key.includes(".lproj")) {
- return [
- l10n,
- {
- ...bundle,
- [key]: buffer
- }
- ];
- }
+ return Object.entries(origin).reduce(
+ ([l10n, bundle], [key, buffer]) => {
+ if (!key.includes(".lproj")) {
+ return [
+ l10n,
+ {
+ ...bundle,
+ [key]: buffer,
+ },
+ ];
+ }
- const pathComponents = key.split(sep);
- const lang = pathComponents[0];
- const file = pathComponents.slice(1).join("/");
+ const pathComponents = key.split(sep);
+ const lang = pathComponents[0];
+ const file = pathComponents.slice(1).join("/");
- (l10n[lang] || (l10n[lang] = {}))[file] = buffer;
+ (l10n[lang] || (l10n[lang] = {}))[file] = buffer;
- return [l10n, bundle];
- }, initialValue);
+ return [l10n, bundle];
+ },
+ initialValue,
+ );
}
type StringSearchMode = "includes" | "startsWith" | "endsWith";
-export function getAllFilesWithName(name: string, source: string[], mode: StringSearchMode = "includes", forceLowerCase: boolean = false): string[] {
- return source.filter(file => (forceLowerCase && file.toLowerCase() || file)[mode](name));
+export function getAllFilesWithName(
+ name: string,
+ source: string[],
+ mode: StringSearchMode = "includes",
+ forceLowerCase: boolean = false,
+): string[] {
+ return source.filter((file) =>
+ ((forceLowerCase && file.toLowerCase()) || file)[mode](name),
+ );
}
-export function hasFilesWithName(name: string, source: string[], mode: StringSearchMode = "includes", forceLowerCase: boolean = false): boolean {
- return source.some(file => (forceLowerCase && file.toLowerCase() || file)[mode](name));
+export function hasFilesWithName(
+ name: string,
+ source: string[],
+ mode: StringSearchMode = "includes",
+ forceLowerCase: boolean = false,
+): boolean {
+ return source.some((file) =>
+ ((forceLowerCase && file.toLowerCase()) || file)[mode](name),
+ );
}
-export function deletePersonalization(source: BundleUnit, logosNames: string[] = []): void {
- [...logosNames, "personalization.json"]
- .forEach(file => delete source[file]);
+export function deletePersonalization(
+ source: BundleUnit,
+ logosNames: string[] = [],
+): void {
+ [...logosNames, "personalization.json"].forEach(
+ (file) => delete source[file],
+ );
}