From f50e38ca94245fdb80d9d0b191d04a15125b7f7f Mon Sep 17 00:00:00 2001 From: Alexander Cerutti Date: Sun, 10 Oct 2021 01:35:47 +0200 Subject: [PATCH] Removed Bundle.autofreezable for Bundle.freezable and made freeze manual when using .pack --- src/Bundle.ts | 40 +++++++++++++++++++++++----------------- src/PKPass.ts | 16 ++++++++++++++-- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/Bundle.ts b/src/Bundle.ts index 964a161..26fbd8b 100644 --- a/src/Bundle.ts +++ b/src/Bundle.ts @@ -2,6 +2,7 @@ import { Stream } from "stream"; import { ZipFile } from "yazl"; export const filesSymbol = Symbol("bundleFiles"); +const freezeSymbol = Symbol("bundleFreeze"); const archiveSymbol = Symbol("zip"); namespace Mime { @@ -26,26 +27,31 @@ export default class Bundle { } /** - * @EXPERIMENTAL + * Creates a bundle and exposes the + * function to freeze it manually once + * completed. + * + * This was made to not expose freeze + * function outside of Bundle class. + * + * Normally, a bundle would get freezed + * when using getAsBuffer or getAsStream + * but when creating a PKPasses archive, + * we need to freeze the bundle so the + * user cannot add more files (we want to + * allow them to only the selected files) + * but also letting them choose how to + * export it. * * @param mimeType + * @returns */ - static autoFreezable(mimeType: `${Mime.type}/${Mime.subtype}`): Bundle { + static freezable( + mimeType: `${Mime.type}/${Mime.subtype}`, + ): [Bundle, Function] { const bundle = new Bundle(mimeType); - - /** - * @TODO - * Might not be the best idea I might have had. - * I have to test this further more to check if - * actually we can leverage of this event loop feature - * to freeze it automatically once we processed every - * promise for bundling; - */ - - setTimeout(bundle.freeze, 0); - - return bundle; + return [bundle, bundle[freezeSymbol]]; } /** @@ -53,7 +59,7 @@ export default class Bundle { * can be added any further. */ - protected freeze() { + protected [freezeSymbol]() { if (this.isFrozen) { return; } @@ -118,7 +124,7 @@ export default class Bundle { */ public getAsStream(): Stream { - this.freeze(); + this[freezeSymbol](); return this[archiveSymbol].outputStream; } } diff --git a/src/PKPass.ts b/src/PKPass.ts index ebd8f05..33f81bd 100644 --- a/src/PKPass.ts +++ b/src/PKPass.ts @@ -125,12 +125,16 @@ export default class PKPass extends Bundle { passes.map((pass) => pass.getAsBuffer()), ); - const bundle = Bundle.autoFreezable("application/vnd.apple.pkpasses"); + const [bundle, freezeBundle] = Bundle.freezable( + "application/vnd.apple.pkpasses", + ); for (let i = 0; i < buffers.length; i++) { bundle.addBuffer(`packed-pass-${i + 1}.pkpass`, buffers[i]); } + freezeBundle(); + return bundle; } @@ -509,6 +513,8 @@ export default class PKPass extends Bundle { */ private [closePassSymbol]() { + const fileNames = Object.keys(this[filesSymbol]); + /** * Filtering colors props that have an * invalid RGB value @@ -536,6 +542,13 @@ export default class PKPass extends Bundle { const passJson = Buffer.from(JSON.stringify(this[propsSymbol])); super.addBuffer("pass.json", passJson); + const ICON_REGEX = /icon(?:@\d{1}x)?/; + if (!fileNames.some(ICON_REGEX.test)) { + console.warn( + "At least one icon file is missing in your bundle. Your pass won't be openable by any Apple Device.", + ); + } + // *********************************** // // *** LOCALIZATION FILES CREATION *** // // *********************************** // @@ -561,7 +574,6 @@ export default class PKPass extends Bundle { // *** PERSONALIZATION *** // // *********************** // - const fileNames = Object.keys(this[filesSymbol]); const meetsPersonalizationRequirements = Boolean( this[filesSymbol]["personalization.json"] && fileNames.find((file) =>