You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
The flow of execution is really easy (once everything is set up):
const PKPass > = require("passkit-generator");
const pass = new PKPass( . >, . >, . >);
Returns:
Description:
PKPass extends an internal class Bundle , which gives it some props. Only the exposed ones will be listed below.
Arguments:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
buffers | object | The initial files buffers to compose a pass. They must be in form path: Buffer . Set to empty object if none is available yet. | false | - |
certificates | object | The certificates object. | false | - |
certificates.wwdr | string | Buffer | The content of Apple WWDR certificate. | false | - |
certificates.signerCert | string | Buffer | The content of Developer certificate file. | false | - |
certificates.signerKey | string | Buffer | The content of developer certificate's key. | false | - |
certificates.signerKeyPassphrase | string | The passphrase to decrypt the developer signerKey | true | - |
props | object | Some pass props that will get merged with the ones in pass.json | true |
A pass can be created through its constructor (creating from scratch) or from another pass or from a template. A "template" here is a model saved on disk. Both can be created by using the static method PKPass.from() .
PKPass.from(source: PKPass | PKPass.Template, props?: Schemas.OverridableProps): Promisetypeof PKPass>;
Throws if the pass source is not valid.
In both cases, additional props can be passed as the second parameter through an object.
Below you can see a few example functions that will be used in the following ways to use PKPass.from .
function getAdditionalPropsForThisPassSomehow() // get your additional props for THIS pass return serialNumber: "12356222", /** moar props . */ >; > function getSomeProps() /** Set your base props for all your passes **/ return description: "Pass for some business activity", webServiceURL: "https://example.com/passkit", /** moar props . */ >; > function getCertificatesSomehow() return signerCert: "" /** string or Buffer **/, signerKey: "" /** string or Buffer **/, wwdr: "" /** string or Buffer **/, signerKeyPassphrase: "" /** string **/, >; >
Description:
Pass another PKPass as the source of PKPass.from to make it clone every property and file in the source object (except manifest and signature).
This is useful if you want to create a runtime template with your buffers and then always use it as a base.
Example:
const passRuntimeTemplate = new PKPass( getBuffersSomehow(), getCertificatesSomehow(), getSomeProps(), ); // later. const passToBeServed = await PKPass.from( passRuntimeTemplate, getAdditionalPropsForThisPassSomehow(), );
Description:
Use this if you have a saved model on your File System and want to read it and use it as the source for your pass.
Arguments:
The following are the arguments to be passed in the object in the first position:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
model | string (path) | The path to your model on File System | false | - |
certificates | object | The object containing certificates data. Refer to PKPass's constructor for all the keys | false | - |
Example:
const passFromDisk = await PKPass.from( model: "../../path/to/your/disk/model", certificates: getCertificatesSomehow(), >, getAdditionalPropsForThisPassSomehow(), );
pass.addBuffer(filePath: string, buffer: Buffer): void;
Description:
This method allows later additions of files to your pass. It has no filters about the type of file you may want to add but for:
In these cases, addBuffer will perform additional checks and might not add the file as-is or at all.
Throws if pass is frozen due to a previous export.
Arguments:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
filePath | string (path) | The path, local to your pass.json, where the file should be added (if it is a localization file, it will be like en.lproj/pass.strings , otherwise just the name, like personalization.json ) | false | - |
buffer | Buffer | The content of your file | false | - |
According to Apple Developer Documentation, localization (L10N) is done by creating a .lproj folder for each language you want to translate your pass, each named with the relative ISO-3166-1 alpha-2 code (e.g. en.lproj ).
There are three ways to include a language in this package:
If you are designing your pass for a language only, you can directly replace the placeholders in pass.json with translation.
pass.localize(lang: string, translations: [key: string]: string >): void;
Returns:
Description:
Use this method to add some translations. Existing translations will be merged with the newly added.
Calling .localize is the same as calling .addBuffer for a pass.strings file, except for the parsing phase. Pass null to translations param to delete everything of a language (translations and files).
Throws if pass is frozen due to a previous export, if the last is not a string or if no translations are provided.
Arguments:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
lang | String | The ISO-3166-1 language code | false | - |
translations | Object | null | Translations in format < : "TRANSLATED-VALUE"> . Pass null to delete everything of a language | false | - |
Example:
pass.localize("it", EVENT: "Evento", LOCATION: "Posizione", >); pass.localize("de", EVENT: "Ereignis", LOCATION: "Ort", >);
pass.setBarcodes(message: string): void; pass.setBarcodes(. barcodes: schema.Barcodes[ ]): void;
Returns:
Description:
Setting barcodes can happen in two ways: controlled and uncontrolled (autogenerated), which means how many barcode structures you will have in your pass.
Passing a string to the method will lead to an uncontrolled way: starting from the message (content), all the structures will be generated. Any further parameters will be ignored.
Passing N barcode structures (see below), will only validate them and push only the valid ones.
Setting barcodes will overwrite previously set barcodes (no matter the source). Pass null to delete all the barcodes.
Throws if pass is frozen due to a previous export.
Please note that, as the barcode property is deprecated, this is the only method available for setting barcodes.
Arguments:
Key | Type | Description | Optional |
---|---|---|---|
message | String | Barcode | first value of barcodes | false |
. rest | Barcode[] | the other barcode values | true |
Examples:
pass.setBarcodes("11424771526"); // or pass.setBarcodes( message: "11424771526", format: "PKBarcodeFormatCode128", altText: "11424771526" >, message: "11424771526", format: "PKBarcodeFormatQR", altText: "11424771526" >, message: "11424771526", format: "PKBarcodeFormatPDF417", altText: "11424771526" >);
pass.setExpirationDate(date: Date): void;
Returns:
Description:
It sets the date of expiration to the passed argument. Pass null as the parameter to remove the value from props. If date parsing fails, an error will be thrown.
Throws if pass is frozen due to a previous export.
Arguments:
Key | Type | Description | Optional |
---|---|---|---|
date | String/date | The date on which the pass will expire | false |
pass.setBeacons(. data: schema.Beacons[ ]): void;
Returns:
Description:
Sets the beacons information in the passes. Setting beacons will overwrite previously setted beacons. Pass null to delete all the beacons.
Throws if pass is frozen due to a previous export.
Arguments:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
. beacons | Beacons[] | null | The beacons structures | false | - |
Example:
pass.setBeacons( major: 55, minor: 0, proximityUUID: "59da0f96-3fb5-43aa-9028-2bc796c3d0c5", >, major: 65, minor: 46, proximityUUID: "fdcbbf48-a4ae-4ffb-9200-f8a373c5c18e", >, );
pass.setLocations(. data: schema.Locations[ ]): void;
Returns:
Description:
Sets the location-relevance information in the passes. Setting locations will overwrite previously setted locations (no matter the source). Pass null to delete all the locations.
Throws if pass is frozen due to a previous export.
Arguments:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
. locations | schema.Locations[] | null | The location structures | false | - |
Example:
pass.setLocations( latitude: 66.45725212, longitude: 33.01000442, >, longitude: 4.42634523, latitude: 5.344233323352, >, );
pass.setRelevantDate(date: Date): void;
Returns:
Description:
It sets the date of relevance to the passed argument. Pass null as the parameter to remove the value from props. If date parsing fails, an error will be thrown.
Throws if pass is frozen due to a previous export.
Arguments:
Key | Type | Description | Optional | Default Value |
---|---|---|---|---|
date | Date | null | The relevant date | false | - |
pass.setNFC(data: schema.NFC): void
Returns:
Description:
It sets NFC info for the current pass. Pass null as a parameter to remove its value from props.
Throws if pass is frozen due to a previous export or if parameter validation fails.
Arguments:
Key | Type | Description | Optional |
---|---|---|---|
data | NFC Dictionary | null | NFC structure | false |
See: NFC
Personalization (or Reward Enrollment passes) is supported only if:
If these conditions are not met, personalization files will get removed from the output pass or not be accepted as an input file.
Notice: There is no way I could test this feature on any real pass 'cause Apple would never give me an encryptionKey for NFC. Also, I don't have an NFC reader. If you need it and this won't work, feel free to contact me and we will investigate together ๐
The opposite is valid as well: if you try to use it and it works, feel free to report it to me, so this warning can be removed
Unlike method-set properties or initialization props, to set fields inside the right property, some getters have been created, one per property. Each extends native Arrays, to let you perform all the operations you need on the fields. Fields already available in pass.json, will be automatically loaded in props.
Please note that they are strictly and directly linked to the pass type property (boardingPass, storeCard, etc. ). This means that if pass type is not available, accessing them will throw an error. Changing the type on runtime will clean all them up.
All the fields are linked together through a keys pool: each key must be unique among all the fields of the whole pass.
Each getter will throw if pass is frozen due to a previous export, when a new element is attempted to be added to the related array.
Examples:
pass.headerFields.push( key: "header1", label: "Data", value: "25 mag", textAlignment: "PKTextAlignmentCenter", >, key: "header2", label: "Volo", value: "EZY997", textAlignment: "PKTextAlignmentCenter", >, ); pass.primaryFields.pop(); pass.auxiliaryFields.push(/*. */); pass.secondaryFields.push(/*. */); pass.backFields.push(/*. */);
pass.transitType = "PKTransitTypeAir";
Description:
Since this property belongs to the "Field Keys" but is not an "array of field dictionaries" like its sibling keys, a setter, and a getter got included to select it.
Allowed values: PKTransitTypeAir, PKTransitTypeBoat, PKTransitTypeBus, PKTransitTypeGeneric, PKTransitTypeTrain", as described in Passkit Package Format Reference.
Please note that it is strictly and directly linked to the pass type property (only boardingPass).
This means that if pass type is not available or is not a boardingPass, accessing or setting it will throw an error. Changing the type on runtime will clean it up.
Pass exporting will throw an error if a boardingPass is exported without transitType .
Setter throws if pass is frozen due to a previous export, if an invalid pass type is invalid, or if current type is not a boardingPass .
Generating the pass is the last step of the process (before enjoying ๐). Generating might happen in three ways: getting a Buffer, a Stream, or Raw files.
All the three ways available, will lock the pass instance to not accept anymore files or props.
pass.getAsBuffer(): Buffer;
Description:
Creates a buffer of the zipped pass. This is useful when passkit-generator is used in contexts where using Streams is not possible, like cloud functions.
Examples:
const passBuffer = pass.getAsBuffer(); doSomethingWithPassBuffer(Buffer);
pass.getAsStream(): Stream;
Description:
Creates a stream for the zipped pass.
Examples:
const passStream = pass.getAsStream(); doSomethingWithPassStream(stream);
pass.getAsRaw(): Readonly [path: string]: Buffer >>;
Description:
Returns a frozen object containing all the files along with their buffers (with compiled signature and manifest).
The purpose of this stands in how zips are created. In passkit-generator v2.x.x, a different and asynchronous library was being used to create zips. Due to a worse API, it was replaced by do-not-zip, which acts more like a buffers concatenator instead of a compressor. This compromise improved the creation of zips by making zips generation synchronous, through a very-lightweight package, but with possibly incremented final archives size.
For this reason, if the developer is already using a different zip library and is providing quite large files, better results in terms of pass weight might be obtained by manipulating the list of files provided by this method and feeding them to the already-available zip library.
Examples:
import toBuffer as doNotZip > from "do-not-zip"; const passFiles = pass.getAsRaw(); const crunchedData = Object.entries(passFiles).map(([path, data]) => ( path, data, >)); doSomethingWithCustomZippedPass(doNotZip(chunchedData));