Removed Bundle.autofreezable for Bundle.freezable and made freeze manual when using .pack

This commit is contained in:
Alexander Cerutti
2021-10-10 01:35:47 +02:00
parent 6905c27885
commit f50e38ca94
2 changed files with 37 additions and 19 deletions

View File

@@ -2,6 +2,7 @@ import { Stream } from "stream";
import { ZipFile } from "yazl"; import { ZipFile } from "yazl";
export const filesSymbol = Symbol("bundleFiles"); export const filesSymbol = Symbol("bundleFiles");
const freezeSymbol = Symbol("bundleFreeze");
const archiveSymbol = Symbol("zip"); const archiveSymbol = Symbol("zip");
namespace Mime { 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 * @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); const bundle = new Bundle(mimeType);
return [bundle, bundle[freezeSymbol]];
/**
* @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;
} }
/** /**
@@ -53,7 +59,7 @@ export default class Bundle {
* can be added any further. * can be added any further.
*/ */
protected freeze() { protected [freezeSymbol]() {
if (this.isFrozen) { if (this.isFrozen) {
return; return;
} }
@@ -118,7 +124,7 @@ export default class Bundle {
*/ */
public getAsStream(): Stream { public getAsStream(): Stream {
this.freeze(); this[freezeSymbol]();
return this[archiveSymbol].outputStream; return this[archiveSymbol].outputStream;
} }
} }

View File

@@ -125,12 +125,16 @@ export default class PKPass extends Bundle {
passes.map((pass) => pass.getAsBuffer()), 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++) { for (let i = 0; i < buffers.length; i++) {
bundle.addBuffer(`packed-pass-${i + 1}.pkpass`, buffers[i]); bundle.addBuffer(`packed-pass-${i + 1}.pkpass`, buffers[i]);
} }
freezeBundle();
return bundle; return bundle;
} }
@@ -509,6 +513,8 @@ export default class PKPass extends Bundle {
*/ */
private [closePassSymbol]() { private [closePassSymbol]() {
const fileNames = Object.keys(this[filesSymbol]);
/** /**
* Filtering colors props that have an * Filtering colors props that have an
* invalid RGB value * invalid RGB value
@@ -536,6 +542,13 @@ export default class PKPass extends Bundle {
const passJson = Buffer.from(JSON.stringify(this[propsSymbol])); const passJson = Buffer.from(JSON.stringify(this[propsSymbol]));
super.addBuffer("pass.json", passJson); 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 *** // // *** LOCALIZATION FILES CREATION *** //
// *********************************** // // *********************************** //
@@ -561,7 +574,6 @@ export default class PKPass extends Bundle {
// *** PERSONALIZATION *** // // *** PERSONALIZATION *** //
// *********************** // // *********************** //
const fileNames = Object.keys(this[filesSymbol]);
const meetsPersonalizationRequirements = Boolean( const meetsPersonalizationRequirements = Boolean(
this[filesSymbol]["personalization.json"] && this[filesSymbol]["personalization.json"] &&
fileNames.find((file) => fileNames.find((file) =>