diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..4b9c305 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules/* +test/project/node_modules +build diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000..0895cdf --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,21 @@ +env: + node: true +parser: "@typescript-eslint/parser" +extends: + - "plugin:@typescript-eslint/recommended" + - "prettier/@typescript-eslint" + - "plugin:prettier/recommended" +parserOptions: + ecmaVersion: 2018 + sourceType: module + project: tsconfig.json +rules: + "@typescript-eslint/array-type": [error, generic] + "@typescript-eslint/interface-name-prefix": [error, never] + "@typescript-eslint/promise-function-async": warning + "@typescript-eslint/explicit-function-return-type": false +overrides: + - files: ["src/**/*.test.ts"] + env: + node: true + jest: true diff --git a/.vscode/settings.json b/.vscode/settings.json index 97bef4c..6887c63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,14 @@ { - "typescript.tsdk": "./node_modules/typescript/lib" + "typescript.tsdk": "./node_modules/typescript/lib", + "editor.formatOnSave": true, + "eslint.autoFixOnSave": true, + "prettier.eslintIntegration": true, + "eslint.enable": true, + "eslint.validate": [ + "javascript", + { + "language": "typescript", + "autoFix": true + } + ] } diff --git a/package-lock.json b/package-lock.json index 2ebbf46..abd52db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@conqa/serverless-openapi-documentation", - "version": "1.0.4", + "version": "1.1.0-alpha", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -544,6 +544,60 @@ "integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.7.0.tgz", + "integrity": "sha512-NUSz1aTlIzzTjFFVFyzrbo8oFjHg3K/M9MzYByqbMCxeFdErhLAcGITVfXzSz+Yvp5OOpMu3HkIttB0NyKl54Q==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "1.7.0", + "@typescript-eslint/typescript-estree": "1.7.0", + "eslint-utils": "1.3.1", + "regexpp": "2.0.1", + "requireindex": "1.2.0", + "tsutils": "3.10.0" + }, + "dependencies": { + "tsutils": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz", + "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.7.0.tgz", + "integrity": "sha512-1QFKxs2V940372srm12ovSE683afqc1jB6zF/f8iKhgLz1yoSjYeGHipasao33VXKI+0a/ob9okeogGdKGvvlg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.7.0", + "eslint-scope": "4.0.3", + "eslint-visitor-keys": "1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.7.0.tgz", + "integrity": "sha512-K5uedUxVmlYrVkFbyV3htDipvLqTE3QMOUQEHYJaKtgzxj6r7c5Ca/DG1tGgFxX+fsbi9nDIrf4arq7Ib7H/Yw==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, "abab": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", @@ -574,6 +628,12 @@ } } }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, "acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", @@ -1186,12 +1246,6 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -1295,6 +1349,12 @@ "upath": "1.1.2" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -1858,30 +1918,6 @@ "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==", "dev": true }, - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", - "dev": true, - "requires": { - "esutils": "1.1.6", - "isarray": "0.0.1" - }, - "dependencies": { - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "domexception": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", @@ -1939,6 +1975,12 @@ "safer-buffer": "2.1.2" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", @@ -2039,11 +2081,304 @@ } } }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0", + "ajv": "6.10.0", + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "debug": "4.1.1", + "doctrine": "3.0.0", + "eslint-scope": "4.0.3", + "eslint-utils": "1.3.1", + "eslint-visitor-keys": "1.0.0", + "espree": "5.0.1", + "esquery": "1.0.1", + "esutils": "2.0.2", + "file-entry-cache": "5.0.1", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.3", + "globals": "11.12.0", + "ignore": "4.0.6", + "import-fresh": "3.0.0", + "imurmurhash": "0.1.4", + "inquirer": "6.3.1", + "js-yaml": "3.13.1", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "progress": "2.0.3", + "regexpp": "2.0.1", + "semver": "5.7.0", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "5.2.3", + "text-table": "0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "1.0.5", + "path-key": "2.0.1", + "semver": "5.7.0", + "shebang-command": "1.2.0", + "which": "1.3.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "2.1.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "0.7.0", + "iconv-lite": "0.4.24", + "tmp": "0.0.33" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "inquirer": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", + "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "dev": true, + "requires": { + "ansi-escapes": "3.2.0", + "chalk": "2.4.2", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "3.0.3", + "figures": "2.0.0", + "lodash": "4.17.11", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rxjs": "6.5.1", + "string-width": "2.1.1", + "strip-ansi": "5.2.0", + "through": "2.3.8" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "4.1.0" + } + } + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + } + } + }, + "eslint-config-prettier": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.2.0.tgz", + "integrity": "sha512-y0uWc/FRfrHhpPZCYflWC8aE0KRJRY04rdZVfl8cL3sEZmOYyaBdhdlQPjKZBnuRMyLVK+JUZr7HaZFClQiH4w==", + "dev": true, + "requires": { + "get-stdin": "6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz", + "integrity": "sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "1.0.0" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "4.2.1", + "estraverse": "4.2.0" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "6.1.1", + "acorn-jsx": "5.0.1", + "eslint-visitor-keys": "1.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", @@ -2257,6 +2592,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -2296,6 +2637,15 @@ "object-assign": "4.1.1" } }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "2.0.1" + } + }, "file-type": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", @@ -2356,6 +2706,23 @@ "locate-path": "2.0.0" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2956,6 +3323,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", @@ -3337,12 +3710,36 @@ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", "dev": true }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "1.0.1", + "resolve-from": "4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -4787,6 +5184,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -4974,6 +5377,12 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -5656,6 +6065,15 @@ "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", "dev": true }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "3.1.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -5851,6 +6269,21 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "prettier": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", + "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "1.2.0" + } + }, "pretty-format": { "version": "24.8.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", @@ -5877,6 +6310,12 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise-queue": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", @@ -6053,6 +6492,12 @@ "safe-regex": "1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "registry-auth-token": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", @@ -6172,6 +6617,12 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", @@ -6248,6 +6699,15 @@ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", "dev": true }, + "rxjs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz", + "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==", + "dev": true, + "requires": { + "tslib": "1.9.3" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -6584,6 +7044,17 @@ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "astral-regex": "1.0.0", + "is-fullwidth-code-point": "2.0.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -6986,6 +7457,70 @@ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", "dev": true }, + "table": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", + "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "dev": true, + "requires": { + "ajv": "6.10.0", + "lodash": "4.17.11", + "slice-ansi": "2.1.0", + "string-width": "3.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "7.0.3", + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "5.2.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "4.1.0" + } + } + } + }, "tabtab": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tabtab/-/tabtab-2.2.2.tgz", @@ -7099,6 +7634,12 @@ } } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", @@ -7305,83 +7846,6 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, - "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.0.0", - "builtin-modules": "1.1.1", - "chalk": "2.4.2", - "commander": "2.20.0", - "diff": "3.5.0", - "glob": "7.1.3", - "js-yaml": "3.13.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "resolve": "1.10.1", - "semver": "5.7.0", - "tslib": "1.9.3", - "tsutils": "2.29.0" - } - }, - "tslint-config-standard": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/tslint-config-standard/-/tslint-config-standard-8.0.1.tgz", - "integrity": "sha512-OWG+NblgjQlVuUS/Dmq3ax2v5QDZwRx4L0kEuDi7qFY9UI6RJhhNfoCV1qI4el8Fw1c5a5BTrjQJP0/jhGXY/Q==", - "dev": true, - "requires": { - "tslint-eslint-rules": "5.4.0" - } - }, - "tslint-config-temando": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/tslint-config-temando/-/tslint-config-temando-1.6.1.tgz", - "integrity": "sha512-49syrumg5jory9H6jNDEfhES1EXWimKwxm48hJKWNVx4OtfHvKp+Tti5joUTu3ga0GRoOaUKW3McaCuGgNudyw==", - "dev": true, - "requires": { - "tslint-config-standard": "8.0.1", - "tslint-eslint-rules": "5.4.0" - } - }, - "tslint-eslint-rules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", - "integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==", - "dev": true, - "requires": { - "doctrine": "0.7.2", - "tslib": "1.9.0", - "tsutils": "3.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", - "dev": true - }, - "tsutils": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz", - "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==", - "dev": true, - "requires": { - "tslib": "1.9.0" - } - } - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "1.9.3" - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -7864,6 +8328,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, "write-file-atomic": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", diff --git a/package.json b/package.json index 7991e6f..f5cd931 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "test": "jest -c ./jest.config.js", "test:build": "jest -c '{ \"testRegex\": \".spec.js$\"}' build", "test:coverage": "jest -c ./jest.config.js --coverage", - "lint": "tslint --format stylish -p tsconfig.json --type-check -c tslint.json", + "lint": "eslint --ext .ts,.tsx .", + "lint:fix": "npm run lint -- --fix", "preversion": "npm run lint && npm run build && npm run test:build && changelog-verify CHANGELOG.md", "version": "version-changelog CHANGELOG.md && changelog-verify CHANGELOG.md && git add CHANGELOG.md", "release": "cd build && npm publish", @@ -48,14 +49,18 @@ "@types/node": "^8.10.48", "@types/serverless": "^1.18.2", "@types/uuid": "^3.4.4", + "@typescript-eslint/eslint-plugin": "^1.7.0", + "@typescript-eslint/parser": "^1.7.0", "changelog-verify": "^1.0.4", + "eslint": "^5.16.0", + "eslint-config-prettier": "^4.2.0", + "eslint-plugin-prettier": "^3.0.1", "jest": "^24.8.0", + "openapi-types": "^1.3.4", + "prettier": "^1.17.0", "serverless": "^1.41.1", "ts-jest": "^24.0.2", - "openapi-types": "^1.3.4", "ts-node": "^3.1.0", - "tslint": "^5.4.3", - "tslint-config-temando": "^1.1.4", "typescript": "^3.4.5", "version-changelog": "^2.1.0" }, diff --git a/src/DefinitionGenerator.ts b/src/DefinitionGenerator.ts index 342bbc9..5f95147 100644 --- a/src/DefinitionGenerator.ts +++ b/src/DefinitionGenerator.ts @@ -1,40 +1,46 @@ -import _ = require('lodash'); +import _ = require("lodash"); // tslint:disable-next-line no-submodule-imports -import { validateSync as openApiValidatorSync } from 'swagger2openapi/validate'; -import * as uuid from 'uuid'; - -import { parseModels } from './parse'; -import { IDefinition, IDefinitionConfig, IOperation, IParameterConfig, IServerlessFunctionConfig } from './types'; -import { cleanSchema } from './utils'; +import { validateSync as openApiValidatorSync } from "swagger2openapi/validate"; +import * as uuid from "uuid"; + +import { parseModels } from "./parse"; +import { + Definition, + DefinitionConfig, + Operation, + ParameterConfig, + ServerlessFunctionConfig +} from "./types"; +import { cleanSchema } from "./utils"; export class DefinitionGenerator { // The OpenAPI version we currently validate against - public version = '3.0.0'; + public version = "3.0.0"; // Base configuration object - public definition = { + public definition: Definition = { openapi: this.version, - components: {}, + components: {} }; - public config: IDefinitionConfig; + public config: DefinitionConfig; private root: string; /** * Constructor */ - constructor (config: IDefinitionConfig, root: string) { + public constructor(config: DefinitionConfig, root: string) { this.config = _.cloneDeep(config); this.root = root; } - public async parse () { + public async parse() { const { - title = '', - description = '', + title = "", + description = "", version = uuid.v4(), - models, + models } = this.config; _.merge(this.definition, { @@ -43,8 +49,8 @@ export class DefinitionGenerator { paths: {}, components: { schemas: {}, - securitySchemes: {}, - }, + securitySchemes: {} + } }); this.definition.components.schemas = await parseModels(models, this.root); @@ -52,7 +58,12 @@ export class DefinitionGenerator { return this; } - public validate (): { valid: boolean, context: string[], warnings: any[], error?: any[] } { + public validate(): { + valid: boolean; + context: Array; + warnings: Array; + error?: Array; + } { const payload: any = {}; try { @@ -68,7 +79,7 @@ export class DefinitionGenerator { * Add Paths to OpenAPI Configuration from Serverless function documentation * @param config Add */ - public readFunctions (config: IServerlessFunctionConfig[]): void { + public readFunctions(config: Array): void { // loop through function configurations for (const funcConfig of config) { // loop through http events @@ -81,9 +92,9 @@ export class DefinitionGenerator { [`/${httpEventConfig.path}`]: { [httpEventConfig.method.toLowerCase()]: this.getOperationFromConfig( funcConfig._functionName, - httpEventConfig.documentation, - ), - }, + httpEventConfig.documentation + ) + } }; // merge path configuration into main configuration @@ -100,9 +111,12 @@ export class DefinitionGenerator { * @param funcName * @param documentationConfig */ - private getOperationFromConfig (funcName: string, documentationConfig): IOperation { - const operationObj: IOperation = { - operationId: funcName, + private getOperationFromConfig( + funcName: string, + documentationConfig + ): Operation { + const operationObj: Operation = { + operationId: funcName }; if (documentationConfig.summary) { @@ -122,7 +136,9 @@ export class DefinitionGenerator { } if (documentationConfig.requestBody) { - operationObj.requestBody = this.getRequestBodiesFromConfig(documentationConfig); + operationObj.requestBody = this.getRequestBodiesFromConfig( + documentationConfig + ); } operationObj.parameters = this.getParametersFromConfig(documentationConfig); @@ -136,19 +152,19 @@ export class DefinitionGenerator { * Derives Path, Query and Request header parameters from Serverless documentation * @param documentationConfig */ - private getParametersFromConfig (documentationConfig): IParameterConfig[] { - const parameters: IParameterConfig[] = []; + private getParametersFromConfig(documentationConfig): Array { + const parameters: Array = []; // Build up parameters from configuration for each parameter type - for (const type of ['path', 'query', 'header', 'cookie']) { + for (const type of ["path", "query", "header", "cookie"]) { let paramBlock; - if (type === 'path' && documentationConfig.pathParams) { + if (type === "path" && documentationConfig.pathParams) { paramBlock = documentationConfig.pathParams; - } else if (type === 'query' && documentationConfig.queryParams) { + } else if (type === "query" && documentationConfig.queryParams) { paramBlock = documentationConfig.queryParams; - } else if (type === 'header' && documentationConfig.requestHeaders) { + } else if (type === "header" && documentationConfig.requestHeaders) { paramBlock = documentationConfig.requestHeaders; - } else if (type === 'cookie' && documentationConfig.cookieParams) { + } else if (type === "cookie" && documentationConfig.cookieParams) { paramBlock = documentationConfig.cookieParams; } else { continue; @@ -156,34 +172,34 @@ export class DefinitionGenerator { // Loop through each parameter in a parameter block and add parameters to array for (const parameter of paramBlock) { - const parameterConfig: IParameterConfig = { + const parameterConfig: ParameterConfig = { name: parameter.name, in: type, - description: parameter.description || '', - required: parameter.required || false, // Note: all path parameters must be required + description: parameter.description || "", + required: parameter.required || false // Note: all path parameters must be required }; // if type is path, then required must be true (@see OpenAPI 3.0-RC1) - if (type === 'path') { + if (type === "path") { parameterConfig.required = true; - } else if (type === 'query') { - parameterConfig.allowEmptyValue = parameter.allowEmptyValue || false; // OpenAPI default is false + } else if (type === "query") { + parameterConfig.allowEmptyValue = parameter.allowEmptyValue || false; // OpenAPI default is false - if ('allowReserved' in parameter) { + if ("allowReserved" in parameter) { parameterConfig.allowReserved = parameter.allowReserved || false; } } - if ('deprecated' in parameter) { + if ("deprecated" in parameter) { parameterConfig.deprecated = parameter.deprecated; } - if ('style' in parameter) { + if ("style" in parameter) { parameterConfig.style = parameter.style; parameterConfig.explode = parameter.explode ? parameter.explode - : parameter.style === 'form'; + : parameter.style === "form"; } if (parameter.schema) { @@ -211,39 +227,56 @@ export class DefinitionGenerator { * Derives request body schemas from event documentation configuration * @param documentationConfig */ - private getRequestBodiesFromConfig (documentationConfig) { + private getRequestBodiesFromConfig(documentationConfig) { const requestBodies = {}; if (!documentationConfig.requestModels) { - throw new Error(`Required requestModels in: ${JSON.stringify(documentationConfig, null, 2)}`); + throw new Error( + `Required requestModels in: ${JSON.stringify( + documentationConfig, + null, + 2 + )}` + ); } // Does this event have a request model? if (documentationConfig.requestModels) { // For each request model type (Sorted by "Content-Type") - for (const requestModelType of Object.keys(documentationConfig.requestModels)) { + for (const requestModelType of Object.keys( + documentationConfig.requestModels + )) { // get schema reference information - const requestModel = this.config.models.filter( - (model) => model.name === documentationConfig.requestModels[requestModelType], - ).pop(); + const requestModel = this.config.models + .filter( + model => + model.name === documentationConfig.requestModels[requestModelType] + ) + .pop(); if (requestModel) { const reqModelConfig = { schema: { - $ref: `#/components/schemas/${documentationConfig.requestModels[requestModelType]}`, - }, + $ref: `#/components/schemas/${ + documentationConfig.requestModels[requestModelType] + }` + } }; this.attachExamples(requestModel, reqModelConfig); - const reqBodyConfig: { content: object, description?: string } = { + const reqBodyConfig: { content: object; description?: string } = { content: { - [requestModelType]: reqModelConfig, - }, + [requestModelType]: reqModelConfig + } }; - if (documentationConfig.requestBody && 'description' in documentationConfig.requestBody) { - reqBodyConfig.description = documentationConfig.requestBody.description; + if ( + documentationConfig.requestBody && + "description" in documentationConfig.requestBody + ) { + reqBodyConfig.description = + documentationConfig.requestBody.description; } _.merge(requestBodies, reqBodyConfig); @@ -254,7 +287,7 @@ export class DefinitionGenerator { return requestBodies; } - private attachExamples (target, config) { + private attachExamples(target, config) { if (target.examples && Array.isArray(target.examples)) { _.merge(config, { examples: _.cloneDeep(target.examples) }); } else if (target.example) { @@ -266,33 +299,38 @@ export class DefinitionGenerator { * Gets response bodies from documentation config * @param documentationConfig */ - private getResponsesFromConfig (documentationConfig) { + private getResponsesFromConfig(documentationConfig) { const responses = {}; if (documentationConfig.methodResponses) { for (const response of documentationConfig.methodResponses) { - const methodResponseConfig: { description: any, content: object, headers?: object } = { - description: ( - (response.responseBody && 'description' in response.responseBody) + const methodResponseConfig: { + description: any; + content: object; + headers?: object; + } = { + description: + response.responseBody && "description" in response.responseBody ? response.responseBody.description - : `Status ${response.statusCode} Response` - ), - content: this.getResponseContent(response.responseModels), + : `Status ${response.statusCode} Response`, + content: this.getResponseContent(response.responseModels) }; if (response.responseHeaders) { methodResponseConfig.headers = {}; for (const header of response.responseHeaders) { methodResponseConfig.headers[header.name] = { - description: header.description || `${header.name} header`, + description: header.description || `${header.name} header` }; if (header.schema) { - methodResponseConfig.headers[header.name].schema = cleanSchema(header.schema); + methodResponseConfig.headers[header.name].schema = cleanSchema( + header.schema + ); } } } _.merge(responses, { - [response.statusCode]: methodResponseConfig, + [response.statusCode]: methodResponseConfig }); } } @@ -300,31 +338,31 @@ export class DefinitionGenerator { return responses; } - private getResponseContent (response) { + private getResponseContent(response) { const content = {}; for (const responseKey of Object.keys(response)) { - const responseModel = this.config.models.find((model) => - model.name === response[responseKey], + const responseModel = this.config.models.find( + model => model.name === response[responseKey] ); if (responseModel) { const resModelConfig = { schema: { - $ref: `#/components/schemas/${response[responseKey]}`, - }, + $ref: `#/components/schemas/${response[responseKey]}` + } }; this.attachExamples(responseModel, resModelConfig); - _.merge(content, { [responseKey] : resModelConfig }); + _.merge(content, { [responseKey]: resModelConfig }); } } return content; } - private getHttpEvents (funcConfig) { - return funcConfig.filter((event) => event.http ? true : false); + private getHttpEvents(funcConfig) { + return funcConfig.filter(event => (event.http ? true : false)); } } diff --git a/src/ServerlessOpenApiDocumentation.ts b/src/ServerlessOpenApiDocumentation.ts index da28ff4..b67527b 100644 --- a/src/ServerlessOpenApiDocumentation.ts +++ b/src/ServerlessOpenApiDocumentation.ts @@ -1,56 +1,55 @@ -import chalk from 'chalk'; -import * as fs from 'fs'; -import * as YAML from 'js-yaml'; -import _ = require('lodash'); -import * as Serverless from 'serverless'; -import { inspect } from 'util'; +import chalk from "chalk"; +import * as fs from "fs"; +import * as YAML from "js-yaml"; +import _ = require("lodash"); +import * as Serverless from "serverless"; +import { inspect } from "util"; -import { DefinitionGenerator } from './DefinitionGenerator'; -import { Format, IDefinitionConfig, IDefinitionType, ILog } from './types'; +import { DefinitionGenerator } from "./DefinitionGenerator"; +import { Format, DefinitionConfig, DefinitionType, ILog } from "./types"; -interface IOptions { +interface Options { indent: number; format: Format; output: string; } -interface IProcessedInput { - options: IOptions; +interface ProcessedInput { + options: Options; } -interface ICustomVars { - documentation: IDefinitionConfig; +interface CustomVars { + documentation: DefinitionConfig; } -interface IService { - custom: ICustomVars; +interface Service { + custom: CustomVars; } -interface IVariables { - service: IService; +interface Variables { + service: Service; } -interface IFullServerless extends Serverless { - variables: IVariables; - processedInput: IProcessedInput; +interface FullServerless extends Serverless { + variables: Variables; + processedInput: ProcessedInput; } export class ServerlessOpenApiDocumentation { public hooks; public commands; /** Serverless Instance */ - private serverless: IFullServerless; + private serverless: FullServerless; /** Serverless Service Custom vars */ - private customVars: ICustomVars; + private customVars: CustomVars; /** * Constructor * @param serverless * @param options */ - constructor (serverless: IFullServerless, options) { - + public constructor(serverless: FullServerless, options) { // pull the serverless instance into our class vars this.serverless = serverless; // Serverless service custom variables @@ -61,54 +60,57 @@ export class ServerlessOpenApiDocumentation { openapi: { commands: { generate: { - lifecycleEvents: [ - 'serverless', - ], - usage: 'Generate OpenAPI v3 Documentation', + lifecycleEvents: ["serverless"], + usage: "Generate OpenAPI v3 Documentation", options: { output: { - usage: 'Output file location [default: openapi.yml|json]', - shortcut: 'o', + usage: "Output file location [default: openapi.yml|json]", + shortcut: "o" }, format: { - usage: 'OpenAPI file format (yml|json) [default: yml]', - shortcut: 'f', + usage: "OpenAPI file format (yml|json) [default: yml]", + shortcut: "f" }, indent: { - usage: 'File indentation in spaces [default: 2]', - shortcut: 'i', - }, - }, - }, - }, - }, + usage: "File indentation in spaces [default: 2]", + shortcut: "i" + } + } + } + } + } }; // Declare the hooks our plugin is interested in this.hooks = { - 'openapi:generate:serverless': this.generate.bind(this), + "openapi:generate:serverless": this.generate.bind(this) }; } - log: ILog = (...str: string[]) => { - process.stdout.write(str.join(' ')); - } + private log: ILog = (...str: Array) => { + process.stdout.write(str.join(" ")); + }; /** * Generates OpenAPI Documentation based on serverless configuration and functions */ - public async generate () { - this.log(chalk.bold.underline('OpenAPI v3 Documentation Generator\n\n')); + public async generate() { + this.log(chalk.bold.underline("OpenAPI v3 Documentation Generator\n\n")); // Instantiate DocumentGenerator - const generator = new DefinitionGenerator(this.customVars.documentation, this.serverless.config.servicePath); + const generator = new DefinitionGenerator( + this.customVars.documentation, + this.serverless.config.servicePath + ); await generator.parse(); // Map function configurations - const funcConfigs = this.serverless.service.getAllFunctions().map((functionName) => { - const func = this.serverless.service.getFunction(functionName); - return _.merge({ _functionName: functionName }, func); - }); + const funcConfigs = this.serverless.service + .getAllFunctions() + .map(functionName => { + const func = this.serverless.service.getFunction(functionName); + return _.merge({ _functionName: functionName }, func); + }); // Add Paths to OpenAPI Output from Function Configuration generator.readFunctions(funcConfigs); @@ -116,24 +118,42 @@ export class ServerlessOpenApiDocumentation { // Process CLI Input options const config = this.processCliInput(); - this.log(`${chalk.bold.yellow('[VALIDATION]')} Validating OpenAPI generated output\n`); + this.log( + `${chalk.bold.yellow( + "[VALIDATION]" + )} Validating OpenAPI generated output\n` + ); const validation = generator.validate(); if (validation.valid) { - this.log(`${chalk.bold.green('[VALIDATION]')} OpenAPI valid: ${chalk.bold.green('true')}\n\n`); + this.log( + `${chalk.bold.green("[VALIDATION]")} OpenAPI valid: ${chalk.bold.green( + "true" + )}\n\n` + ); } else { - this.log(`${chalk.bold.red('[VALIDATION]')} Failed to validate OpenAPI document: \n\n`); - this.log(`${chalk.bold.green('Context:')} ${JSON.stringify(validation.context, null, 2)}\n`); - - if (typeof validation.error === 'string') { + this.log( + `${chalk.bold.red( + "[VALIDATION]" + )} Failed to validate OpenAPI document: \n\n` + ); + this.log( + `${chalk.bold.green("Context:")} ${JSON.stringify( + validation.context, + null, + 2 + )}\n` + ); + + if (typeof validation.error === "string") { this.log(`${validation.error}\n\n`); } else { for (const info of validation.error) { - this.log(chalk.grey('\n\n--------\n\n')); - this.log(' ', chalk.blue(info.dataPath), '\n'); - this.log(' ', info.schemaPath, chalk.bold.yellow(info.message)); - this.log(chalk.grey('\n\n--------\n\n')); + this.log(chalk.grey("\n\n--------\n\n")); + this.log(" ", chalk.blue(info.dataPath), "\n"); + this.log(" ", info.schemaPath, chalk.bold.yellow(info.message)); + this.log(chalk.grey("\n\n--------\n\n")); this.log(`${inspect(info, { colors: true, depth: 2 })}\n\n`); } } @@ -145,46 +165,52 @@ export class ServerlessOpenApiDocumentation { let output; switch (config.format.toLowerCase()) { - case 'json': - output = JSON.stringify(definition, null, config.indent); - break; - case 'yaml': - default: - output = YAML.safeDump(definition, { indent: config.indent }); - break; + case "json": + output = JSON.stringify(definition, null, config.indent); + break; + case "yaml": + default: + output = YAML.safeDump(definition, { indent: config.indent }); + break; } fs.writeFileSync(config.file, output); - this.log(`${chalk.bold.green('[OUTPUT]')} To "${chalk.bold.red(config.file)}"\n`); + this.log( + `${chalk.bold.green("[OUTPUT]")} To "${chalk.bold.red(config.file)}"\n` + ); } /** * Processes CLI input by reading the input from serverless * @returns config IConfigType */ - private processCliInput (): IDefinitionType { - const config: IDefinitionType = { + private processCliInput(): DefinitionType { + const config: DefinitionType = { format: Format.yaml, - file: 'openapi.yml', - indent: 2, + file: "openapi.yml", + indent: 2 }; config.indent = this.serverless.processedInput.options.indent || 2; - config.format = this.serverless.processedInput.options.format || Format.yaml; + config.format = + this.serverless.processedInput.options.format || Format.yaml; if ([Format.yaml, Format.json].indexOf(config.format) < 0) { - throw new Error('Invalid Output Format Specified - must be one of "yaml" or "json"'); + throw new Error( + 'Invalid Output Format Specified - must be one of "yaml" or "json"' + ); } - config.file = this.serverless.processedInput.options.output || - ((config.format === 'yaml') ? 'openapi.yml' : 'openapi.json'); + config.file = + this.serverless.processedInput.options.output || + (config.format === "yaml" ? "openapi.yml" : "openapi.json"); this.log( - `${chalk.bold.green('[OPTIONS]')}`, + `${chalk.bold.green("[OPTIONS]")}`, `format: "${chalk.bold.red(config.format)}",`, `output file: "${chalk.bold.red(config.file)}",`, - `indentation: "${chalk.bold.red(String(config.indent))}"\n\n`, + `indentation: "${chalk.bold.red(String(config.indent))}"\n\n` ); return config; diff --git a/src/__tests__/DefinitionGenerator.spec.ts b/src/__tests__/DefinitionGenerator.spec.ts index e94cd0e..cd66dac 100644 --- a/src/__tests__/DefinitionGenerator.spec.ts +++ b/src/__tests__/DefinitionGenerator.spec.ts @@ -1,7 +1,7 @@ -import _ = require('lodash'); -import * as path from 'path'; -import * as Serverless from 'serverless'; -import { DefinitionGenerator } from '../DefinitionGenerator'; +import _ = require("lodash"); +import * as path from "path"; +import * as Serverless from "serverless"; +import { DefinitionGenerator } from "../DefinitionGenerator"; class ServerlessInterface extends Serverless { public service: any = {}; @@ -11,43 +11,50 @@ class ServerlessInterface extends Serverless { public variables: any = {}; } -describe('OpenAPI Documentation Generator', () => { +describe("OpenAPI Documentation Generator", () => { let sls: ServerlessInterface; - const servicePath = path.join(__dirname, '../../test/project'); + const servicePath = path.join(__dirname, "../../test/project"); beforeEach(async () => { - - const serverlessYamlPath = path.join(servicePath, './serverless.yml'); + const serverlessYamlPath = path.join(servicePath, "./serverless.yml"); sls = new Serverless(); sls.config.update({ - servicePath, + servicePath }); const config = await sls.yamlParser.parse(serverlessYamlPath); - sls.pluginManager.cliOptions = { stage: 'dev' }; + sls.pluginManager.cliOptions = { stage: "dev" }; await sls.service.load(config); await sls.variables.populateService(); - if (!('documentation' in sls.service.custom)) { - throw new Error('Cannot find "documentation" in custom section of "serverless.yml"'); + if (!("documentation" in sls.service.custom)) { + throw new Error( + 'Cannot find "documentation" in custom section of "serverless.yml"' + ); } }); - it('Generates OpenAPI document', async () => { - const docGen = new DefinitionGenerator(sls.service.custom.documentation, servicePath); + it("Generates OpenAPI document", async () => { + const docGen = new DefinitionGenerator( + sls.service.custom.documentation, + servicePath + ); expect(docGen).not.toBeNull(); }); - it('adds paths to OpenAPI output from function configuration', async () => { - const docGen = new DefinitionGenerator(sls.service.custom.documentation, servicePath); + it("adds paths to OpenAPI output from function configuration", async () => { + const docGen = new DefinitionGenerator( + sls.service.custom.documentation, + servicePath + ); // implementation copied from ServerlessOpenApiDocumentation.ts await docGen.parse(); - const funcConfigs = sls.service.getAllFunctions().map((functionName) => { + const funcConfigs = sls.service.getAllFunctions().map(functionName => { const func = sls.service.getFunction(functionName); return _.merge({ _functionName: functionName }, func); }); @@ -55,41 +62,38 @@ describe('OpenAPI Documentation Generator', () => { docGen.readFunctions(funcConfigs); // get the parameters from the `/create POST' endpoint - const actual = docGen.definition.paths['/create'].post.parameters; + const actual = docGen.definition.paths["/create"].post.parameters; const expected = [ { - description: 'The username for a user to create', - in: 'path', - name: 'username', + description: "The username for a user to create", + in: "path", + name: "username", required: true, schema: { - pattern: '^[-a-z0-9_]+$', - type: 'string', - }, + pattern: "^[-a-z0-9_]+$", + type: "string" + } }, { allowEmptyValue: false, description: `The user's Membership Type`, - in: 'query', - name: 'membershipType', + in: "query", + name: "membershipType", required: false, schema: { - enum: [ - 'premium', - 'standard', - ], - type: 'string', - }, + enum: ["premium", "standard"], + type: "string" + } }, { - description: 'A Session ID variable', - in: 'cookie', - name: 'SessionId', + description: "A Session ID variable", + in: "cookie", + name: "SessionId", required: false, schema: { - type: 'string', - }, - }, + type: "string" + } + } ]; expect(actual).toEqual(expected); diff --git a/src/index.ts b/src/index.ts index e0e1541..c01caeb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { ServerlessOpenApiDocumentation } from './ServerlessOpenApiDocumentation'; +import { ServerlessOpenApiDocumentation } from "./ServerlessOpenApiDocumentation"; // tslint:disable-next-line no-default-export export default ServerlessOpenApiDocumentation; diff --git a/src/parse.ts b/src/parse.ts index 12bc1e0..eaaa76c 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,36 +1,12 @@ -import { JSONSchema7 } from 'json-schema'; -import * as $RefParser from 'json-schema-ref-parser'; -import * as _ from 'lodash'; -import * as path from 'path'; +import { JSONSchema7 } from "json-schema"; +import * as $RefParser from "json-schema-ref-parser"; +import * as _ from "lodash"; +import * as path from "path"; -import { IModel } from './types'; -import { cleanSchema } from './utils'; +import { Model } from "./types"; +import { cleanSchema } from "./utils"; -export async function parseModels (models: IModel[], root: string): Promise<{}> { - const schemas = {}; - - if (!_.isArrayLike(models)) { - throw new Error('Empty models'); - } - - for (const model of models) { - if (!model.schema) { - continue; - } - - const schema = (typeof model.schema === 'string' - ? await $RefParser.bundle(path.resolve(root, model.schema)) - : model.schema) as JSONSchema7; - - _.assign(schemas, updateReferences(schema.definitions), { - [model.name]: updateReferences(cleanSchema(schema)), - }); - } - - return schemas; -} - -function updateReferences (schema: JSONSchema7): JSONSchema7 { +function updateReferences(schema: JSONSchema7): JSONSchema7 { if (!schema) { return schema; } @@ -40,17 +16,44 @@ function updateReferences (schema: JSONSchema7): JSONSchema7 { if (cloned.$ref) { return { ...cloned, - $ref: cloned.$ref.replace('#/definitions', '#/components/schemas'), + $ref: cloned.$ref.replace("#/definitions", "#/components/schemas") }; } for (const key of Object.getOwnPropertyNames(cloned)) { const value = cloned[key]; - if (typeof value === 'object') { + if (typeof value === "object") { cloned[key] = updateReferences(value); } } return cloned; } + +export async function parseModels( + models: Array, + root: string +): Promise<{}> { + const schemas = {}; + + if (!_.isArrayLike(models)) { + throw new Error("Empty models"); + } + + for (const model of models) { + if (!model.schema) { + continue; + } + + const schema = (typeof model.schema === "string" + ? await $RefParser.bundle(path.resolve(root, model.schema)) + : model.schema) as JSONSchema7; + + _.assign(schemas, updateReferences(schema.definitions), { + [model.name]: updateReferences(cleanSchema(schema)) + }); + } + + return schemas; +} diff --git a/src/types.ts b/src/types.ts index 452d03d..d61f109 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,38 +1,38 @@ -import { JSONSchema7 } from 'json-schema'; +import { JSONSchema7 } from "json-schema"; -export interface IModel { +export interface Model { name: string; description: string; contentType: string; schema: string | JSONSchema7; - examples: any[]; + examples: Array; example: object; } -export interface IDefinitionConfig { +export interface DefinitionConfig { title: string; description: string; version?: string; - models: IModel[]; + models: Array; } export enum Format { - yaml = 'yaml', - json = 'json', + yaml = "yaml", + json = "json" } -export interface IDefinitionType { +export interface DefinitionType { file: string; format: Format; indent: number; } -export interface IServerlessFunctionConfig { +export interface ServerlessFunctionConfig { _functionName: string; handler: string; description?: string; environment?: object; - events?: any[]; + events?: Array; } // TODO: We could use another TS based OpenAPI project to get type information @@ -40,48 +40,48 @@ export interface IServerlessFunctionConfig { // @see https://github.com/Mermade/awesome-openapi3#parsersmodelsvalidators // @see https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#operation-object -export interface IOperation { - tags?: string[]; +export interface Operation { + tags?: Array; summary?: string; description?: string; externalDocs?: any; operationId?: string; - parameters?: IParameterConfig[]; + parameters?: Array; requestBody?: any; responses?: any; callbacks?: any; deprecated?: boolean; - security?: any[]; - servers?: any[]; + security?: Array; + servers?: Array; } // @see https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#parameterObject -export interface IParameterConfig { +export interface ParameterConfig { name: string; - in: 'path' | 'query' | 'header' | 'cookie'; + in: "path" | "query" | "header" | "cookie"; description: string; required?: boolean; schema?: object; deprecated?: boolean; allowEmptyValue?: boolean; - style?: 'form' | 'simple'; + style?: "form" | "simple"; explode?: boolean; allowReserved?: boolean; example?: any; - examples?: any[]; + examples?: Array; content?: Map; } // FIXME: -export interface IDefinition { +export interface Definition { openapi: string; - info: any; - servers?: any[]; - paths: any; + info?: any; + servers?: Array; + paths?: any; components?: any; - security?: any[]; - tags?: any[]; - externalDocs: any; + security?: Array; + tags?: Array; + externalDocs?: any; } -export type ILog = (...str: string[]) => void; +export type ILog = (...str: Array) => void; diff --git a/src/utils.ts b/src/utils.ts index eb02269..3f7be8f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,3 @@ +import _ = require("lodash"); -import _ = require('lodash'); - -export const cleanSchema = (schema) => _.omit(schema, '$schema', 'definitions'); +export const cleanSchema = schema => _.omit(schema, "$schema", "definitions");