ajv-keywords icon indicating copy to clipboard operation
ajv-keywords copied to clipboard

generated code is wrong with that schema

Open kapouer opened this issue 3 years ago • 7 comments

EDIT: a simpler schema

{
 "type": "object",
 "properties": {
  "email": { "type": "string", "transform": ["trim"] }
 }
}

gives SyntaxError: Unexpected token ':'.

const schema43 = scope.schema[23];const func0 = scope.func[0];const func86 = scope.func[2];return function validate29(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){let vErrors = null;let errors = 0;if(data && typeof data == "object" && !Array.isArray(data)){for(const key0 of Object.keys(data)){if(!(key0 === "email")){delete data[key0];}}if(data.email !== undefined && func0.call(data, "email")){let data0 = data.email;if(typeof data0 !== "string"){let dataType0 = typeof data0;let coerced0 = undefined;if(dataType0 == 'object' && Array.isArray(data0) && data0.length == 1){data0 = data0[0];dataType0 = typeof data0;if(typeof data0 === "string"){coerced0 = data0;}}if(!(coerced0 !== undefined)){if(dataType0 == "number" || dataType0 == "boolean"){coerced0 = "" + data0;}else if(data0 === null){coerced0 = "";}else {const err0 = {instancePath:instancePath+"/email",schemaPath:"#/properties/email/type",keyword:"type",params:{type: "string"},message:"must be string"};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}}if(coerced0 !== undefined){data0 = coerced0;if(data !== undefined){data["email"] = coerced0;}}}if(typeof {"str":"data0"} == "string" && {"str":"data"} !== undefined){data0 = {"str":"func86","prefix":"func","value":{"code":{"_items":["require(\"ajv-keywords/dist/definitions/transform\").transform",".trim",""]}},"scopePath":{"_items":[".",{"str":"func"},"[",2,"]"]}}({"str":"data0"});{"str":"data"}[{"_items":["","\"email\"",""]}] = data0;}}}else {const err1 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}validate29.errors = vErrors;return errors === 0;}

kapouer avatar Jun 01 '22 18:06 kapouer

Removing transform fixes it...

kapouer avatar Jun 01 '22 18:06 kapouer

It is initialized with

const Ajv = require('ajv');
const AjvKeywords = require('ajv-keywords');
const AjvFormats = require('ajv-formats');
const ajv = new Ajv({strictSchema: false});
AjvFormats(ajv);
AjvKeywords(ajv);

kapouer avatar Jun 01 '22 20:06 kapouer

I'm running into the same issue. The following is the generated code containing the syntax error beautified:

if (typeof {
        "str": "data4"
    } == "string" && {
        "str": "data"
    } !== undefined) {
    data4 = {
        "str": "func4",
        "prefix": "func",
        "value": {
            "code": {
                "_items": ["require(\"ajv-keywords/dist/definitions/transform\").transform", ".toLowerCase", ""]
            }
        },
        "scopePath": {
            "_items": [".", {
                "str": "func"
            }, "[", 2, "]"]
        }
    }({
        "str": "func5",
        "prefix": "func",
        "value": {
            "code": {
                "_items": ["require(\"ajv-keywords/dist/definitions/transform\").transform", ".trim", ""]
            }
        },
        "scopePath": {
            "_items": [".", {
                "str": "func"
            }, "[", 3, "]"]
        }
    }({
        "str": "data4"
    })); {
        "str": "data"  // Syntax error here: Unexpected ":", expected
    } [{
        "_items": ["", "\"email\"", ""]semicolon
    }] = data4;
}

I can't really make sense of this code – no idea what these free-floating objects are supposed to do.

The syntax error happens where an object literal is defined but because there is no const or let it gets parsed as a statement block, so the parser chokes on the :.

I'm using [email protected] and [email protected].

felixfbecker avatar Apr 24 '23 17:04 felixfbecker

I have some issue. Do you have any ideas for solving this?

tequila99 avatar Jul 24 '23 07:07 tequila99

I am seeing the same issue with [email protected] and [email protected] (and also at 5.0.0). It's being used together with objection.js.

Removing keywords(ajv) fixes the issue, and the syntax error is the exact same as reported by @felixfbecker above.

aorsten avatar Aug 31 '23 06:08 aorsten

I have also tried returning to ajv-keywords specific peerDependency of [email protected], but that also does not work, unfortunately.

Has transform worked at all with ajv 8?

aorsten avatar Aug 31 '23 17:08 aorsten

I believe I have solved it on my end. The issue for me has been that I'm using ajv and ajv-keywords inside a monorepo, where multiple packages are using ajv. Basically the issue has been that the "ajv" package was installed multiple times within node_modules. I have solved it by using the overrides keyword in package.json and also installing ajv at the top level package.json of my monorepo. (Caveat: overrides only work in top-level package, not each sub-package).

So my new package.json looks something like this:

// package.json

{
  // (...)
  "dependencies": {
    "ajv": "8.8.2"
  },
  
  "overrides": {
    "some-package-i-use": {
      "ajv": "$ajv"
    },
    "ajv-formats": {
      "ajv": "$ajv"
    },
    "ajv-keywords": {
      "ajv": "$ajv"
    }
  },

I am now going to retry using the latest ajv version, which I expect will work just as well, so long as every package uses the same installation of ajv.

aorsten avatar Sep 01 '23 13:09 aorsten