mirror of
https://github.com/marcogll/passkit-generator.git
synced 2026-03-15 21:25:26 +00:00
Updated examples
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* examples, creation through templates is already shown
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import { PKPass } from "passkit-generator";
|
||||
@@ -62,7 +62,11 @@ async function readDirectory(filePath: string) {
|
||||
|
||||
return dirContent.map(async (fileName) => {
|
||||
const content = await fs.readFile(path.resolve(filePath, fileName));
|
||||
return getObjectFromModelFile(filePath, content, 1);
|
||||
return getObjectFromModelFile(
|
||||
path.resolve(filePath, fileName),
|
||||
content,
|
||||
2,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,42 +74,43 @@ async function readDirectory(filePath: string) {
|
||||
// *** EXAMPLE FROM NOW ON *** //
|
||||
// *************************** //
|
||||
|
||||
/**
|
||||
* Reading model before answering. Maybe we need to do
|
||||
* something else with it.
|
||||
*/
|
||||
const passTemplate = new Promise<PKPass>(async (resolve) => {
|
||||
const modelPath = path.resolve(__dirname, `../models/examplePass.pass`);
|
||||
const [modelFilesList, certificates] = await Promise.all([
|
||||
fs.readdir(modelPath),
|
||||
getCertificates(),
|
||||
]);
|
||||
|
||||
const modelPath = path.resolve(__dirname, `../models/examplePass.pass`);
|
||||
const modelRecords = (
|
||||
await Promise.all(
|
||||
/**
|
||||
* Obtaining flattened array of buffer records
|
||||
* containing file name and the buffer itself.
|
||||
*
|
||||
* This goes also to read every nested l10n
|
||||
* subfolder.
|
||||
*/
|
||||
|
||||
const modelFilesList = await fs.readdir(modelPath);
|
||||
modelFilesList.map((fileOrDirectoryPath) => {
|
||||
const fullPath = path.resolve(modelPath, fileOrDirectoryPath);
|
||||
|
||||
const modelRecords = (
|
||||
await Promise.all(
|
||||
/**
|
||||
* Obtaining flattened array of buffer records
|
||||
* containing file name and the buffer itself.
|
||||
*
|
||||
* This goes also to read every nested l10n
|
||||
* subfolder.
|
||||
*/
|
||||
|
||||
modelFilesList.map((fileOrDirectoryPath) => {
|
||||
const fullPath = path.resolve(modelPath, fileOrDirectoryPath);
|
||||
|
||||
return readFileOrDirectory(fullPath);
|
||||
}),
|
||||
return readFileOrDirectory(fullPath);
|
||||
}),
|
||||
)
|
||||
)
|
||||
)
|
||||
.flat(1)
|
||||
.reduce((acc, current) => ({ ...acc, ...current }), {});
|
||||
.flat(1)
|
||||
.reduce((acc, current) => ({ ...acc, ...current }), {});
|
||||
|
||||
/** Creating a PKPass Template */
|
||||
/** Creating a PKPass Template */
|
||||
|
||||
const templatePass = new PKPass(modelRecords, {
|
||||
wwdr: path.resolve(__dirname, "../../certificates/WWDR.pem"),
|
||||
signerCert: path.resolve(__dirname, "../../certificates/signerCert.pem"),
|
||||
signerKey: path.resolve(__dirname, "../../certificates/signerKey.pem"),
|
||||
signerKeyPassphrase: "123456",
|
||||
return resolve(
|
||||
new PKPass(modelRecords, {
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
app.all(async function manageRequest(request, response) {
|
||||
@@ -114,6 +119,8 @@ app.all(async function manageRequest(request, response) {
|
||||
"_" +
|
||||
new Date().toISOString().split("T")[0].replace(/-/gi, "");
|
||||
|
||||
const templatePass = await passTemplate;
|
||||
|
||||
try {
|
||||
const pass = await PKPass.from(
|
||||
templatePass,
|
||||
|
||||
@@ -4,42 +4,78 @@
|
||||
* Here it is showed manual model reading and
|
||||
* creating through another PKPass because in the other
|
||||
* examples, creation through templates is already shown
|
||||
*
|
||||
* PLEASE NOTE THAT, AT TIME OF WRITING, THIS EXAMPLE WORKS
|
||||
* ONLY IF PASSES ARE DOWNLOADED FROM SAFARI, due to the
|
||||
* support of PKPasses archives. To test this, you might
|
||||
* need to open a tunnel through NGROK if you cannot access
|
||||
* to your local machine (in my personal case, developing
|
||||
* under WSL is a pretty big limitation sometimes).
|
||||
*
|
||||
* @TODO test again this example with next iOS 15 versions.
|
||||
* Currently, pass viewer seems to be soooo bugged.
|
||||
*
|
||||
* https://imgur.com/bDTbcDg.jpg
|
||||
* https://imgur.com/Y4GpuHT.jpg
|
||||
* https://i.imgur.com/qbJMy1d.jpg
|
||||
*
|
||||
* Alberto, come to look at APPLE.
|
||||
*
|
||||
* MAMMA MIA!
|
||||
*
|
||||
* A feedback to Apple have been sent for this.
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import { PKPass } from "passkit-generator";
|
||||
|
||||
const iconFromModel = await fs.readFile(
|
||||
path.resolve(__dirname, "models/exampleBooking.pass/icon.png"),
|
||||
);
|
||||
|
||||
// *************************** //
|
||||
// *** EXAMPLE FROM NOW ON *** //
|
||||
// *************************** //
|
||||
|
||||
function getRandomColorPart() {
|
||||
return Math.floor(Math.random() * 255);
|
||||
}
|
||||
|
||||
async function generatePass(props: Object) {
|
||||
const [iconFromModel, certificates] = await Promise.all([
|
||||
fs.readFile(
|
||||
path.resolve(__dirname, "../models/exampleBooking.pass/icon.png"),
|
||||
),
|
||||
getCertificates(),
|
||||
]);
|
||||
|
||||
const pass = new PKPass(
|
||||
{},
|
||||
{
|
||||
wwdr: path.resolve(__dirname, "../../certificates/WWDR.pem"),
|
||||
signerCert: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerCert.pem",
|
||||
),
|
||||
signerKey: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerKey.pem",
|
||||
),
|
||||
signerKeyPassphrase: "123456",
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
},
|
||||
{
|
||||
...props,
|
||||
description: "Example Apple Wallet Pass",
|
||||
passTypeIdentifier: "pass.com.passkitgenerator",
|
||||
serialNumber: "nmyuxofgna",
|
||||
organizationName: `Test Organization ${Math.random()}`,
|
||||
teamIdentifier: "F53WB8AE67",
|
||||
foregroundColor: `rgb(${getRandomColorPart()}, ${getRandomColorPart()}, ${getRandomColorPart()})`,
|
||||
labelColor: `rgb(${getRandomColorPart()}, ${getRandomColorPart()}, ${getRandomColorPart()})`,
|
||||
backgroundColor: `rgb(${getRandomColorPart()}, ${getRandomColorPart()}, ${getRandomColorPart()})`,
|
||||
},
|
||||
props,
|
||||
);
|
||||
|
||||
pass.type = "boardingPass";
|
||||
pass.transitType = "PKTransitTypeAir";
|
||||
|
||||
pass.setBarcodes({
|
||||
message: "123456789",
|
||||
format: "PKBarcodeFormatQR",
|
||||
});
|
||||
|
||||
pass.headerFields.push(
|
||||
{
|
||||
key: "header-field-test-1",
|
||||
@@ -93,7 +129,7 @@ app.all(async function manageRequest(request, response) {
|
||||
|
||||
response.set({
|
||||
"Content-type": pkpasses.mimeType,
|
||||
"Content-disposition": `attachment; filename=${passName}.pkpass`,
|
||||
"Content-disposition": `attachment; filename=${passName}.pkpasses`,
|
||||
});
|
||||
|
||||
const stream = pkpasses.getAsStream();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* @Author: Alexander P. Cerutti
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import path from "path";
|
||||
import { PKPass } from "passkit-generator";
|
||||
|
||||
@@ -19,24 +19,17 @@ app.all(async function manageRequest(request, response) {
|
||||
"_" +
|
||||
new Date().toISOString().split("T")[0].replace(/-/gi, "");
|
||||
|
||||
const certificates = await getCertificates();
|
||||
|
||||
try {
|
||||
const pass = await PKPass.from(
|
||||
{
|
||||
model: path.resolve(__dirname, "../models/exampleBooking"),
|
||||
certificates: {
|
||||
wwdr: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/WWDR.pem",
|
||||
),
|
||||
signerCert: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerCert.pem",
|
||||
),
|
||||
signerKey: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerKey.pem",
|
||||
),
|
||||
signerKeyPassphrase: "123456",
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
},
|
||||
},
|
||||
request.body || request.params || request.query,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* .pkpass file and check for .lproj folders
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import path from "path";
|
||||
import { PKPass } from "passkit-generator";
|
||||
/** Symbols are exported just for tests and examples. Replicate only if really needed. */
|
||||
@@ -16,6 +16,8 @@ app.all(async function manageRequest(request, response) {
|
||||
"_" +
|
||||
new Date().toISOString().split("T")[0].replace(/-/gi, "");
|
||||
|
||||
const certificates = await getCertificates();
|
||||
|
||||
try {
|
||||
const pass = await PKPass.from(
|
||||
{
|
||||
@@ -24,42 +26,15 @@ app.all(async function manageRequest(request, response) {
|
||||
`../models/${request.params.modelName}`,
|
||||
),
|
||||
certificates: {
|
||||
wwdr: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/WWDR.pem",
|
||||
),
|
||||
signerCert: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerCert.pem",
|
||||
),
|
||||
signerKey: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerKey.pem",
|
||||
),
|
||||
signerKeyPassphrase: "123456",
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
},
|
||||
},
|
||||
request.body || request.params || request.query,
|
||||
);
|
||||
|
||||
/**
|
||||
* For each language you include, an .lproj folder in pass bundle
|
||||
* is created or included. You may not want to add translations
|
||||
* but only images for a specific language. So you create manually
|
||||
* an .lproj folder in your pass model then add the language here
|
||||
* below. If no translations does not get added, the folder is
|
||||
* included or created but without pass.strings file.
|
||||
*
|
||||
*
|
||||
* In this example, English does not have an .lproj folder yet and
|
||||
* doesn't have nor receive translations.
|
||||
*
|
||||
* Text placeholders may not be showed for the english language
|
||||
* (e.g. "Event" and "Location" as literal) and another language may be used instead
|
||||
*/
|
||||
|
||||
pass.localize("en");
|
||||
|
||||
// Italian, already has an .lproj which gets included...
|
||||
pass.localize("it", {
|
||||
EVENT: "Evento",
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
* by adding files later and not adding pass.json
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import { PKPass } from "passkit-generator";
|
||||
|
||||
const iconFromModel = await fs.readFile(
|
||||
path.resolve(__dirname, "models/exampleBooking.pass/icon.png"),
|
||||
);
|
||||
function getRandomColorPart() {
|
||||
return Math.floor(Math.random() * 255);
|
||||
}
|
||||
|
||||
app.all(async function manageRequest(request, response) {
|
||||
const passName =
|
||||
@@ -18,22 +18,33 @@ app.all(async function manageRequest(request, response) {
|
||||
"_" +
|
||||
new Date().toISOString().split("T")[0].replace(/-/gi, "");
|
||||
|
||||
const [iconFromModel, certificates] = await Promise.all([
|
||||
fs.readFile(
|
||||
path.resolve(__dirname, "../models/exampleBooking.pass/icon.png"),
|
||||
),
|
||||
await getCertificates(),
|
||||
]);
|
||||
|
||||
try {
|
||||
const pass = new PKPass(
|
||||
{},
|
||||
{
|
||||
wwdr: path.resolve(__dirname, "../../certificates/WWDR.pem"),
|
||||
signerCert: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerCert.pem",
|
||||
),
|
||||
signerKey: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerKey.pem",
|
||||
),
|
||||
signerKeyPassphrase: "123456",
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
},
|
||||
{
|
||||
...(request.body || request.params || request.query),
|
||||
description: "Example Apple Wallet Pass",
|
||||
passTypeIdentifier: "pass.com.passkitgenerator",
|
||||
serialNumber: "nmyuxofgna",
|
||||
organizationName: `Test Organization ${Math.random()}`,
|
||||
teamIdentifier: "F53WB8AE67",
|
||||
foregroundColor: `rgb(${getRandomColorPart()}, ${getRandomColorPart()}, ${getRandomColorPart()})`,
|
||||
labelColor: `rgb(${getRandomColorPart()}, ${getRandomColorPart()}, ${getRandomColorPart()})`,
|
||||
backgroundColor: `rgb(${getRandomColorPart()}, ${getRandomColorPart()}, ${getRandomColorPart()})`,
|
||||
},
|
||||
request.body || request.params || request.query,
|
||||
);
|
||||
|
||||
pass.type = "boardingPass";
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* by a string
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import { PKPass } from "passkit-generator";
|
||||
import path from "path";
|
||||
|
||||
@@ -18,6 +18,8 @@ app.all(async function manageRequest(request, response) {
|
||||
"_" +
|
||||
new Date().toISOString().split("T")[0].replace(/-/gi, "");
|
||||
|
||||
const certificates = await getCertificates();
|
||||
|
||||
try {
|
||||
const pass = await PKPass.from(
|
||||
{
|
||||
@@ -26,19 +28,10 @@ app.all(async function manageRequest(request, response) {
|
||||
`../models/${request.params.modelName}`,
|
||||
),
|
||||
certificates: {
|
||||
wwdr: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/WWDR.pem",
|
||||
),
|
||||
signerCert: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerCert.pem",
|
||||
),
|
||||
signerKey: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerKey.pem",
|
||||
),
|
||||
signerKeyPassphrase: "123456",
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
},
|
||||
},
|
||||
request.body || request.params || request.query || {},
|
||||
@@ -65,11 +58,6 @@ app.all(async function manageRequest(request, response) {
|
||||
message: "Thank you for using this package <3",
|
||||
format: "PKBarcodeFormatPDF417",
|
||||
},
|
||||
{
|
||||
message: "Thank you for using this package <3",
|
||||
// @ts-expect-error
|
||||
format: "PKBarcodeFormatMock44617",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* have to wait two minutes.
|
||||
*/
|
||||
|
||||
import app from "./webserver";
|
||||
import app, { getCertificates } from "./webserver";
|
||||
import path from "path";
|
||||
import { PKPass } from "passkit-generator";
|
||||
|
||||
@@ -19,6 +19,8 @@ app.all(async function manageRequest(request, response) {
|
||||
return;
|
||||
}
|
||||
|
||||
const certificates = await getCertificates();
|
||||
|
||||
const passName =
|
||||
request.params.modelName +
|
||||
"_" +
|
||||
@@ -32,19 +34,10 @@ app.all(async function manageRequest(request, response) {
|
||||
`../models/${request.params.modelName}`,
|
||||
),
|
||||
certificates: {
|
||||
wwdr: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/WWDR.pem",
|
||||
),
|
||||
signerCert: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerCert.pem",
|
||||
),
|
||||
signerKey: path.resolve(
|
||||
__dirname,
|
||||
"../../certificates/signerKey.pem",
|
||||
),
|
||||
signerKeyPassphrase: "123456",
|
||||
wwdr: certificates.wwdr,
|
||||
signerCert: certificates.signerCert,
|
||||
signerKey: certificates.signerKey,
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
},
|
||||
},
|
||||
Object.assign(
|
||||
@@ -62,6 +55,10 @@ app.all(async function manageRequest(request, response) {
|
||||
|
||||
// setting the expiration
|
||||
pass.setExpirationDate(d);
|
||||
console.log(
|
||||
"EXPIRATION DATE EXPECTED:",
|
||||
pass.props["expirationDate"],
|
||||
);
|
||||
}
|
||||
|
||||
const stream = pass.getAsStream();
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
|
||||
import express from "express";
|
||||
import { promises as fs } from "fs";
|
||||
import path from "path";
|
||||
export const app = express();
|
||||
|
||||
app.use(express.json());
|
||||
@@ -25,3 +27,41 @@ app.route("/gen").all((req, res) => {
|
||||
});
|
||||
|
||||
export default app.route("/gen/:modelName");
|
||||
const certificatesCache: Partial<{
|
||||
signerCert: Buffer;
|
||||
signerKey: Buffer;
|
||||
wwdr: Buffer;
|
||||
signerKeyPassphrase: string;
|
||||
}> = {};
|
||||
|
||||
export async function getCertificates(): Promise<typeof certificatesCache> {
|
||||
if (Object.keys(certificatesCache).length) {
|
||||
return certificatesCache;
|
||||
}
|
||||
|
||||
const [signerCert, signerKey, wwdr, signerKeyPassphrase] =
|
||||
await Promise.all([
|
||||
fs.readFile(
|
||||
path.resolve(__dirname, "../../certificates/signerCert.pem"),
|
||||
"utf-8",
|
||||
),
|
||||
fs.readFile(
|
||||
path.resolve(__dirname, "../../certificates/signerKey.pem"),
|
||||
"utf-8",
|
||||
),
|
||||
fs.readFile(
|
||||
path.resolve(__dirname, "../../certificates/WWDR.pem"),
|
||||
"utf-8",
|
||||
),
|
||||
Promise.resolve("123456"),
|
||||
]);
|
||||
|
||||
Object.assign(certificatesCache, {
|
||||
signerCert,
|
||||
signerKey,
|
||||
wwdr,
|
||||
signerKeyPassphrase,
|
||||
});
|
||||
|
||||
return certificatesCache;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user