passkit-generator
Version:
The easiest way to generate custom Apple Wallet passes in Node.js
358 lines • 20 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Template = exports.PassProps = exports.OverridablePassProps = exports.PassType = exports.PassKindsProps = exports.PassPropsFromMethods = exports.RelevantDate = exports.PreferredStyleSchemes = void 0;
exports.assertValidity = assertValidity;
exports.validate = validate;
exports.filterValid = filterValid;
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./Barcode.js"), exports);
tslib_1.__exportStar(require("./Beacon.js"), exports);
tslib_1.__exportStar(require("./Location.js"), exports);
tslib_1.__exportStar(require("./Field.js"), exports);
tslib_1.__exportStar(require("./NFC.js"), exports);
tslib_1.__exportStar(require("./Semantics.js"), exports);
tslib_1.__exportStar(require("./PassFields.js"), exports);
tslib_1.__exportStar(require("./Personalize.js"), exports);
tslib_1.__exportStar(require("./Certificates.js"), exports);
const joi_1 = tslib_1.__importDefault(require("joi"));
const Barcode_js_1 = require("./Barcode.js");
const Location_js_1 = require("./Location.js");
const Beacon_js_1 = require("./Beacon.js");
const NFC_js_1 = require("./NFC.js");
const PassFields_js_1 = require("./PassFields.js");
const Semantics_js_1 = require("./Semantics.js");
const Messages = tslib_1.__importStar(require("../messages.js"));
const regexps_js_1 = require("./regexps.js");
exports.PreferredStyleSchemes = joi_1.default.array().items("posterEventTicket", "eventTicket");
exports.RelevantDate = joi_1.default.alternatives(joi_1.default.object().keys({
startDate: joi_1.default.alternatives(joi_1.default.string().isoDate(), joi_1.default.date().iso()).required(),
endDate: joi_1.default.alternatives(joi_1.default.string().isoDate(), joi_1.default.date().iso()).required(),
}), joi_1.default.object().keys({
relevantDate: joi_1.default.alternatives(joi_1.default.string().isoDate(), joi_1.default.date().iso()).required(),
}));
exports.PassPropsFromMethods = joi_1.default.object({
nfc: NFC_js_1.NFC,
beacons: joi_1.default.array().items(Beacon_js_1.Beacon),
barcodes: joi_1.default.array().items(Barcode_js_1.Barcode),
relevantDate: joi_1.default.string().isoDate(),
relevantDates: joi_1.default.array().items(exports.RelevantDate),
expirationDate: joi_1.default.string().isoDate(),
locations: joi_1.default.array().items(Location_js_1.Location),
preferredStyleSchemes: exports.PreferredStyleSchemes,
});
exports.PassKindsProps = joi_1.default.object({
coupon: PassFields_js_1.PassFields.disallow("transitType"),
generic: PassFields_js_1.PassFields.disallow("transitType"),
storeCard: PassFields_js_1.PassFields.disallow("transitType"),
eventTicket: PassFields_js_1.PassFields.disallow("transitType"),
boardingPass: PassFields_js_1.PassFields,
});
exports.PassType = joi_1.default.string().regex(/(boardingPass|coupon|eventTicket|storeCard|generic)/);
exports.OverridablePassProps = joi_1.default.object({
formatVersion: joi_1.default.number().default(1),
semantics: Semantics_js_1.Semantics,
voided: joi_1.default.boolean(),
logoText: joi_1.default.string(),
description: joi_1.default.string(),
serialNumber: joi_1.default.string(),
appLaunchURL: joi_1.default.string(),
teamIdentifier: joi_1.default.string(),
organizationName: joi_1.default.string(),
passTypeIdentifier: joi_1.default.string(),
sharingProhibited: joi_1.default.boolean(),
groupingIdentifier: joi_1.default.string(),
suppressStripShine: joi_1.default.boolean(),
maxDistance: joi_1.default.number().positive(),
authenticationToken: joi_1.default.string().min(16),
labelColor: joi_1.default.string().regex(regexps_js_1.RGB_HEX_COLOR_REGEX),
stripColor: joi_1.default.string().regex(regexps_js_1.RGB_HEX_COLOR_REGEX),
backgroundColor: joi_1.default.string().regex(regexps_js_1.RGB_HEX_COLOR_REGEX),
foregroundColor: joi_1.default.string().regex(regexps_js_1.RGB_HEX_COLOR_REGEX),
associatedStoreIdentifiers: joi_1.default.array().items(joi_1.default.number()),
userInfo: joi_1.default.alternatives(joi_1.default.object().unknown(), joi_1.default.array()),
webServiceURL: joi_1.default.string().regex(regexps_js_1.URL_REGEX),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
bagPolicyURL: joi_1.default.string().regex(regexps_js_1.URL_REGEX),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
orderFoodURL: joi_1.default.string().regex(regexps_js_1.URL_REGEX),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
parkingInformationURL: joi_1.default.string().regex(regexps_js_1.URL_REGEX),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
directionsInformationURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* URL to a resource to buy or access
* the parking spot.
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
purchaseParkingURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* URL to a resource to buy the
* merchandise.
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
merchandiseURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* URL to a resource about public or
* private transportation to reach the
* venue.
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
transitInformationURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* URL to a resource about accessibility
* in the events venue.
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
accessibilityURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* An URL to link experiences to the
* pass (upgrades and more).
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
addOnURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
contactVenueEmail: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
contactVenuePhoneNumber: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
* @passDomain Event Guide
*
* @description
*
* To show buttons in the event guide,
* at least two among those marked with
* "@passDomain Event Guide" must be used.
*/
contactVenueWebsite: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
*
* @description
*
* Will add a button among options near "share"
*/
transferURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
*
* @description
*
* Will add a button among options near "share"
*/
sellURL: joi_1.default.string(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
*
* @description
*
* Will remove an automatic shadow in the new
* event ticket layouts.
*/
suppressHeaderDarkening: joi_1.default.boolean(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
*
* @description
*
* By default, the chin is colored with a
* blur. Through this option, it is possible
* to specify a different and specific color
* for it.
*/
footerBackgroundColor: joi_1.default.string().regex(regexps_js_1.RGB_HEX_COLOR_REGEX),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
*
* @description
*
* Enables the automatic calculation of the
* `foregroundColor` and `labelColor` based
* on the background image in the new event
* ticket passes.
*
* If enabled, `foregroundColor` and `labelColor`
* are ignored.
*/
useAutomaticColor: joi_1.default.boolean(),
/**
* @iOSVersion 18
* @passStyle eventTicket (new layout)
*
* @description
*
* Applications AppStore Identifiers
* related to the event ticket.
*
* It is not mandatory for the app to
* be related to the pass issuer.
*
* Such applications won't be able to read
* the passes users has (probably differently
* by `associatedStoreIdentifiers`).
*/
auxiliaryStoreIdentifiers: joi_1.default.array().items(joi_1.default.number()),
}).with("webServiceURL", "authenticationToken");
exports.PassProps = joi_1.default.object()
.concat(exports.OverridablePassProps)
.concat(exports.PassKindsProps)
.concat(exports.PassPropsFromMethods);
exports.Template = joi_1.default.object({
model: joi_1.default.string().required(),
certificates: joi_1.default.object().required(),
});
// --------- UTILITIES ---------- //
/**
* Performs validation of a schema on an object.
* If it fails, will throw an error.
*
* @param schema
* @param data
*/
function assertValidity(schema, data, customErrorMessage) {
const validation = schema.validate(data);
if (validation.error) {
if (customErrorMessage) {
console.warn(validation.error);
throw new TypeError(`${validation.error.name} happened. ${Messages.format(customErrorMessage, validation.error.message)}`);
}
throw new TypeError(validation.error.message);
}
}
/**
* Performs validation and throws the error if there's one.
* Otherwise returns a (possibly patched) version of the specified
* options (it depends on the schema)
*
* @param schema
* @param options
* @returns
*/
function validate(schema, options) {
const validationResult = schema.validate(options, {
stripUnknown: true,
abortEarly: true,
});
if (validationResult.error) {
throw validationResult.error;
}
return validationResult.value;
}
function filterValid(schema, source) {
if (!source) {
return [];
}
return source.reduce((acc, current) => {
try {
return [...acc, validate(schema, current)];
}
catch (err) {
console.warn(Messages.format(Messages.FILTER_VALID.INVALID, err));
return [...acc];
}
}, []);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2NoZW1hcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUF1dEJBLHdDQW9CQztBQVlELDRCQWNDO0FBRUQsa0NBZ0JDOztBQXZ4QkQsdURBQTZCO0FBQzdCLHNEQUE0QjtBQUM1Qix3REFBOEI7QUFDOUIscURBQTJCO0FBQzNCLG1EQUF5QjtBQUN6Qix5REFBK0I7QUFDL0IsMERBQWdDO0FBQ2hDLDJEQUFpQztBQUNqQyw0REFBa0M7QUFFbEMsc0RBQXNCO0FBR3RCLDZDQUF1QztBQUN2QywrQ0FBeUM7QUFDekMsMkNBQXFDO0FBQ3JDLHFDQUErQjtBQUMvQixtREFBMEQ7QUFDMUQsaURBQTJDO0FBRzNDLGlFQUEyQztBQUMzQyw2Q0FBOEQ7QUFJakQsUUFBQSxxQkFBcUIsR0FBRyxhQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxDQUNyRCxtQkFBbUIsRUFDbkIsYUFBYSxDQUMrQixDQUFDO0FBMEJqQyxRQUFBLFlBQVksR0FBRyxhQUFHLENBQUMsWUFBWSxDQUMzQyxhQUFHLENBQUMsTUFBTSxFQUFxQixDQUFDLElBQUksQ0FBQztJQUNwQyxTQUFTLEVBQUUsYUFBRyxDQUFDLFlBQVksQ0FDMUIsYUFBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUN0QixhQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQ2hCLENBQUMsUUFBUSxFQUFFO0lBQ1osT0FBTyxFQUFFLGFBQUcsQ0FBQyxZQUFZLENBQ3hCLGFBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFDdEIsYUFBRyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUNoQixDQUFDLFFBQVEsRUFBRTtDQUNaLENBQUMsRUFDRixhQUFHLENBQUMsTUFBTSxFQUFrQixDQUFDLElBQUksQ0FBQztJQUNqQyxZQUFZLEVBQUUsYUFBRyxDQUFD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