mirror of
https://github.com/marcogll/passkit-generator.git
synced 2026-03-15 20:25:26 +00:00
125 lines
2.5 KiB
TypeScript
125 lines
2.5 KiB
TypeScript
import { Stream } from "stream";
|
|
import { ZipFile } from "yazl";
|
|
|
|
export const filesSymbol = Symbol("bundleFiles");
|
|
const archiveSymbol = Symbol("zip");
|
|
|
|
namespace Mime {
|
|
export type type = string;
|
|
export type subtype = string;
|
|
}
|
|
|
|
/**
|
|
* Defines a container ready to be distributed.
|
|
* If no mimeType is passed to the constructor,
|
|
* it will throw an error.
|
|
*/
|
|
|
|
export default class Bundle {
|
|
private [filesSymbol]: { [key: string]: Buffer } = {};
|
|
private [archiveSymbol] = new ZipFile();
|
|
|
|
constructor(public mimeType: `${Mime.type}/${Mime.subtype}`) {
|
|
if (!mimeType) {
|
|
throw new Error("Cannot build Bundle. MimeType is missing");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @EXPERIMENTAL
|
|
*
|
|
* @param mimeType
|
|
*/
|
|
|
|
static autoFreezable(mimeType: `${Mime.type}/${Mime.subtype}`): Bundle {
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Freezes the bundle so no more files
|
|
* can be added any further.
|
|
*/
|
|
|
|
protected freeze() {
|
|
if (this.isFrozen) {
|
|
return;
|
|
}
|
|
|
|
Object.freeze(this[filesSymbol]);
|
|
this[archiveSymbol].end();
|
|
}
|
|
|
|
/**
|
|
* Tells if this bundle still allows files to be added
|
|
* @returns
|
|
*/
|
|
|
|
public get isFrozen() {
|
|
return Object.isFrozen(this[filesSymbol]);
|
|
}
|
|
|
|
/**
|
|
* Allows files to be added to the bundle.
|
|
* If the bundle is closed, it will throw an error.
|
|
*
|
|
* @param fileName
|
|
* @param buffer
|
|
*/
|
|
|
|
public addBuffer(fileName: string, buffer: Buffer) {
|
|
if (this.isFrozen) {
|
|
throw new Error("Cannot add file. Bundle is closed.");
|
|
}
|
|
|
|
this[filesSymbol][fileName] = buffer;
|
|
this[archiveSymbol].addBuffer(buffer, fileName);
|
|
}
|
|
|
|
/**
|
|
* Closes the bundle and returns it as a Buffer.
|
|
* Once closed, the bundle does not allow files
|
|
* to be added any further.
|
|
*
|
|
* @returns Promise<Buffer>
|
|
*/
|
|
|
|
public getAsBuffer(): Promise<Buffer> {
|
|
const stream = this.getAsStream();
|
|
const chunks = [];
|
|
|
|
return new Promise((resolve) => {
|
|
stream.on("data", (data: Buffer) => {
|
|
chunks.push(data);
|
|
});
|
|
|
|
stream.on("end", () => resolve(Buffer.from(chunks)));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Closes the bundle and returns it as a stream.
|
|
* Once closed, the bundle does not allow files
|
|
* to be added any further.
|
|
*
|
|
* @returns
|
|
*/
|
|
|
|
public getAsStream(): Stream {
|
|
this.freeze();
|
|
return this[archiveSymbol].outputStream;
|
|
}
|
|
}
|