-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Hi there! 👋
I've been toying with your project and I tried to add form validation but I see you don't use the inertia router/form helper to consume the api controller instead you use Ky so I was wondering how could the error injection to the form could be performed.
This is my approach to form validation:
export class BaseField<T = unknown> implements Serializable {
// ...
protected attributes: Record<string, any> = {};
protected options: Record<string, any> = {};
+ protected rules: Record<string, any> = {};
protected display: FieldDisplayOptions = {
index: true,
create: true,
update: true,
peek: true,
};
// ...
+ protected buildRules(): SchemaTypes | null {
+ return null;
+ }
toJSON() {
return {
kind: this.$kind,
name: this.$name,
label: this.$label,
icon: this.$icon,
attributes: this.attributes,
options: this.options,
display: this.display,
defaultValue: this.$defaultValue,
+ rules: this.buildRules(),
};
}The field should add their own rules and then compile the vine object:
export class TextField extends BaseField {
// ...
min(value: number) {
if (value <= 0) {
throw Error('Min length must be positive');
}
this.rules['min'] = value;
return this;
}
protected buildRules(): VineString {
let rule = vine.string();
if (!this.attributes['required']) {
rule.optional()
}
if (this.rules['min']) {
rule.minLength(this.rules['min']);
}
return rule;
}
}Then we can validate in the LucidBaseResource:
async create(data: any): Promise<TRecord> {
const validator = this.compileValidator();
const processedData = await validator.validate(data) as Partial<ModelAttributes<InstanceType<TModel>>>;
const record = await this.model.create(processedData);
return record as TRecord;
}
// ...
compileValidator() {
let rules: Record<string, SchemaTypes> = {};
this.toJSON().fields.forEach(field => field.fields.forEach(field => {
if (field.rules) {
rules[field.name] = field.rules;
}
}));
return vine.compile(vine.object(rules));
}The thing is that if we dont send the Accept: application/json or the X-Inertia: true header the client only gets a error page instead of json response, if we send the inertia header we get the full inertia response including the error page prop but the X-Inertia-Version is missing so we receive a 409 conflict, if we send the application/json it wont get the full inertia response but it does return the errors in standard REST.
I would like to contribute to the project but I'm not a Typescript expert.
What's your proposal for handling errors?
Great project btw!