{"id":19544748,"url":"https://github.com/flagpolejs/json-validator","last_synced_at":"2026-04-16T17:07:27.166Z","repository":{"id":143749098,"uuid":"398924748","full_name":"flagpolejs/json-validator","owner":"flagpolejs","description":null,"archived":false,"fork":false,"pushed_at":"2021-09-12T16:52:20.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-05T07:32:31.054Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flagpolejs.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-22T23:50:09.000Z","updated_at":"2021-09-12T16:52:23.000Z","dependencies_parsed_at":"2023-07-22T18:01:54.320Z","dependency_job_id":null,"html_url":"https://github.com/flagpolejs/json-validator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/flagpolejs/json-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagpolejs%2Fjson-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagpolejs%2Fjson-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagpolejs%2Fjson-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagpolejs%2Fjson-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flagpolejs","download_url":"https://codeload.github.com/flagpolejs/json-validator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flagpolejs%2Fjson-validator/sbom","scorecard":{"id":402411,"data":{"date":"2025-08-11","repo":{"name":"github.com/flagpolejs/json-validator","commit":"969bac660de1a679457097127871962f53f5217a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/3 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-18T20:22:20.919Z","repository_id":143749098,"created_at":"2025-08-18T20:22:20.920Z","updated_at":"2025-08-18T20:22:20.920Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285101683,"owners_count":27115042,"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","status":"online","status_checked_at":"2025-11-18T02:00:05.759Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-11T03:31:21.888Z","updated_at":"2025-11-18T17:03:16.674Z","avatar_url":"https://github.com/flagpolejs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# json-validator\n\nThis validator allows you to test whether a given JSON response matches this defined structure.\n\nThe format is very similar to the popular JSON Schema [https://json-schema.org/] format. However, it could be difficult to read and write manually. For basic formats, we can get away with something easier. This library was created to be small in size, not designing for every possible use case (but covering the most common ones), being legible, and able to be manually written.\n\n## Getting Started and the Schema\n\nIn its simplest form you can just define an object with properties of the JSON property names and strings with the type.\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    isActive: \"boolean\",\n    teams: \"array\",\n  },\n};\n```\n\nThis would match a JSON body like this:\n\n```javascript\n{\n    id: 5,\n    firstName: \"George\",\n    lastName: \"Brett\",\n    isActive: false,\n    teams: [\n        \"Kansas City Royals\"\n    ]\n}\n```\n\nWhenever we define a value in our schema as a string, we are defining its type. Technically, we could use a more verbose schema definition for the same thing, like this:\n\n```javascript\nconst schema = {\n  properties: {\n    id: { type: \"number\" },\n    firstName: { type: \"string\" },\n    lastName: { type: \"string\" },\n    isActive: { type: \"boolean\" },\n    teams: { type: \"array\" },\n  },\n};\n```\n\nBut there really is no point in doing that if we simply want to verify the type.\n\nThe above works well for a flat structure, but when we start to get nested with arrays or objects then what? Well the next step is we want to make sure every team listed inside the `teams` array of our JSON body above is a string. Here's how we can do that.\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    isActive: \"boolean\",\n    teams: {\n      type: \"array\",\n      items: \"string\",\n    },\n  },\n};\n```\n\nFor our teams property, we used that object notation check that it was an array with the `type` property. But we also see the `items` property. Setting this to a string value will verify that each item in the array is a string. Obviously you could put \"number\" or \"boolean\" or whatever other type there in that `items` property to test that every element in the array is that type.\n\nBut what if our JSON structure was more complicated? What if the array contained objects with multiple properties? Let's assume our JSON body is this...\n\n```javascript\n{\n    id: 5,\n    firstName: \"George\",\n    lastName: \"Brett\",\n    isActive: false,\n    teams: [\n        {\n            name: \"Kansas City Royals\"\n            firstSeason: 1973,\n            lastSeason: 1994\n        }\n    ]\n}\n```\n\nWe would define this schema like this:\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    isActive: \"boolean\",\n    teams: {\n      type: \"array\",\n      items: {\n        type: \"object\",\n        properties: {\n          name: \"string\",\n          firstSeason: \"number\",\n          lastSeason: \"number\",\n        },\n      },\n    },\n  },\n};\n```\n\nSo, rather than setting `items` to a string, this time we set it to another object. This effectively is a nested sub-schema. We could keep going with this as deep as we needed to go.\n\nAlright great. George Brett is long retired, so he has a `firstSeason` and `lastSeason` property. However, let's say in our schema that if a player is currently active the `lastSeason` property will be absent from the response. We still want to make sure that if it is present it is a number. But we don't want our schema to fail if it's not there.\n\nThis is where the `optional` property comes in.\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    isActive: \"boolean\",\n    teams: {\n      type: \"array\",\n      items: {\n        type: \"object\",\n        properties: {\n          name: \"string\",\n          firstSeason: \"number\",\n          lastSeason: {\n            type: \"number\",\n            optional: true,\n          },\n        },\n      },\n    },\n  },\n};\n```\n\nWell that was easy! Okay, that works when the field is absent for active players. What if lastSeason is always there, but instead it is `null` when they are still active? No problemo!\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    isActive: \"boolean\",\n    teams: {\n      type: \"array\",\n      items: {\n        type: \"object\",\n        properties: {\n          name: \"string\",\n          firstSeason: \"number\",\n          lastSeason: [\"number\", \"null\"],\n        },\n      },\n    },\n  },\n};\n```\n\nIf we set any of our properties to an array of strings, instead of a string, the schema will verify that it is one of those types.\n\nLet's keep amping up the game. Now, rather than just the type, we also want our schema to have an opinion on the actual value. So first, let's start when there are a small set of allowed values. For example, position in baseball. So let's assume our JSON body is this (trimmed it down for simplicity):\n\n```javascript\n{\n    id: 5,\n    firstName: \"George\",\n    lastName: \"Brett\",\n    positionsPlayed: [ \"1b\", \"3b\", \"dh\" ]\n}\n```\n\nWe could validate that all of the values in the `positionsPlayed` array are a valid baseball position.\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    positionsPlayed: {\n      type: \"array\",\n      properties: {\n        type: \"string\",\n        enum: [\"1b\", \"2b\", \"ss\", \"3b\", \"of\", \"sp\", \"rp\", \"c\", \"dh\"],\n      },\n    },\n  },\n};\n```\n\nAnd that works fine, but baseball players also have numbers on their jersey. But no baseball player is going to have a number over 99, so we want to make sure that it seems valid. Here's our new JSON body:\n\n```javascript\n{\n    id: 5,\n    firstName: \"George\",\n    lastName: \"Brett\",\n    jerseyNumber: 5\n}\n```\n\nSo let's use a regular expression to verify the `jerseyNumber`.\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    jerseyNumber: {\n      type: \"number\",\n      pattern: /^[0-9]{1,2}$/,\n    },\n  },\n};\n```\n\nWe could have also done this with another property which is `test`. This property is a function that allows you to run whatever kind of logic you want. So let's change our last one to use a test callback instead.\n\n```javascript\nconst schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n    jerseyNumber: {\n      type: \"number\",\n      test: function (value) {\n        return value \u003e= 0 \u0026\u0026 value \u003c 100;\n      },\n    },\n  },\n};\n```\n\nObviously using the `test` function you could get more complicated with your logic. Besides the first `value` argument called above, the `test` method also receives a second `opts` argument. This contains the following properties:\n\n- path = The path of the current item\n- parent = The last parent item, which would be the array or object this propert is a part of\n- root = The root document that we are evaluating\n\nThis allows us to potentially look back at previous values to make sure the current one makes sense relative to the others. For example, it would not make sense for `firstSeason` to be after `lastSeason`. So let's test that.\n\nHere's the JSON structure that we are testing:\n\n```javascript\n{\n    id: 5,\n    firstName: \"George\",\n    lastName: \"Brett\",\n    firstSeason: 1973,\n    lastSeason: 1994\n}\n```\n\nWe will apply this schema to be sure the season years are valid:\n\n```javascript\nconst schema = {\n    properties: {\n        id: \"number\",\n        firstName: \"string\",\n        lastName: \"string\",\n        firstSeason: \"number\",\n        lastSeason: {\n            type: [ \"number\", \"null\" ]\n            test: function(value, opts) {\n                return (\n                    value === null ||\n                    value \u003e= opts.parent.firstSeason\n                );\n            }\n        }\n    }\n}\n```\n\n# JsonValidator\n\nThis is a class that allows you to validate a schema.\n\nThe constructor accepts the schema and JSON document to be evaluated.\n\n```typescript\nconst personSchema: Schema = {\n  properties: {\n    id: \"number\",\n    firstName: \"string\",\n    lastName: \"string\",\n  },\n};\nconst jsonBody = {\n  id: 234,\n  firstName: \"Karl\",\n  lastName: \"Snyder\",\n};\n\nconst validator = new JsonValidator.validate(schema, jsonBody);\nif (validator.isValid) {\n  console.log(\"Valid!\");\n} else {\n  console.log(validator.errors);\n}\n```\n\n## Static Method\n\n### JsonValidator.validate(schema: any, root: any): JsonValidator\n\nCreates a new instance of JsonValidator and runs the validate method on it. This is shorthand.\n\n## Properties\n\n### errors: ValidationError[]\n\nGives you the list of errors encountered during the validation process. This will be empty until the `validate()` method is run.\n\n### isValid: boolean\n\nWhether the document was true or false. Note: If `validate()` has not been run yet, this will always be true.\n\n## Methods\n\n### validate(schema: any, root: any): JsonValidator\n\nExecutes the validation process.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflagpolejs%2Fjson-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflagpolejs%2Fjson-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflagpolejs%2Fjson-validator/lists"}