{"id":23580688,"url":"https://github.com/for-get/jesse","last_synced_at":"2025-05-16T12:12:09.995Z","repository":{"id":2811820,"uuid":"47450647","full_name":"for-GET/jesse","owner":"for-GET","description":"jesse (JSon Schema Erlang) is an implementation of a JSON Schema validator for Erlang.","archived":false,"fork":false,"pushed_at":"2024-09-03T16:11:43.000Z","size":7328,"stargazers_count":128,"open_issues_count":15,"forks_count":65,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-16T12:12:06.094Z","etag":null,"topics":["erlang","json-schema"],"latest_commit_sha":null,"homepage":"https://github.com/for-get/jesse","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/for-GET.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-05T09:50:17.000Z","updated_at":"2025-04-14T03:46:40.000Z","dependencies_parsed_at":"2024-01-17T00:55:11.297Z","dependency_job_id":"e9fbd29f-47b6-4c82-a8cd-3a1f567351b3","html_url":"https://github.com/for-GET/jesse","commit_stats":{"total_commits":490,"total_committers":37,"mean_commits":"13.243243243243244","dds":0.563265306122449,"last_synced_commit":"26cf7ea166f7bc720be90abd3530962935801b0c"},"previous_names":[],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fjesse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fjesse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fjesse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/for-GET%2Fjesse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/for-GET","download_url":"https://codeload.github.com/for-GET/jesse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254527099,"owners_count":22085919,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["erlang","json-schema"],"created_at":"2024-12-27T00:11:39.018Z","updated_at":"2025-05-16T12:12:09.970Z","avatar_url":"https://github.com/for-GET.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jesse [![Build Status][2]][1]\n\njesse (JSON Schema Erlang) is an implementation of a JSON Schema validator\nfor Erlang, though it can work just as well as a CLI tool.\n\njesse implements the following specifications:\n\n* [Draft 03](http://tools.ietf.org/html/draft-zyp-json-schema-03)\n* [Draft 04](http://tools.ietf.org/html/draft-zyp-json-schema-04)\n* [Draft 06](https://datatracker.ietf.org/doc/html/draft-wright-json-schema-00)\n\nInstall from git or https://hex.pm/packages/jesse .\n\nFor convenience, [available as a Docker image too](https://hub.docker.com/r/ysoftwareab/jesse): `docker run --rm -it -v $PWD:$PWD -w $PWD ysoftwareab/jesse ...`.\n\nAnd [whalebrew package](https://github.com/whalebrew/whalebrew): `brew install whalebrew \u0026\u0026 sudo whalebrew install ysoftwareab/jesse; jesse ...`\n\n## Erlang API Docs\n\nAutomatically generated docs are available https://dev.erldocs.com/github.com/for-get/jesse/ .\n\nPlease keep in mind that the public API is the `jesse.erl` module alone.\n\n## Command-Line Interface\n\nYou can either build the `bin/jesse` executable yourself (just type `make`),\nor you can use a Docker image a call it with `docker run ysoftwareab/jesse`.\n\nYou can fire up `jesse` from the CLI, with\n```bash\nbin/jesse [path_to_json_schema] path_to_json_schema -- path_to_json_instance [path_to_json_instance]\n```\n\nYou can also output the result in JSON format, with `--json`, and beautify it e.g. with python\n```bash\nbin/jesse [path_to_json_schema] path_to_json_schema --json -- path_to_json_instance [path_to_json_instance] | python -m json.tool\n```\n\nYou can pass multiple JSON schemas which should be loaded into jesse in-memory storage, but JSON instances will be validated against the last JSON schema passed.\n\n## Erlang Interface\n\nThere are two ways of using jesse:\n\n* to use jesse internal in-memory storage to keep all your schema definitions\n  In this case jesse will look up a schema definition in its own storage,\n  and then validate given a JSON instance.\n* it is also possible to provide jesse with schema definitions when jesse is called.\n\n## Examples\n\n    NOTE: jesse doesn't have any parsing functionality. It currently works with four\n          formats: mochijson2, jiffy, jsx and Erlang 17+ maps, so JSON needs to be\n          parsed in advance, or you can specify a callback which jesse will use to\n          parse JSON.\n\n          In examples below and in jesse test suite jiffy parser is used.\n\n* Use jesse's internal in-memory storage:\n\n(parse JSON in advance)\n\n```erlang\n1\u003e Schema = jiffy:decode(\u003c\u003c\"{\\\"items\\\": {\\\"type\\\": \\\"integer\\\"}}\"\u003e\u003e).\n{[{\u003c\u003c\"items\"\u003e\u003e,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"integer\"\u003e\u003e}]}}]}\n2\u003e jesse:add_schema(\"some_key\", Schema).\nok\n3\u003e Json1 = jiffy:decode(\u003c\u003c\"[1, 2, 3]\"\u003e\u003e).\n[1,2,3]\n4\u003e jesse:validate(\"some_key\", Json1).\n{ok,[1,2,3]}\n5\u003e Json2 = jiffy:decode(\u003c\u003c\"[1, \\\"x\\\"]\"\u003e\u003e).\n[1,\u003c\u003c\"x\"\u003e\u003e]\n6\u003e jesse:validate(\"some_key\", Json2).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"integer\"\u003e\u003e}]},\n                      wrong_type,\u003c\u003c\"x\"\u003e\u003e,\n                      [1]}]}\n```\n\nThe `[1]` in the error is the path in the original value to `\u003c\u003c\"x\"\u003e\u003e` where the\nvalidation failed. See *Validation errors* below for the full error format.\n\n(using a callback)\n\n```erlang\n1\u003e jesse:add_schema(\"some_key\",\n1\u003e                  \u003c\u003c\"{\\\"uniqueItems\\\": true}\"\u003e\u003e,\n1\u003e                  [{parser_fun, fun jiffy:decode/1}]).\nok\n2\u003e jesse:validate(\"some_key\",\n2\u003e                \u003c\u003c\"[1, 2]\"\u003e\u003e,\n2\u003e                [{parser_fun, fun jiffy:decode/1}]).\n{ok,[1, 2]}\n3\u003e jesse:validate(\"some_key\",\n3\u003e                \u003c\u003c\"[{\\\"foo\\\": \\\"bar\\\"}, {\\\"foo\\\": \\\"bar\\\"}] \"\u003e\u003e,\n3\u003e                [{parser_fun, fun jiffy:decode/1}]).\n{error,[{data_invalid,{[{\u003c\u003c\"uniqueItems\"\u003e\u003e,true}]},\n                      {not_unique,{[{\u003c\u003c\"foo\"\u003e\u003e,\u003c\u003c\"bar\"\u003e\u003e}]}},\n                      [{[{\u003c\u003c\"foo\"\u003e\u003e,\u003c\u003c\"bar\"\u003e\u003e}]},{[{\u003c\u003c\"foo\"\u003e\u003e,\u003c\u003c\"bar\"\u003e\u003e}]}],\n                      []}]}\n```\n\n* Call jesse with schema definition in place (do not use internal storage)\n\n(parse JSON in advance)\n\n```erlang\n1\u003e Schema = jiffy:decode(\u003c\u003c\"{\\\"pattern\\\": \\\"^a*$\\\"}\"\u003e\u003e).\n{[{\u003c\u003c\"pattern\"\u003e\u003e,\u003c\u003c\"^a*$\"\u003e\u003e}]}\n2\u003e Json1 = jiffy:decode(\u003c\u003c\"\\\"aaa\\\"\"\u003e\u003e).\n\u003c\u003c\"aaa\"\u003e\u003e\n3\u003e jesse:validate_with_schema(Schema, Json1).\n{ok,\u003c\u003c\"aaa\"\u003e\u003e}\n4\u003e Json2 = jiffy:decode(\u003c\u003c\"\\\"abc\\\"\"\u003e\u003e).\n\u003c\u003c\"abc\"\u003e\u003e\n5\u003e jesse:validate_with_schema(Schema, Json2).\n{error,[{data_invalid,{[{\u003c\u003c\"pattern\"\u003e\u003e,\u003c\u003c\"^a*$\"\u003e\u003e}]},\n                      no_match,\n                      \u003c\u003c\"abc\"\u003e\u003e,[]}]}\n```\n\n(using a callback)\n\n```erlang\n1\u003e Schema = \u003c\u003c\"{\\\"patternProperties\\\": {\\\"f.*o\\\": {\\\"type\\\": \\\"integer\\\"}}}\"\u003e\u003e.\n\u003c\u003c\"{\\\"patternProperties\\\": {\\\"f.*o\\\": {\\\"type\\\": \\\"integer\\\"}}}\"\u003e\u003e\n2\u003e jesse:validate_with_schema(Schema,\n2\u003e                            \u003c\u003c\"{\\\"foo\\\": 1, \\\"foooooo\\\" : 2}\"\u003e\u003e,\n2\u003e                            [{parser_fun, fun jiffy:decode/1}]).\n{ok,{[{\u003c\u003c\"foo\"\u003e\u003e,1},{\u003c\u003c\"foooooo\"\u003e\u003e,2}]}}\n3\u003e jesse:validate_with_schema(Schema,\n3\u003e                            \u003c\u003c\"{\\\"foo\\\": \\\"bar\\\", \\\"fooooo\\\": 2}\"\u003e\u003e,\n3\u003e                            [{parser_fun, fun jiffy:decode/1}]).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"integer\"\u003e\u003e}]},\n                      wrong_type,\u003c\u003c\"bar\"\u003e\u003e,\n                      [\u003c\u003c\"foo\"\u003e\u003e]}]}\n```\n\n* Since 0.4.0 it's possible to instruct jesse to collect errors, and not stop\n  immediately when it finds an error in the given JSON instance:\n\n```erlang\n1\u003e Schema = \u003c\u003c\"{\\\"properties\\\": {\\\"a\\\": {\\\"type\\\": \\\"integer\\\"}, \\\"b\\\": {\\\"type\\\": \\\"string\\\"}, \\\"c\\\": {\\\"type\\\": \\\"boolean\\\"}}}\"\u003e\u003e.\n\u003c\u003c\"{\\\"properties\\\": {\\\"a\\\": {\\\"type\\\": \\\"integer\\\"}, \\\"b\\\": {\\\"type\\\": \\\"string\\\"}, \\\"c\\\": {\\\"type\\\": \\\"boolean\\\"}}}\"\u003e\u003e\n2\u003e jesse:validate_with_schema(Schema,\n2\u003e                            \u003c\u003c\"{\\\"a\\\": 1, \\\"b\\\": \\\"b\\\", \\\"c\\\": true}\"\u003e\u003e,\n2\u003e                            [{parser_fun, fun jiffy:decode/1}]).\n{ok,{[{\u003c\u003c\"a\"\u003e\u003e,1},{\u003c\u003c\"b\"\u003e\u003e,\u003c\u003c\"b\"\u003e\u003e},{\u003c\u003c\"c\"\u003e\u003e,true}]}}\n```\n\nnow let's change the value of the field \"b\" to an integer\n\n```erlang\n3\u003e jesse:validate_with_schema(Schema,\n3\u003e                            \u003c\u003c\"{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": true}\"\u003e\u003e,\n3\u003e                            [{parser_fun, fun jiffy:decode/1}]).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"string\"\u003e\u003e}]},\n                      wrong_type,2,\n                      [\u003c\u003c\"b\"\u003e\u003e]}]}\n```\n\nworks as expected, but let's change the value of the field \"c\" as well\n\n```erlang\n4\u003e jesse:validate_with_schema(Schema,\n4\u003e                            \u003c\u003c\"{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": 3}\"\u003e\u003e,\n4\u003e                            [{parser_fun, fun jiffy:decode/1}]).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"string\"\u003e\u003e}]},\n                      wrong_type,2,\n                      [\u003c\u003c\"b\"\u003e\u003e]}]}\n```\n\nstill works as expected, jesse stops validating as soon as finds an error.\n\nLet's use the `allowed_errors` option, and set it to 1\n\n```erlang\n5\u003e jesse:validate_with_schema(Schema,\n5\u003e                            \u003c\u003c\"{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": 3}\"\u003e\u003e,\n5\u003e                            [{parser_fun, fun jiffy:decode/1},\n5\u003e                             {allowed_errors, 1}]).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"boolean\"\u003e\u003e}]},\n                      wrong_type,3,\n                      [\u003c\u003c\"c\"\u003e\u003e]},\n        {data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"string\"\u003e\u003e}]},\n                      wrong_type,2,\n                      [\u003c\u003c\"b\"\u003e\u003e]}]}\n```\n\nnow we got a list of two errors.\n\nLet's now change the value of the field \"a\" to a boolean\n\n```erlang\n6\u003e jesse:validate_with_schema(Schema,\n6\u003e                            \u003c\u003c\"{\\\"a\\\": true, \\\"b\\\": 2, \\\"c\\\": 3}\"\u003e\u003e,\n6\u003e                            [{parser_fun, fun jiffy:decode/1},\n6\u003e                             {allowed_errors, 1}]).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"string\"\u003e\u003e}]},\n                      wrong_type,2,\n                      [\u003c\u003c\"b\"\u003e\u003e]},\n        {data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"integer\"\u003e\u003e}]},\n                      wrong_type,true,\n                      [\u003c\u003c\"a\"\u003e\u003e]}]}\n```\n\nwe still got only two errors.\n\nLet's try using 'infinity' as the argument for the `allowed_errors` option\n\n```erlang\n7\u003e jesse:validate_with_schema(Schema,\n7\u003e                            \u003c\u003c\"{\\\"a\\\": true, \\\"b\\\": 2, \\\"c\\\": 3}\"\u003e\u003e,\n7\u003e                            [{parser_fun, fun jiffy:decode/1},\n7\u003e                             {allowed_errors, infinity}]).\n{error,[{data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"boolean\"\u003e\u003e}]},\n                      wrong_type,3,\n                      [\u003c\u003c\"c\"\u003e\u003e]},\n        {data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"string\"\u003e\u003e}]},\n                      wrong_type,2,\n                      [\u003c\u003c\"b\"\u003e\u003e]},\n        {data_invalid,{[{\u003c\u003c\"type\"\u003e\u003e,\u003c\u003c\"integer\"\u003e\u003e}]},\n                      wrong_type,true,\n                      [\u003c\u003c\"a\"\u003e\u003e]}]}\n```\n\nMaps example\n\n```erlang\n8\u003e jesse:validate_with_schema(Schema,\n8\u003e                            \u003c\u003c\"{\\\"a\\\": 1, \\\"b\\\": 2, \\\"c\\\": true}\"\u003e\u003e,\n8\u003e                            [{parser_fun, fun(Bin) -\u003e jiffy:decode(Bin, [return_maps]) end}]).\n{error,[{data_invalid,#{\u003c\u003c\"type\"\u003e\u003e =\u003e \u003c\u003c\"string\"\u003e\u003e},\n                      wrong_type,2,\n                      [\u003c\u003c\"b\"\u003e\u003e]}]}\n9\u003e jesse:validate_with_schema(Schema,\n9\u003e                            \u003c\u003c\"{\\\"a\\\": 1, \\\"b\\\": \\\"val\\\", \\\"c\\\": true}\"\u003e\u003e,\n9\u003e                            [{parser_fun, fun(Bin) -\u003e jiffy:decode(Bin, [return_maps]) end}]).\n{ok, #{\u003c\u003c\"a\"\u003e\u003e =\u003e 1, \u003c\u003c\"b\"\u003e\u003e =\u003e \u003c\u003c\"val\"\u003e\u003e, \u003c\u003c\"c\"\u003e\u003e =\u003e true}}\n```\n\n## JSON Schema versions\n\njesse currently supports JSON Schema draft3, draft4 and draft6. To decide which\nvalidator to use jesse tries to read `$schema` property from the given schema,\nand checks if it's a supported one, otherwise it will return an error.\nIf `$schema` property isn't provided in the given schema, jesse will use the\ndefault validator (currently the validator for draft3).\n\nTo specify which validator to use by default (if there's no `schema` property in\nthe given schema), one should use 'default_schema_ver' option when call\n`jesse:validate/3` or `jesse:validate_with_schema/3`, the value should be\na binary consisting a schema path,\n i.e. \u003c\u003c\"http://json-schema.org/draft-03/schema#\"\u003e\u003e.\n\n## Validation errors\n\nThe validation functions `jesse:validate/2` and `jesse:validate_with_schema/2,3`\nreturn `{ok, Value}` on success and `{error, ListOfErrors}` on failure. An error\nis either `data_invalid` or `schema_invalid`.\n\nA `data_invalid` error is a tuple on the form `{data_invalid, Schema, ErrorType,\nValue, Path}` where\n\n* Schema is the part of the schema where validation failed\n* ErrorType is the type of error, usually an atom such as `wrong_type`,\n  `not_in_range` or `no_match`\n* Value is The part of the value where failed validation against Schema\n* Path is a path to where validation failed within the original value. The path\n  is a list of property names and zero-based array indices referencing the\n  properties and array items within a JSON document; e.g. in the JSON document\n  `{\"foo\": [42, 43, 44]}`, the path `[\u003c\u003c\"foo\"\u003e\u003e, 0]` refers to the value 42. An\n  empty list refers to the whole JSON document.\n\nA `schema_invalid` error is a tuple on the form `{schema_invalid, Schema,\nErrorType}` where\n* Schema is the part of the schema which is invalid\n* ErrorType is an atom such as `missing_id_field` or a tuple such as\n  `{wrong_type_dependency, Dependency}`.\n\n## Caveats\n\n* pattern and patternProperty attributes:\n\n  jesse uses standard erlang module `re` for regexp matching, therefore there\n  could be some incompatible regular expressions in schemas you define.\n\n  From the [erlang docs](https://www.erlang.org/doc/man/re.html#description):\n\n  \u003e The matching algorithms of the library are based on the PCRE library, but\n  \u003e not all of the PCRE library is interfaced and some parts of the library go\n  \u003e beyond what PCRE offers.\n\n  Most common cases should work fine. Note that jesse provides an application\n  environment setting, `re_options` (default: `[unicode, ucp]`), for customizing\n  its use of the `re` module. `ucp` provides the widest compatibility for\n  matching unicode code points beyond ISO Latin-1 in character classes like\n  `\\w`, `\\s`, and `\\d`, but hurts performance. If maximum compatibility is not\n  required and performance is a significant concern, set `re_options` to\n  `[unicode]` instead. See notes on the `ucp` option at\n  [`re:compile/2`](https://www.erlang.org/doc/man/re.html#compile-2) for more\n  details.\n\n* internal references (id attribute) are NOT supported\n\n  http://json-schema.org/latest/json-schema-core.html#rfc.section.8.2.1\n\n## Contributing\n\nIf you see something missing or incorrect, a pull request is most welcome!\n\n## License\n\n[Apache 2.0](LICENSE)\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/for-GET/jesse.svg)](https://starchart.cc/for-GET/jesse)\n\n  [1]: https://github.com/for-GET/jesse/actions?query=workflow%3ACI+branch%3Amaster\n  [2]: https://github.com/for-GET/jesse/workflows/CI/badge.svg?branch=master\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffor-get%2Fjesse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffor-get%2Fjesse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffor-get%2Fjesse/lists"}