ajv-keywords
ajv-keywords copied to clipboard
generated code is wrong with that schema
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;}
Removing transform fixes it...
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);
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].
I have some issue. Do you have any ideas for solving this?
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.
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?
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.