{"id":17087846,"url":"https://github.com/geraintluff/json-model","last_synced_at":"2026-03-02T11:01:33.843Z","repository":{"id":17893910,"uuid":"20844533","full_name":"geraintluff/json-model","owner":"geraintluff","description":"Generate JavaScript classes/code from JSON Schema","archived":false,"fork":false,"pushed_at":"2014-09-09T21:18:41.000Z","size":656,"stargazers_count":45,"open_issues_count":6,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-12T15:52:23.308Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/geraintluff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-14T23:59:35.000Z","updated_at":"2024-07-15T11:08:43.000Z","dependencies_parsed_at":"2022-09-14T22:55:19.961Z","dependency_job_id":null,"html_url":"https://github.com/geraintluff/json-model","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/geraintluff/json-model","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geraintluff%2Fjson-model","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geraintluff%2Fjson-model/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geraintluff%2Fjson-model/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geraintluff%2Fjson-model/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geraintluff","download_url":"https://codeload.github.com/geraintluff/json-model/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geraintluff%2Fjson-model/sbom","scorecard":{"id":423546,"data":{"date":"2025-08-11","repo":{"name":"github.com/geraintluff/json-model","commit":"a8fb420d935d248b51af73af5f18ee86f5da38cf"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 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":"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":"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":"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":"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":"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":"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":"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":"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":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":"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":"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":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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-19T01:47:30.116Z","repository_id":17893910,"created_at":"2025-08-19T01:47:30.116Z","updated_at":"2025-08-19T01:47:30.116Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29999217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T09:59:02.300Z","status":"ssl_error","status_checked_at":"2026-03-02T09:59:02.001Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-10-14T13:35:07.353Z","updated_at":"2026-03-02T11:01:33.533Z","avatar_url":"https://github.com/geraintluff.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON Models\n\nThis package handles JSON data and associated JSON Schemas.  This includes [fast schema validation/assignment](#speed-table), and a wrapper class that adds events plus HTML bindings for UI/display (HTML on server-side, DOM in browser with shared code).\n\n## API\n\nOn Node/CommonJS, use the `'json-model'` package:\n\n```javascript\nvar JsonModel = require('json-model');\n```\n\nIn the browser, it registers itself as the `JsonModel` global object.\n\n### Getting a validator\n\nTo get a validator for a given schema:\n\n```javascript\nvar validator = JsonModel.validator(schema);\n\nvar result = validator(data);\nconsole.log(result.valid);\nconsole.log(result.errors); // List of errors\nconsole.log(result.schemas); // Map from JSON Pointer paths --\u003e schema URLs\nconsole.log(result.links); // Map: path --\u003e links\nconsole.log(result.missing); // Map: path --\u003e missing schemas\n```\n\nIf some schemas need to be fetched, then the validator will not be completely functional at first.  You can supply a callback function to be notified when the validator is ready (which also supplies the same validator as a result):\n\n```javascript\nJsonModel.validator(schema, function (error, validator) {\n});\n```\n\n### Setting the request function\n\nThis module has the ability to fetch schemas/data, but it needs you to supply an appropriate request function:\n\n```javascript\nJsonModel.setRequestFunction(function (params, callback) {\n\t/* do whatever */\n\tcallback(error, jsonData, headers);\n});\n```\n\nThe arguments to the callback are `error`, `jsonData` (the fetched data, JSON-decoded), and `headers` (an *object* representing the headers).  `headers` may be omitted (e.g. when loading from a file).  Non-JSON responses do not need to be supported.\n\n### Creating/opening data\n\nYou can create a JsonModel wrapper directly:\n\n```javascript\nvar model = JsonModel.create(jsonData, url, schemas, callback);\n```\n\nEverything except the initial value (`jsonData`) is optional, but if you supply `schemas` you must supply `url` as well (although it may be `null`).  If `callback` is provided, it will be called (with two arguments `error` and `model`) after all relevant schemas have loaded.  The `model` argument will be the same as the return value of `create()`.\n\nYou can also open remote data: (`hintSchemas` is an optional set of schemas to use if the remote resource doesn't supply its own)\n\n```javascript\nJsonModel.open('http://example.com/json', hintSchemas, function (error, model) {...});\n```\n\nIn both cases, the callback is only called when all the schemas have been loaded.\n\nThe `schemas`/`hintSchemas` arguments can be strings (URIs), objects (anonymous schemas), or arrays of strings/objects.\n\n\u003c!--\n\n### UI bindings\n\nThe UI bindings are mostly HTML-based.\n\n#### In the browser\n\n```javascript\nmodel.bindTo(element);\n```\n\nMost bindings will output their interaces as HTML.  The supplied HTML is not dumped directly into the page, but is instead parsed into a DOM, and the existing document is coerced into that shape.\n\n#### On the server\n\n```javascript\nvar html = model.html(tag, attrs);\nmodel.html(tag, attrs, function (error, html) {...});\n```\n\n`tag` and `attrs` are optional in both forms.  The HTML returned does not include the opening/closing tags itself, instead the HTML meant to sit between them.\n\n--\u003e\n\n### Model methods\n\nThe following methods are also available on wrapper objects:\n\n#### Events and inspection\n\n* `model.on(event, callback)`, `model.off([event, [listener]]`, `model.once(event, callback)`, `model.emit(event, ...)` - event methods. `addListener()`/etc. variants are also present\n* `model.errors([pathSpec], [includeFetchErrors])` - returns current validation errors.  If the `includeFetchErrors` flag is set, then missing schemas (that encountered an error during fetching) are included as errors\n* `model.path([pathSpec])` - a child model\n* `model.pointer()` - the JSON Pointer of this model relative to the document root\n\n#### Generic value methods\n* `model.jsonType()` - the current basic type of the data (null/boolean/string/number/object/array)\n* `model.get([pathSpec])` - gets the value from the model.\n* `model.set([pathSpec], value)` - gets the value from the model.\n* `model.getHtml([pathSpec])` - gets the value, HTML-encoded\n* `model.schemas([pathSpec])` - gets the schemas (URLs if known, or the schema itself for anonymous schemas)\n* `model.hasSchema(url)` - whether\n\n#### Array methods\n* `model.length()` - array length\n* `model.item(index)` - a child item\n* `model.items(callback)` - iterate over the child items (`function callback(itemModel, index) {...}`)\n* `model.map(callback)` - maps the array value to a new array\n\n#### Object methods\n* `model.keys()` - array length\n* `model.prop(key)` - a child property\n* `model.props(callback)` - iterate over the child properties (`function callback(propModel, key) {...}`)\n* `model.props(keys, callback)` - iterate over a particular set of child properties, in order\n* `model.mapProps(callback)` - maps the object value to a new object\n* `model.mapProps(keys, callback)` - maps the object value to an array (corresponding to a particular set of keys)\n\nFor any method that takes an (optional) first `pathSpec` argument, this may either be a JSON Pointer (e.g. `\"/foo/bar\"`), or a property/index (e.g. `\"foo\"` or `5`).  If it is missing then the immediate value is returned.\n\n### Other utilities\n\n* `JsonModel.is(model)` - whether the supplied object is a JsonModel wrapper or not\n* `JsonModel.schemasFetched()` - whether all schemas have been fetched for the moment\n* `JsonModel.whenSchemasFetched(callback)` - callback is executed when all schemas have been fetched\n* `JsonModel.extend(newMethods)` - adds methods to the model prototype\n\n## Fast validation/assignment (when re-using schemas)\n\nSchemas are compiled into validators (generating custom JS code), which has an up-front overhead but leads to much faster validation upon re-use.\n\n### Speed table\n\nHere's a table of measured times for various validation setups (using the [JSON Schema Test Suite](https://github.com/json-schema/JSON-Schema-Test-Suite)) on Node:\n\n\u003c!--SPEEDSTART--\u003e\n\u003ctable width=\"100%\"\u003e\u003ctr class=\"json-array-header\"\u003e\u003cth\u003eSetup\u003c/th\u003e\u003cth\u003eTime (ms)\u003c/th\u003e\u003cth\u003eRelative speed\u003c/th\u003e\u003cth\u003eTest score\u003c/th\u003e\u003cth\u003eRepeats\u003c/th\u003e\u003c/tr\u003e\u003ctr class=\"json-array-item\"\u003e\u003ctd class=\"json-array-item-key\"\u003e\u003cspan\u003ejson-model@0.2.24 (precompiled)\u003c/span\u003e\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e0.4\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e1\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e100%\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e9769\u003c/td\u003e\u003c/tr\u003e\u003ctr class=\"json-array-item\"\u003e\u003ctd class=\"json-array-item-key\"\u003e\u003cspan\u003ejson-model@0.2.24 (compile and validate)\u003c/span\u003e\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e60.1\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e158.2\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e100%\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e62\u003c/td\u003e\u003c/tr\u003e\u003ctr class=\"json-array-item\"\u003e\u003ctd class=\"json-array-item-key\"\u003e\u003cspan\u003etv4 (validateResult)\u003c/span\u003e\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e27.8\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e73.1\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e94.7%\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e134\u003c/td\u003e\u003c/tr\u003e\u003ctr class=\"json-array-item\"\u003e\u003ctd class=\"json-array-item-key\"\u003e\u003cspan\u003etv4 (validateMultiple)\u003c/span\u003e\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e28.2\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e74.2\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e94.7%\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e132\u003c/td\u003e\u003c/tr\u003e\u003ctr class=\"json-array-item\"\u003e\u003ctd class=\"json-array-item-key\"\u003e\u003cspan\u003ejson-model@old (sanity check)\u003c/span\u003e\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e0.4\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e1\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e100%\u003c/td\u003e\u003ctd class=\"json-array-item-key\"\u003e9583\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c!--SPEEDEND--\u003e\n\nAs you can see, the first time you compile a validator it is definitely slower than [tv4](https://www.npmjs.org/package/tv4).  However, if you re-use that compiled validator then it is faster than tv4 by an order of magnitude.  If you're going to be validating against the same schema multiple times, then this will probably end up faster.\n\n## Schema assignment\n\nThe result object you get back from a validator includes a `schema` property, which is a map from JSON Pointer paths to schema URIs:\n\n```json\n{\n\t\"valid\": true,\n\t\"errors\": [],\n\t\"schemas\": {\n\t\t\"\": [\"http://example.com/schema\"],\n\t\t\"/foo\": [\"http://example.com/schema#/properties/foo\"],\n\t\t\"/foo/0\": [\"http://example.com/schema#/definitions/fooItems\"]\n\t}\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeraintluff%2Fjson-model","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeraintluff%2Fjson-model","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeraintluff%2Fjson-model/lists"}