mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-30 10:29:42 +00:00
Refactor and enhance ValidationException
handling across types and components
- Simplify and extend type definitions in `types.ts` for dynamic and normalized keys. - Update `ValidationExceptionInterface` to include new methods for filtering violations. - Refactor `apiMethods.ts` to leverage updated exception types and key parsing. - Adjust `WritePersonViolationMap` for stricter type definitions. - Enhance `PersonEdit.vue` to use refined violation methods, improving validation error handling.
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
import { Scope } from "../../types";
|
||||
import {
|
||||
DynamicKeys,
|
||||
Scope,
|
||||
ValidationExceptionInterface,
|
||||
ValidationProblemFromMap,
|
||||
ViolationFromMap
|
||||
} from "../../types";
|
||||
|
||||
export type body = Record<string, boolean | string | number | null>;
|
||||
export type fetchOption = Record<string, boolean | string | number | null>;
|
||||
@@ -25,50 +31,10 @@ export interface TransportExceptionInterface {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type ViolationFromMap<
|
||||
M extends Record<string, Record<string, unknown>>,
|
||||
> = {
|
||||
[K in Extract<keyof M, string>]: {
|
||||
propertyPath: K;
|
||||
title: string;
|
||||
parameters?: M[K];
|
||||
type?: string;
|
||||
};
|
||||
}[Extract<keyof M, string>];
|
||||
|
||||
export type ValidationProblemFromMap<
|
||||
M extends Record<string, Record<string, unknown>>,
|
||||
> = {
|
||||
type: string;
|
||||
title: string;
|
||||
detail?: string;
|
||||
violations: ViolationFromMap<M>[];
|
||||
} & Record<string, unknown>;
|
||||
|
||||
export interface ValidationExceptionInterface<
|
||||
M extends Record<string, Record<string, unknown>> = Record<
|
||||
string,
|
||||
Record<string, unknown>
|
||||
>,
|
||||
> extends Error {
|
||||
name: "ValidationException";
|
||||
/** Full server payload copy */
|
||||
problems: ValidationProblemFromMap<M>;
|
||||
/** A list of all violations, with property key */
|
||||
violationsList: ViolationFromMap<M>[];
|
||||
/** Compact list "Title: path" */
|
||||
violations: string[];
|
||||
/** Only titles */
|
||||
titles: string[];
|
||||
/** Only property paths */
|
||||
propertyPaths: Extract<keyof M, string>[];
|
||||
/** Indexing by property (useful for display by field) */
|
||||
byProperty: Record<Extract<keyof M, string>, string[]>;
|
||||
}
|
||||
export class ValidationException<
|
||||
M extends Record<string, Record<string, unknown>> = Record<
|
||||
M extends Record<string, Record<string, string|number>> = Record<
|
||||
string,
|
||||
Record<string, unknown>
|
||||
Record<string, string|number>
|
||||
>,
|
||||
>
|
||||
extends Error
|
||||
@@ -79,7 +45,7 @@ export class ValidationException<
|
||||
public readonly violations: string[];
|
||||
public readonly violationsList: ViolationFromMap<M>[];
|
||||
public readonly titles: string[];
|
||||
public readonly propertyPaths: Extract<keyof M, string>[];
|
||||
public readonly propertyPaths: DynamicKeys<M> & string[];
|
||||
public readonly byProperty: Record<Extract<keyof M, string>, string[]>;
|
||||
|
||||
constructor(problem: ValidationProblemFromMap<M>) {
|
||||
@@ -98,11 +64,11 @@ export class ValidationException<
|
||||
|
||||
this.propertyPaths = problem.violations.map(
|
||||
(v) => v.propertyPath,
|
||||
) as Extract<keyof M, string>[];
|
||||
) as DynamicKeys<M> & string[];
|
||||
|
||||
this.byProperty = problem.violations.reduce(
|
||||
(acc, v) => {
|
||||
const key = v.propertyPath as Extract<keyof M, string>;
|
||||
const key = v.propertyPath.replace('/\[\d+\]$/', "") as Extract<keyof M, string>;
|
||||
(acc[key] ||= []).push(v.title);
|
||||
return acc;
|
||||
},
|
||||
@@ -113,13 +79,38 @@ export class ValidationException<
|
||||
Error.captureStackTrace(this, ValidationException);
|
||||
}
|
||||
}
|
||||
|
||||
violationsByNormalizedProperty(property: Extract<keyof M, string>): ViolationFromMap<M>[] {
|
||||
return this.violationsList.filter((v) => v.propertyPath.replace(/\[\d+\]$/, "") === property);
|
||||
}
|
||||
|
||||
violationsByNormalizedPropertyAndParams<
|
||||
P extends Extract<keyof M, string>,
|
||||
K extends Extract<keyof M[P], string>
|
||||
>(
|
||||
property: P,
|
||||
param: K,
|
||||
param_value: M[P][K]
|
||||
): ViolationFromMap<M>[]
|
||||
{
|
||||
const list = this.violationsByNormalizedProperty(property);
|
||||
|
||||
return list.filter(
|
||||
(v): boolean =>
|
||||
!!v.parameters &&
|
||||
// `with_parameter in v.parameters` check indexing
|
||||
param in v.parameters &&
|
||||
// the cast is safe, because we have overloading that bind the types
|
||||
(v.parameters as M[P])[param] === param_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the exception is a ValidationExceptionInterface
|
||||
* @param x
|
||||
*/
|
||||
export function isValidationException<M extends Record<string, Record<string, unknown>>>(
|
||||
export function isValidationException<M extends Record<string, Record<string, string|number>>>(
|
||||
x: unknown,
|
||||
): x is ValidationExceptionInterface<M> {
|
||||
return (
|
||||
@@ -315,9 +306,9 @@ export interface ConflictHttpExceptionInterface
|
||||
export const makeFetch = async <
|
||||
Input,
|
||||
Output,
|
||||
M extends Record<string, Record<string, unknown>> = Record<
|
||||
M extends Record<string, Record<string, string|number>> = Record<
|
||||
string,
|
||||
Record<string, Primitive>
|
||||
Record<string, string|number>
|
||||
>,
|
||||
>(
|
||||
method: "POST" | "GET" | "PUT" | "PATCH" | "DELETE",
|
||||
|
Reference in New Issue
Block a user