diff --git a/src/card.ts b/src/card.ts index f970088f..8a887bbc 100644 --- a/src/card.ts +++ b/src/card.ts @@ -377,7 +377,7 @@ export class FrigateCard extends LitElement { * @param error The ZodError object from parsing. * @returns An array of string error paths. */ - protected _getParseErrorPaths(error: z.ZodError): string[] { + protected _getParseErrorPaths(error: z.ZodError): Set | null { /* Zod errors involving unions are complex, as Zod may not be able to tell * where the 'real' error is vs simply a union option not matching. This * function finds all ZodError "issues" that don't have an error with 'type' @@ -388,7 +388,7 @@ export class FrigateCard extends LitElement { * exactly why (or rather Zod simply says it doesn't match any of the * available unions). This usually suggests the user specified an incorrect * type name entirely. */ - let contenders: string[] = []; + const contenders = new Set(); if (error && error.issues) { for (let i = 0; i < error.issues.length; i++) { const issue = error.issues[i]; @@ -396,17 +396,17 @@ export class FrigateCard extends LitElement { const unionErrors = (issue as z.ZodInvalidUnionIssue).unionErrors; for (let j = 0; j < unionErrors.length; j++) { const nestedErrors = this._getParseErrorPaths(unionErrors[j]); - if (nestedErrors.length) { - contenders = contenders.concat(nestedErrors); + if (nestedErrors && nestedErrors.size) { + nestedErrors.forEach(contenders.add, contenders); } } } else if (issue.code == 'invalid_type') { if (issue.path[issue.path.length - 1] == 'type') { - return []; + return null; } - contenders.push(this._getParseErrorPathString(issue.path)); + contenders.add(this._getParseErrorPathString(issue.path)); } else if (issue.code != 'custom') { - contenders.push(this._getParseErrorPathString(issue.path)); + contenders.add(this._getParseErrorPathString(issue.path)); } } } @@ -454,8 +454,8 @@ export class FrigateCard extends LitElement { throw new Error( upgradeMessage + `${localize('error.invalid_configuration')}: ` + - (hint.length - ? JSON.stringify(hint, null, ' ') + (hint && hint.size + ? JSON.stringify([...hint], null, ' ') : localize('error.invalid_configuration_no_hint')), ); } diff --git a/src/types.ts b/src/types.ts index 0e37f670..a7c52b24 100644 --- a/src/types.ts +++ b/src/types.ts @@ -103,6 +103,8 @@ const customActionSchema = z.object({ action: z.literal('fire-dom-event'), }) export const frigateCardCustomActionSchema = customActionSchema.merge(z.object({ + // Syntactic sugar to avoid 'fire-dom-event' as part of an external API. + action: z.literal('fire-dom-event').or(z.literal('custom:frigate-card-action').transform(() => 'fire-dom-event')), frigate_card_action: z.string(), })) export type FrigateCardCustomAction = z.infer;