Ajv-error not compatible with 3.7

I’m using customs ajv-errors.

after update from 3.6 to 3.7 the error messages are no more customs…

my main call looks like ;
<JsonForms

        //i18n={{translate: translator}}

        schema={schemasQuery.data.schema as JsonSchema}

        uischema={schemasQuery.data.uiSchema}

        data={isEmpty(jsonFormData) ? schemasQuery.data.data : jsonFormData}

        renderers={renderers}

        cells={materialCells}

        ajv={xcreateAjv()}

        validationMode="ValidateAndShow"

        onChange={({ data, errors }) => {

          setJsonFormData(data);

          setJsonFormErrors(errors);

        }}

and my ajv.ts containng the xcreateajv is :

import ajvErrors from ‘ajv-errors’;

import { createAjv } from ‘@jsonforms/core’;

const formats = {

email: {

type: 'string', 

validate: (data: string) => /^\[^\\s@\]+@\[^\\s@\]+\\.\[^\\s@\]+$/.test(data),

},

phone: {

type: 'string',

validate: (data: string) => /^\\+\[0-9\]+$/.test(data), 

},

url: {

type: 'string',

validate: (data: string) => /^https:\\/\\/.+/.test(data),

},

linkedin: {

type: 'string', 

validate: (data: string) => /^https:\\/\\/(www\\.)?linkedin\\.com\\/(in|company)\\/\[\\w-\]+\\/?$/.test(data),

},

// reconnaître le format SVG et arrêter les messages d’erreur //////////////////////DO NOT WORK as not in schema (in schemaui)

‘upload-logo’: {

validate: (str: string) => {

  return typeof str === 'string';

},

errorMessageKey: 'validation_svgInvalid',

errorMessage: "URL invalid - must begin with https://",

}

};

export const xcreateAjv = () => {

const myAjv=createAjv({

allErrors: true,

verbose: true,

$data: true, 

strict: false,

messages: true

});

ajvErrors(myAjv);

// Define the totalPercentage keyword

myAjv.addKeyword({

keyword: 'totalPercentage',

type: 'array',

validate: function (schema: any, data: any) {

  if (!Array.isArray(data)) return false; // Ensure data is an array

  const total = data.reduce((sum: number, entry: any) => sum + (entry.percent || 0), 0);

  return total === 100; // Check if total equals 100

},

errors: false, // Set to true if you want to use custom error messages

});

Object.entries(formats).forEach((\[name, format\]) => {

  myAjv.addFormat(name, format.validate);

});

return myAjv;

};

I tried with or without updating ajv package, both failed

which version of ajv should we use?

how should we write with new jsonforms?

Thx a lot!

Hi @clysss , there should not have been an AJV update between 3.6 and 3.7 or at least not a major version one.
Effectively, 3.7.0 uses AJV 8.13.0.
Pre-release version 3.7.0-alpha.0 uses 8.18.0. This is recommended to be used as AJV belo 8.18 has a severe security flaw.

Can you give a whole example to execute and specify which version of ajv errors you use.
It could be worth checking if you updated the ajv errros version with updating to JSON Forms 3.7. Maybe that leads to unexpected behavior.

Best regards,
Lucas

Hello Lucas
,thanks a lot for your message,
Can I send you the files by email?.. including the package.json
Best regards

Hi @clysss ,
sure you can. Note that I will post the solution here though and will mention essential facts (e.g. an installed package version).
If you can, pushing them to a small repo might be even better :slight_smile:
Best regards,
Lucas

Sure, i’ll be happy you put the reply here:)

1 Like

Hi @clysss ,

To summarize the issue to help others that might run into the same issue:

You’re using @jsonforms/core together with ajv-errors and getting a massive type error like this on the ajvErrors(myAjv) call:

Argument of type 'Ajv' is not assignable to parameter of type 'Ajv'.
  Types of property 'opts' are incompatible.
    ...
      Property '_names' is protected but type 'Scope' is not a class derived from 'Scope'.

The root cause is that @jsonforms/core bundles its own nested copy of ajv inside node_modules/@jsonforms/core/node_modules/ajv/. When you call createAjv() from @jsonforms/core, it returns an Ajv instance typed against that internal copy. But ajv-errors (installed at the top level) expects an Ajv instance typed against the top-level ajv. TypeScript sees these as two entirely different and incompatible types, even though they are the same library.

Fix: force deduplication with resolutions when using yarn

In your package.json, add a resolutions field to tell your package manager to use a single version of ajv everywhere:

"resolutions": {
  "ajv": "^8.18.0"
}

After re-installing dependencies, this replaces @jsonforms/core’s nested ajv copy with the top-level one, making both createAjv() and ajv-errors share the same type space.

For me, the error is gone with that.

Hope that helps,
Lucas

Thanks a lot, seems to work now :slight_smile:

1 Like