├── .gitignore ├── .npmignore ├── .thought └── partials │ ├── installation.md.hbs │ ├── overview.md.hbs │ └── usage.md.hbs ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── handlebars ├── helpers.js └── partials │ ├── base │ └── body.hbs │ └── json-schema │ ├── additionalProperties.hbs │ ├── allOf.hbs │ ├── anyOf.hbs │ ├── array-items.hbs │ ├── body.hbs │ ├── datatype.hbs │ ├── definitions.hbs │ ├── main-panel.hbs │ ├── properties.hbs │ ├── reference.hbs │ └── type-object.hbs ├── index.js ├── less ├── theme.less └── variables.less ├── package.json └── test ├── fstab ├── LICENSE ├── fstab-spec.js └── schema.json ├── helper-spec.js ├── main-spec.js └── mocha.opts /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | node_modules 3 | target 4 | /test-output/ 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | node_modules 3 | target 4 | -------------------------------------------------------------------------------- /.thought/partials/installation.md.hbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bootprint/bootprint-json-schema/4c2f990ebd48a2bba924dc93bbf008e1328d071f/.thought/partials/installation.md.hbs -------------------------------------------------------------------------------- /.thought/partials/overview.md.hbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bootprint/bootprint-json-schema/4c2f990ebd48a2bba924dc93bbf008e1328d071f/.thought/partials/overview.md.hbs -------------------------------------------------------------------------------- /.thought/partials/usage.md.hbs: -------------------------------------------------------------------------------- 1 | This module is meant for use with the {{npm 'bootprint'}} module: 2 | 3 | ```bash 4 | npm install -g bootprint 5 | npm install -g bootprint-json-schema 6 | bootprint json-schema http://json-schema.org/schema target 7 | ``` 8 | 9 | The directory "target" should now contain a file `index.html` and `main.css` which contain a readble 10 | form of the [Core/Validation Meta-Schema](http://json-schema.org). 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: "node_js" 3 | node_js: 4 | - "0.10" 5 | - "0.12" 6 | - "iojs" 7 | - "4" 8 | - "6" 9 | - "7" 10 | before_script: 11 | - npm install standard 12 | - standard 13 | script: 14 | - npm install istanbul 15 | - istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --recursive 16 | after_script: 17 | - npm install coveralls 18 | - cat ./coverage/lcov.info | coveralls -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release notes 2 | 3 | 4 | 5 | # Version 1.1.0 (Mon, 13 Feb 2017 21:33:41 GMT) 6 | 7 | * [c83458c](https://github.com/bootprint/bootprint-json-schema/commit/c83458c) Add string pattern (#10) - Alex Collins 8 | 9 | # Version 1.0.0 (Sat, 24 Dec 2016 20:43:54 GMT) 10 | 11 | * [bb00a2e](https://github.com/bootprint/bootprint-json-schema/commit/bb00a2e) Prepare for 1.0 release (#9) - Nils Knappmeier 12 | 13 | # Version 0.8.6 (Thu, 24 Mar 2016 07:31:16 GMT) 14 | 15 | * [4d70db8](https://github.com/bootprint/bootprint-json-schema/commit/4d70db8) #3: Corrected typo in partial (maxLength-variable spelled wrongly) - Nils Knappmeier 16 | 17 | # Version 0.8.5 (Tue, 15 Mar 2016 14:27:33 GMT) 18 | 19 | * [40ca080](https://github.com/bootprint/bootprint-json-schema/commit/40ca080) Generate README with "thought" - Nils Knappmeier 20 | * [2222c27](https://github.com/bootprint/bootprint-json-schema/commit/2222c27) Add "require" to main-spec in order to get (low) coverage - Nils Knappmeier 21 | * [2cfccb8](https://github.com/bootprint/bootprint-json-schema/commit/2cfccb8) Add mocha and chai as dev-dependencies - Nils Knappmeier 22 | * [98a14f8](https://github.com/bootprint/bootprint-json-schema/commit/98a14f8) Adjust travis-configuration - Nils Knappmeier 23 | * [3b7b322](https://github.com/bootprint/bootprint-json-schema/commit/3b7b322) Move to bootprint-organization and enable ghook for StandardJS - Nils Knappmeier 24 | 25 | ## v0.8.4 - 2015-10-21 26 | 27 | # Fix 28 | 29 | * Remove `bootprint` as peer-dependency, because `npm` versions 1 and 2 download it needlessly. 30 | 31 | ## v0.8.3 - 2015-10-19 32 | 33 | # Fix 34 | 35 | * Typo in `files`-property, causing the build to be broken (Thanks @davoad for PR #6) 36 | 37 | ## v0.8.2 - 2015-10-19 (BROKEN) 38 | 39 | # Fix 40 | 41 | * Add `files`-property to package.json 42 | 43 | ## v0.8.1 - 2015-10-17 44 | 45 | ### Add 46 | 47 | * Enums are linked to subschema-definitions, if a property is a swagger-discriminator 48 | 49 | ## v0.8.0 - 2015-10-14 50 | 51 | ### Change 52 | 53 | * bootprint-swagger#39: Attempting to resolve invalid JSON-references (e.g. for Swagger responses) 54 | now throws an error 55 | 56 | ## v0.7.2 - 2015-10-13 57 | 58 | ### Add 59 | 60 | * Enums are linked to subschema-definitions, if a property is a swagger-discriminator 61 | 62 | ### Fix 63 | 64 | * Silently ignore missing `items` tag in `array`-definitions 65 | 66 | ## v0.7.1 - 2015-09-27 67 | ### Fix 68 | 69 | * bootprint-swagger#35: "allOf" renders incorrect HTML doc 70 | 71 | ## v0.7.0 - 2015-09-25 72 | ### Add 73 | 74 | * Display string-length limits 75 | 76 | ## v0.6.2 - 2015-09-22 77 | ### Fix 78 | 79 | * Be forgiving on calling datatype-helper with empty argument 80 | 81 | ## v0.6.1 - 2015-09-19 82 | ### Fix 83 | 84 | * Helper for resolving $ref-properties now returns "undefined" instead of an exception 85 | when a path cannot be followed completely (because a property in the middle of the path 86 | is missing) 87 | 88 | ## v0.6.0 - 2015-09-18 89 | ### Add 90 | 91 | * Helper for resolving $ref-properties to their reference object (needed for bootprint-swagger#31) 92 | 93 | ## v0.5.3 - 2015-09-10 94 | ### Fix 95 | 96 | * bootprint-swagger#28: Read-only fields in parameter schema 97 | 98 | ## v0.5.2 - 2015-09-05 99 | ### Fix 100 | 101 | * bootprint-swagger#26: Definition objects not getting any details 102 | 103 | ## v0.5.1 - 2015-09-01 104 | ### Fix 105 | 106 | * bootprint-swagger#18: Details about primitive (string, number, etc). array-item-types were not displayed. 107 | 108 | ## The dark past 109 | 110 | * You'll have to look through the commit log to get details. 111 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Contributions and feedback are always welcome. The expected procedure is the following: 4 | 5 | ### Bugs, Features and Feedback 6 | 7 | * Please, create github issues for **feature-requests**, **bug reports**. 8 | * Feel free to open issues for **questions and problems you have**, even if they are not bugs 9 | or feature requests. 10 | * You may even open an issue just to say you like the project. 11 | * For small changes, such as **typo and formatting corrections**, you can immediately 12 | create a pull-request. You can use the github web-interface, but keep in mind that most of the documentation 13 | is created with Thought, so you should change the template in the `.thought` directory or change the default 14 | templates in [the thought project](https://github.com/nknapp/thought/tree/master/handlebars). 15 | * If you have an idea for a **new feature** that you would like to implement, please **open an issue** first and ask 16 | for feedback. Maybe someone else has a similar problem and different ideas. 17 | * If you encounter a bug you can submit a **pull-request for a failing unit test**, you should then also open an issue 18 | for the bug. 19 | * Before making a pull-request, make sure that you commit corresponds to the coding-style. You can do this by 20 | running `npm test`. 21 | 22 | **People submitting relevant contributions will be granted commit access to the repository.** 23 | 24 | 25 | ### Coding style 26 | 27 | [![standard][standard-image]][standard-url] 28 | 29 | This repository uses [`standard`][standard-url] to maintain code style and consistency, 30 | and to avoid style arguments. You can run `npm run format` to apply the coding-style, but 31 | you may need to fix some things manually. Make sure to use the latest version of `standard`. 32 | 33 | 34 | ### Installing & Testing 35 | 36 | You can fork and clone the repo from github. Run 37 | 38 | * Run `npm install` to install all the dependencies needed to build and run the project. 39 | * Run `npm test` to run unit tests and validate the `standard` coding-style. 40 | * Run `npm run thought` to generate the README.md and other markdown files in the repository. 41 | 42 | It is intentional to don't have `standard`, `thought`, `istanbul` and `coveralls` in the devDependencies. 43 | `standard` is a rather large package which you would not want to have copied into the `node_modules`-folder 44 | of each of your projects. 45 | 46 | Instead, the `pretest`- and `preformat`-scripts ensure that `standard` and `thought` are installed globally. 47 | If you are not allowed to install packages globally, please raise an issue, so that we can try to find a solution. 48 | 49 | 50 | ### About this text 51 | 52 | This text is part of the [Thought](https://github.com/nknapp/thought)-project. If you have any suggestions or wishes 53 | to change the text, please raise an issue there for discussion. 54 | 55 | [standard-image]: https://cdn.rawgit.com/feross/standard/master/badge.svg 56 | [standard-url]: https://github.com/feross/standard 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Nils Knappmeier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bootprint-json-schema 2 | 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/bootprint/bootprint-json-schema.svg)](https://greenkeeper.io/) 4 | 5 | [![NPM version](https://badge.fury.io/js/bootprint-json-schema.svg)](http://badge.fury.io/js/bootprint-json-schema) 6 | [![Travis Build Status](https://travis-ci.org/bootprint/bootprint-json-schema.svg?branch=master)](https://travis-ci.org/bootprint/bootprint-json-schema) 7 | [![Coverage Status](https://img.shields.io/coveralls/bootprint/bootprint-json-schema.svg)](https://coveralls.io/r/bootprint/bootprint-json-schema) 8 | 9 | 10 | > Converts a json-schema into a static html page 11 | 12 | 13 | 14 | This module is meant for use with the [bootprint](https://npmjs.com/package/bootprint) module: 15 | 16 | ```bash 17 | npm install -g bootprint 18 | npm install -g bootprint-json-schema 19 | bootprint json-schema http://json-schema.org/schema target 20 | ``` 21 | 22 | The directory "target" should now contain a file `index.html` and `main.css` which contain a readble 23 | form of the [Core/Validation Meta-Schema](http://json-schema.org). 24 | 25 | ## API-reference 26 | 27 | 28 | 29 | 30 | ## License 31 | 32 | `bootprint-json-schema` is published under the MIT-license. 33 | See [LICENSE](LICENSE) for details. 34 | 35 | ## Release-Notes 36 | 37 | For release notes, see [CHANGELOG.md](CHANGELOG.md) 38 | 39 | ## Contributing guidelines 40 | 41 | See [CONTRIBUTING.md](CONTRIBUTING.md). -------------------------------------------------------------------------------- /handlebars/helpers.js: -------------------------------------------------------------------------------- 1 | var util = require('util') 2 | 3 | module.exports = { 4 | 'json-schema--datatype': dataType, 5 | /** 6 | * Extract then name of a subschema from a $ref property 7 | * @param url 8 | * @returns {*} 9 | */ 10 | 'json-schema--subschema-name': function (url) { 11 | return url.replace('#/definitions/', '') 12 | }, 13 | 14 | /** 15 | * Resolve a (local) json-schema- 16 | * @param reference 17 | */ 18 | 'json-schema--resolve-ref': function (reference, options) { 19 | reference = reference.trim() 20 | if (reference.lastIndexOf('#', 0) < 0) { 21 | console.warn('Remote references not supported yet. Reference must start with "#" (but was ' + reference + ')') 22 | return {} 23 | } 24 | var components = reference.split('#') 25 | // var url = components[0] 26 | var hash = components[1] 27 | var hashParts = hash.split('/') 28 | // TODO : Download remote json from url if url not empty 29 | var current = options.data.root 30 | hashParts.forEach(function (hashPart) { 31 | // Traverse schema from root along the path 32 | if (hashPart.trim().length > 0) { 33 | if (typeof current === 'undefined') { 34 | throw new Error("Reference '" + reference + "' cannot be resolved. '" + hashPart + "' is undefined.") 35 | } 36 | current = current[hashPart] 37 | } 38 | }) 39 | return current 40 | }, 41 | /** 42 | * 43 | * @param range a json-schema object with minimum, maximum, exclusiveMinimum, exclusiveMaximum 44 | * @param {number=} [range.minimum] 45 | * @param {number=} [range.maximum] 46 | * @param {string} [range.type] the json-type (integer, or number) 47 | * @param {boolean} [range.minimumExclusive] 48 | * @param {boolean} [range.maximumExclusive] 49 | */ 50 | 'json-schema--range': function (range) { 51 | var hasMinimum = range.minimum || range.minimum === 0 52 | var hasMaximum = range.maximum || range.maximum === 0 53 | 54 | if (!hasMinimum && !hasMaximum) { 55 | // There is no range 56 | return '' 57 | } 58 | 59 | var numberSet = '' 60 | if (range.type === 'integer') { 61 | numberSet = '\u2208 \u2124' // ELEMENT OF - DOUBLE-STRUCK CAPITAL Z 62 | } else if (range.type === 'number') { 63 | numberSet = '\u2208 \u211D' // ELEMENT OF - DOUBLE-STRUCK CAPITAL R 64 | } 65 | 66 | if (hasMinimum && !hasMaximum) { 67 | return util.format(', { x %s | x %s %d }', 68 | numberSet, 69 | range.minimumExclusive ? '>' : '\u2265', 70 | range.minimum) 71 | } else if (hasMaximum && !hasMinimum) { 72 | return util.format(', { x %s | x %s %d }', 73 | numberSet, 74 | range.maximumExclusive ? '<' : '\u2264', 75 | range.maximum) 76 | } else { 77 | // if (hasMaxmium && hasMinimum) 78 | return util.format(', { x %s | %d %s x %s %d }', 79 | numberSet, 80 | range.minimum, 81 | range.minimumExclusive ? '<' : '\u2264', 82 | range.maximumExclusive ? '<' : '\u2264', 83 | range.maximum) 84 | } 85 | } 86 | } 87 | 88 | /** 89 | * Returns a descriptive string for a datatype 90 | * @param value 91 | * @returns {String} a string like string[] or object[][] 92 | */ 93 | function dataType (value) { 94 | if (!value) return null 95 | if (value['anyOf'] || value['allOf'] || value['oneOf']) { 96 | return '' 97 | } 98 | if (!value.type) { 99 | return 'object' 100 | } 101 | if (value.type === 'array') { 102 | return dataType(value.items || {}) + '[]' 103 | } 104 | return value.type 105 | } 106 | -------------------------------------------------------------------------------- /handlebars/partials/base/body.hbs: -------------------------------------------------------------------------------- 1 | {{!-- 2 | Renders the main-schema as panel and the sub-schemas below. 3 | This partial can be overridden if json-schema is only part of 4 | what should be displayed. 5 | @public 6 | --}} 7 | {{>json-schema/main-panel}} 8 | {{#if definitions}} 9 |

Definitions

10 | {{>json-schema/definitions}} 11 | {{/if}} -------------------------------------------------------------------------------- /handlebars/partials/json-schema/additionalProperties.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | Show a subschema for additionaProperties of a `object` definition. 3 | }} 4 |
5 | {{>json-schema/datatype}} 6 | {{>json-schema/body}} 7 |
8 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/allOf.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | renders a json-schema "allOf"-definition. 3 | }} 4 |
5 | {{! Display ref (i.e. superclasses)}} 6 |
7 | 12 |
13 |
14 | {{#each .}} 15 | {{#unless $ref}} 16 | {{>json-schema/body}} 17 | {{/unless}} 18 | {{/each}} 19 |
20 |
21 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/anyOf.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | renders a json-schema "anyOf"-definition. 3 | }} 4 |
5 | {{! Display ref (i.e. superclasses)}} 6 |
7 | {{#each .}} 8 |
9 | {{>json-schema/datatype}} 10 |
11 |
12 | {{>json-schema/body $ref=""}} 13 |
14 | {{/each}} 15 |
16 | 17 |
18 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/array-items.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | renders a json-schema "items"-definition of array-types. 3 | }} 4 |
5 | {{>json-schema/datatype .}} 6 |
7 | {{>json-schema/body}} 8 |
9 |
-------------------------------------------------------------------------------- /handlebars/partials/json-schema/body.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | Renders a json-schema without the surrounding panel. 3 | @param {boolean} showType whether or not to show the plain datatype for primitives 4 | }} 5 | {{#if description}} 6 |
7 | {{md description}} 8 |
9 | {{/if}} 10 | {{#if example}} 11 |
12 | {{json example}} 13 |
14 | {{/if}} 15 | 16 | {{#if type}} 17 | {{! Render differently depending on type}} 18 | {{#ifeq type 'object'}} 19 | {{>json-schema/type-object}} 20 | {{else}} 21 | {{#ifeq type 'array'}} 22 | {{#if items}} 23 | {{>json-schema/array-items items}} 24 | {{/if}} 25 | {{/ifeq}} 26 | {{/ifeq}} 27 | {{else}} 28 | {{>json-schema/type-object}} 29 | {{/if}} 30 | {{#if allOf}} 31 | {{>json-schema/allOf allOf}} 32 | {{/if}} 33 | {{#if anyOf}} 34 | {{>json-schema/anyOf anyOf}} 35 | {{/if}} 36 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/datatype.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | When properties are renderered this partial renders the datatype of a property, 3 | with a link to the type-definition (in case of a $ref). 4 | Depending on the input, it renders an augmented data-type (e.g. "string[]"), 5 | the 'format'-value (e.g. "date-time") and "enum"-values. 6 | 7 | @param {boolean} discriminator true, this property is a swagger-discriminator (in which case enums are rendered as links) 8 | }} 9 | 10 | 11 | {{~#if $ref}} 12 | {{~>json-schema/reference $ref}} 13 | {{~else}} 14 | {{~json-schema--datatype .}} 15 | {{~/if}} 16 | 17 | {{~#if format}} 18 | ({{format}}) 19 | {{~/if~}} 20 | 21 | 22 | {{!-- Enum values --}} 23 | {{~#if enum}} 24 | , x ∈ { 25 | {{#each enum}} 26 | {{! Render enums in the descriminator as links to the appropriate definitions}} 27 | {{#if ../discriminator}} 28 | {{.}} 29 | {{else}} 30 | {{.}} 31 | {{/if}} 32 | {{#ifeq ../default .}} 33 | (default) 34 | {{/ifeq}} 35 | {{#unless @last}},{{/unless}} 36 | {{/each}} 37 | } 38 | 39 | {{~/if}} 40 | 41 | {{!-- min- and max-values --}} 42 | 43 | {{~json-schema--range . ~}} 44 | 45 | 46 | {{!-- Default values (for non-enum types) --}} 47 | {{~#unless enum}} 48 | {{~#if default}} 49 | {{~default}} 50 | {{/if}} 51 | {{~/unless}} 52 | {{#if minLength}} 53 | 54 | {{#if maxLength}} 55 | ({{minLength}} to {{maxLength}} chars) 56 | {{else}} 57 | (at least {{minLength}} chars) 58 | {{/if}} 59 | 60 | {{else}} 61 | {{#if maxLength}} 62 | 63 | (up to {{maxLength}} chars) 64 | 65 | {{/if}} 66 | {{/if}} 67 | {{#if pattern}} 68 | , must match {{pattern}} 69 | {{/if}} 70 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/definitions.hbs: -------------------------------------------------------------------------------- 1 | {{!Renders all subschemas}} 2 | {{#if definitions}} 3 | {{#eachSorted definitions}} 4 | {{>json-schema/main-panel . title=@key anchor=true}} 5 | {{/eachSorted}} 6 | {{/if}} 7 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/main-panel.hbs: -------------------------------------------------------------------------------- 1 | {{! 2 | Renders a json.schema inside a bootstrap-panel. 3 | @public 4 | @readonly 5 | }} 6 |
7 | {{#if title}} 8 |
9 | {{#if anchor}} 10 |

{{title}}: 11 | {{>json-schema/datatype}} 12 |

13 | {{else}} 14 |

{{title}}

15 | {{/if}} 16 |
17 | {{/if}} 18 |
19 | {{#if $ref}} 20 | {{>json-schema/reference $ref}} 21 | {{else}} 22 | {{>json-schema/body}} 23 | {{/if}} 24 |
25 |
-------------------------------------------------------------------------------- /handlebars/partials/json-schema/properties.hbs: -------------------------------------------------------------------------------- 1 | {{!Renders json-schema object properties.}} 2 | {{#if properties}} 3 |
4 |
5 | {{#each properties}} 6 |
7 | {{!Single property, default type is "object"}} 8 | {{@key}}: 9 | {{>json-schema/datatype discriminator=(equal @key ../discriminator)}} 10 | {{#ifcontains ../required @key}} 11 | 12 | {{/ifcontains}} 13 | {{#ifeq @key ../discriminator}} 14 | 15 | {{/ifeq}} 16 | {{#if readOnly}} 17 | 18 | {{/if}} 19 |
20 |
21 | {{md description}} 22 | {{!Show details of nested property schema}} 23 |
24 | {{>json-schema/body $ref="" description=""}} 25 |
26 |
27 | {{/each}} 28 |
29 |
30 | {{/if}} 31 | -------------------------------------------------------------------------------- /handlebars/partials/json-schema/reference.hbs: -------------------------------------------------------------------------------- 1 | {{!Renders a reference to a subschema}} 2 | {{#if .}} 3 | {{json-schema--subschema-name .}} 4 | {{/if}} -------------------------------------------------------------------------------- /handlebars/partials/json-schema/type-object.hbs: -------------------------------------------------------------------------------- 1 | {{!-- 2 | Renders the properties of an `object` 3 | --}} 4 | {{>json-schema/properties}} 5 | {{#if additionalProperties}} 6 | {{>json-schema/additionalProperties additionalProperties}} 7 | {{/if}} 8 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | 3 | // Export function to create new config (builder is passed in from outside) 4 | module.exports = function (builder) { 5 | return builder 6 | .load(require('bootprint-base')) 7 | .merge({ 8 | 'handlebars': { 9 | 'partials': path.join(__dirname, 'handlebars/partials'), 10 | 'helpers': require.resolve('./handlebars/helpers.js') 11 | }, 12 | 'less': { 13 | 'main': [ 14 | require.resolve('./less/theme.less'), 15 | require.resolve('./less/variables.less') 16 | ] 17 | } 18 | }) 19 | } 20 | 21 | // Add "package" to be used by bootprint-doc-generator 22 | module.exports.package = require('./package') 23 | -------------------------------------------------------------------------------- /less/theme.less: -------------------------------------------------------------------------------- 1 | .panel-definition { 2 | .panel-variant(@definition-panel-border-color, @definition-panel-header-text-color, @definition-panel-header-bg-color, @definition-panel-border-color); 3 | } 4 | 5 | // Named sections 6 | .named-section(@title) { 7 | &:before { 8 | font-weight: bold; 9 | color: @named-section-text-color; 10 | text-transform: uppercase; 11 | content: @title; 12 | padding-bottom: 0.5em; 13 | display: block; 14 | } 15 | &:not(:last-child) { 16 | padding-bottom: 1.5em; 17 | } 18 | } 19 | 20 | .json-schema-description { 21 | .named-section(@msg-json-section-description); 22 | } 23 | 24 | .json-schema-properties { 25 | .named-section(@msg-json-section-properties); 26 | 27 | dd:not(:last-child) { 28 | padding-bottom: 1em; 29 | } 30 | 31 | dl { 32 | margin: 0; 33 | } 34 | } 35 | 36 | .json-schema-example { 37 | .named-section(@msg-json-section-example); 38 | } 39 | 40 | .json-schema-array-items { 41 | .named-section(@msg-json-section-items); 42 | } 43 | 44 | .json-schema-allOf-inherited { 45 | .named-section(@msg-json-section-inherited); 46 | ul { 47 | .list-unstyled(); 48 | } 49 | } 50 | 51 | .json-schema-anyOf { 52 | > dl { 53 | border-left: 2px solid @definition-panel-inner-border-color; 54 | padding-left: 1em; 55 | 56 | dt:not(:first-child):before { 57 | content: "or "; 58 | } 59 | 60 | dt:first-child:before { 61 | content: "either "; 62 | } 63 | 64 | } 65 | } 66 | 67 | .json-schema-additionalProperties { 68 | .named-section(@msg-json-section-additionalProperties); 69 | } 70 | 71 | .json-inner-schema { 72 | .json-schema-properties, 73 | .json-schema-array-items, 74 | .json-schema-description, 75 | .json-schema-example { 76 | padding-left: 1em; 77 | margin-top: 0.5em; 78 | padding-bottom: 0.5em; 79 | border-left: 2px solid @definition-panel-inner-border-color; 80 | } 81 | } 82 | 83 | .named-label(@name) { 84 | &:before { 85 | .label(); 86 | .label-default(); 87 | content: @name; 88 | } 89 | } 90 | 91 | .json-property-discriminator { 92 | .named-label(@msg-json-discriminator) 93 | } 94 | 95 | .json-property-required { 96 | .named-label(@msg-json-required) 97 | } 98 | 99 | .json-property-read-only { 100 | .named-label(@msg-json-read-only) 101 | } 102 | 103 | .json-property-pattern { 104 | font-weight: lighter; 105 | font-size: small; 106 | } 107 | 108 | .json-schema--regex { 109 | &:before, &:after { 110 | color: lighten(@text-color, 30%); 111 | content: '/'; 112 | } 113 | &:extend(code); 114 | } 115 | 116 | .json-property-type { 117 | font-style: italic; 118 | font-weight: 100; 119 | } 120 | 121 | .json-property-format { 122 | font-size: smaller; 123 | } 124 | 125 | .json-property-enum { 126 | font-weight: lighter; 127 | font-size: small; 128 | } 129 | 130 | .json-property-default-value { 131 | font-weight: lighter; 132 | font-size: small; 133 | &:before { 134 | content: '(default: "'; 135 | } 136 | &:after { 137 | content: '")'; 138 | } 139 | } 140 | 141 | .json-property-enum-item { 142 | &:before, &:after { 143 | content: "\"" 144 | } 145 | font-weight: lighter; 146 | font-size: small; 147 | 148 | } 149 | 150 | .json-schema--reference { 151 | font-size: 90%; 152 | } 153 | -------------------------------------------------------------------------------- /less/variables.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Label of the "description"-section within a json-schema box 3 | * @public 4 | */ 5 | @msg-json-section-description: "Description"; 6 | 7 | /** 8 | * Label of the "properties"-section within a json-schema box 9 | * @public 10 | */ 11 | @msg-json-section-properties: "Properties"; 12 | @msg-json-section-items: "Items"; 13 | @msg-json-section-inherited: "Inherited"; 14 | @msg-json-section-anyOf: "Any of"; 15 | @msg-json-discriminator: "discriminator"; 16 | @msg-json-read-only: "read only"; 17 | @msg-json-required: "required"; 18 | @msg-json-ref-prefix: "Details: "; 19 | @msg-json-section-additionalProperties: "Additional properties"; 20 | @msg-json-section-example: "Example"; 21 | 22 | /** 23 | * This color is used as border for definition boxes and for border within the definition 24 | */ 25 | @definition-panel-header-bg-color: @gray-lighter; 26 | @definition-panel-header-text-color: contrast(@definition-panel-header-bg-color); 27 | @definition-panel-border-color: darken(@definition-panel-header-bg-color, 30%); 28 | @definition-panel-inner-border-color: @definition-panel-border-color; 29 | @named-section-text-color: @gray; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootprint-json-schema", 3 | "version": "1.1.0", 4 | "description": "Converts a json-schema into a static html page", 5 | "main": "index.js", 6 | "scripts": { 7 | "pretest": "standard --version || npm -g install standard", 8 | "test": "mocha --recursive && standard", 9 | "preformat": "standard --version || npm -g install standard", 10 | "format": "standard --fix", 11 | "thought": "thought run -a", 12 | "prethoughtcheck": "thought --version || npm -g install thought", 13 | "thoughtcheck": "thought check-engines", 14 | "version": "thoughtful changelog -o -a && npm run thought", 15 | "preversion": "npm run thoughtcheck" 16 | }, 17 | "preferGlobal": true, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/bootprint/bootprint-json-schema.git" 21 | }, 22 | "author": "Nils Knappmeier", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/bootprint/bootprint-json-schema/issues" 26 | }, 27 | "homepage": "https://github.com/bootprint/bootprint-json-schema", 28 | "dependencies": { 29 | "bootprint-base": "^1.0.0", 30 | "lodash": "^4.17.2" 31 | }, 32 | "peerDependencies": { 33 | "bootprint": "^1.0.0" 34 | }, 35 | "files": [ 36 | "handlebars", 37 | "less", 38 | "index.js" 39 | ], 40 | "config": { 41 | "ghooks": { 42 | "pre-push": "standard && thoughtful precommit" 43 | } 44 | }, 45 | "devDependencies": { 46 | "bootprint-unit-testing": "^1.0.0", 47 | "chai": "^3.5.0", 48 | "ghooks": "^2.0.0", 49 | "handlebars": "^4.0.6", 50 | "mocha": "^3.2.0", 51 | "thoughtful-release": "^0.3.0", 52 | "trace-and-clarify-if-possible": "^1.0.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/fstab/LICENSE: -------------------------------------------------------------------------------- 1 | The contents of the file `schema.json` is copied from http://json-schema.org/example2.html 2 | and release under the [Academic Free License (AFL)](https://opensource.org/licenses/AFL-3.0) or the BSD License. 3 | -------------------------------------------------------------------------------- /test/fstab/fstab-spec.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootprint-swagger 3 | * 4 | * Copyright (c) 2015 Nils Knappmeier. 5 | * Released under the MIT license. 6 | */ 7 | 8 | /* global describe */ 9 | /* global it */ 10 | /* global before */ 11 | var expect = require('chai').expect 12 | var core = require('bootprint-unit-testing')(require('../..'), __dirname) 13 | 14 | describe('The fstab-fixture', function () { 15 | this.timeout(10000) 16 | var context = {} 17 | before(function () { 18 | return core.run(require('./schema.json'), context) 19 | }) 20 | 21 | it('should have a pattern-block in the fstab-section', function () { 22 | expect(context.$('#definition-diskUUID .json-property-pattern .json-schema--regex').text()) 23 | .to.equal('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$') 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /test/fstab/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "http://some.site.somewhere/entry-schema#", 3 | "$schema": "http://json-schema.org/draft-04/schema#", 4 | "description": "schema for an fstab entry", 5 | "type": "object", 6 | "required": [ 7 | "storage" 8 | ], 9 | "properties": { 10 | "storage": { 11 | "type": "object", 12 | "oneOf": [ 13 | { 14 | "$ref": "#/definitions/diskDevice" 15 | }, 16 | { 17 | "$ref": "#/definitions/diskUUID" 18 | }, 19 | { 20 | "$ref": "#/definitions/nfs" 21 | }, 22 | { 23 | "$ref": "#/definitions/tmpfs" 24 | } 25 | ] 26 | }, 27 | "fstype": { 28 | "enum": [ 29 | "ext3", 30 | "ext4", 31 | "btrfs" 32 | ] 33 | }, 34 | "options": { 35 | "type": "array", 36 | "minItems": 1, 37 | "items": { 38 | "type": "string" 39 | }, 40 | "uniqueItems": true 41 | }, 42 | "readonly": { 43 | "type": "boolean" 44 | } 45 | }, 46 | "definitions": { 47 | "diskDevice": { 48 | "properties": { 49 | "type": { 50 | "enum": [ 51 | "disk" 52 | ] 53 | }, 54 | "device": { 55 | "type": "string", 56 | "pattern": "^/dev/[^/]+(/[^/]+)*$" 57 | } 58 | }, 59 | "required": [ 60 | "type", 61 | "device" 62 | ], 63 | "additionalProperties": false 64 | }, 65 | "diskUUID": { 66 | "properties": { 67 | "type": { 68 | "enum": [ 69 | "disk" 70 | ] 71 | }, 72 | "label": { 73 | "type": "string", 74 | "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" 75 | } 76 | }, 77 | "required": [ 78 | "type", 79 | "label" 80 | ], 81 | "additionalProperties": false 82 | }, 83 | "nfs": { 84 | "properties": { 85 | "type": { 86 | "enum": [ 87 | "nfs" 88 | ] 89 | }, 90 | "remotePath": { 91 | "type": "string", 92 | "pattern": "^(/[^/]+)+$" 93 | }, 94 | "server": { 95 | "type": "string", 96 | "oneOf": [ 97 | { 98 | "format": "host-name" 99 | }, 100 | { 101 | "format": "ipv4" 102 | }, 103 | { 104 | "format": "ipv6" 105 | } 106 | ] 107 | } 108 | }, 109 | "required": [ 110 | "type", 111 | "server", 112 | "remotePath" 113 | ], 114 | "additionalProperties": false 115 | }, 116 | "tmpfs": { 117 | "properties": { 118 | "type": { 119 | "enum": [ 120 | "tmpfs" 121 | ] 122 | }, 123 | "sizeInMB": { 124 | "type": "integer", 125 | "minimum": 16, 126 | "maximum": 512 127 | } 128 | }, 129 | "required": [ 130 | "type", 131 | "sizeInMB" 132 | ], 133 | "additionalProperties": false 134 | } 135 | } 136 | } -------------------------------------------------------------------------------- /test/helper-spec.js: -------------------------------------------------------------------------------- 1 | /* global describe */ 2 | /* global it */ 3 | 4 | var expect = require('chai').expect 5 | 6 | var helpers = require('../handlebars/helpers.js') 7 | var Handlebars = require('handlebars').create() 8 | Handlebars.registerHelper(helpers) 9 | 10 | function run (template, json) { 11 | return Handlebars.compile(template)(json) 12 | } 13 | 14 | describe('The Handlebars-helpers:', function () { 15 | describe('the json-schema--datatype helper', function () { 16 | // Call the datatype-helper 17 | function dt (obj) { 18 | return run('{{json-schema--datatype type}}', {type: obj}) 19 | } 20 | 21 | it('should handle undefined gracefully', function () { 22 | expect(dt(undefined)).to.equal('') 23 | }) 24 | 25 | it('should handle null gracefully', function () { 26 | expect(dt(null)).to.equal('') 27 | }) 28 | 29 | it('should return an empty string for composite schema, since they are rendered in partials null and undefined gracefully', function () { 30 | expect(dt({ anyOf: [] })).to.equal('') 31 | expect(dt({ oneOf: [] })).to.equal('') 32 | expect(dt({ allOf: [] })).to.equal('') 33 | }) 34 | 35 | it('should treat unspecific types as object', function () { 36 | expect(dt({})).to.equal('object') 37 | }) 38 | 39 | it('should treat unspecific array types as object[]', function () { 40 | expect(dt({ type: 'array' })).to.equal('object[]') 41 | }) 42 | 43 | it('should treat arrays with unspecific types object[]', function () { 44 | expect(dt({ type: 'array', items: {} })).to.equal('object[]') 45 | }) 46 | 47 | it('should write type[] for specific arrays', function () { 48 | expect(dt({ type: 'array', items: { type: 'string' } })).to.equal('string[]') 49 | }) 50 | 51 | it('should write recurse multiple steps of array types', function () { 52 | expect(dt({ type: 'array', items: { type: 'array', items: { type: 'string' } } })).to.equal('string[][]') 53 | }) 54 | }) 55 | 56 | describe('the json-schema--datatype helper', function () { 57 | // Call the datatype-helper 58 | function range (obj) { 59 | return run('{{{json-schema--range range}}}', { range: obj }) 60 | } 61 | 62 | it('should handle empty ranges gracefully', function () { 63 | expect(range({})).to.equal('') 64 | }) 65 | 66 | it('should render a range for only minimum (starting with coma)', function () { 67 | expect(range({ minimum: 2, type: 'number' })).to.equal(', { x ∈ ℝ | x ≥ 2 }') 68 | }) 69 | 70 | it('should render a range for only maximum (starting with coma)', function () { 71 | expect(range({ maximum: 2, type: 'number' })).to.equal(', { x ∈ ℝ | x ≤ 2 }') 72 | }) 73 | 74 | it('should render a range with minimum and maximum (starting with coma)', function () { 75 | expect(range({ maximum: 2, minimum: 0, type: 'number' })).to.equal(', { x ∈ ℝ | 0 ≤ x ≤ 2 }') 76 | }) 77 | 78 | it('should render a range with minimumExclusive and maximum (starting with coma)', function () { 79 | expect(range({ maximum: 2, minimum: 0, minimumExclusive: true, type: 'number' })).to.equal(', { x ∈ ℝ | 0 < x ≤ 2 }') 80 | }) 81 | 82 | it('should render a range with minimum and maximumExclusive (starting with coma)', function () { 83 | expect(range({ maximum: 2, maximumExclusive: true, minimum: 0, type: 'number' })).to.equal(', { x ∈ ℝ | 0 ≤ x < 2 }') 84 | }) 85 | 86 | it('should render the correct set-symbol for integers', function () { 87 | expect(range({ type: 'integer', minimum: 0 })).to.equal(', { x ∈ ℤ | x ≥ 0 }') 88 | }) 89 | }) 90 | }) 91 | -------------------------------------------------------------------------------- /test/main-spec.js: -------------------------------------------------------------------------------- 1 | // Tests are still missing, but some are in bootprint-openapi 2 | 3 | require('..') 4 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require trace-and-clarify-if-possible --------------------------------------------------------------------------------