Skip to content

Migrating from v1 to v2

Alexander Cerutti edited this page Nov 12, 2020 · 5 revisions

A new major version has been released, it brought a lot of breaking changes and improvements into passkit-generator and I'm soooo thrilled about this.

Welcome to the Factory

The new version completely changes how a pass "entity" is generated. The old version was syncronous up to .generate() (as it was the responsible of reading the model, the certificates and so on). In the new version, the flow is reversed: a new factory method createPass has been created and it will read the model and the certificates once.

Its signature is the following one:

async function createPass(options: FactoryOptions): Promise<Pass>

Example snippet:

OLD:

const pass = new Pass({ ... });
pass.localize("en", { ... });

try {
	const stream = await pass.generate();
	doSomethingWithStream(stream);
} catch (err) {
	doSomethingWithError(err);
}

NEW:

try {
	const pass = await createPass({ ... });
	pass.localize("en", { ... });

	const stream = pass.generate();
	doSomethingWithStream(stream);
} catch (err) {
	doSomethingWithError(err);
}

Instance option changes

  • In the new version, parameter shouldOverwrite has been removed as pass.json now gets parsed on createPass and its contents is inserted automatically into the Pass class. For this reason, a new getter has been made available: props. You'll be still able to edit your Fields as arrays as before. Also, passing null to many methods, will reset their value. Please refer to documentation to see all the supported methods.

    Example:

    If your model has already locations in it, but you want to remove some of them, you'll be able to do something like this.

     const pass = await createPass({ ... });
     const currentLocations = pass.props["locations"];
    
     // resetting
     pass.locations(null);
    
    
     const filteredLocations = currentLocations.filter(loc => { ... });
     pass.locations(...filteredLocations);
  • Passkit-generator has been built to use a "physical" template on the disk. Anyway it wasn't enough. Therefore, now the model parameter will accept both a string/path and an Object with { [key: string]: Buffer } as signature.

    Examples:

    ✅ Physical model:

     await createPass({
       model: "../myExamplePass.pass",
       ...
     });

    ✅ Preprocessed model:

     await createPass({
       model: {
         "thumbnail": Buffer.from([ ... ]),
         "pass.json": Buffer.from([ ... ]),
         "it.lproj/pass.strings": Buffer.from([ ... ])
       }
     });

New methods and changes

  • relevance() method has been splitted up. While maxDistance property has been added to overrides, beacons, locations and relevantDate now have their own functions to be set and validated. Also, there is no more need to specify the format of the date for relevantDate, as now only Date native object is accepted.

    Example:

    OLD:

     pass
     	.relevance("beacons", [ ... ])
     	.relevance("locations", [ ... ])
     	.relevance("maxDistance", 150, undefined)
     	.relevance("relevantDate", "2021-04-15", "YYYY-MM-DD");

    NEW:

     const pass = await createPass({
     	...
     	overrides: {
     		maxDistance: 150
     	}
     });
    
     pass
     	.beacons({ ... }, { ... }, ...)
     	.locations({ ... }, { ... }, ...)
     	.relevantDate(new Date("2021-04-15"));

Barcodes

For the introduction of .props, there is not anymore need for the special return type of barcode.

Therefore, it does not return anymore the length property. Also backward and autocomplete methods have been removed as returned members.

barcode method has been now renamed to barcodes and backward to barcode. Also, barcodes now won't set barcode in pass.json anymore.

Old Version New Version
barcode barcodes
backward barcode

The autocomplete method has been removed. Instead, barcodes now will automatically generate all the structures only if a string (the message) is passed as parameter.

barcodes signature, moreover, can be used as below:

.barcodes("your-pass-message");
.barcodes({ ... }, { ... }, { ... }, ...);

barcode method, as backward, will accept a format to pick from barcodes. Therefore, to use it, barcodes must be already been set. Please remember that PKBarcodeFormatCode128 format is still not supported as barcode.

pass
	.barcodes(...)
	.barcode("PKBarcodeFormatPDF417");

Loading contents

In v1.x, a method .load was available to download the contents directly from passkit-generator. In v2.x this method has been removed for different reasons:

  • It shouldn't be role of passkit-generator to download the contents
  • Keeping a dependency only to download the contents from a package is very bad as users might have a different dependency to download contents from the web and this would mean to increase the weight of the package itself and whole implementer project's weight.
  • Therefore, anyone should be able to decide whether to include a dependency or not to download contents.

Downloading contents must now be done before creating the pass instance. As downloading contents usually returns a Buffer, to avoid forcing the usage of createPass in "bundle-mode" (instead of model-mode), another parameter called additionalBuffers has been added to createPass as second argument. It is an object in the following format, that will specify new files to be added to the resulting .zip file. additionalBundles have a higher priority on model/bundle files.

{
    "it.lproj/background.png": Buffer< ... >,
    "[email protected]": Buffer< ... >
}

Hope you are enjoying this new version. Again, any contribution is welcome!

Thank you for using Passkit-generator ❤