diff --git a/src/pass.ts b/src/pass.ts index c4c8c64..15d571f 100644 --- a/src/pass.ts +++ b/src/pass.ts @@ -30,13 +30,15 @@ export class Pass { private [passProps]: schema.ValidPass = {}; private type: keyof schema.ValidPassType; private fieldsKeys: Set = new Set(); - private passCore: schema.ValidPass = {}; + private passCore: schema.ValidPass; - public headerFields: FieldsArray; - public primaryFields: FieldsArray; - public secondaryFields: FieldsArray; - public auxiliaryFields: FieldsArray; - public backFields: FieldsArray; + // Setting these as possibly undefined because we set + // them all in an loop later + public headerFields: FieldsArray | undefined; + public primaryFields: FieldsArray | undefined; + public secondaryFields: FieldsArray | undefined; + public auxiliaryFields: FieldsArray | undefined; + public backFields: FieldsArray | undefined; private Certificates: schema.FinalCertificates; private [transitType]: string = ""; @@ -72,7 +74,8 @@ export class Pass { } // Parsing and validating pass.json keys - const validatedPassKeys = Object.keys(this.passCore).reduce((acc, current) => { + const passCoreKeys = Object.keys(this.passCore) as (keyof schema.ValidPass)[]; + const validatedPassKeys = passCoreKeys.reduce((acc, current) => { if (this.type === current) { // We want to exclude type keys (eventTicket, // boardingPass, ecc.) and their content @@ -86,10 +89,13 @@ export class Pass { return { ...acc, [current]: this.passCore[current] }; } - const currentSchema = propsSchemaMap.get(current); + const currentSchema = propsSchemaMap.get(current)!; if (Array.isArray(this.passCore[current])) { - const valid = getValidInArray(currentSchema, this.passCore[current]); + const valid = getValidInArray( + currentSchema, + this.passCore[current] as schema.ArrayPassSchema[] + ); return { ...acc, [current]: valid }; } else { return { @@ -201,7 +207,7 @@ export class Pass { * and returning the compiled manifest */ const archive = new ZipFile(); - const manifest = Object.keys(finalBundle).reduce((acc, current) => { + const manifest = Object.keys(finalBundle).reduce((acc, current) => { let hashFlow = forge.md.sha1.create(); hashFlow.update(finalBundle[current].toString("binary")); @@ -504,7 +510,7 @@ export class Pass { * @returns {Buffer} */ - private _sign(manifest: { [key: string]: string }): Buffer { + private _sign(manifest: schema.Manifest): Buffer { const signature = forge.pkcs7.createSignedData(); signature.content = forge.util.createBuffer(JSON.stringify(manifest), "utf8"); @@ -577,8 +583,8 @@ export class Pass { * and then delete it from the passFile. */ - ["backgroundColor", "foregroundColor", "labelColor"] - .filter(v => this[passProps][v] && !isValidRGB(this[passProps][v])) + const passColors = ["backgroundColor", "foregroundColor", "labelColor"] as Array; + passColors.filter(v => this[passProps][v] && !isValidRGB(this[passProps][v])) .forEach(v => delete this[passProps][v]); Object.assign(passFile, this[passProps]); @@ -630,7 +636,7 @@ function barcodesFromUncompleteData(message: string): schema.Barcode[] { "PKBarcodeFormatPDF417", "PKBarcodeFormatAztec", "PKBarcodeFormatCode128" - ].map(format => schema.getValidated({ format, message }, "barcode")); + ].map(format => schema.getValidated({ format, message }, "barcode") as schema.Barcode); } function processRelevancySet(key: string, data: T[]): T[] { diff --git a/src/schema.ts b/src/schema.ts index a4eec48..bbf57ac 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -3,6 +3,10 @@ import debug from "debug"; const schemaDebug = debug("Schema"); +export interface Manifest { + [key: string]: string; +} + export interface Certificates { wwdr?: string; signerCert?: string; @@ -71,7 +75,7 @@ export interface OverridesSupportedOptions { teamIdentifier?: string; appLaunchURL?: string; associatedStoreIdentifiers?: Array; - userInfo?: Object | Array; + userInfo?: { [key: string]: any }; webServiceURL?: string; authenticationToken?: string; sharingProhibited?: boolean; @@ -294,7 +298,7 @@ export interface ValidPassType { storeCard?: PassFields; } -export interface ValidPass extends OverridesSupportedOptions, ValidPassType { +interface PassInterfacesProps { barcode?: Barcode; barcodes?: Barcode[]; beacons?: Beacon[]; @@ -306,6 +310,12 @@ export interface ValidPass extends OverridesSupportedOptions, ValidPassType { voided?: boolean; } +type AllPassProps = PassInterfacesProps & ValidPassType & OverridesSupportedOptions; +export type ValidPass = { + [K in keyof AllPassProps]: AllPassProps[K]; +}; +export type PassColors = Pick; + export interface Barcode { altText?: string; messageEncoding?: string; @@ -464,6 +474,7 @@ const schemas = { }; export type Schema = keyof typeof schemas; +export type ArrayPassSchema = Beacon | Location | Barcode; function resolveSchemaName(name: Schema) { return schemas[name] || undefined; @@ -500,7 +511,7 @@ export function isValid(opts: any, schemaName: Schema): boolean { * @returns {object} the filtered value or empty object */ -export function getValidated(opts: any, schemaName: Schema): T { +export function getValidated(opts: any, schemaName: Schema): T | null { const resolvedSchema = resolveSchemaName(schemaName); if (!resolvedSchema) { diff --git a/src/utils.ts b/src/utils.ts index 1e42384..539f471 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -11,7 +11,7 @@ import { sep } from "path"; * @returns {Boolean} True if valid rgb, false otherwise */ -export function isValidRGB(value: string): boolean { +export function isValidRGB(value?: string): boolean { if (!value || typeof value !== "string") { return false; } @@ -89,8 +89,10 @@ export function generateStringFile(lang: { [index: string]: string }): Buffer { * @param origin */ -export function splitBufferBundle(origin: Object): [PartitionedBundle["l10nBundle"], PartitionedBundle["bundle"]] { - return Object.keys(origin).reduce(([ l10n, bundle ], current) => { +type PartitionedBundleElements = [PartitionedBundle["l10nBundle"], PartitionedBundle["bundle"]]; + +export function splitBufferBundle(origin: any): PartitionedBundleElements { + return Object.keys(origin).reduce(([ l10n, bundle ], current) => { if (!current.includes(".lproj")) { return [ l10n, { ...bundle, [current]: origin[current] }]; }