mirror of
https://github.com/marcogll/passkit-generator.git
synced 2026-03-15 22:25:24 +00:00
Moved Schema.js to typescript with Joi-matched interfaces
This commit is contained in:
@@ -1,5 +1,35 @@
|
|||||||
const Joi = require("joi");
|
import Joi from "joi";
|
||||||
const debug = require("debug")("Schema");
|
import debug from "debug";
|
||||||
|
|
||||||
|
const schemaDebug = debug("Schema");
|
||||||
|
|
||||||
|
export interface FactoryOptions {
|
||||||
|
model: { [key: string]: Buffer } | string;
|
||||||
|
certificates: {
|
||||||
|
wwdr: string;
|
||||||
|
signerCert: string;
|
||||||
|
signerKey: {
|
||||||
|
keyFile: string;
|
||||||
|
passphrase?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
overrides?: Object;
|
||||||
|
shouldOverwrite?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PassInstance {
|
||||||
|
model: { [key: string]: Buffer };
|
||||||
|
certificates: {
|
||||||
|
wwdr: string;
|
||||||
|
signerCert: string;
|
||||||
|
signerKey: {
|
||||||
|
keyFile: string;
|
||||||
|
passphrase?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
overrides?: OverridesSupportedOptions;
|
||||||
|
shouldOverwrite?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const instance = Joi.object().keys({
|
const instance = Joi.object().keys({
|
||||||
model: Joi.string().required(),
|
model: Joi.string().required(),
|
||||||
@@ -15,6 +45,20 @@ const instance = Joi.object().keys({
|
|||||||
shouldOverwrite: Joi.boolean()
|
shouldOverwrite: Joi.boolean()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface OverridesSupportedOptions {
|
||||||
|
serialNumber?: string;
|
||||||
|
description?: string;
|
||||||
|
userInfo?: Object | Array<any>;
|
||||||
|
webServiceURL?: string;
|
||||||
|
authenticationToken?: string;
|
||||||
|
sharingProhibited?: boolean;
|
||||||
|
backgroundColor?: string;
|
||||||
|
foregroundColor?: string;
|
||||||
|
labelColor?: string;
|
||||||
|
groupingIdentifier?: string;
|
||||||
|
suppressStripShine?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const supportedOptions = Joi.object().keys({
|
const supportedOptions = Joi.object().keys({
|
||||||
serialNumber: Joi.string(),
|
serialNumber: Joi.string(),
|
||||||
description: Joi.string(),
|
description: Joi.string(),
|
||||||
@@ -34,16 +78,35 @@ const supportedOptions = Joi.object().keys({
|
|||||||
|
|
||||||
/* For a correct usage of semantics, please refer to https://apple.co/2I66Phk */
|
/* For a correct usage of semantics, please refer to https://apple.co/2I66Phk */
|
||||||
|
|
||||||
|
interface CurrencyAmount {
|
||||||
|
currencyCode: string;
|
||||||
|
amount: string;
|
||||||
|
}
|
||||||
|
|
||||||
const currencyAmount = Joi.object().keys({
|
const currencyAmount = Joi.object().keys({
|
||||||
currencyCode: Joi.string().required(),
|
currencyCode: Joi.string().required(),
|
||||||
amount: Joi.string().required(),
|
amount: Joi.string().required(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface PersonNameComponent {
|
||||||
|
givenName: string;
|
||||||
|
familyName: string;
|
||||||
|
}
|
||||||
|
|
||||||
const personNameComponents = Joi.object().keys({
|
const personNameComponents = Joi.object().keys({
|
||||||
givenName: Joi.string().required(),
|
givenName: Joi.string().required(),
|
||||||
familyName: Joi.string().required()
|
familyName: Joi.string().required()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface Seat {
|
||||||
|
seatSection?: string;
|
||||||
|
seatRow?: string;
|
||||||
|
seatNumber?: string;
|
||||||
|
seatIdentifier?: string;
|
||||||
|
seatType?: string;
|
||||||
|
seatDescription?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const seat = Joi.object().keys({
|
const seat = Joi.object().keys({
|
||||||
seatSection: Joi.string(),
|
seatSection: Joi.string(),
|
||||||
seatRow: Joi.string(),
|
seatRow: Joi.string(),
|
||||||
@@ -58,6 +121,69 @@ const location = Joi.object().keys({
|
|||||||
longitude: Joi.number().required()
|
longitude: Joi.number().required()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface Semantics {
|
||||||
|
totalPrice?: CurrencyAmount;
|
||||||
|
duration?: number;
|
||||||
|
seats?: Seat[];
|
||||||
|
silenceRequested?: boolean;
|
||||||
|
departureLocation?: Location;
|
||||||
|
destinationLocation?: Location;
|
||||||
|
destinationLocationDescription?: Location;
|
||||||
|
transitProvider?: string;
|
||||||
|
vehicleName?: string;
|
||||||
|
vehicleType?: string;
|
||||||
|
originalDepartureDate?: string;
|
||||||
|
currentDepartureDate?: string;
|
||||||
|
originalArrivalDate?: string;
|
||||||
|
currentArrivalDate?: string;
|
||||||
|
originalBoardingDate?: string;
|
||||||
|
currentBoardingDate?: string;
|
||||||
|
boardingGroup?: string;
|
||||||
|
boardingSequenceNumber?: string;
|
||||||
|
confirmationNumber?: string;
|
||||||
|
transitStatus?: string;
|
||||||
|
transitStatuReason?: string;
|
||||||
|
passengetName?: PersonNameComponent;
|
||||||
|
membershipProgramName?: string;
|
||||||
|
membershipProgramNumber?: string;
|
||||||
|
priorityStatus?: string;
|
||||||
|
securityScreening?: string;
|
||||||
|
flightCode?: string;
|
||||||
|
airlineCode?: string;
|
||||||
|
flightNumber?: number;
|
||||||
|
departureAirportCode?: string;
|
||||||
|
departureAirportName?: string;
|
||||||
|
destinationTerminal?: string;
|
||||||
|
destinationGate?: string;
|
||||||
|
departurePlatform?: string;
|
||||||
|
departureStationName?: string;
|
||||||
|
destinationPlatform?: string;
|
||||||
|
destinationStationName?: string;
|
||||||
|
carNumber?: string;
|
||||||
|
eventName?: string;
|
||||||
|
venueName?: string;
|
||||||
|
venueLocation?: Location;
|
||||||
|
venueEntrance?: string;
|
||||||
|
venuePhoneNumber?: string;
|
||||||
|
venueRoom?: string;
|
||||||
|
eventType?: "PKEventTypeGeneric" | "PKEventTypeLivePerformance" | "PKEventTypeMovie" | "PKEventTypeSports" | "PKEventTypeConference" | "PKEventTypeConvention" | "PKEventTypeWorkshop" | "PKEventTypeSocialGathering";
|
||||||
|
eventStartDate?: string;
|
||||||
|
eventEndDate?: string;
|
||||||
|
artistIDs?: string;
|
||||||
|
performerNames?: string[];
|
||||||
|
genre?: string;
|
||||||
|
leagueName?: string;
|
||||||
|
leagueAbbreviation?: string;
|
||||||
|
homeTeamLocation?: string;
|
||||||
|
homeTeamName?: string;
|
||||||
|
homeTeamAbbreviation?: string;
|
||||||
|
awayTeamLocation?: string;
|
||||||
|
awayTeamName?: string;
|
||||||
|
awayTeamAbbreviation?: string;
|
||||||
|
sportName?: string;
|
||||||
|
balance?: CurrencyAmount;
|
||||||
|
}
|
||||||
|
|
||||||
const semantics = Joi.object().keys({
|
const semantics = Joi.object().keys({
|
||||||
// All
|
// All
|
||||||
totalPrice: currencyAmount,
|
totalPrice: currencyAmount,
|
||||||
@@ -129,6 +255,13 @@ const semantics = Joi.object().keys({
|
|||||||
balance: currencyAmount
|
balance: currencyAmount
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface Barcode {
|
||||||
|
altText?: string;
|
||||||
|
messageEncoding?: string;
|
||||||
|
format: string;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
const barcode = Joi.object().keys({
|
const barcode = Joi.object().keys({
|
||||||
altText: Joi.string(),
|
altText: Joi.string(),
|
||||||
messageEncoding: Joi.string().default("iso-8859-1"),
|
messageEncoding: Joi.string().default("iso-8859-1"),
|
||||||
@@ -136,6 +269,24 @@ const barcode = Joi.object().keys({
|
|||||||
message: Joi.string().required()
|
message: Joi.string().required()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface Field {
|
||||||
|
attributedValue?: string | number | Date;
|
||||||
|
changeMessage?: string;
|
||||||
|
dataDetectorType?: string[];
|
||||||
|
label?: string;
|
||||||
|
textAlignment?: string;
|
||||||
|
key: string;
|
||||||
|
value: string | number | Date;
|
||||||
|
semantics: Semantics;
|
||||||
|
dateStyle?: string;
|
||||||
|
ignoreTimeZone?: boolean;
|
||||||
|
isRelative?: boolean;
|
||||||
|
timeStyle?: string;
|
||||||
|
currencyCode?: string;
|
||||||
|
numberStyle?: string;
|
||||||
|
row?: number;
|
||||||
|
}
|
||||||
|
|
||||||
const field = Joi.object().keys({
|
const field = Joi.object().keys({
|
||||||
attributedValue: Joi.alternatives(Joi.string().allow(""), Joi.number(), Joi.date().iso()),
|
attributedValue: Joi.alternatives(Joi.string().allow(""), Joi.number(), Joi.date().iso()),
|
||||||
changeMessage: Joi.string(),
|
changeMessage: Joi.string(),
|
||||||
@@ -164,6 +315,13 @@ const field = Joi.object().keys({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface Beacon {
|
||||||
|
major?: number;
|
||||||
|
minor?: number;
|
||||||
|
relevantText?: string;
|
||||||
|
proximityUUID: string;
|
||||||
|
}
|
||||||
|
|
||||||
const beaconsDict = Joi.object().keys({
|
const beaconsDict = Joi.object().keys({
|
||||||
major: Joi.number().integer().positive().max(65535).greater(Joi.ref("minor")),
|
major: Joi.number().integer().positive().max(65535).greater(Joi.ref("minor")),
|
||||||
minor: Joi.number().integer().positive().max(65535).less(Joi.ref("major")),
|
minor: Joi.number().integer().positive().max(65535).less(Joi.ref("major")),
|
||||||
@@ -171,6 +329,13 @@ const beaconsDict = Joi.object().keys({
|
|||||||
relevantText: Joi.string()
|
relevantText: Joi.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface Location {
|
||||||
|
relevantText?: string;
|
||||||
|
altitude?: number;
|
||||||
|
latitude: number;
|
||||||
|
longitude: number;
|
||||||
|
}
|
||||||
|
|
||||||
const locationsDict = Joi.object().keys({
|
const locationsDict = Joi.object().keys({
|
||||||
altitude: Joi.number(),
|
altitude: Joi.number(),
|
||||||
latitude: Joi.number().required(),
|
latitude: Joi.number().required(),
|
||||||
@@ -178,6 +343,14 @@ const locationsDict = Joi.object().keys({
|
|||||||
relevantText: Joi.string()
|
relevantText: Joi.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface Pass {
|
||||||
|
auxiliaryFields: Field[];
|
||||||
|
backFields: Field[];
|
||||||
|
headerFields: Field[];
|
||||||
|
primaryFields: Field[];
|
||||||
|
secondaryFields: Field[];
|
||||||
|
}
|
||||||
|
|
||||||
const passDict = Joi.object().keys({
|
const passDict = Joi.object().keys({
|
||||||
auxiliaryFields: Joi.array().items(Joi.object().keys({
|
auxiliaryFields: Joi.array().items(Joi.object().keys({
|
||||||
row: Joi.number().max(1).min(0)
|
row: Joi.number().max(1).min(0)
|
||||||
@@ -188,8 +361,15 @@ const passDict = Joi.object().keys({
|
|||||||
secondaryFields: Joi.array().items(field)
|
secondaryFields: Joi.array().items(field)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type TransitType = "PKTransitTypeAir" | "PKTransitTypeBoat" | "PKTransitTypeBus" | "PKTransitTypeGeneric" | "PKTransitTypeTrain";
|
||||||
|
|
||||||
const transitType = Joi.string().regex(/(PKTransitTypeAir|PKTransitTypeBoat|PKTransitTypeBus|PKTransitTypeGeneric|PKTransitTypeTrain)/);
|
const transitType = Joi.string().regex(/(PKTransitTypeAir|PKTransitTypeBoat|PKTransitTypeBus|PKTransitTypeGeneric|PKTransitTypeTrain)/);
|
||||||
|
|
||||||
|
export interface NFC {
|
||||||
|
message: string;
|
||||||
|
encryptionPublicKey?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const nfcDict = Joi.object().keys({
|
const nfcDict = Joi.object().keys({
|
||||||
message: Joi.string().required().max(64),
|
message: Joi.string().required().max(64),
|
||||||
encryptionPublicKey: Joi.string()
|
encryptionPublicKey: Joi.string()
|
||||||
@@ -197,7 +377,10 @@ const nfcDict = Joi.object().keys({
|
|||||||
|
|
||||||
// --------- UTILITIES ---------- //
|
// --------- UTILITIES ---------- //
|
||||||
|
|
||||||
const schemas = {
|
type Schemas = {
|
||||||
|
[index: string]: Joi.ObjectSchema | Joi.StringSchema;
|
||||||
|
};
|
||||||
|
const schemas: Schemas = {
|
||||||
instance,
|
instance,
|
||||||
barcode,
|
barcode,
|
||||||
field,
|
field,
|
||||||
@@ -209,8 +392,8 @@ const schemas = {
|
|||||||
supportedOptions
|
supportedOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
function resolveSchemaName(name) {
|
function resolveSchemaName(name: keyof Schemas) {
|
||||||
return schemas[name] || "";
|
return schemas[name] || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -220,18 +403,18 @@ function resolveSchemaName(name) {
|
|||||||
* @returns {boolean} - result of the check
|
* @returns {boolean} - result of the check
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function isValid(opts, schemaName) {
|
export function isValid(opts: any, schemaName: keyof Schemas): boolean {
|
||||||
let resolvedSchema = resolveSchemaName(schemaName);
|
const resolvedSchema = resolveSchemaName(schemaName);
|
||||||
|
|
||||||
if (!resolvedSchema) {
|
if (!resolvedSchema) {
|
||||||
debug(`validation failed due to missing or mispelled schema name`);
|
schemaDebug(`validation failed due to missing or mispelled schema name`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let validation = Joi.validate(opts, resolvedSchema);
|
const validation = Joi.validate(opts, resolvedSchema);
|
||||||
|
|
||||||
if (validation.error) {
|
if (validation.error) {
|
||||||
debug(`validation failed due to error: ${validation.error.message}`);
|
schemaDebug(`validation failed due to error: ${validation.error.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !validation.error;
|
return !validation.error;
|
||||||
@@ -244,19 +427,14 @@ function isValid(opts, schemaName) {
|
|||||||
* @returns {object} the filtered value or empty object
|
* @returns {object} the filtered value or empty object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getValidated(opts, schemaName) {
|
export function getValidated(opts: any, schemaName: keyof Schemas): Object {
|
||||||
let resolvedSchema = resolveSchemaName(schemaName);
|
let resolvedSchema = resolveSchemaName(schemaName);
|
||||||
let validation = Joi.validate(opts, resolvedSchema, { stripUnknown: true });
|
let validation = Joi.validate(opts, resolvedSchema, { stripUnknown: true });
|
||||||
|
|
||||||
if (validation.error) {
|
if (validation.error) {
|
||||||
debug(`Validation failed in getValidated due to error: ${validation.error.message}`);
|
schemaDebug(`Validation failed in getValidated due to error: ${validation.error.message}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return validation.value;
|
return validation.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
isValid,
|
|
||||||
getValidated
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user