validation not working (invalid data accepted) when a schema is defined using shell process substitution/named pipes
The bash shell has a feature called process substitution (details below) which allows creating named pipes.
ajv (CLI) does not appear to work well with such named pipes
$ ajv validate -s <(longer pipeline that yield a JSON or YAML schema) <(longer pipeline that yield a JSON or YAML data file)
/dev/fd/62 valid
this shows the data is valid, even when it does not satisfy the schema.
Rewritten in a way that should be equivalent from a bash script yields different ajv results:
$ (longer pipeline that yield a JSON or YAML schema) > schema.json
$ (longer pipeline that yield a JSON or YAML data file) > data.json
$ ajv validate -s schema.json -d data.json
data.json invalid
[
{
instancePath: '/info/breakingChanges',
schemaPath: '#/properties/info/properties/breakingChanges/const',
keyword: 'const',
params: { allowedValue: true },
message: 'must be equal to constant'
}
]
Here's a simpler use case
Save the attached files, which unfortunately GitHub required me to rename with .txt extensions, so rename with
$ mv schema.yaml.txt schema.yaml
$ mv data.yaml.txt data.yaml
)
Use the shell and js-yaml to convert the files from YAML to JSON:
$ npm i -g ajv-cli js-yaml # Install if you don't already have these commands
$ ajv --spec=draft2020 validate -s <(js-yaml schema.yaml) -d <(js-yaml data.yaml)
/dev/fd/62 valid
Even though data.yaml is invalid (as per schema.yaml), this command incorrectly shows the file as valid.
(here, /dev/fd/62 is the named pipe for the pipeline js-yaml data.yaml )
Running ajv directly
$ ajv --spec=draft2020 validate -s schema.yaml -d data.yaml
data.yaml invalid
[
{
instancePath: '/info/breakingChanges',
schemaPath: '#/properties/info/properties/breakingChanges/const',
keyword: 'const',
params: { allowedValue: true },
message: 'must be equal to constant'
}
]
In situations where longer pipelines are used to derive the schema (i.e. text pipelines on YAML or other content ) and a schema.yaml or schema.json file is not directly available, I think ajv should work with named pipes
ajv validate -s <(longer pipeline that yield a JSON or YAML schema) <(longer pipeline that yield a JSON or YAML data file)
without having to resort to temp files that one must then clean up/manage etc.
From the bash(1) man page:
Process Substitution
Process substitution allows a process's input or output to be
referred to using a filename. It takes the form of <(list) or
>(list). The process list is run asynchronously, and its input
or output appears as a filename. This filename is passed as an
argument to the current command as the result of the expansion.
I came back here to check on the status of this.... and realized I forgot to upload the files. Doing so now.
As noted above, rename these as schema.yaml and data.yaml then try
ajv --spec=draft2020 validate -s <(js-yaml schema.yaml) -d <(js-yaml data.yaml)
while ajv can natively process yaml files, please consider other pipelines other than just js-yaml (for example, output of jq or many other command line tools)