├── .circleci └── config.yml ├── .dockerignore ├── .editorconfig ├── .eslintrc.json ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── LICENSE ├── README.md ├── docs ├── .gitignore ├── .tool-versions ├── 404.html ├── CNAME ├── Gemfile ├── Gemfile.lock ├── Rakefile ├── _config.yml ├── _data │ └── rules.yml ├── _includes │ ├── footer.html │ ├── google-analytics.html │ ├── head.html │ ├── rules-list.html │ └── sidenav.html ├── _layouts │ ├── default.html │ ├── home.html │ └── page.html ├── _sass │ ├── _base.scss │ ├── _layout.scss │ ├── bootstrap │ │ ├── _alert.scss │ │ ├── _badge.scss │ │ ├── _breadcrumb.scss │ │ ├── _button-group.scss │ │ ├── _buttons.scss │ │ ├── _card.scss │ │ ├── _carousel.scss │ │ ├── _close.scss │ │ ├── _code.scss │ │ ├── _custom-forms.scss │ │ ├── _dropdown.scss │ │ ├── _forms.scss │ │ ├── _functions.scss │ │ ├── _grid.scss │ │ ├── _images.scss │ │ ├── _input-group.scss │ │ ├── _jumbotron.scss │ │ ├── _list-group.scss │ │ ├── _media.scss │ │ ├── _mixins.scss │ │ ├── _modal.scss │ │ ├── _nav.scss │ │ ├── _navbar.scss │ │ ├── _pagination.scss │ │ ├── _popover.scss │ │ ├── _print.scss │ │ ├── _progress.scss │ │ ├── _reboot.scss │ │ ├── _root.scss │ │ ├── _tables.scss │ │ ├── _tooltip.scss │ │ ├── _transitions.scss │ │ ├── _type.scss │ │ ├── _utilities.scss │ │ ├── _variables.scss │ │ ├── bootstrap.scss │ │ ├── mixins │ │ │ ├── _alert.scss │ │ │ ├── _background-variant.scss │ │ │ ├── _badge.scss │ │ │ ├── _border-radius.scss │ │ │ ├── _box-shadow.scss │ │ │ ├── _breakpoints.scss │ │ │ ├── _buttons.scss │ │ │ ├── _caret.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _float.scss │ │ │ ├── _forms.scss │ │ │ ├── _gradients.scss │ │ │ ├── _grid-framework.scss │ │ │ ├── _grid.scss │ │ │ ├── _hover.scss │ │ │ ├── _image.scss │ │ │ ├── _list-group.scss │ │ │ ├── _lists.scss │ │ │ ├── _nav-divider.scss │ │ │ ├── _navbar-align.scss │ │ │ ├── _pagination.scss │ │ │ ├── _reset-text.scss │ │ │ ├── _resize.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _size.scss │ │ │ ├── _table-row.scss │ │ │ ├── _text-emphasis.scss │ │ │ ├── _text-hide.scss │ │ │ ├── _text-truncate.scss │ │ │ ├── _transition.scss │ │ │ └── _visibility.scss │ │ └── utilities │ │ │ ├── _align.scss │ │ │ ├── _background.scss │ │ │ ├── _borders.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _display.scss │ │ │ ├── _embed.scss │ │ │ ├── _flex.scss │ │ │ ├── _float.scss │ │ │ ├── _position.scss │ │ │ ├── _screenreaders.scss │ │ │ ├── _sizing.scss │ │ │ ├── _spacing.scss │ │ │ ├── _text.scss │ │ │ └── _visibility.scss │ └── resume │ │ ├── _bootstrap-overrides.scss │ │ ├── _global.scss │ │ ├── _mixins.scss │ │ ├── _nav.scss │ │ ├── _resume-item.scss │ │ ├── _variables.scss │ │ └── resume.scss ├── assets │ ├── img │ │ └── speccy.jpg │ └── main.scss ├── index.md ├── package-lock.json ├── rules.html ├── rules │ ├── 1-rulesets.md.html │ └── 2-custom-rulesets.md └── vendor │ ├── devicons │ ├── css │ │ ├── devicons.css │ │ ├── devicons.min.css │ │ └── devicons.scss │ └── fonts │ │ ├── devicons.eot │ │ ├── devicons.svg │ │ ├── devicons.ttf │ │ └── devicons.woff │ ├── font-awesome │ ├── css │ │ ├── font-awesome.css │ │ └── font-awesome.min.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── less │ │ ├── animated.less │ │ ├── bordered-pulled.less │ │ ├── core.less │ │ ├── fixed-width.less │ │ ├── font-awesome.less │ │ ├── icons.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── mixins.less │ │ ├── path.less │ │ ├── rotated-flipped.less │ │ ├── screen-reader.less │ │ ├── stacked.less │ │ └── variables.less │ └── scss │ │ ├── _animated.scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _path.scss │ │ ├── _rotated-flipped.scss │ │ ├── _screen-reader.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ └── font-awesome.scss │ └── simple-line-icons │ ├── css │ └── simple-line-icons.css │ ├── fonts │ ├── Simple-Line-Icons.eot │ ├── Simple-Line-Icons.svg │ ├── Simple-Line-Icons.ttf │ ├── Simple-Line-Icons.woff │ └── Simple-Line-Icons.woff2 │ ├── less │ └── simple-line-icons.less │ └── scss │ └── simple-line-icons.scss ├── examples ├── no-contact.yaml └── petstore.yaml ├── lib ├── config.js ├── loader.js ├── rules.js └── server.js ├── lint.js ├── package-lock.json ├── package.json ├── resolve.js ├── rules ├── default.yaml └── strict.yaml ├── schemas ├── gnostic-3.0.json ├── json_v5.json └── openapi-3.0.json ├── serve.js ├── speccy.js ├── templates └── index.html └── test ├── fixtures ├── config │ ├── empty.yaml │ ├── valid.json │ └── valid.yaml ├── integration │ ├── invalid-key.yaml │ ├── missing-contact.yaml │ └── missing-ref.yaml ├── loader │ ├── duplicates.yaml │ ├── json-schema │ │ ├── a.json │ │ └── openapi.yaml │ ├── not-openapi.txt │ ├── openapi.json │ ├── openapi.yaml │ └── refs │ │ ├── a.yaml │ │ ├── definitions │ │ └── b.yml │ │ ├── openapi.yaml │ │ └── parameters.yaml └── profiles │ ├── default.json │ └── strict.json ├── integration └── lint.test.js └── lib ├── config.test.js ├── loader.test.js ├── rules.test.js └── server.test.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | commands: 4 | # Command based on instructions from CircleCI blog for avoiding fork secret leakage or failures 5 | # https://circleci.com/blog/managing-secrets-when-you-have-pull-requests-from-outside-contributors/ 6 | early-return-forks: 7 | description: >- 8 | If this build is from a fork, stop executing the current job and return success. 9 | This is useful to avoid steps that will fail due to missing credentials. 10 | steps: 11 | - run: 12 | name: Early return if this build is from a forked PR 13 | command: | 14 | if [ -n "$CIRCLE_PR_NUMBER" ]; then 15 | echo "Nothing to do for forked PRs, so marking this step successful" 16 | circleci step halt 17 | fi 18 | 19 | install-and-test: 20 | description: >- 21 | Install everything required to run the test suite, then run it. 22 | steps: 23 | - checkout 24 | - restore_cache: 25 | key: dependency-cache-{{ checksum "package.json" }} 26 | - run: 27 | name: Update npm 28 | command: 'sudo npm install -g npm@latest' 29 | - run: 30 | name: Install npm dependencies 31 | command: npm install 32 | - save_cache: 33 | key: dependency-cache-{{ checksum "package.json" }} 34 | paths: 35 | - node_modules 36 | - run: 37 | name: Tests 38 | command: npx jest --ci --coverage 39 | - early-return-forks 40 | - run: 41 | name: Report Coverage 42 | command: npx coveralls < coverage/lcov.info 43 | 44 | jobs: 45 | node-latest: 46 | docker: 47 | - image: circleci/node:latest 48 | steps: 49 | - install-and-test 50 | 51 | node-11: 52 | docker: 53 | - image: circleci/node:11 54 | steps: 55 | - install-and-test 56 | 57 | node-10: 58 | docker: 59 | - image: circleci/node:10 60 | steps: 61 | - install-and-test 62 | 63 | node-8: 64 | docker: 65 | - image: circleci/node:8 66 | steps: 67 | - install-and-test 68 | 69 | build: 70 | machine: true 71 | steps: 72 | - checkout 73 | - run: 74 | name: Lint Dockerfile 75 | command: docker run --rm -i hadolint/hadolint < Dockerfile 76 | - run: 77 | name: Attempt Docker Build 78 | command: docker build . 79 | 80 | push-docker: 81 | machine: true 82 | environment: 83 | - DOCKER_REPOSITORY: wework/speccy 84 | steps: 85 | - checkout 86 | - early-return-forks 87 | - run: 88 | name: 89 | command: | 90 | 91 | docker_tag=$DOCKER_REPOSITORY:$(echo $CIRCLE_SHA1 | cut -c1-7) 92 | 93 | docker build -t $docker_tag . 94 | docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD 95 | 96 | if [[ -n "$CIRCLE_TAG" ]]; then 97 | version_number=$(echo $CIRCLE_TAG | sed "s/^v//") 98 | 99 | patch_tag=$DOCKER_REPOSITORY:$version_number 100 | docker tag $docker_tag $patch_tag 101 | 102 | major_tag=$DOCKER_REPOSITORY:$(echo $version_number | cut -d . -f 1) 103 | docker tag $docker_tag $major_tag 104 | 105 | minor_tag=$DOCKER_REPOSITORY:$(echo $version_number | cut -d . -f 1-2) 106 | docker tag $docker_tag $minor_tag 107 | 108 | docker tag $docker_tag $DOCKER_REPOSITORY:latest 109 | else 110 | tag=$DOCKER_REPOSITORY:$(echo $CIRCLE_BRANCH | sed "s|/|-|g") 111 | docker tag $docker_tag $tag 112 | fi 113 | 114 | docker push $DOCKER_REPOSITORY 115 | 116 | workflows: 117 | version: 2 118 | commit: 119 | jobs: 120 | - build 121 | - node-latest 122 | - node-11 123 | - node-10 124 | - node-8 125 | 126 | deploy: 127 | jobs: 128 | - push-docker: 129 | filters: 130 | tags: 131 | only: /^v.*/ 132 | 133 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | /.circleci 2 | /.git 3 | /.github 4 | /*.md 5 | /Dockerfile 6 | /docs 7 | /.dockerignore 8 | /.editorconfig 9 | /.eslintrc.json 10 | /.gitignore 11 | /test 12 | 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_style = space 6 | indent_size = 4 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "rules": { 8 | "accessor-pairs": "error", 9 | "array-bracket-spacing": [ 10 | "error", 11 | "never" 12 | ], 13 | "array-callback-return": "error", 14 | "arrow-body-style": "error", 15 | "arrow-parens": [ 16 | "error", 17 | "as-needed" 18 | ], 19 | "arrow-spacing": [ 20 | "error", 21 | { 22 | "after": true, 23 | "before": true 24 | } 25 | ], 26 | "block-spacing": "error", 27 | "brace-style": [ 28 | "error", 29 | "stroustrup" 30 | ], 31 | "camelcase": "error", 32 | "class-methods-use-this": "error", 33 | "comma-style": [ 34 | "error", 35 | "last" 36 | ], 37 | "computed-property-spacing": [ 38 | "error", 39 | "never" 40 | ], 41 | "consistent-this": "error", 42 | "default-case": "error", 43 | "dot-location": [ 44 | "error", 45 | "property" 46 | ], 47 | "dot-notation": [ 48 | "error", 49 | { 50 | "allowKeywords": true 51 | } 52 | ], 53 | "eol-last": "error", 54 | "func-call-spacing": "error", 55 | "id-blacklist": "error", 56 | "id-match": "error", 57 | "jsx-quotes": "error", 58 | "linebreak-style": [ 59 | "error", 60 | "unix" 61 | ], 62 | "lines-around-comment": "error", 63 | "lines-around-directive": "error", 64 | "max-nested-callbacks": "error", 65 | "max-statements-per-line": "error", 66 | "multiline-ternary": [ 67 | "error", 68 | "never" 69 | ], 70 | "new-parens": "error", 71 | "no-alert": "error", 72 | "no-array-constructor": "error", 73 | "no-bitwise": "error", 74 | "no-caller": "error", 75 | "no-confusing-arrow": "error", 76 | "no-console": "off", 77 | "no-div-regex": "error", 78 | "no-duplicate-imports": "error", 79 | "no-empty": [ 80 | "error", 81 | { 82 | "allowEmptyCatch": true 83 | } 84 | ], 85 | "no-eq-null": "error", 86 | "no-eval": "error", 87 | "no-extra-bind": "error", 88 | "no-extra-label": "error", 89 | "no-floating-decimal": "error", 90 | "no-global-assign": "error", 91 | "no-implicit-globals": "error", 92 | "no-implied-eval": "error", 93 | "no-inner-declarations": [ 94 | "error", 95 | "functions" 96 | ], 97 | "no-invalid-this": "error", 98 | "no-iterator": "error", 99 | "no-label-var": "error", 100 | "no-labels": "error", 101 | "no-lone-blocks": "error", 102 | "no-mixed-operators": "error", 103 | "no-mixed-requires": "error", 104 | "no-multi-spaces": "error", 105 | "no-multi-str": "error", 106 | "no-multiple-empty-lines": "error", 107 | "no-negated-condition": "error", 108 | "no-new": "error", 109 | "no-new-func": "error", 110 | "no-new-object": "error", 111 | "no-new-require": "error", 112 | "no-new-wrappers": "error", 113 | "no-octal-escape": "error", 114 | "no-path-concat": "error", 115 | "no-proto": "error", 116 | "no-prototype-builtins": "error", 117 | "no-restricted-globals": "error", 118 | "no-restricted-imports": "error", 119 | "no-restricted-modules": "error", 120 | "no-restricted-properties": "error", 121 | "no-restricted-syntax": "error", 122 | "no-script-url": "error", 123 | "no-self-compare": "error", 124 | "no-sequences": "error", 125 | "no-shadow-restricted-names": "error", 126 | "no-spaced-func": "error", 127 | "no-template-curly-in-string": "error", 128 | "no-throw-literal": "error", 129 | "no-trailing-spaces": "error", 130 | "no-undef-init": "error", 131 | "no-undefined": "error", 132 | "no-underscore-dangle": "error", 133 | "no-unmodified-loop-condition": "error", 134 | "no-unneeded-ternary": [ 135 | "error", 136 | { 137 | "defaultAssignment": true 138 | } 139 | ], 140 | "no-unsafe-negation": "error", 141 | "no-unused-expressions": "error", 142 | "no-unused-vars": "warn", 143 | "no-useless-call": "error", 144 | "no-useless-computed-key": "error", 145 | "no-useless-concat": "error", 146 | "no-useless-constructor": "error", 147 | "no-useless-escape": "error", 148 | "no-useless-rename": "error", 149 | "no-void": "error", 150 | "no-whitespace-before-property": "error", 151 | "no-with": "error", 152 | "object-curly-newline": "error", 153 | "object-property-newline": [ 154 | "error", 155 | { 156 | "allowMultiplePropertiesPerLine": true 157 | } 158 | ], 159 | "one-var-declaration-per-line": "error", 160 | "prefer-numeric-literals": "error", 161 | "prefer-rest-params": "error", 162 | "prefer-spread": "error", 163 | "radix": "error", 164 | "rest-spread-spacing": "error", 165 | "semi-spacing": "error", 166 | "sort-imports": "error", 167 | "sort-vars": "error", 168 | "space-in-parens": [ 169 | "error", 170 | "never" 171 | ], 172 | "space-unary-ops": "error", 173 | "strict": "error", 174 | "symbol-description": "error", 175 | "template-curly-spacing": "error", 176 | "unicode-bom": [ 177 | "error", 178 | "never" 179 | ], 180 | "wrap-iife": "error", 181 | "yield-star-spacing": "error", 182 | "yoda": [ 183 | "error", 184 | "never" 185 | ] 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Detailed description 4 | 5 | Provide a detailed description of the change or addition you are proposing. 6 | 7 | Make it clear if the issue is a bug, an enhancement or just a question. 8 | 9 | ## Context 10 | 11 | Why is this change important to you? How would you use it? 12 | 13 | How can it benefit other users? 14 | 15 | ## Possible implementation 16 | 17 | Not obligatory, but suggest an idea for implementing addition or change. 18 | 19 | ## Your environment 20 | 21 | Include as many relevant details about the environment you experienced the bug in and how to reproduce it. 22 | 23 | * Node Version: 24 | * Operating system and version (e.g. Ubuntu 16.04, Windows 7): 25 | * Link to your project: 26 | * ... 27 | * ... 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build.sh 2 | .coveralls.yml 3 | .node-version 4 | .nyc_output 5 | yarn.lock 6 | resolved.yaml 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directories 29 | node_modules 30 | jspm_packages 31 | 32 | # Optional npm cache directory 33 | .npm 34 | 35 | # Optional REPL history 36 | .node_repl_history 37 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at oss-conduct@wework.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | 78 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:11.1-alpine as builder 2 | 3 | WORKDIR /opt/speccy 4 | 5 | COPY . /opt/speccy/ 6 | 7 | ENV NODE_ENV=production 8 | 9 | # Ignore version locking to avoid undesired breaks due to changes in upstream 10 | # hadolint ignore=DL3018 11 | RUN apk add --no-cache git \ 12 | && npm install 13 | 14 | FROM node:11.1-alpine 15 | 16 | COPY --from=builder /opt/speccy/ /opt/speccy/ 17 | 18 | RUN ln -s /opt/speccy/speccy.js /usr/local/bin/speccy 19 | 20 | WORKDIR /project 21 | 22 | EXPOSE 5000 23 | ENTRYPOINT ["speccy"] 24 | CMD ["-h"] 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 WeWork 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .sass-cache 3 | .jekyll-metadata 4 | -------------------------------------------------------------------------------- /docs/.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 2.5.1 2 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 18 | 19 |
20 |

404

21 | 22 |

Page not found :(

23 |

The requested page could not be found.

24 |
25 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | speccy.io -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem 'github-pages', group: :jekyll_plugins 4 | gem 'jekyll-assets' 5 | gem 'jekyll-seo-tag' 6 | 7 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 8 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 9 | # gem "github-pages", group: :jekyll_plugins 10 | 11 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 12 | gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] 13 | -------------------------------------------------------------------------------- /docs/Rakefile: -------------------------------------------------------------------------------- 1 | title: "Speccy - The #WellActually Assistant for your API Specifications!" 2 | description: >- 3 | Make sure your OpenAPI 3.0 specifications are more than just valid, make sure they're useful! 4 | url: "https://speccy.io/" # the base hostname & protocol for your site, e.g. http://example.com 5 | 6 | # Build settings 7 | markdown: kramdown 8 | 9 | plugins: 10 | - jekyll-assets 11 | - jekyll-seo-tag 12 | 13 | exclude: 14 | - Gemfile 15 | - Gemfile.lock 16 | - .tools-versions 17 | - .gitignore 18 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: "Speccy - The #WellActually Assistant for your API Specifications!" 2 | description: >- 3 | Make sure your OpenAPI 3.0 specifications are more than just valid, make sure they're useful! 4 | url: "https://speccy.io/" # the base hostname & protocol for your site, e.g. http://example.com 5 | 6 | # Build settings 7 | markdown: kramdown 8 | 9 | plugins: 10 | - jekyll-assets 11 | - jekyll-seo-tag 12 | 13 | exclude: 14 | - Gemfile 15 | - Gemfile.lock 16 | - .tools-versions 17 | - .gitignore 18 | - node_modules/ 19 | -------------------------------------------------------------------------------- /docs/_includes/footer.html: -------------------------------------------------------------------------------- 1 | 51 | 52 | -------------------------------------------------------------------------------- /docs/_includes/google-analytics.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /docs/_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {%- seo -%} 6 | 7 | {%- if jekyll.environment == 'production' and site.google_analytics -%} 8 | {%- include google-analytics.html -%} 9 | {%- endif -%} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/_includes/rules-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% for rule in include.rules %} 10 | 11 | 14 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 |
NameOpenAPI ObjectDescription
12 | {{ rule.name }} 13 | 15 | {% if rule.object == "*" %} 16 | everything 17 | {% else %} 18 | {{ rule.object }} 19 | {% endif %} 20 | {{ rule.description }}
{{ rule.more | markdownify }}
28 | -------------------------------------------------------------------------------- /docs/_includes/sidenav.html: -------------------------------------------------------------------------------- 1 | {%- assign default_paths = site.pages | map: "path" -%} 2 | {%- assign page_paths = site.header_pages | default: default_paths -%} 3 | 4 | 28 | -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {%- include head.html -%} 5 | 6 | 7 | 8 | {%- include sidenav.html -%} 9 | 10 |
11 | 12 | {{ content }} 13 | 14 |
15 | 16 | {%- include footer.html -%} 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |
7 |

Speccy

8 |

A handy toolkit for OpenAPI, with a linter to enforce quality rules, documentation rendering, and resolution.

9 |

10 | GitHub 11 | NPM 12 |

13 |
14 |
15 | 16 |
17 | {{ content }} 18 |
19 | -------------------------------------------------------------------------------- /docs/_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 |
7 |

{{ page.title }}

8 | 9 | {{ content }} 10 |
11 |
12 | -------------------------------------------------------------------------------- /docs/_sass/_base.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.0.0 (https://getbootstrap.com) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | @import "bootstrap/bootstrap"; 9 | -------------------------------------------------------------------------------- /docs/_sass/_layout.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Open Sans', serif; 3 | padding-top: 54px; 4 | color: #868e96; 5 | } 6 | 7 | @media (min-width: 992px) { 8 | body { 9 | padding-top: 0; 10 | padding-left: 17rem; 11 | } 12 | } 13 | 14 | h1, 15 | h2, 16 | h3, 17 | h4, 18 | h5, 19 | h6 { 20 | font-family: 'Saira Extra Condensed', serif; 21 | font-weight: 700; 22 | text-transform: uppercase; 23 | color: #343a40; 24 | } 25 | 26 | h1 { 27 | font-size: 6rem; 28 | line-height: 5.5rem; 29 | } 30 | 31 | h2 { 32 | font-size: 3.5rem; 33 | } 34 | 35 | .subheading { 36 | text-transform: uppercase; 37 | font-weight: 500; 38 | font-family: 'Saira Extra Condensed', serif; 39 | font-size: 1.35rem; 40 | } 41 | 42 | #sideNav .navbar-nav .nav-item .nav-link { 43 | font-weight: 600; 44 | } 45 | 46 | @media (min-width: 992px) { 47 | #sideNav { 48 | text-align: center; 49 | position: fixed; 50 | top: 0; 51 | left: 0; 52 | display: flex; 53 | flex-direction: column; 54 | width: 17rem; 55 | height: 100vh; 56 | } 57 | #sideNav .navbar-brand { 58 | display: flex; 59 | margin: auto auto 0; 60 | padding: 0.5rem; 61 | } 62 | #sideNav .navbar-brand .img-profile { 63 | max-width: 10rem; 64 | max-height: 10rem; 65 | border: 0.5rem solid rgba(255, 255, 255, 0.2); 66 | } 67 | #sideNav .navbar-collapse { 68 | display: flex; 69 | align-items: flex-start; 70 | flex-grow: 0; 71 | width: 100%; 72 | margin-bottom: auto; 73 | } 74 | #sideNav .navbar-collapse .navbar-nav { 75 | flex-direction: column; 76 | width: 100%; 77 | } 78 | #sideNav .navbar-collapse .navbar-nav .nav-item { 79 | display: block; 80 | } 81 | #sideNav .navbar-collapse .navbar-nav .nav-item .nav-link { 82 | display: block; 83 | color: black; 84 | } 85 | } 86 | 87 | .bg-primary { 88 | background-color: #ffd16d !important; 89 | } 90 | -------------------------------------------------------------------------------- /docs/_sass/bootstrap/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | position: relative; 7 | padding: $alert-padding-y $alert-padding-x; 8 | margin-bottom: $alert-margin-bottom; 9 | border: $alert-border-width solid transparent; 10 | @include border-radius($alert-border-radius); 11 | } 12 | 13 | // Headings for larger alerts 14 | .alert-heading { 15 | // Specified to prevent conflicts of changing $headings-color 16 | color: inherit; 17 | } 18 | 19 | // Provide class for links that match alerts 20 | .alert-link { 21 | font-weight: $alert-link-font-weight; 22 | } 23 | 24 | 25 | // Dismissible alerts 26 | // 27 | // Expand the right padding and account for the close button's positioning. 28 | 29 | .alert-dismissible { 30 | padding-right: ($close-font-size + $alert-padding-x * 2); 31 | 32 | // Adjust close link position 33 | .close { 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | padding: $alert-padding-y $alert-padding-x; 38 | color: inherit; 39 | } 40 | } 41 | 42 | 43 | // Alternate styles 44 | // 45 | // Generate contextual modifier classes for colorizing the alert. 46 | 47 | @each $color, $value in $theme-colors { 48 | .alert-#{$color} { 49 | @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /docs/_sass/bootstrap/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | display: inline-block; 8 | padding: $badge-padding-y $badge-padding-x; 9 | font-size: $badge-font-size; 10 | font-weight: $badge-font-weight; 11 | line-height: 1; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | @include border-radius($badge-border-radius); 16 | 17 | // Empty badges collapse automatically 18 | &:empty { 19 | display: none; 20 | } 21 | } 22 | 23 | // Quick fix for badges in buttons 24 | .btn .badge { 25 | position: relative; 26 | top: -1px; 27 | } 28 | 29 | // Pill badges 30 | // 31 | // Make them extra rounded with a modifier to replace v3's badges. 32 | 33 | .badge-pill { 34 | padding-right: $badge-pill-padding-x; 35 | padding-left: $badge-pill-padding-x; 36 | @include border-radius($badge-pill-border-radius); 37 | } 38 | 39 | // Colors 40 | // 41 | // Contextual variations (linked badges get darker on :hover). 42 | 43 | @each $color, $value in $theme-colors { 44 | .badge-#{$color} { 45 | @include badge-variant($value); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /docs/_sass/bootstrap/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: $breadcrumb-padding-y $breadcrumb-padding-x; 5 | margin-bottom: $breadcrumb-margin-bottom; 6 | list-style: none; 7 | background-color: $breadcrumb-bg; 8 | @include border-radius($border-radius); 9 | } 10 | 11 | .breadcrumb-item { 12 | // The separator between breadcrumbs (by default, a forward-slash: "/") 13 | + .breadcrumb-item::before { 14 | display: inline-block; // Suppress underlining of the separator in modern browsers 15 | padding-right: $breadcrumb-item-padding; 16 | padding-left: $breadcrumb-item-padding; 17 | color: $breadcrumb-divider-color; 18 | content: "#{$breadcrumb-divider}"; 19 | } 20 | 21 | // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built 22 | // without `