Skip to content
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

Error when validating with standalone/precompiled function #1837

Open
lance opened this issue Dec 8, 2021 · 4 comments
Open

Error when validating with standalone/precompiled function #1837

lance opened this issue Dec 8, 2021 · 4 comments
Labels

Comments

@lance
Copy link

lance commented Dec 8, 2021

I'd like to precompile my validation functions, and also use some custom formatters but am getting errors when doing so. I've created a project here to illustrate the issue: https://github.com/lance/ajv-test

My schema in schema/schema.json is simple. There is a single time field with a custom format of js-date-time. The format validation code is in schema/formats.js.

I generate the validation function with the command

ajv compile -c ./schema/formats.js -s ./schema/schema.json -o ./schema/validate.js

This can also be run via npm run build for convenience, outputting a nicely formatted JS file.

The code that uses this validation function is in app.js and simply attempts to validate an object with what should be a valid value. When I call validate(), however, I get an error.

TypeError: formats0 is not a function

If you look at the prettified JavaScript generated for the validation function, it's easy to see that, in fact, formats0 is not a function.

const formats0 = {
  _items: ['require("ajv-formats/dist/formats").', { str: "fullFormats" }, ""],
}["js-date-time"];

I'm not sure what I am doing wrong here. Any guidance is appreciated.

What version of Ajv are you using? Does the issue happen if you use the latest version?

8.8.2 - the latest as of this writing

Ajv options object

Called from the CLI with the following options

ajv compile -c ./schema/formats.js -s ./schema/schema.json

JSON Schema

{
  "$ref": "#/definitions/event",
  "definitions": {
    "event": {
      "properties": {
        "time": {
          "$ref": "#/definitions/time"
        }
      },
      "type": "object"
    },
    "time": {
      "format": "js-date-time",
      "type": "string"
    }
  },
  "type": "object"
}

Sample data

{ time: new Date().toString() }

Your code

Please see this simplified test project: https://github.com/lance/ajv-test

Validation result, data AFTER validation, error messages

> node app.js

/home/lanceball/src/github.com/lance/ajv-test/schema/validate.js:37
              if (!formats0(data0)) {
                   ^

TypeError: formats0 is not a function
    at validate21 (/home/lanceball/src/github.com/lance/ajv-test/schema/validate.js:37:20)
    at validate20 (/home/lanceball/src/github.com/lance/ajv-test/schema/validate.js:99:6)
    at Object.<anonymous> (/home/lanceball/src/github.com/lance/ajv-test/app.js:3:6)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
    at node:internal/main/run_main_module:17:47

What results did you expect?

Successful validation of the test object.

Are you going to resolve the issue?

If you tell me how! :)

@lance lance changed the title Standalone validation function error when validating Error when validating with standalone/precompiled function Dec 8, 2021
@epoberezkin
Copy link
Member

epoberezkin commented Dec 8, 2021

There are two ways it can be done with standalone code:

  1. add you format definition to the object with all formats exported by ajv-formats.
  2. Setting code.formats object to point to some other object with all formats definitions (after calling ajv-formats, as it sets it to point to itself).

Both approaches are a bit hacky, but it works.

@lance
Copy link
Author

lance commented Dec 10, 2021

@epoberezkin thanks for the quick response! I'm sorry but I don't really understand either of the suggestions you are making. Can you possibly provide some kind of example code to illustrate this?

@lance
Copy link
Author

lance commented Jan 6, 2022

@epoberezkin ping - bumping this up in your awareness after the holidays and the new year. Any assistance you can provide would be much appreciated. Thanks!

@marcbachmann
Copy link

What @epoberezkin meant is that you just set the format before loading the custom compile function:

require('ajv-formats/dist/formats')['js-date-time'] = {validate, compile}

mcdurdin added a commit to keymanapp/keyman that referenced this issue Oct 5, 2023
ajv seems to have some bugs around precompiling and formats, particularly
when using ESM:

* ajv-validator/ajv#1837
* ajv-validator/ajv-cli#200

Workaround for non-esm works for cloudevents/sdk-javascript#471

So if we want to work with this, we should look at how that is done, but
it is taking too many cycles to pursue for now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants