@1amageek/passkit
Version:
passkit.ts is Passkit generator
255 lines • 9.13 kB
JavaScript
;
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