passkit-generator
Version:
The easiest way to generate custom Apple Wallet passes in Node.js
803 lines • 56.4 kB
JavaScript
var _a, _b, _c;
import { Buffer } from "node:buffer";
import path from "node:path";
import FieldsArray from "./FieldsArray.js";
import Bundle, { filesSymbol } from "./Bundle.js";
import getModelFolderContents from "./getModelFolderContents.js";
import * as Schemas from "./schemas/index.js";
import * as Signature from "./Signature.js";
import * as Strings from "./StringsUtils.js";
import * as Utils from "./utils.js";
import * as Messages from "./messages.js";
const propsSymbol = Symbol("props");
const localizationSymbol = Symbol("pass.l10n");
const importMetadataSymbol = Symbol("import.pass.metadata");
const createManifestSymbol = Symbol("pass.manifest");
const closePassSymbol = Symbol("pass.close");
const passTypeSymbol = Symbol("pass.type");
const certificatesSymbol = Symbol("pass.certificates");
const RegExps = {
PASS_JSON: /pass\.json/,
MANIFEST_OR_SIGNATURE: /manifest|signature/,
PERSONALIZATION: {
JSON: /personalization\.json/,
LOGO: /personalizationLogo@(?:.{2})/,
},
PASS_STRINGS: /(?<lang>[a-zA-Z-]{2,}).lproj\/pass\.strings/,
PASS_ICON: /icon(?:@\d{1}x)?/,
};
export default class PKPass extends Bundle {
/**
* Either create a pass from another one
* or a disk path.
*
* @param source
* @returns
*/
static async from(source, props) {
let certificates = undefined;
let buffers = undefined;
if (!source) {
throw new TypeError(Messages.format(Messages.FROM.MISSING_SOURCE, source));
}
if (source instanceof PKPass) {
/** Cloning is happening here */
certificates = source[certificatesSymbol];
buffers = {};
const buffersEntries = Object.entries(source[filesSymbol]);
/** Cloning all the buffers to prevent unwanted edits */
for (let i = 0; i < buffersEntries.length; i++) {
const [fileName, contentBuffer] = buffersEntries[i];
buffers[fileName] = Buffer.alloc(contentBuffer.length);
contentBuffer.copy(buffers[fileName]);
}
/**
* Moving props to pass.json instead of overrides
* because many might get excluded when passing
* through validation
*/
buffers["pass.json"] = Buffer.from(JSON.stringify(source[propsSymbol]));
}
else {
Schemas.assertValidity(Schemas.Template, source, Messages.TEMPLATE.INVALID);
buffers = await getModelFolderContents(source.model);
certificates = source.certificates;
}
return new PKPass(buffers, certificates, props);
}
/**
* Creates a Bundle made of PKPass to be distributed
* as a `.pkpasses` zip file. Returns a Bundle instance
* so it can be outputted both as stream or as a buffer.
*
* Using this will freeze all the instances passed as
* parameter.
*
* Throws if not all the files are instance of PKPass.
*
* @param passes
*/
static pack(...passes) {
const [bundle, freezeBundle] = Bundle.freezable("application/vnd.apple.pkpasses");
for (let i = 0; i < passes.length; i++) {
const pass = passes[i];
if (!(pass instanceof PKPass)) {
throw new Error(Messages.PACK.INVALID);
}
bundle.addBuffer(`packed-pass-${i + 1}.pkpass`, pass.getAsBuffer());
}
freezeBundle();
return bundle;
}
// **************** //
// *** INSTANCE *** //
// **************** //
constructor(buffers, certificates, props) {
super("application/vnd.apple.pkpass");
this[_a] = {};
this[_b] = {};
this[_c] = undefined;
if (buffers && typeof buffers === "object") {
const buffersEntries = Object.entries(buffers);
for (let i = buffersEntries.length, buffer; (buffer = buffersEntries[--i]);) {
const [fileName, contentBuffer] = buffer;
this.addBuffer(fileName, contentBuffer);
}
}
else {
console.warn(Messages.format(Messages.INIT.INVALID_BUFFERS, typeof buffers));
}
if (props) {
/** Overrides validation and pushing in props */
const overridesValidation = Schemas.validate(Schemas.OverridablePassProps, props);
Object.assign(this[propsSymbol], overridesValidation);
}
if (certificates) {
this.certificates = certificates;
}
}
/**
* Allows changing the certificates, if needed.
* They are actually expected to be received in
* the constructor, but they can get overridden
* here for whatever purpose.
*
* When using this setter, all certificates are
* expected to be received, or an exception will
* be thrown.
*
* @param certs
*/
set certificates(certs) {
Utils.assertUnfrozen(this);
Schemas.assertValidity(Schemas.CertificatesSchema, certs, Messages.CERTIFICATES.INVALID);
this[certificatesSymbol] = certs;
}
/**
* Allows retrieving current languages
*/
get languages() {
return Object.keys(this[localizationSymbol]);
}
/**
* Allows getting an image of the props
* that are composing your pass instance.
*/
get props() {
return Utils.cloneRecursive(this[propsSymbol]);
}
/**
* Allows accessing to iOS 18 new property
* `preferredStyleSchemes`.
*
* @throws if current type is not "eventTicket" and is not "boardingPass".
*/
get preferredStyleSchemes() {
if (this.type !== "eventTicket" && this.type !== "boardingPass") {
throw new TypeError(Messages.PREFERRED_STYLE_SCHEMES.UNEXPECTED_PASS_TYPE_GET);
}
return this[propsSymbol].preferredStyleSchemes;
}
/**
* Allows setting a preferredStyleSchemes property
* for a eventTicket. Use this to select
* either the Poster Event Tickets (iOS 18+) or the Semantic
* Boarding passes (iOS 26+).
*
* @throws if current type is not "eventTicket".
* @param value
*/
set preferredStyleSchemes(value) {
Utils.assertUnfrozen(this);
if (this.type !== "eventTicket" && this.type !== "boardingPass") {
throw new TypeError(Messages.PREFERRED_STYLE_SCHEMES.UNEXPECTED_PASS_TYPE_SET);
}
Schemas.assertValidity(Schemas.PreferredStyleSchemes, value, Messages.PREFERRED_STYLE_SCHEMES.INVALID);
this[propsSymbol].preferredStyleSchemes = value;
}
/**
* Allows setting UpcomingPassInformation for poster event tickets
* (iOS 26+).
*
* @throws if current type is not "eventTicket"
* @throws if preferredStyleSchemes is not set or does not include "posterEventTicket"
*/
set upcomingPassInformation(value) {
var _d;
Utils.assertUnfrozen(this);
if (this.type !== "eventTicket") {
throw new TypeError(Messages.UPCOMING_PASS_INFORMATION.UNEXPECTED_PASS_TYPE_SET);
}
if (!((_d = this.preferredStyleSchemes) === null || _d === void 0 ? void 0 : _d.includes("posterEventTicket"))) {
throw new TypeError(Messages.UPCOMING_PASS_INFORMATION.UNEXPECTED_STYLE_SCHEME);
}
for (const entry of value) {
Schemas.assertValidity(Schemas.UpcomingPassInformationEntry, entry, Messages.UPCOMING_PASS_INFORMATION.INVALID);
}
this[propsSymbol].upcomingPassInformation = value;
}
get upcomingPassInformation() {
if (this.type !== "eventTicket") {
throw new TypeError(Messages.UPCOMING_PASS_INFORMATION.UNEXPECTED_PASS_TYPE_GET);
}
return this[propsSymbol].upcomingPassInformation || [];
}
/**
* Allows setting a transitType property
* for a boardingPass.
*
* @throws if current type is not "boardingPass".
* @param value
*/
set transitType(value) {
Utils.assertUnfrozen(this);
if (this.type !== "boardingPass") {
throw new TypeError(Messages.TRANSIT_TYPE.UNEXPECTED_PASS_TYPE);
}
Schemas.assertValidity(Schemas.TransitType, value, Messages.TRANSIT_TYPE.INVALID);
this[propsSymbol]["boardingPass"].transitType = value;
}
/**
* Allows getting the current transitType
* from pass props.
*
* @throws (automatically) if current type is not "boardingPass".
*/
get transitType() {
return this[propsSymbol]["boardingPass"].transitType;
}
/**
* Allows accessing to primaryFields object.
*
* @throws (automatically) if no valid pass.json
* has been parsed yet or, anyway, if current
* instance has not a valid type set yet.
*/
get primaryFields() {
return this[propsSymbol][this.type].primaryFields;
}
/**
* Allows accessing to secondaryFields object
*
* @throws (automatically) if no valid pass.json
* has been parsed yet or, anyway, if current
* instance has not a valid type set yet.
*/
get secondaryFields() {
return this[propsSymbol][this.type].secondaryFields;
}
/**
* Allows accessing to auxiliaryFields object
*
* For Typescript users: this signature allows
* in any case to add the 'row' field, but on
* runtime they are only allowed on "eventTicket"
* passes.
*
* @throws (automatically) if no valid pass.json
* has been parsed yet or, anyway, if current
* instance has not a valid type set yet.
*/
get auxiliaryFields() {
return this[propsSymbol][this.type].auxiliaryFields;
}
/**
* Allows accessing to headerFields object
*
* @throws (automatically) if no valid pass.json
* has been parsed yet or, anyway, if current
* instance has not a valid type set yet.
*/
get headerFields() {
return this[propsSymbol][this.type].headerFields;
}
/**
* Allows accessing to backFields object
*
* @throws (automatically) if no valid pass.json
* has been parsed yet or, anyway, if current
* instance has not a valid type set yet.
*/
get backFields() {
return this[propsSymbol][this.type].backFields;
}
/**
* Allows accessing to new iOS 18
* event ticket additional fields
*
* @throws (automatically) if no valid pass.json
* has been parsed yet or, anyway, if current
* type is not "eventTicket".
*/
get additionalInfoFields() {
return this[propsSymbol]["eventTicket"].additionalInfoFields;
}
/**
* Allows setting a pass type.
*
* **Warning**: setting a type with this setter,
* will reset all the fields (primaryFields,
* secondaryFields, headerFields, auxiliaryFields, backFields),
* both imported or manually set.
*/
set type(nextType) {
Utils.assertUnfrozen(this);
Schemas.assertValidity(Schemas.PassType, nextType, Messages.PASS_TYPE.INVALID);
/** Shut up, typescript strict mode! */
const type = nextType;
if (this.type) {
/**
* Removing reference to previous type and its content because
* we might have some differences between types. It is way easier
* to reset everything instead of making checks.
*/
this[propsSymbol][this.type] = undefined;
this[propsSymbol].preferredStyleSchemes = undefined;
}
const sharedKeysPool = new Set();
this[passTypeSymbol] = type;
this[propsSymbol][type] = {
headerFields /******/: new FieldsArray(this, sharedKeysPool, Schemas.PassFieldContent),
primaryFields /*****/: new FieldsArray(this, sharedKeysPool, Schemas.PassFieldContent),
secondaryFields /***/: new FieldsArray(this, sharedKeysPool, Schemas.PassFieldContent),
auxiliaryFields /***/: new FieldsArray(this, sharedKeysPool, type === "eventTicket"
? Schemas.PassFieldContentWithRow
: Schemas.PassFieldContent),
backFields /********/: new FieldsArray(this, sharedKeysPool, Schemas.PassFieldContent),
additionalInfoFields: new FieldsArray(this, sharedKeysPool, Schemas.PassFieldContent),
transitType: undefined,
};
}
get type() {
var _d;
return (_d = this[passTypeSymbol]) !== null && _d !== void 0 ? _d : undefined;
}
// **************************** //
// *** ASSETS SETUP METHODS *** //
// **************************** //
/**
* Allows adding a new asset inside the pass / bundle with
* the following exceptions:
*
* - Empty buffers are ignored;
* - `manifest.json` and `signature` files will be ignored;
* - `pass.json` will be read validated and merged in the
* current instance, if it wasn't added previously.
* It's properties will overwrite the instance ones.
* You might loose data;
* - `pass.strings` files will be read, parsed and merged
* with the current translations. Comments will be ignored;
* - `personalization.json` will be read, validated and added.
* They will be stripped out when exporting the pass if
* it won't have NFC details or if any of the personalization
* files is missing;
*
* @param pathName
* @param buffer
*/
addBuffer(pathName, buffer) {
if (!(buffer === null || buffer === void 0 ? void 0 : buffer.length)) {
return;
}
if (RegExps.MANIFEST_OR_SIGNATURE.test(pathName)) {
return;
}
if (RegExps.PASS_JSON.test(pathName)) {
if (this[filesSymbol]["pass.json"]) {
/**
* Ignoring any further addition. In a
* future we might consider merging instead
*/
return;
}
try {
this[importMetadataSymbol](validateJSONBuffer(buffer, Schemas.PassProps));
}
catch (err) {
console.warn(Messages.format(Messages.PASS_SOURCE.INVALID, err));
return;
}
/**
* Adding an empty buffer just for reference
* that we received a valid pass.json file.
* It will be reconciliated in export phase.
*/
return super.addBuffer(pathName, Buffer.alloc(0));
}
if (RegExps.PERSONALIZATION.JSON.test(pathName)) {
/**
* We are still allowing `personalizationLogo@XX.png`
* to be added to the bundle, but we'll delete it
* once the pass is getting closed, if needed.
*/
try {
validateJSONBuffer(buffer, Schemas.Personalize);
}
catch (err) {
console.warn(Messages.format(Messages.PERSONALIZE.INVALID, err));
return;
}
return super.addBuffer(pathName, buffer);
}
/**
* Converting Windows path to Unix path
* @example de.lproj\\icon.png => de.lproj/icon.png
*/
const normalizedPathName = pathName.replace(path.sep, "/");
/**
* If a new pass.strings file is added, we want to
* prevent it from being merged and, instead, save
* its translations for later
*/
let match;
if ((match = normalizedPathName.match(RegExps.PASS_STRINGS))) {
const [, lang] = match;
const parsedTranslations = Strings.parse(buffer).translations;
if (!parsedTranslations.length) {
return;
}
this.localize(lang, Object.fromEntries(parsedTranslations));
return;
}
return super.addBuffer(normalizedPathName, buffer);
}
/**
* Given data from a pass.json, reads them to bring them
* into the current pass instance.
*
* @param data
*/
[(_a = propsSymbol, _b = localizationSymbol, _c = passTypeSymbol, importMetadataSymbol)](data) {
const possibleTypes = [
"boardingPass",
"coupon",
"eventTicket",
"storeCard",
"generic",
];
const type = possibleTypes.find((type) => Boolean(data[type]));
const { boardingPass, coupon, storeCard, generic, eventTicket, ...otherPassData } = data;
if (Object.keys(this[propsSymbol]).length) {
console.warn(Messages.PASS_SOURCE.JOIN);
}
Object.assign(this[propsSymbol], otherPassData);
if (!type) {
if (!this[passTypeSymbol]) {
console.warn(Messages.PASS_SOURCE.UNKNOWN_TYPE);
}
}
else {
this.type = type;
const { headerFields = [], primaryFields = [], secondaryFields = [], auxiliaryFields = [], backFields = [], transitType, additionalInfoFields = [], } = data[type] || {};
this.headerFields.push(...headerFields);
this.primaryFields.push(...primaryFields);
this.secondaryFields.push(...secondaryFields);
this.auxiliaryFields.push(...auxiliaryFields);
this.backFields.push(...backFields);
if (this.type === "boardingPass") {
this.transitType = transitType;
}
if (this.type === "eventTicket") {
this.additionalInfoFields.push(...additionalInfoFields);
}
}
}
/**
* Creates the manifest starting from files
* added to the bundle
*/
[createManifestSymbol]() {
const manifest = Object.entries(this[filesSymbol]).reduce((acc, [fileName, buffer]) => ({
...acc,
[fileName]: Signature.createHash(buffer),
}), {});
return Buffer.from(JSON.stringify(manifest));
}
/**
* Applies the last validation checks against props,
* applies the props to pass.json and creates l10n
* files and folders and creates manifest and
* signature files
*/
[closePassSymbol]() {
if (!this.type) {
throw new TypeError(Messages.CLOSE.MISSING_TYPE);
}
const fileNames = Object.keys(this[filesSymbol]);
const passJson = Buffer.from(JSON.stringify(this[propsSymbol]));
super.addBuffer("pass.json", passJson);
if (!fileNames.some((fileName) => RegExps.PASS_ICON.test(fileName))) {
console.warn(Messages.CLOSE.MISSING_ICON);
}
// *********************************** //
// *** LOCALIZATION FILES CREATION *** //
// *********************************** //
const localizationEntries = Object.entries(this[localizationSymbol]);
for (let i = localizationEntries.length - 1; i >= 0; i--) {
const [lang, translations] = localizationEntries[i];
const stringsFile = Strings.create(translations);
if (stringsFile.length) {
super.addBuffer(`${lang}.lproj/pass.strings`, stringsFile);
}
}
// *********************** //
// *** PERSONALIZATION *** //
// *********************** //
const meetsPersonalizationRequirements = Boolean(this[propsSymbol]["nfc"] &&
this[filesSymbol]["personalization.json"] &&
fileNames.find((file) => RegExps.PERSONALIZATION.LOGO.test(file)));
if (!meetsPersonalizationRequirements) {
/**
* Looking for every personalization file
* and removing it
*/
for (let i = 0; i < fileNames.length; i++) {
if (fileNames[i].includes("personalization")) {
console.warn(Messages.format(Messages.CLOSE.PERSONALIZATION_REMOVED, fileNames[i]));
delete this[filesSymbol][fileNames[i]];
}
}
}
// ******************************** //
// *** BOARDING PASS VALIDATION *** //
// ******************************** //
if (this.type === "boardingPass" && !this.transitType) {
throw new TypeError(Messages.CLOSE.MISSING_TRANSIT_TYPE);
}
// ****************************** //
// *** SIGNATURE AND MANIFEST *** //
// ****************************** //
const manifestBuffer = this[createManifestSymbol]();
super.addBuffer("manifest.json", manifestBuffer);
const signatureBuffer = Signature.create(manifestBuffer, this[certificatesSymbol]);
super.addBuffer("signature", signatureBuffer);
}
// ************************* //
// *** EXPORTING METHODS *** //
// ************************* //
/**
* Exports the pass as a zip buffer. When this method
* is invoked, the bundle will get frozen and, thus,
* no files will be allowed to be added any further.
*
* @returns
*/
getAsBuffer() {
if (!this.isFrozen) {
this[closePassSymbol]();
}
return super.getAsBuffer();
}
/**
* Exports the pass as a zip stream. When this method
* is invoked, the bundle will get frozen and, thus,
* no files will be allowed to be added any further.
*
* @returns
*/
getAsStream() {
if (!this.isFrozen) {
this[closePassSymbol]();
}
return super.getAsStream();
}
/**
* Exports the pass as a list of file paths and buffers.
* When this method is invoked, the bundle will get
* frozen and, thus, no files will be allowed to be
* added any further.
*
* This allows developers to choose a different way
* of serving, analyzing or zipping the file, outside the
* default compression system.
*
* @returns a frozen object containing files paths as key
* and Buffers as content.
*/
getAsRaw() {
if (!this.isFrozen) {
this[closePassSymbol]();
}
return super.getAsRaw();
}
// ************************** //
// *** DATA SETUP METHODS *** //
// ************************** //
/**
* Allows to add a localization details to the
* final bundle with some translations.
*
* If the language already exists, translations will be
* merged with the existing ones.
*
* Setting `translations` to `null` fully deletes a language,
* its translations and its files.
*
* @see https://developer.apple.com/documentation/walletpasses/creating_the_source_for_a_pass#3736718
* @param lang
* @param translations
*/
localize(lang, translations) {
var _d;
var _e;
Utils.assertUnfrozen(this);
if (typeof lang !== "string") {
throw new TypeError(Messages.format(Messages.LANGUAGES.INVALID_LANG, typeof lang));
}
if (translations === null) {
delete this[localizationSymbol][lang];
const allFilesKeys = Object.keys(this[filesSymbol]);
const langFolderIdentifier = `${lang}.lproj`;
for (let i = allFilesKeys.length - 1; i >= 0; i--) {
const filePath = allFilesKeys[i];
if (filePath.startsWith(langFolderIdentifier)) {
delete this[filesSymbol][filePath];
}
}
return;
}
if (!translations || !Object.keys(translations).length) {
console.warn(Messages.format(Messages.LANGUAGES.NO_TRANSLATIONS, lang));
return;
}
(_d = (_e = this[localizationSymbol])[lang]) !== null && _d !== void 0 ? _d : (_e[lang] = {});
if (typeof translations === "object" && !Array.isArray(translations)) {
Object.assign(this[localizationSymbol][lang], translations);
}
}
/**
* Allows to specify an expiration date for the pass.
*
* Pass `null` to remove the expiration date.
*
* @param date
* @throws if pass is frozen due to previous export
* @returns
*/
setExpirationDate(date) {
Utils.assertUnfrozen(this);
if (date === null) {
delete this[propsSymbol]["expirationDate"];
return;
}
try {
this[propsSymbol]["expirationDate"] = Utils.processDate(date);
}
catch (err) {
throw new TypeError(Messages.format(Messages.DATE.INVALID, "expirationDate", date));
}
}
setBeacons(...beacons) {
Utils.assertUnfrozen(this);
if (beacons[0] === null) {
delete this[propsSymbol]["beacons"];
return;
}
this[propsSymbol]["beacons"] = Schemas.filterValid(Schemas.Beacon, beacons);
}
setLocations(...locations) {
Utils.assertUnfrozen(this);
if (locations[0] === null) {
delete this[propsSymbol]["locations"];
return;
}
this[propsSymbol]["locations"] = Schemas.filterValid(Schemas.Location, locations);
}
/**
* Allows setting a series of relevancy intervals or
* relevancy entries for the pass.
*
* Please note that `RelevantDate[]` `relevantDate` property was renamed
* in "date" since iOS 26. Since retro-compatibility is not ensured,
* this methods takes `date`, and fallbacks to `relevantDate`, and use
* the first value found for both properties.
*
* @param {Schemas.RelevantDate[] | null} relevancyEntries
* @returns {void}
*/
setRelevantDates(relevancyEntries) {
Utils.assertUnfrozen(this);
if (relevancyEntries === null) {
this[propsSymbol]["relevantDates"] = undefined;
return;
}
const processedDateEntries = relevancyEntries.reduce((acc, entry) => {
try {
Schemas.validate(Schemas.RelevantDate, entry);
if (isRelevantEntry(entry)) {
const date = Utils.processDate(new Date(entry.date || entry.relevantDate));
acc.push({
relevantDate: date,
date,
});
return acc;
}
acc.push({
startDate: Utils.processDate(new Date(entry.startDate)),
endDate: Utils.processDate(new Date(entry.endDate)),
});
}
catch (err) {
console.warn(new TypeError(Messages.RELEVANT_DATE.INVALID));
}
return acc;
}, []);
this[propsSymbol]["relevantDates"] = processedDateEntries;
}
/**
* Allows setting a relevant date in which the OS
* should show this pass.
*
* Pass `null` to remove relevant date from this pass.
*
* @param {Date | null} date
* @throws if pass is frozen due to previous export
*
* @warning `relevantDate` property has been deprecated in iOS 18
* in order to get replaced by `relevantDates` array of intervals
* (`relevantDates[].startDate` + `relevantDates[].endDate`)
* or single date (`relevantDates[].relevantDate`).
*/
setRelevantDate(date) {
Utils.assertUnfrozen(this);
if (date === null) {
delete this[propsSymbol]["relevantDate"];
return;
}
try {
this[propsSymbol]["relevantDate"] = Utils.processDate(date);
}
catch (err) {
throw new TypeError(Messages.format(Messages.DATE.INVALID, "relevantDate", date));
}
}
setBarcodes(...barcodes) {
Utils.assertUnfrozen(this);
if (!barcodes.length) {
return;
}
if (barcodes[0] === null) {
delete this[propsSymbol]["barcodes"];
return;
}
let finalBarcodes;
if (typeof barcodes[0] === "string") {
/**
* A string has been received instead of objects. We can
* only auto-fill them all with the same data.
*/
const supportedFormats = [
"PKBarcodeFormatQR",
"PKBarcodeFormatPDF417",
"PKBarcodeFormatAztec",
"PKBarcodeFormatCode128",
];
finalBarcodes = supportedFormats.map((format) => Schemas.validate(Schemas.Barcode, {
format,
message: barcodes[0],
}));
}
else {
finalBarcodes = Schemas.filterValid(Schemas.Barcode, barcodes);
}
this[propsSymbol]["barcodes"] = finalBarcodes;
}
/**
* Allows to specify details to make this, an
* NFC-capable pass.
*
* Pass `null` as parameter to remove it at all.
*
* @see https://developer.apple.com/documentation/walletpasses/pass/nfc
* @param data
* @throws if pass is frozen due to previous export
* @returns
*/
setNFC(nfc) {
var _d;
Utils.assertUnfrozen(this);
if (nfc === null) {
delete this[propsSymbol]["nfc"];
return;
}
this[propsSymbol]["nfc"] =
(_d = Schemas.validate(Schemas.NFC, nfc)) !== null && _d !== void 0 ? _d : undefined;
}
}
function validateJSONBuffer(buffer, schema) {
let contentAsJSON;
try {
contentAsJSON = JSON.parse(buffer.toString("utf8"));
}
catch (err) {
throw new TypeError(Messages.JSON.INVALID);
}
return Schemas.validate(schema, contentAsJSON);
}
function isRelevantEntry(entry) {
const isRelevantDateAvailable = Object.prototype.hasOwnProperty.call(entry, "relevantDate") &&
"relevantDate" in entry;
const isDateAvailable = Object.prototype.hasOwnProperty.call(entry, "date") && "date" in entry;
return isRelevantDateAvailable || isDateAvailable;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUEtQYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL1BLUGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxXQUFXLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEQsT0FBTyxzQkFBc0IsTUFBTSw2QkFBNkIsQ0FBQztBQUNqRSxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxTQUFTLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxtQkFBbUIsQ0FBQztBQUM3QyxPQUFPLEtBQUssS0FBSyxNQUFNLFlBQVksQ0FBQztBQUNwQyxPQUFPLEtBQUssUUFBUSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDL0MsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQztBQUM1RCxNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUNyRCxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDN0MsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNDLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFFdkQsTUFBTSxPQUFPLEdBQUc7SUFDZixTQUFTLEVBQUUsWUFBWTtJQUN2QixxQkFBcUIsRUFBRSxvQkFBb0I7SUFDM0MsZUFBZSxFQUFFO1FB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