UNPKG

@1amageek/passkit

Version:
255 lines 9.13 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generate = exports.RGB = exports.initialize = exports.certificates = exports.Certificates = exports.Template = exports.Assets = void 0; const path = require("path"); const fs = require("fs"); const os = require("os"); const https = require("https"); const mkdirp = require("mkdirp"); const request = require("request"); const Archiver = require("archiver"); const assets_1 = require("./assets"); exports.Assets = assets_1.default; const template_1 = require("./template"); exports.Template = template_1.default; const manifest_1 = require("./manifest"); const tmpDir = process.env.NODE_ENV === 'production' ? `${os.tmpdir()}/passkit` : `${process.cwd()}/temp`; class Certificates { constructor(options) { this.options = options; this.secret = options.secret; this.wwdr = options.wwdr; } mountCertificate(url, destination) { return __awaiter(this, void 0, void 0, function* () { const writeStream = fs.createWriteStream(destination); return new Promise((resolve, reject) => { https .get(url, (res) => { res.pipe(writeStream); }) .on('close', () => { resolve(destination); }); }); }); } mountIfNeeded() { return __awaiter(this, void 0, void 0, function* () { const secretDir = `${tmpDir}/keys`; if (!this.options.passTypeIdentifier) { console.error("[Passkit] error: passTypeIdentifier is required."); return; } /// load secret if (!this.isExistFile(this.secret)) { const identifier = this.options.passTypeIdentifier.replace(/^pass./, ""); if (this.options.delegate) { try { this.secret = yield this.options.delegate.loadSecret(identifier); } catch (error) { throw error; } } else { const destination = path.resolve(secretDir, `${identifier}.pem`); const tempLocalDir = path.dirname(destination); yield mkdirp.sync(tempLocalDir); try { this.secret = yield this.mountCertificate(this.options.secretURL, destination); } catch (error) { throw error; } } } /// load wwdr if (!this.isExistFile(this.wwdr)) { if (this.options.delegate) { try { this.wwdr = yield this.options.delegate.loadWWDR(); } catch (error) { throw error; } } else { const destination = path.resolve(secretDir, `wwdr.pem`); try { this.wwdr = yield this.mountCertificate(this.options.wwdrURL, destination); } catch (error) { throw error; } } } }); } isExistFile(file) { try { fs.statSync(file); return true; } catch (err) { return false; } } } exports.Certificates = Certificates; /// PassKit initialize exports.initialize = (options) => { exports.certificates = new Certificates(options); }; /// RGB class class RGB { constructor(r, g, b) { this.r = 255; this.g = 255; this.b = 255; this.r = r; this.g = g; this.b = b; } toValue() { return { r: this.r, g: this.g, b: this.b }; } toString() { return `rgb(${this.r}, ${this.g}, ${this.b})`; } } exports.RGB = RGB; const loadImage = (url) => __awaiter(void 0, void 0, void 0, function* () { const regex = new RegExp('https?://'); // local if (url.search(regex) === -1) { return new Promise((resolve, reject) => { fs.readFile(url, (error, data) => { if (error) { reject(error); } else { resolve(data); } }); }); } // https|http else { return new Promise((resolve, reject) => { request.get(url, { encoding: null }, (error, res, body) => __awaiter(void 0, void 0, void 0, function* () { if (error) { reject(error); } else { if (res.statusCode === 200) { resolve(body); } else { reject(new Error(`[Passkit] error: ${url} not found.`)); } } })); }); } }); const imageArchive = (archive, manifest, filename, urlOrLoader) => __awaiter(void 0, void 0, void 0, function* () { if (typeof urlOrLoader === 'string') { return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () { try { const data = yield loadImage(urlOrLoader); archive.append(data, { name: filename }); manifest.addFile(data, filename, "utf8"); resolve(); } catch (error) { reject(error); } })); } return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () { try { const data = yield urlOrLoader(); archive.append(data, { name: filename }); manifest.addFile(data, filename, "utf8"); resolve(); } catch (error) { reject(error); } })); }); const cleanup = (targetPath) => __awaiter(void 0, void 0, void 0, function* () { const files = fs.readdirSync(targetPath); for (const file in files) { fs.unlinkSync(path.resolve(targetPath, files[file])); } fs.rmdirSync(targetPath); }); exports.generate = (template, assets, personalization) => __awaiter(void 0, void 0, void 0, function* () { assets.validate(); const manifest = new manifest_1.default(); const filePath = `/pass/${template.serialNumber}`; const tempLocalFile = path.join(tmpDir, `${filePath}/pass.pkpass`); const tempLocalDir = path.dirname(tempLocalFile); mkdirp.sync(tempLocalDir); const passWriteStream = fs.createWriteStream(tempLocalFile); const archive = Archiver.create('zip', { store: true }); archive.pipe(passWriteStream); // Add personalization.json if (personalization) { const personalizationName = 'personalization.json'; const personalizationBuffer = Buffer.from(JSON.stringify(personalization), 'utf-8'); yield manifest.addFile(personalizationBuffer, personalizationName, "utf8"); archive.append(personalizationBuffer, { name: personalizationName }); } // Add pass.json const passName = 'pass.json'; const buffer = Buffer.from(JSON.stringify(template.toPass()), 'utf-8'); yield manifest.addFile(buffer, passName, "utf8"); archive.append(buffer, { name: passName }); // Add images const tasks = []; for (const key in assets) { const filename = `${key.replace('2x', '@2x').replace('3x', '@3x')}.png`; const url = assets[key]; const task = imageArchive(archive, manifest, filename, url); tasks.push(task); } try { yield Promise.all(tasks); } catch (error) { archive.abort(); cleanup(tempLocalDir); throw error; } // Add manifest const manifestJSON = manifest.toJSON(); archive.append(manifestJSON, { name: 'manifest.json' }); // Add signature try { const signature = yield manifest.sign(); archive.append(signature, { name: "signature" }); archive.finalize(); return tempLocalFile; } catch (error) { archive.abort(); throw error; } }); //# sourceMappingURL=index.js.map