UNPKG

passkit-generator

Version:

The easiest way to generate custom Apple Wallet passes in Node.js

351 lines 18.8 kB
export * from "./Barcode.js"; export * from "./Beacon.js"; export * from "./Location.js"; export * from "./Field.js"; export * from "./NFC.js"; export * from "./Semantics.js"; export * from "./PassFields.js"; export * from "./Personalize.js"; export * from "./Certificates.js"; import Joi from "joi"; import { Barcode } from "./Barcode.js"; import { Location } from "./Location.js"; import { Beacon } from "./Beacon.js"; import { NFC } from "./NFC.js"; import { PassFields } from "./PassFields.js"; import { Semantics } from "./Semantics.js"; import * as Messages from "../messages.js"; import { RGB_HEX_COLOR_REGEX, URL_REGEX } from "./regexps.js"; export const PreferredStyleSchemes = Joi.array().items("posterEventTicket", "eventTicket"); export const RelevantDate = Joi.alternatives(Joi.object().keys({ startDate: Joi.alternatives(Joi.string().isoDate(), Joi.date().iso()).required(), endDate: Joi.alternatives(Joi.string().isoDate(), Joi.date().iso()).required(), }), Joi.object().keys({ relevantDate: Joi.alternatives(Joi.string().isoDate(), Joi.date().iso()).required(), })); export const PassPropsFromMethods = Joi.object({ nfc: NFC, beacons: Joi.array().items(Beacon), barcodes: Joi.array().items(Barcode), relevantDate: Joi.string().isoDate(), relevantDates: Joi.array().items(RelevantDate), expirationDate: Joi.string().isoDate(), locations: Joi.array().items(Location), preferredStyleSchemes: PreferredStyleSchemes, }); export const PassKindsProps = Joi.object({ coupon: PassFields.disallow("transitType"), generic: PassFields.disallow("transitType"), storeCard: PassFields.disallow("transitType"), eventTicket: PassFields.disallow("transitType"), boardingPass: PassFields, }); export const PassType = Joi.string().regex(/(boardingPass|coupon|eventTicket|storeCard|generic)/); export const OverridablePassProps = Joi.object({ formatVersion: Joi.number().default(1), semantics: Semantics, voided: Joi.boolean(), logoText: Joi.string(), description: Joi.string(), serialNumber: Joi.string(), appLaunchURL: Joi.string(), teamIdentifier: Joi.string(), organizationName: Joi.string(), passTypeIdentifier: Joi.string(), sharingProhibited: Joi.boolean(), groupingIdentifier: Joi.string(), suppressStripShine: Joi.boolean(), maxDistance: Joi.number().positive(), authenticationToken: Joi.string().min(16), labelColor: Joi.string().regex(RGB_HEX_COLOR_REGEX), stripColor: Joi.string().regex(RGB_HEX_COLOR_REGEX), backgroundColor: Joi.string().regex(RGB_HEX_COLOR_REGEX), foregroundColor: Joi.string().regex(RGB_HEX_COLOR_REGEX), associatedStoreIdentifiers: Joi.array().items(Joi.number()), userInfo: Joi.alternatives(Joi.object().unknown(), Joi.array()), webServiceURL: Joi.string().regex(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.string().regex(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.string().regex(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.string().regex(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.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.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.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.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.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.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.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.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.string(), /** * @iOSVersion 18 * @passStyle eventTicket (new layout) * * @description * * Will add a button among options near "share" */ transferURL: Joi.string(), /** * @iOSVersion 18 * @passStyle eventTicket (new layout) * * @description * * Will add a button among options near "share" */ sellURL: Joi.string(), /** * @iOSVersion 18 * @passStyle eventTicket (new layout) * * @description * * Will remove an automatic shadow in the new * event ticket layouts. */ suppressHeaderDarkening: Joi.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.string().regex(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.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.array().items(Joi.number()), }).with("webServiceURL", "authenticationToken"); export const PassProps = Joi.object() .concat(OverridablePassProps) .concat(PassKindsProps) .concat(PassPropsFromMethods); export const Template = Joi.object({ model: Joi.string().required(), certificates: Joi.object().required(), }); // --------- UTILITIES ---------- // /** * Performs validation of a schema on an object. * If it fails, will throw an error. * * @param schema * @param data */ export 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 */ export function validate(schema, options) { const validationResult = schema.validate(options, { stripUnknown: true, abortEarly: true, }); if (validationResult.error) { throw validationResult.error; } return validationResult.value; } export 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2NoZW1hcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLFVBQVUsQ0FBQztBQUN6QixjQUFjLGdCQUFnQixDQUFDO0FBQy9CLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxrQkFBa0IsQ0FBQztBQUNqQyxjQUFjLG1CQUFtQixDQUFDO0FBRWxDLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQztBQUd0QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxVQUFVLEVBQWUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHM0MsT0FBTyxLQUFLLFFBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBSTlELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxLQUFLLENBQ3JELG1CQUFtQixFQUNuQixhQUFhLENBQytCLENBQUM7QUEwQjlDLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUMsWUFBWSxDQUMzQyxHQUFHLENBQUMsTUFBTSxFQUFxQixDQUFDLElBQUksQ0FBQztJQUNwQyxTQUFTLEVBQUUsR0FBRyxDQUFDLFlBQVks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