-
-
Notifications
You must be signed in to change notification settings - Fork 877
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
【BUG】removeAdditional will remove the valid properties #264
Comments
That is not a bug, it is correct behaviour. Please see #129 and also #140. The problem here is that "additional properties" are meant in the sense of The solution is not to use To remove not allowed properties properties in widget you can whitelist all properties on the top level (that may still pass through properties from invalid branch of oneOf). The alternative solution is to use {
"switch": [
{
"if": { "properties": { "widgetType": { "constant": "pic" } } },
"then": { /*schema for "pic" widget, should include "additionalProperties": false */ }
},
{
"if": { "properties": { "widgetType": { "constant": "text" } } },
"then": { /*schema for "text" widget, should include "additionalProperties": false */ }
},
// ...
]
} Make sure to use |
@epoberezkin in my example, it seems that Ajv matched the wrong schema, if with "widgets": {"type":"array","default":[],"items":{"oneOf":[{"type":"object","required":["DATAREF_ID"],"properties":{"type":{"type":"string","default":"widget","enum":["widget"]},"title":{"type":"string","default":"艺术字"},"widgetType":{"type":"string","default":"artword","enum":["artword"]},"attr":{"type":"object","default":{},"properties":{"text":{"type":"string","default":"请在右侧更改文字"},"retUrl":{"type":["string","null"],"default":""}}},"textStyle":{"type":"object","default":{},"properties":{"color":{"type":"string","default":"#000"},"font-family":{"type":"string","default":"微软雅黑"},"font-size":{"type":["number","string"],"default":"24px"},"text-decoration":{"type":"string","default":"none"}}},"style":{"type":"object","default":{},"properties":{"z-index":{"type":"integer","default":1},"left":{"type":["number"],"default":0},"top":{"type":["number"],"default":0},"width":{"type":["number"],"default":200},"height":{"type":["number"],"default":100},"background-color":{"type":"string","default":"transparent"},"border-style":{"type":"string"},"border-width":{"type":["number"]},"border-color":{"type":"string"},"border-radius":{"type":["number"]},"transform":{"type":"string","default":"none"}}},"single":{"type":["number"],"default":0},"DATAREF_ID":{"type":["number"]},"info":{"type":"object","default":{}}}}]}} it will not remove the |
Ajv is not matching sub-schemas, it simply removes additional properties as each sub-schema is validated, whether this subschema is valid or not. "Additional property" is understood in the same meaning as the standard uses for "additionalProperties" keyword - local to the current subschema (not used in "properties" and "patrernProperties" keyword in the current schema object only), not global to the whole schema as in "used in some other place of the schema". If you add a property in all sub-schemas it won't be additional in any of them, so it won't be removed. I have suggested several approaches that would work for you, there is nothing that has to be changed in Ajv. I will probably add some example to clarify it. |
I mean with Also there is example in readme already that shows exactly your situation and shows how to construct the schema correctly - see Filtering Data section. |
I also tested that it seems
it means this behavior is the |
Yes
Removing additional properties is ajv feature, it's not the part of the standard. But it relies on the definition of "additional property" in the standard. "oneOf" must validate all subschemas so all additional properties will be removed. "switch" only validates "then" subschemas that pass "if" test, so you have better control which properties will be considered additional. But have a look at the example in readme, this approach will also work in your case. |
@epoberezkin Got it, Thanks for your patient! |
@epoberezkin i have tried switch, but a weird problem comes. {"type":"object","required":["idCounter"],"properties":{"LAYJSON_VERSION":{"type":["number"],"default":""},"idCounter":{"type":["number"]},"components":{"type":"array","default":[],"items":{"type":"object","required":["DATAREF_ID"],"properties":{"_id":{"type":["number","null"]},"_setting":{"oneOf":[{"type":"object","properties":{"TagId":{"type":["number"],"default":null}}},{"type":"null"}]},"title":{"type":["string"],"default":"新建模块"},"description":{"type":["string","null"],"default":null},"type":{"type":"string","default":"component","enum":["component"]},"style":{"type":"object","default":{},"properties":{"z-index":{"type":"integer","default":0},"height":{"type":["number","string"],"default":200},"background-color":{"type":["string"],"default":"transparent"},"background-size":{"type":["string"],"default":"100% 100%"},"background-repeat":{"type":"string","default":"no-repeat","enum":["no-repeat","repeat"]}}},"show":{"type":"boolean","default":true},"attr":{"type":"object","default":{},"properties":{"bgUrl":{"type":["string","null"],"default":""}}},"widgets":{"type":"array","default":[],"items":{"switch":[{"if":{"properties":{"widgetType":{"constant":"artword"}}},"then":{"type":"object","required":["DATAREF_ID"],"properties":{"type":{"type":"string","default":"widget","constant":"widget"},"title":{"type":"string","default":"艺术字"},"widgetType":{"type":"string","default":"artword","constant":"artword"},"attr":{"type":"object","default":{},"properties":{"text":{"type":"string","default":"请在右侧更改文字"},"retUrl":{"type":["string","null"],"default":""}}},"textStyle":{"type":"object","default":{},"properties":{"color":{"type":"string","default":"#000"},"font-family":{"type":"string","default":"微软雅黑"},"font-size":{"type":["number","string"],"default":"24px"},"text-decoration":{"type":"string","default":"none"}}},"style":{"type":"object","default":{},"properties":{"z-index":{"type":"integer","default":1},"left":{"type":["number","string"],"default":0},"top":{"type":["number","string"],"default":0},"width":{"type":["number","string"],"default":200},"height":{"type":["number","string"],"default":100},"background-color":{"type":"string","default":"transparent"},"border-style":{"type":"string"},"border-width":{"type":["number","string"]},"border-color":{"type":"string"},"border-radius":{"type":["number","string"]},"transform":{"type":"string","default":"none"}}},"single":{"type":["number"],"default":0},"DATAREF_ID":{"type":["number"]},"info":{"type":"object","default":{}}}}}]}},"single":{"type":["number"],"default":0},"DATAREF_ID":{"type":["number"]},"info":{"type":"object","default":{}}}}}}} the options includes: var ajv = new Ajv({
v5: true,
coerceTypes: true,
useDefaults: true,
removeAdditional: 'all'
}); the json for validating: var json = ; then validated failed with: [{"keyword":"required","dataPath":".components[0].widgets[0]","schemaPath":"#/properties/components/items/properties/widgets/items/switch/0/then/required","params":{"missingProperty":"DATAREF_ID"},"message":"should have required property 'DATAREF_ID'"}] BUT the |
Can you make a smaller sample please? |
@epoberezkin I made a smaller testing scripts at: https://jsfiddle.net/ppoo24/fckyt5rm/ , i have formatted and simplified the json and schema, the error happened as usual |
All properties get removed when |
The properties you see in the final json are defaults (from |
@epoberezkin So when executing |
Ajv does nothing but validation. There is a schema inside
For any moderately complex schema
|
Maybe |
@epoberezkin appreciate your answer! i'm using |
@ppoo24 Could you shorten your code sample please? It makes the issue a pain to read 😅. Thanks! |
@ngryman sorry about that |
The json schema:
The json value for testing:
Then validate with option
removeAdditional: 'all'
, the result json below:Let us just focus on the datapath:
components[0].widgets[0]
, when using the schema to validate the testing value, the propertytextStyle
will be unproper removed.the right logic should be matching the scheme of
widget - artword
(which has defined the property -textStyle
).I guess Ajv was just trying to match the one with less properties, when matched, with option
removeAdditional: 'all'
, it will remove the extra properties (in this situation, the validtextStyle
was removed).This became a big problem, made losing more users' data in production environment.
May provide a solution?
The text was updated successfully, but these errors were encountered: