-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose Ajv in order to support alternate schemas #794
Conversation
…tion, allowing users to validate jsonschema 4.0
Imo this code is clean and can be merged. |
Sorry for the delay in reviewing -- the holidays got the better of me. I agree that the use case is important and I agree equally that this approach probably isn't the way to go. Sharing a single global variable as the singleton validator is already probably not great, but if we start modifying it, I think it would be worse. I'm not a React expert either, but I think passing it as a prop, as you do in your final example, would be better. We could treat the existing |
Indeed, I also think that avoiding to have a global variable that anyone can change, it would probably be better to set the ajv variable from the props , something like :
|
I think that the need to change validation schema is independent of the fact that the project uses a specific schema validator currently. I would prefer to use my final example above, but I would name the attribute |
- extranous properties in ui:order not throwing errors rjsf-team/react-jsonschema-form#814 - exported validator instance for customization rjsf-team/react-jsonschema-form#794
In which release will be included this feature ? |
Having another prop on https://github.com/epoberezkin/ajv#addschemaarrayobjectobject-schema--string-key---ajv As it stands I am likely going to have to downgrade the version of AlliterativelyThis could be bundled with providing an external validators - in which case providing an example validators using AJV would be ideal |
I do plan on finishing this pull request once I reach a point in a project where I need this functionality, probably in a week or two. However it seems we haven't come to an agreement on what method to use. Personally, I do not want to create a custom AJV instance especially because an update to this project may update AJV and my custom configuration might not even be valid / may create a conflict. Instead, I would like to provide a schema that this module would validate against, because even if down the line another JSON validator takes its place, this module will still understand that I want to use a specific schema to validate against. Per @narthollis note adding other customizable features, I think it'd be best to decide if those are implementation-independent and if we should support adding those customizable features as properties as well, leaving the current AJV implementation untouched -- as part of a different PR.
|
My initial thought of passing a custom meta-schema is not going to work, because now additional work needs to be done in order to set up v4 meta-schema: I now think the three available options are:
|
The more I interact with and think about this issue, the more I am inclined to say that the property should be a custom validator, with defined shape eg interface CustomValidator {
validate(formData: any, schema: JSONSchema4 | JsonSchema6 | JsonSchema7): ValidationError[]
}
interface ValidationError {
name: string; // Ajv.ErrorObject.keyword
property: string; // Ajv.ErrorObject.dataPath
message: string; // Ajv.ErrorObject.message
params?: Ajv.ErrorParameters;
stack: string; // Ajv.ErrorObject.dataPath + Ajv.ErrorObject.message
} If React JSON Schema Form continues to use AJV then the internal AJV Error to Validation Error methods should be exposed to allow easier creation of a custom validator. My resonsing for using passing an Object with a validation method on it is to make it easier for sharing AJV instances (or instances of other validators) Usage could be something like: import metaSchema4 from 'ajv/lib/refs/json-schema-draft-04.json';
import { transformAjvErrors } from 'src/validate.js'; // this would need to be exported in some better way
class CustomValidator {
constructor() {
this.ajv = new Ajv({
meta: false,
extendRefs: true,
unknownFormats: 'ignore',
});
ajv.addMetaSchema(metaSchema4);
ajv._opts.defaultMeta = metaSchema.id;
}
public validate(formData: any, schema: JSONSchema4 | JsonSchema6 | JsonSchema7) {
this.ajv.validate(schema, formData);
return transformAjvErrors(this.ajv.errors);
}
}
export const MyCustomValidatorSingleton = new CustomValidator();
### Break
import * as React from 'react';
import RJSF from 'react-jsonschema-form';
import { MyCustomValidatorSingleton } from 'customValidator';
interface Props {
schema: JSONSchema4;
}
export default MyFormComponent extends React.PureComponent<Props> {
public render(): React.ReactNode {
return <RJSF
schema={this.props.schema}
customValidator={MyCustomValidatorSingleton}
/>;
}
} |
@narthollis that is certainly useful for the purpose you are describing. But I think in your case it might be easier to just allow the user to completely override the
So the only change to your code would be the form call:
I would say, however, that for someone who only wants to change the JSON Schema, this is overkill. I would rather something like adding callbacks to the AJV initialization process itself, allowing me to change the args used to create the object, and also allowing a dev to perform actions immediately after initialization. I'm going to do a proof of concept of that within this pull request as that is what I think my solution is. |
Unfortunately, I ended up removing the shared schema due to complexity so someone else will have to maintain a PR if there is interest in this. Edit: I'll leave this open while a path forward is determined. |
Unfortunately, I stopped using this repo almost a year ago, so I'm not the correct person to ask. I initially just wanted to use a v4 schema which hadn't been supported any longer, in order to integrate with another piece of technology from a backend server. I assumed that if I ran into that issue, that future schema versions would cause the issue again, so I recommended extensibility when implementing a fix. However I decided to manage the data models and presentation layer separately as things became more complex, so I won't be able to contribute any more thorough feedback to this PR. |
Okay, thanks for letting me know. Closing this as #1130 seems to do the job. |
Reasons for making this change
react-jsonschema-form
does not expose its Ajv implementation so that users can configure Ajv with different schemas and whatnot. a la #783My use case: implementing ASP.Net React Forms via https://github.com/RSuter/NJsonSchema
This is probably not the way to do it, but I figured I'd offer my implementation. This implementation allows a dev to do this:
I might rather something like the following, but I'm also using TypeScript and it cried when I attempted to implement this so it tells me it might not be the way to go.
I might even go so far as to say the following is the real way, but I really have no idea which is the React way as I'm just learning it.
Either way, I'd like feedback before implementing anything further than I have.
Checklist
npm run cs-format
on my branch to conform my code to prettier coding style