Skip to content
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

Bump/ajv #2542

Closed
wants to merge 8 commits into from
Closed

Bump/ajv #2542

wants to merge 8 commits into from

Conversation

newt10
Copy link
Collaborator

@newt10 newt10 commented Sep 10, 2021

Reasons for making this change

AJV@6 is EOL. This PR updates the ajv to v7.

If this is related to existing tickets, include links to them as well. Use the syntax fixes #2541 .

Checklist

  • I'm updating documentation
  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
  • I'm adding a new feature
    • I've updated the playground with an example use of the feature

Tests

All tests have been updated to work with the new ajv library and all tests are passing

Playground

All playground forms are rendering as expected with the correct response submit.

@newt10 newt10 self-assigned this Sep 10, 2021
@newt10 newt10 linked an issue Sep 10, 2021 that may be closed by this pull request
3 tasks
@newt10 newt10 marked this pull request as ready for review September 10, 2021 01:35

### JSON Schema draft-04

This version drops support for JSON schema draft04.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use "draft-04" and "draft-07"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


## Breaking changes

### JSON Schema draft-04
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explicitly mention that we're bumping ajv to v7, therefore:

  • lost support for draft-04
  • etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// ajv@7.0^ has changed the format of error.dataPath. In ajv@6.0^ the error
// in the illformed key will result in dataPath = ['bar.\\'"[]()=+*&^%$#@!'].
// However in ajv@7.0 and higher this key results in
// dataPath = bar.'"[]()=+*&^%$#@!. lodash breaks this into error paths
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to @epicfaace -- look into why this is happening

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newt10 provide code sample to test this on ajv

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@epicfaace epicfaace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also update https://github.com/rjsf-team/react-jsonschema-form/blob/3ec17f1c0ff40401b7a99c5e9891ac2834a1e73f/docs/usage/validation.md#custom-error-messages to reflect what we actually get (we might get a json pointer instead of a dot notation path)

Copy link
Member

@epicfaace epicfaace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@epicfaace epicfaace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @param {string} property source of error in the data.
* @returns {stringp[]} array of object paths.
*/
function genPaths(property) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace this with using the json-pointer npm library and use pointer.parse (https://www.npmjs.com/package/json-pointer)

validationError.message &&
typeof validationError.message === "string" &&
validationError.message.includes("no schema with key or ref ");
const includeValidationErrors = shouldIncludeSchemaErrors(validationError);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment: #1130 (comment)

Commit: 2e5d5b9

} catch (err) {
validationError = err;
}

if (validationError === null) {
try {
ajv.validate(schema, formData);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ajv v7 changes:

  • If you call ajv.validate on an invalid schema twice, the second time it will (incorrectly) not throw any errors due to the schema being invalid.

In general, to note about ajv:

  • If you call ajv.validateSchema, it usually returns false if the schema is invalid. However, if the meta schema is not found, it will throw an exception.

Goal: Go around ajv v7 changes. Aim for same behavior as before (we want to catch all metaschema errors in validationError).

Current solution: Call ajv.validateSchema beforehand, but regardless of whether the schema is valid, call ajv.validate.

New solution: ???

allErrors: true,
multipleOfPrecision: 8,
schemaId: "auto",
unknownFormats: "ignore",
strictTypes: "log",
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest that we allow overriding ajv instance options.

Suggested change
function createAjvInstance(options) {
const ajv = new Ajv({
allErrors: true,
multipleOfPrecision: 8,
strictTypes: "log",
...options
});

Copy link

@kikonejacob kikonejacob Sep 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That way we can pass the options in the form validation

export default function validateFormData(
  formData,
  schema,
  customValidate,
  transformErrors,
  additionalMetaSchemas = [],
  customFormats = {}
  validationOptions={}
) {
  // Include form data with undefined values, which is required for validation.
  const rootSchema = schema;
  formData = getDefaultFormState(schema, formData, rootSchema, true);

  const newMetaSchemas = !deepEquals(formerMetaSchema, additionalMetaSchemas);
  const newFormats = !deepEquals(formerCustomFormats, customFormats);

  if (newMetaSchemas || newFormats|| validationOptions) {
    ajv = createAjvInstance(validationOptions);
  }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows more control over validation without having to reimplement custom validate function
https://ajv.js.org/options.html

@kikonejacob
Copy link

@newt10 any update on this PR?

@JulienBlacas
Copy link

Is this PR still maintained by someone ? It would be definitely nice to have AJV v7 here :)

@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 5, 2022

as work has stalled here, and no work has happened on the ajv 7.x line, It seems like going straight to ajv 8 might make more sense at the next rjsf version bump. https://github.com/ajv-validator/ajv/blob/master/docs/v6-to-v8-migration.md

@epicfaace
Copy link
Member

epicfaace commented Feb 5, 2022 via email

@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 6, 2022

going straight to ajv 8 might make more sense at the next rjsf version bump

agreed

Another way to think about it, might be to have more of an interface-driven design, as with themes, that hid the ajv-specific exports.

This would potentially offer some trades between size, start-up time, and live performance, such as:

  • for backwards compatibility with draft4, a @rjsf/validator-ajv6
  • on-going effort targeted at improving a @rjsf/validator-ajv8
    • a build could opt for a custom, pre-compiled validator
  • a la ajv dependency size #869, Build size too high #1625 one could use a lighter-weight validator... or a no-op validator

@epicfaace
Copy link
Member

Another way to think about it, might be to have more of an interface-driven design, as with themes, that hid the ajv-specific exports.

That would indeed be nice!

@bollwyvl bollwyvl mentioned this pull request Feb 8, 2022
10 tasks
@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 8, 2022

I've hoisted some of these ideas over here: #2693

@heath-freenome
Copy link
Member

@newt10 Closing this as we have extracted the validation code into its own package(s) which is used as a required plug-in to Form. Also we are now providing an ajv8 based version of the validator see (@rjsf/validator-ajv8)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ajv6 is past EOL, upgrade AJV
6 participants