mirror of
https://github.com/marcogll/passkit-generator.git
synced 2026-03-15 14:25:17 +00:00
Added new method setRelevantDates
This commit is contained in:
@@ -87,6 +87,11 @@ const modelFiles = {};
|
|||||||
|
|
||||||
const EXAMPLE_PATH_RELATIVE = "../examples/models/examplePass.pass";
|
const EXAMPLE_PATH_RELATIVE = "../examples/models/examplePass.pass";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} folder
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
|
||||||
function unpackFolder(folder) {
|
function unpackFolder(folder) {
|
||||||
const entryList = fs.readdirSync(path.resolve(__dirname, folder));
|
const entryList = fs.readdirSync(path.resolve(__dirname, folder));
|
||||||
|
|
||||||
@@ -859,35 +864,107 @@ describe("PKPass", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("relevant date", () => {
|
describe("Date relevancy", () => {
|
||||||
it("should set pass relevant date", () => {
|
describe("(deprecated iOS 18) (root).relevantDate", () => {
|
||||||
pkpass.setRelevantDate(new Date("2023-04-11T00:15+10:00"));
|
it("should set pass relevant date", () => {
|
||||||
|
pkpass.setRelevantDate(new Date("2023-04-11T00:15+10:00"));
|
||||||
|
|
||||||
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
||||||
|
|
||||||
expect(passjsonGenerated.relevantDate).toBe(
|
expect(passjsonGenerated.relevantDate).toBe(
|
||||||
"2023-04-10T14:15:00.000Z",
|
"2023-04-10T14:15:00.000Z",
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should reset relevant date", () => {
|
||||||
|
pkpass.setRelevantDate(new Date(2023, 3, 10, 14, 15));
|
||||||
|
pkpass.setRelevantDate(null);
|
||||||
|
|
||||||
|
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
||||||
|
|
||||||
|
expect(passjsonGenerated.relevantDate).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw if an invalid date is received", () => {
|
||||||
|
expect(() =>
|
||||||
|
// @ts-expect-error
|
||||||
|
pkpass.setRelevantDate("32/18/228317"),
|
||||||
|
).toThrowError();
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(() => pkpass.setRelevantDate(undefined)).toThrowError();
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(() => pkpass.setRelevantDate(5)).toThrowError();
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(() => pkpass.setRelevantDate({})).toThrowError();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reset relevant date", () => {
|
describe("setRelevantDates", () => {
|
||||||
pkpass.setRelevantDate(new Date(2023, 3, 10, 14, 15));
|
it("should accept strings", () => {
|
||||||
pkpass.setRelevantDate(null);
|
pkpass.setRelevantDates([
|
||||||
|
{
|
||||||
|
startDate: "2025-01-08T22:17:30.000Z",
|
||||||
|
endDate: "2025-01-08T23:58:25.000Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relevantDate: "2025-01-08T22:17:30.000Z",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
||||||
|
|
||||||
expect(passjsonGenerated.relevantDate).toBeUndefined();
|
expect(passjsonGenerated.relevantDates).toMatchObject([
|
||||||
});
|
{
|
||||||
|
startDate: "2025-01-08T22:17:30.000Z",
|
||||||
|
endDate: "2025-01-08T23:58:25.000Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relevantDate: "2025-01-08T22:17:30.000Z",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it("should throw if an invalid date is received", () => {
|
it("should accept dates", () => {
|
||||||
// @ts-expect-error
|
pkpass.setRelevantDates([
|
||||||
expect(() => pkpass.setRelevantDate("32/18/228317")).toThrowError();
|
{
|
||||||
// @ts-expect-error
|
startDate: new Date(2025, 1, 8, 23, 58, 25),
|
||||||
expect(() => pkpass.setRelevantDate(undefined)).toThrowError();
|
endDate: new Date(2025, 1, 8, 23, 58, 25),
|
||||||
// @ts-expect-error
|
},
|
||||||
expect(() => pkpass.setRelevantDate(5)).toThrowError();
|
{
|
||||||
// @ts-expect-error
|
relevantDate: new Date(2025, 1, 8, 23, 58, 25),
|
||||||
expect(() => pkpass.setRelevantDate({})).toThrowError();
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
||||||
|
|
||||||
|
expect(passjsonGenerated.relevantDates).toMatchObject([
|
||||||
|
{
|
||||||
|
startDate: "2025-02-08T22:58:25.000Z",
|
||||||
|
endDate: "2025-02-08T22:58:25.000Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relevantDate: "2025-02-08T22:58:25.000Z",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow resetting", () => {
|
||||||
|
pkpass.setRelevantDates([
|
||||||
|
{
|
||||||
|
startDate: "2025-01-08T22:17:30.000Z",
|
||||||
|
endDate: "2025-01-08T23:58:25.000Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relevantDate: "2025-01-08T22:17:30.000Z",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
pkpass.setRelevantDates(null);
|
||||||
|
|
||||||
|
const passjsonGenerated = getGeneratedPassJson(pkpass);
|
||||||
|
|
||||||
|
expect(passjsonGenerated.relevantDates).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -956,6 +956,54 @@ export default class PKPass extends Bundle {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows setting a series of relevancy intervals or
|
||||||
|
* relevancy entries for the pass.
|
||||||
|
*
|
||||||
|
* @param {Schemas.RelevantDate[] | null} relevancyEntries
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public setRelevantDates(
|
||||||
|
relevancyEntries: Schemas.RelevantDate[] | null,
|
||||||
|
): void {
|
||||||
|
Utils.assertUnfrozen(this);
|
||||||
|
|
||||||
|
if (relevancyEntries === null) {
|
||||||
|
this[propsSymbol]["relevantDates"] = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const processedDateEntries = relevancyEntries.reduce<
|
||||||
|
Schemas.RelevantDate[]
|
||||||
|
>((acc, entry) => {
|
||||||
|
try {
|
||||||
|
Schemas.validate(Schemas.RelevantDate, entry);
|
||||||
|
|
||||||
|
if (isRelevantEntry(entry)) {
|
||||||
|
acc.push({
|
||||||
|
relevantDate: Utils.processDate(
|
||||||
|
new Date(entry.relevantDate),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
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
|
* Allows setting a relevant date in which the OS
|
||||||
* should show this pass.
|
* should show this pass.
|
||||||
@@ -964,6 +1012,13 @@ export default class PKPass extends Bundle {
|
|||||||
*
|
*
|
||||||
* @param {Date | null} date
|
* @param {Date | null} date
|
||||||
* @throws if pass is frozen due to previous export
|
* @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`). This method will
|
||||||
|
* set both the original, as the new one will get ignored in older
|
||||||
|
* iOS versions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public setRelevantDate(date: Date | null): void {
|
public setRelevantDate(date: Date | null): void {
|
||||||
@@ -1086,3 +1141,9 @@ function validateJSONBuffer(
|
|||||||
|
|
||||||
return Schemas.validate(schema, contentAsJSON);
|
return Schemas.validate(schema, contentAsJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRelevantEntry(
|
||||||
|
entry: Schemas.RelevantDate,
|
||||||
|
): entry is Schemas.RelevancyEntry {
|
||||||
|
return Object.prototype.hasOwnProperty.call(entry, "relevantDate");
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ export const FIELDS = {
|
|||||||
"Cannot add field with key '%s': another field already owns this key. Ignored.",
|
"Cannot add field with key '%s': another field already owns this key. Ignored.",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const RELEVANT_DATE = {
|
||||||
|
INVALID: "Cannot set relevant date. Date format is invalid",
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const DATE = {
|
export const DATE = {
|
||||||
INVALID: "Cannot set %s. Invalid date %s",
|
INVALID: "Cannot set %s. Invalid date %s",
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ export const PreferredStyleSchemes = Joi.array().items(
|
|||||||
/**
|
/**
|
||||||
* A single interval can span at most 24 hours
|
* A single interval can span at most 24 hours
|
||||||
*/
|
*/
|
||||||
interface RelevancyInterval {
|
export interface RelevancyInterval {
|
||||||
startDate: string;
|
startDate: string | Date;
|
||||||
endDate: string;
|
endDate: string | Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RelevancyEntry {
|
export interface RelevancyEntry {
|
||||||
relevantDate: string;
|
relevantDate: string | Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,13 +52,22 @@ interface RelevancyEntry {
|
|||||||
|
|
||||||
export type RelevantDate = RelevancyInterval | RelevancyEntry;
|
export type RelevantDate = RelevancyInterval | RelevancyEntry;
|
||||||
|
|
||||||
const RelevantDate = Joi.alternatives(
|
export const RelevantDate = Joi.alternatives(
|
||||||
Joi.object<RelevancyInterval>().keys({
|
Joi.object<RelevancyInterval>().keys({
|
||||||
startDate: Joi.string().required(),
|
startDate: Joi.alternatives(
|
||||||
endDate: Joi.string().required(),
|
Joi.string().isoDate(),
|
||||||
|
Joi.date().iso(),
|
||||||
|
).required(),
|
||||||
|
endDate: Joi.alternatives(
|
||||||
|
Joi.string().isoDate(),
|
||||||
|
Joi.date().iso(),
|
||||||
|
).required(),
|
||||||
}),
|
}),
|
||||||
Joi.object<RelevancyEntry>().keys({
|
Joi.object<RelevancyEntry>().keys({
|
||||||
relevantDate: Joi.string().required(),
|
relevantDate: Joi.alternatives(
|
||||||
|
Joi.string().isoDate(),
|
||||||
|
Joi.date().iso(),
|
||||||
|
).required(),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -492,7 +501,7 @@ export const Template = Joi.object<Template>({
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function assertValidity<T>(
|
export function assertValidity<T>(
|
||||||
schema: Joi.ObjectSchema<T> | Joi.StringSchema | Joi.Schema<T>,
|
schema: Joi.Schema<T>,
|
||||||
data: T,
|
data: T,
|
||||||
customErrorMessage?: string,
|
customErrorMessage?: string,
|
||||||
): void {
|
): void {
|
||||||
@@ -524,7 +533,7 @@ export function assertValidity<T>(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function validate<T extends Object>(
|
export function validate<T extends Object>(
|
||||||
schema: Joi.ObjectSchema<T> | Joi.StringSchema,
|
schema: Joi.Schema<T>,
|
||||||
options: T,
|
options: T,
|
||||||
): T {
|
): T {
|
||||||
const validationResult = schema.validate(options, {
|
const validationResult = schema.validate(options, {
|
||||||
|
|||||||
Reference in New Issue
Block a user