diff --git a/Makefile b/Makefile index a37d1975..870c94e7 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,11 @@ test-debug: .PHONY: lint lint: - eslint src/ + tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts' + +.PHONY: fix +fix: + tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts' --fix .PHONY: tsbuild tsbuild: diff --git a/package-lock.json b/package-lock.json index f0e7f771..65e03a49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ketting", - "version": "1.1.1", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -407,41 +407,6 @@ "acorn": "^5.0.0" } }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", @@ -509,21 +474,6 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -893,6 +843,12 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "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 + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -943,21 +899,6 @@ "unset-value": "^1.0.0" } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -1009,12 +950,6 @@ } } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1066,12 +1001,6 @@ "safe-buffer": "^5.0.1" } }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -1470,12 +1399,6 @@ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -1486,21 +1409,6 @@ "isobject": "^3.0.1" } }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1551,15 +1459,6 @@ "randombytes": "^2.0.0" } }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -1652,52 +1551,6 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - } - }, "eslint-scope": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", @@ -1708,37 +1561,12 @@ "estraverse": "^4.1.1" } }, - "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": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", "dev": true }, - "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.0.0" - } - }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", @@ -1913,17 +1741,6 @@ } } }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1960,24 +1777,12 @@ } } }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "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", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -1987,16 +1792,6 @@ "escape-string-regexp": "^1.0.5" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -2040,18 +1835,6 @@ "locate-path": "^2.0.0" } }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -2650,12 +2433,6 @@ } } }, - "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 - }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -2721,26 +2498,6 @@ "integrity": "sha512-3DrmGj2TP+96cABk9TfMp6f3knH/Y46dqvWznTU3Tf6/bDGLDAn15tFluQ7BcloykOcdY16U0WGq0BQblYOxJQ==", "dev": true }, - "globals": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", - "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -2905,12 +2662,6 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, - "ignore": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", - "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", - "dev": true - }, "import-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", @@ -2954,28 +2705,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, "interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", @@ -3102,30 +2831,6 @@ } } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -3141,12 +2846,6 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -3183,9 +2882,9 @@ "dev": true }, "js-yaml": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3198,18 +2897,6 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "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 - }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -3415,16 +3102,6 @@ "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", "dev": true }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, "loader-runner": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", @@ -3779,12 +3456,6 @@ "to-regex": "^3.0.1" } }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -6618,20 +6289,6 @@ "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=", "dev": true }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -6757,12 +6414,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -6797,6 +6448,12 @@ } } }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", @@ -6838,27 +6495,6 @@ "resolved": "https://registry.npmjs.org/pct-encode/-/pct-encode-1.0.2.tgz", "integrity": "sha1-uZt7BE1r18OeSDmnqAEirXUVyqU=" }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", @@ -6868,12 +6504,6 @@ "find-up": "^2.1.0" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, "popsicle": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-9.2.0.tgz", @@ -6891,12 +6521,6 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -6908,12 +6532,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -7077,12 +6695,6 @@ "safe-regex": "^1.1.0" } }, - "regexpp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.0.1.tgz", - "integrity": "sha512-8Ph721maXiOYSLtaDGKVmDn5wdsNaF6Px85qFNeMPQq0r8K5Y10tgP6YuR65Ws35n4DvzFcCxEnRNBIXQunzLw==", - "dev": true - }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -7113,14 +6725,13 @@ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "resolve": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.0.tgz", + "integrity": "sha512-MNcwJ8/K9iJqFDBDyhcxZuDWvf/ai0GcAJWetx2Cvvcz4HLfA8j0KasWR5Z6ChcbjYZ+FaczcXjN2jrCXCjQ4w==", "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "path-parse": "^1.0.5" } }, "resolve-cwd": { @@ -7140,12 +6751,6 @@ } } }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, "resolve-path": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", @@ -7215,21 +6820,6 @@ "aproba": "^1.1.1" } }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, "rxjs": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.1.tgz", @@ -7396,15 +6986,6 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7800,44 +7381,18 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - } - }, "tapable": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", "dev": true }, - "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 - }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -7992,21 +7547,41 @@ "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==", "dev": true }, + "tslint": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz", + "integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.12.1" + } + }, + "tsutils": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.27.1.tgz", + "integrity": "sha512-AE/7uzp32MmaHvNNFES85hhUDHFdFZp6OAiZcd6y4ZKKIg6orJTm8keYWBhIhrJQH3a4LzNKat7ZPXZt5aTf6w==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, "type-detect": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", @@ -8481,12 +8056,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, "worker-farm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", @@ -8543,15 +8112,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index c09ee42d..b91ec92d 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@types/sax": "^1.0.0", "awesome-typescript-loader": "^5.0.0", "chai": "^4.1.2", - "eslint": "^4.19.1", + "tslint": "^5.10.0", "koa": "^2.5.1", "koa-bodyparser": "^4.2.1", "koa-logger": "^3.2.0", diff --git a/src/followable-promise.ts b/src/followable-promise.ts index 77c13051..794847c8 100644 --- a/src/followable-promise.ts +++ b/src/followable-promise.ts @@ -14,13 +14,10 @@ type Executor = * It's really just a thin wrapper around the promise. Note that we're not * extending the built-in Promise object, but proxy it as browsers don't allow * extending the Promise object. - * - * @param {Function} executor - * @constructor */ export default class FollowablePromise { - realPromise: Promise + realPromise: Promise; constructor(executor: Executor ) { this.realPromise = new Promise(executor); @@ -53,12 +50,12 @@ export default class FollowablePromise { */ follow(rel: string, variables?: object): FollowablePromise { - return new FollowablePromise((resolve: (value: FollowablePromise) => void, reject: Function) => { + return new FollowablePromise((resolve: (value: FollowablePromise) => void, reject: (reason: any) => void) => { this.realPromise.then((resource: Resource) => { resolve(resource.follow(rel, variables)); - }).catch(function(err) { + }).catch(err => { reject(err); }); diff --git a/src/http-error.ts b/src/http-error.ts index 88f00731..bd002f60 100644 --- a/src/http-error.ts +++ b/src/http-error.ts @@ -10,8 +10,8 @@ */ export class HttpError extends Error { - response: Response - status: number + response: Response; + status: number; constructor(response: Response) { super('HTTP error ' + response.status); @@ -19,7 +19,7 @@ export class HttpError extends Error { this.status = response.status; } -}; +} /** * Problem extends the HttpError object. If a server emits a HTTP error, and @@ -36,7 +36,7 @@ export class Problem extends HttpError { body: { title?: string - } + }; constructor(response: Response, problemBody: object) { super(response); @@ -68,5 +68,5 @@ export default async function problemFactory(response: Response): Promise { let item = contentType.mime; - if (contentType.q) item+=';q=' + contentType.q; + if (contentType.q) { item += ';q=' + contentType.q; } return item; } ) .join(', '); @@ -187,7 +188,7 @@ export default class Ketting { request.headers.set('Content-Type', this.contentTypes[0].mime); } if (!request.headers.has('Authorization') && this.auth) { - switch(this.auth.type) { + switch (this.auth.type) { case 'basic' : request.headers.set('Authorization', 'Basic ' + base64.encode(this.auth.userName + ':' + this.auth.password)); @@ -217,7 +218,7 @@ export default class Ketting { contentType = contentType.split(';')[0]; } contentType = contentType.trim(); - const result = this.contentTypes.find(function(item) { + const result = this.contentTypes.find(item => { return item.mime === contentType; }); @@ -225,7 +226,7 @@ export default class Ketting { throw new Error('Could not find a representor for contentType: ' + contentType); } - switch(result.representor) { + switch (result.representor) { case 'html' : return HtmlRepresentor; case 'hal' : diff --git a/src/link.ts b/src/link.ts index e567a3ae..0afa01fa 100644 --- a/src/link.ts +++ b/src/link.ts @@ -9,7 +9,7 @@ type LinkInit = { templated?: boolean, title?: string, type?: string, -} +}; /** * The Link object represents a hyperlink. @@ -19,12 +19,12 @@ export default class Link { /** * The base href of the parent document. Used for expanding relative links. */ - baseHref: string + baseHref: string; /** * The URI of the link. Might be relative */ - href: string + href: string; /** * The name for a link. This might be used to disambiguate the link. @@ -32,36 +32,36 @@ export default class Link { * If you're looking at this, chances are that you might want 'title' * instead. */ - name?: string + name?: string; /** * The relationship type */ - rel: string + rel: string; /** * Is it a URI template or not? */ - templated: boolean + templated: boolean; /** * A human-readable label for the link. */ - title: string | null + title: string | null; /** * A mimetype */ - type: string | null + type: string | null; constructor(properties: LinkInit) { this.templated = false; this.title = null; this.type = null; - for(const key of ['baseHref', 'href', 'name', 'rel', 'templated', 'title', 'type']) { - if ((properties)[key]) { - (this)[key] = (properties)[key]; + for (const key of ['baseHref', 'href', 'name', 'rel', 'templated', 'title', 'type']) { + if (( properties)[key]) { + ( this)[key] = ( properties)[key]; } } @@ -93,6 +93,6 @@ export default class Link { return resolve(this.baseHref, expanded); } - }; + } } diff --git a/src/representor/base.ts b/src/representor/base.ts index 72615c58..49202847 100644 --- a/src/representor/base.ts +++ b/src/representor/base.ts @@ -9,13 +9,13 @@ import Link from '../link'; */ export default class Representation { - body: any - contentType: string + body: any; + contentType: string; embedded: { [uri: string]: object - } - links: Link[] - uri: string + }; + links: Link[]; + uri: string; constructor(uri: string, contentType: string, body: any) { @@ -27,4 +27,4 @@ export default class Representation { } -}; +} diff --git a/src/representor/hal.ts b/src/representor/hal.ts index bb76d0f3..50e123e2 100644 --- a/src/representor/hal.ts +++ b/src/representor/hal.ts @@ -1,6 +1,6 @@ -import Representation from './base'; import Link from '../link'; import { resolve } from '../utils/url'; +import Representation from './base'; /** * The Representation class is basically a 'body' of a request @@ -10,7 +10,7 @@ import { resolve } from '../utils/url'; */ export default class Hal extends Representation { - body: { [s: string]: any } + body: { [s: string]: any }; constructor(uri: string, contentType: string, body: any) { @@ -39,11 +39,11 @@ export default class Hal extends Representation { /** * Parse the Hal _links object and populate the 'links' property. */ -const parseHalLinks = function(representation: Hal): void { +const parseHalLinks = (representation: Hal): void => { - for(const relType of Object.keys((representation.body)._links)) { + for (const relType of Object.keys(( representation.body)._links)) { - let links = (representation.body)._links[relType]; + let links = ( representation.body)._links[relType]; if (!Array.isArray(links)) { links = [links]; } @@ -63,9 +63,9 @@ type HalLink = { /** * Parses a single HAL link from a _links object, or a list of links. */ -const parseHalLink = function(representation: Hal, rel: string, links: HalLink[]): void { +const parseHalLink = (representation: Hal, rel: string, links: HalLink[]): void => { - for(const link of links) { + for (const link of links) { representation.links.push( new Link({ rel: rel, @@ -84,15 +84,15 @@ const parseHalLink = function(representation: Hal, rel: string, links: HalLink[] * Parse the HAL _embedded object. Right now we're just grabbing the * information from _embedded and turn it into links. */ -const parseHalEmbedded = function(representation: Hal): void { +const parseHalEmbedded = (representation: Hal): void => { - for(const relType of Object.keys((representation).body._embedded)) { + for (const relType of Object.keys(( representation).body._embedded)) { - let embedded = (representation).body._embedded[relType]; + let embedded = ( representation).body._embedded[relType]; if (!Array.isArray(embedded)) { embedded = [embedded]; } - for(const embeddedItem of embedded) { + for (const embeddedItem of embedded) { const uri = resolve( representation.uri, diff --git a/src/representor/html.ts b/src/representor/html.ts index f528d3e6..c04c4c28 100644 --- a/src/representor/html.ts +++ b/src/representor/html.ts @@ -1,6 +1,6 @@ -import Representation from './base'; -import Link from '../link'; import sax from 'sax'; +import Link from '../link'; +import Representation from './base'; /** * The Representation class is basically a 'body' of a request @@ -10,7 +10,7 @@ import sax from 'sax'; * intended for browsers. The regular html.js is intended for node.js. */ export default class Html extends Representation { - + constructor(uri: string, contentType: string, body: string) { super(uri, contentType, body); @@ -26,15 +26,15 @@ export default class Html extends Representation { return; } - const rels = node.attributes.REL; + const rels = node.attributes.REL; - for(const rel of rels.split(' ')) { + for (const rel of rels.split(' ')) { const link = new Link({ rel: rel, baseHref: this.uri, - href: node.attributes.HREF, - type: node.attributes.TYPE || undefined + href: node.attributes.HREF, + type: node.attributes.TYPE || undefined }); this.links.push(link); diff --git a/src/representor/html.web.ts b/src/representor/html.web.ts index 14973f55..a8381b42 100644 --- a/src/representor/html.web.ts +++ b/src/representor/html.web.ts @@ -1,5 +1,5 @@ -import Representation from './base'; import Link from '../link'; +import Representation from './base'; /** * The Representation class is basically a 'body' of a request @@ -29,11 +29,11 @@ export default class Html extends Representation { } -}; +} function linkFromTags(htmlDoc: Html, elements: NodeListOf) { - for(const node of elements) { + for (const node of elements) { const rels = node.getAttribute('rel'); const href = node.getAttribute('href'); @@ -43,7 +43,7 @@ function linkFromTags(htmlDoc: Html, elements: NodeListOf) { continue; } - for(const rel of rels.split(' ')) { + for (const rel of rels.split(' ')) { const link = new Link({ rel: rel, diff --git a/src/resource.ts b/src/resource.ts index 5612241a..5bdca6c7 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -1,12 +1,12 @@ -import { resolve } from './utils/url'; +import { Headers, Request } from 'cross-fetch'; +import LinkHeader from 'http-link-header'; import FollowablePromise from './followable-promise'; -import { Request, Headers } from 'cross-fetch'; import problemFactory from './http-error'; -import LinkHeader from 'http-link-header'; +import Ketting from './ketting'; import Link from './link'; -import { mergeHeaders } from './utils/fetch-helper'; import Representation from './representor/base'; -import Ketting from './ketting'; +import { mergeHeaders } from './utils/fetch-helper'; +import { resolve } from './utils/url'; /** * A 'resource' represents an endpoint on the server. @@ -23,11 +23,11 @@ import Ketting from './ketting'; */ export default class Resource { - client: Ketting - repr: Representation | null - uri: string + client: Ketting; + repr: Representation | null; + uri: string; - constructor(client: Ketting, uri:string) { + constructor(client: Ketting, uri: string) { this.client = client; this.uri = uri; @@ -40,7 +40,7 @@ export default class Resource { * Returns a promise that resolves to a parsed json object. */ async get(): Promise { - + const r = await this.representation(); return r.body; @@ -101,7 +101,7 @@ export default class Resource { return this.client.getResource( resolve( this.uri, - response.headers.get('location') + response.headers.get('location') ) ); } @@ -143,7 +143,7 @@ export default class Resource { const response = await this.fetchAndThrow({method: 'GET'}); const body = await response.text(); - + const contentType = response.headers.get('Content-Type'); if (!contentType) { throw new Error('Server did not respond with a Content-Type header'); @@ -198,7 +198,7 @@ export default class Resource { const r = await this.representation(); - if (!rel) return r.links; + if (!rel) { return r.links; } return r.links.filter( item => item.rel === rel ); @@ -213,7 +213,7 @@ export default class Resource { */ follow(rel: string, variables?: object): FollowablePromise { - return new FollowablePromise(async(res: any, rej: any) => { + return new FollowablePromise(async (res: any, rej: any) => { try { const links = await this.links(rel); @@ -273,7 +273,7 @@ export default class Resource { await this.refresh(); } - return this.repr; + return this.repr; } @@ -291,7 +291,7 @@ export default class Resource { fetch(input: Request|string|RequestInit, init?: RequestInit): Promise { let uri = null; - let newInit:RequestInit = {}; + let newInit: RequestInit = {}; if (input === undefined) { // Nothing was provided, we're operating on the resource uri. @@ -304,7 +304,7 @@ export default class Resource { } else if (input instanceof Request) { // We were passed a request object. We need to extract all its // information into the init object. - uri = resolve(this.uri, (input).url); + uri = resolve(this.uri, ( input).url); newInit.method = input.method; newInit.headers = new Headers(input.headers); @@ -323,7 +323,7 @@ export default class Resource { // is not allowed in the default Fetch API, but we do allow it because // in the resource, specifying the uri is optional. uri = this.uri; - newInit = input; + newInit = input; } else { throw new TypeError('When specified, input must be a string, Request object or a key-value object'); } @@ -332,12 +332,12 @@ export default class Resource { // in newInit. if (init) { - for(const key of Object.keys(init)) { - if (key==='headers') { + for (const key of Object.keys(init)) { + if (key === 'headers') { // special case. continue; } - (newInit)[key] = (init)[key]; + ( newInit)[key] = ( init)[key]; } newInit.headers = mergeHeaders([ newInit.headers, diff --git a/src/types/uri-template.d.ts b/src/types/uri-template.d.ts index 14be4a8b..59f6c6e6 100644 --- a/src/types/uri-template.d.ts +++ b/src/types/uri-template.d.ts @@ -1,9 +1,9 @@ -declare module "uri-template" { +declare module 'uri-template' { export interface Template { - expand(variables: object): string + expand(variables: object): string; } - export function parse(href: string): Template + export function parse(href: string): Template; } diff --git a/src/utils/base64.web.ts b/src/utils/base64.web.ts index e2c58394..068b4e0c 100644 --- a/src/utils/base64.web.ts +++ b/src/utils/base64.web.ts @@ -5,4 +5,4 @@ export function encode(input: string): string { return btoa(input); -}; +} diff --git a/src/utils/fetch-helper.ts b/src/utils/fetch-helper.ts index 6b0080a5..beaeaa66 100644 --- a/src/utils/fetch-helper.ts +++ b/src/utils/fetch-helper.ts @@ -11,7 +11,7 @@ import * as crossFetch from 'cross-fetch'; */ export function createFetchRequest(input: any, init: any, defaultInit: any): Request { - const trueInit:any = {}; + const trueInit: any = {}; if (init) { Object.assign(trueInit, defaultInit, init); @@ -45,15 +45,15 @@ type HeaderSet = any; export function mergeHeaders(headerSets: HeaderSet[]): Headers { const result = new crossFetch.Headers(); - for(const headerSet of headerSets) { + for (const headerSet of headerSets) { if (headerSet instanceof crossFetch.Headers) { - for(const key of headerSet.keys()) { - result.set(key, headerSet.get(key)); + for (const key of headerSet.keys()) { + result.set(key, headerSet.get(key)); } } else if (headerSet) { // not falsey, must be a key->value object. - for(const index in headerSet) { + for (const index of Object.keys(headerSet)) { result.set(index, headerSet[index]); } } diff --git a/src/utils/oauth.ts b/src/utils/oauth.ts index c3a0e942..5eab32b9 100644 --- a/src/utils/oauth.ts +++ b/src/utils/oauth.ts @@ -11,18 +11,18 @@ export type OAuth2Init = { }, owner: { userName: string, - password: string, + password: string } }; export class OAuth2Helper { - client: ClientOAuth2 - token: null | Token + client: ClientOAuth2; + token: null | Token; owner: { userName: string, password: string - } + }; constructor(options: OAuth2Init) { @@ -44,10 +44,10 @@ export class OAuth2Helper { * one, and attempt to refresh the token if it was expired. */ async fetch(request: Request): Promise { - - let token = await this.getToken(); + + const token = await this.getToken(); request.headers.set('Authorization', 'Bearer ' + token.accessToken); - + const response = await fetch(request); if (response.status !== 401) { diff --git a/src/utils/url.ts b/src/utils/url.ts index eb453bf2..1ce716bc 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -1,4 +1,4 @@ -import url from 'url'; +import url from 'url'; /** * Resolves a relative url using another url. diff --git a/src/utils/url.web.ts b/src/utils/url.web.ts index 3943ad50..e02b8bb1 100644 --- a/src/utils/url.web.ts +++ b/src/utils/url.web.ts @@ -13,23 +13,22 @@ export function resolve(base: string, relative: string): string { // Code taken from this gist:; // https://gist.github.com/johan/3915545#file-resolveurl-js - var doc = document - , old_base = doc.getElementsByTagName('base')[0] - , old_href = old_base && old_base.href - , doc_head = doc.head || doc.getElementsByTagName('head')[0] - , our_base = old_base || doc_head.appendChild(doc.createElement('base')) - , resolver = doc.createElement('a') - , resolved_url - ; - our_base.href = base; + const doc = document; + const oldBase = doc.getElementsByTagName('base')[0]; + const oldHref = oldBase && oldBase.href; + const docHead = doc.head || doc.getElementsByTagName('head')[0]; + const ourBase = oldBase || docHead.appendChild(doc.createElement('base')); + const resolver = doc.createElement('a'); + + ourBase.href = base; resolver.href = relative; - resolved_url = resolver.href; // browser magic at work here + const resolvedUrl = resolver.href; // browser magic at work here - if (old_base) { - old_base.href = old_href; + if (oldBase) { + oldBase.href = oldHref; } else { - doc_head.removeChild(our_base); + docHead.removeChild(ourBase); } - return resolved_url; + return resolvedUrl; } diff --git a/test/integration/basic-auth.ts b/test/integration/basic-auth.ts index ef1e90d6..c61064f1 100644 --- a/test/integration/basic-auth.ts +++ b/test/integration/basic-auth.ts @@ -1,10 +1,10 @@ -import Ketting from '../../src/ketting'; import { expect } from 'chai'; +import Ketting from '../../src/ketting'; describe('Basic Authentication', () => { - it('should return 401 if no credentials were passed.', async() => { - + it('should return 401 if no credentials were passed.', async () => { + const ketting = new Ketting('http://localhost:3000/hal1.json'); const resource = await ketting.follow('auth-basic'); const response = await resource.fetch(); @@ -12,14 +12,14 @@ describe('Basic Authentication', () => { }); - it('should return 401 if incorrect credentials were passed.', async() => { + it('should return 401 if incorrect credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { type: 'basic', userName: 'foo', password: 'bar' - } + } }); const resource = await ketting.follow('auth-basic'); const response = await resource.fetch(); @@ -27,14 +27,14 @@ describe('Basic Authentication', () => { }); - it('should return 200 OK if correct credentials were passed.', async() => { + it('should return 200 OK if correct credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { type: 'basic', userName: 'user', password: 'pass' - } + } }); const resource = await ketting.follow('auth-basic'); const response = await resource.fetch(); diff --git a/test/integration/bearer-auth.ts b/test/integration/bearer-auth.ts index 0ac79e15..669584f6 100644 --- a/test/integration/bearer-auth.ts +++ b/test/integration/bearer-auth.ts @@ -1,9 +1,9 @@ -import Ketting from '../../src/ketting'; import { expect } from 'chai'; +import Ketting from '../../src/ketting'; describe('Bearer Authentication', () => { - it('should return 401 if no credentials were passed.', async() => { + it('should return 401 if no credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); const resource = await ketting.follow('auth-bearer'); @@ -12,7 +12,7 @@ describe('Bearer Authentication', () => { }); - it('should return 401 if incorrect credentials were passed.', async() => { + it('should return 401 if incorrect credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { @@ -26,7 +26,7 @@ describe('Bearer Authentication', () => { }); - it('should return 200 OK if correct credentials were passed.', async() => { + it('should return 200 OK if correct credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { diff --git a/test/integration/delete.ts b/test/integration/delete.ts index 6556197b..490ebf4f 100644 --- a/test/integration/delete.ts +++ b/test/integration/delete.ts @@ -1,14 +1,14 @@ -import Ketting from '../../src/ketting'; -import Resource from '../../src/resource'; import { expect } from 'chai'; import { Problem } from '../../src/http-error'; +import Ketting from '../../src/ketting'; +import Resource from '../../src/resource'; describe('Issuing a DELETE request', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); let resource: Resource; - before( async() => { + before( async () => { resource = ketting.getResource(); // Priming the cache @@ -16,46 +16,46 @@ describe('Issuing a DELETE request', async () => { }); - it('should not fail', async() => { + it('should not fail', async () => { await resource.delete(); - + }); - it('should have cleared the resource representation', async() => { + it('should have cleared the resource representation', async () => { let ok = false; - try { + try { await resource.get(); } catch (e) { // we're expecting an exception ok = true; } expect(ok).to.eql(true); - + }); - it('should have cleared the global cache', async() => { + it('should have cleared the global cache', async () => { let ok = false; - try { + try { await ketting.getResource().get(); } catch (e) { // we're expecting an exception ok = true; } expect(ok).to.eql(true); - + }); - it('should throw an exception when there was a HTTP error', async() => { + it('should throw an exception when there was a HTTP error', async () => { // Resetting the server await ketting.getResource('/reset').post({}); ketting.resourceCache = {}; - const resource = await ketting.follow('error400'); + const resource2 = await ketting.follow('error400'); let exception; try { - await resource.delete(); + await resource2.delete(); } catch (ex) { exception = ex; } @@ -63,15 +63,15 @@ describe('Issuing a DELETE request', async () => { }); - it('should throw a Problem exception when there was a HTTP error with a application/problem+json response', async() => { + it('should throw a Problem exception when there was a HTTP error with a application/problem+json response', async () => { // Resetting the server await ketting.getResource('/reset').post({}); ketting.resourceCache = {}; - const resource = await ketting.follow('problem'); + const resource2 = await ketting.follow('problem'); let exception; try { - await resource.delete(); + await resource2.delete(); } catch (ex) { exception = ex; } @@ -81,7 +81,7 @@ describe('Issuing a DELETE request', async () => { }); - after( async() => { + after( async () => { await ketting.getResource('/reset').post({}); diff --git a/test/integration/fetch-api.ts b/test/integration/fetch-api.ts index ad997b85..7650ad04 100644 --- a/test/integration/fetch-api.ts +++ b/test/integration/fetch-api.ts @@ -1,7 +1,7 @@ -import Ketting from '../../src/ketting'; -import Resource from '../../src/resource'; import { expect } from 'chai'; import { Request } from 'cross-fetch'; +import Ketting from '../../src/ketting'; +import Resource from '../../src/resource'; describe('Using the fetch api', () => { @@ -12,7 +12,7 @@ describe('Using the fetch api', () => { hal2 = await ketting.follow('next'); }); - it('should return a response object', async() => { + it('should return a response object', async () => { const response = await hal2.fetch('?foo=bar'); expect(response).to.have.property('status'); @@ -20,7 +20,7 @@ describe('Using the fetch api', () => { }); - it('should also work when passing a Request object', async() => { + it('should also work when passing a Request object', async () => { // @ts-ignore cross-fetch has broken types. const request = new Request('?foo=bar'); @@ -30,7 +30,7 @@ describe('Using the fetch api', () => { }); - it('should allow overriding the HTTP method', async() => { + it('should allow overriding the HTTP method', async () => { const response = await hal2.fetch({ method: 'PUT' }); expect(response).to.have.property('status'); @@ -38,7 +38,7 @@ describe('Using the fetch api', () => { }); - it('should allow overriding the url', async() => { + it('should allow overriding the url', async () => { const response = await hal2.fetch('?foo=bar', { method: 'PUT', @@ -51,7 +51,7 @@ describe('Using the fetch api', () => { }); - it('should allow overriding the Content-Type header', async() => { + it('should allow overriding the Content-Type header', async () => { const tempKetting = new Ketting('http://localhost:3000/hal1.json', { fetchInit: { @@ -74,7 +74,7 @@ describe('Using the fetch api', () => { }); - it('should allow overriding the User-Agent header', async() => { + it('should allow overriding the User-Agent header', async () => { const headersResource = await ketting.follow('headerTest'); const response = await headersResource.fetch({ @@ -89,9 +89,9 @@ describe('Using the fetch api', () => { }); - it('Calling fetch on the client itself should also work', async() => { + it('Calling fetch on the client itself should also work', async () => { - const response = await ketting.fetch('http://localhost:3000/hal1.json',{ + const response = await ketting.fetch('http://localhost:3000/hal1.json', { method: 'PUT', headers: { 'X-Foo' : 'Bar' @@ -102,7 +102,7 @@ describe('Using the fetch api', () => { }); - it('should throw a TypeError when passing an incorrect value for input', async() => { + it('should throw a TypeError when passing an incorrect value for input', async () => { let result; try { @@ -115,7 +115,7 @@ describe('Using the fetch api', () => { }); - after( async() => { + after( async () => { // Clearing any changes. await ketting.getResource('/reset').post({}); diff --git a/test/integration/follow-hal-template.ts b/test/integration/follow-hal-template.ts index 7ebc60a4..bfa3a53b 100644 --- a/test/integration/follow-hal-template.ts +++ b/test/integration/follow-hal-template.ts @@ -1,14 +1,14 @@ +import { expect } from 'chai'; import Ketting from '../../src/ketting'; import Resource from '../../src/resource'; -import { expect } from 'chai'; describe('Following a templated link', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); - let hal2:Resource; + let hal2: Resource; - it('should have expanded the uri', async() => { + it('should have expanded the uri', async () => { hal2 = await ketting.follow('templated', {foo: 'bar'}); expect(hal2).to.be.an.instanceof(Resource); @@ -16,9 +16,9 @@ describe('Following a templated link', async () => { }); - it('should have expanded the uri after several follows', async() => { + it('should have expanded the uri after several follows', async () => { - hal2= await ketting.follow('next').follow('prev').follow('templated', {foo: 'bar'}); + hal2 = await ketting.follow('next').follow('prev').follow('templated', {foo: 'bar'}); expect(hal2).to.be.an.instanceof(Resource); expect(hal2.uri).to.eql('http://localhost:3000/templated.json?foo=bar'); diff --git a/test/integration/follow-hal.ts b/test/integration/follow-hal.ts index ccaf3913..70f5c843 100644 --- a/test/integration/follow-hal.ts +++ b/test/integration/follow-hal.ts @@ -1,36 +1,36 @@ +import { expect } from 'chai'; import Ketting from '../../src/ketting'; import Resource from '../../src/resource'; -import { expect } from 'chai'; describe('Following a link', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); - let hal2:Resource; + let hal2: Resource; - it('should return a resource', async() => { + it('should return a resource', async () => { hal2 = await ketting.follow('next'); expect(hal2).to.be.an.instanceof(Resource); }); - it('should get the correct response to GET', async() => { + it('should get the correct response to GET', async () => { const body = await hal2.get(); - expect(body).to.eql({'title': 'HAL 2!'}); + expect(body).to.eql({title: 'HAL 2!'}); }); - it('should be chainable', async() => { + it('should be chainable', async () => { const hal1 = await ketting.follow('next').follow('prev'); const body = await hal1.get(); - expect(body).to.eql({'title': 'Hal 1', 'foo': 'bar'}); + expect(body).to.eql({title: 'Hal 1', foo: 'bar'}); }); - it('should throw an error following non-existent relationships', async() => { + it('should throw an error following non-existent relationships', async () => { let result; try { @@ -44,15 +44,15 @@ describe('Following a link', async () => { }); - it('should be chainable several times', async() => { + it('should be chainable several times', async () => { const hal1 = await ketting.follow('next').follow('prev').follow('next').follow('prev'); const body = await hal1.get(); - expect(body).to.eql({'title': 'Hal 1', 'foo': 'bar'}); + expect(body).to.eql({title: 'Hal 1', foo: 'bar'}); }); - it('should work with embedded resources', async() => { + it('should work with embedded resources', async () => { const items = await ketting.follow('collection').followAll('item'); expect(items).to.have.length(2); diff --git a/test/integration/get.ts b/test/integration/get.ts index 43737d75..7f2e3b73 100644 --- a/test/integration/get.ts +++ b/test/integration/get.ts @@ -1,7 +1,7 @@ -import Ketting from '../../src/ketting'; -import Resource from '../../src/resource'; import { expect } from 'chai'; +import Ketting from '../../src/ketting'; import Link from '../../src/link'; +import Resource from '../../src/resource'; describe('Issuing a GET request', async () => { @@ -9,33 +9,33 @@ describe('Issuing a GET request', async () => { let resource: Resource; let result: any; - before( async() => { + before( async () => { resource = await ketting.follow('headerTest'); }); - it('should not fail', async() => { + it('should not fail', async () => { result = await resource.get(); }); - it('should have sent the correct headers', async() => { + it('should have sent the correct headers', async () => { expect(result).to.have.property('user-agent'); expect(result['user-agent']).to.match(/^Ketting\//); - expect(result['accept']).to.eql('application/hal+json;q=1.0, application/json;q=0.9, text/html;q=0.8'); + expect(result.accept).to.eql('application/hal+json;q=1.0, application/json;q=0.9, text/html;q=0.8'); expect(result['content-type']).to.eql('application/hal+json'); }); - it('should throw an exception when there was a HTTP error', async() => { + it('should throw an exception when there was a HTTP error', async () => { - const resource = await ketting.follow('error400'); + const resource2 = await ketting.follow('error400'); let exception; try { - await resource.get(); + await resource2.get(); } catch (ex) { exception = ex; } @@ -43,28 +43,44 @@ describe('Issuing a GET request', async () => { }); - it('should support the HTTP Link header', async() => { + it('should support the HTTP Link header', async () => { - const resource = await ketting.follow('linkHeader'); - const links = await resource.links(); + const resource2 = await ketting.follow('linkHeader'); + const links = await resource2.links(); const expected = [ - new Link({rel: 'next', baseHref: 'http://localhost:3000/link-header', href: '/hal2.json'}), - new Link({rel: 'previous', baseHref: 'http://localhost:3000/link-header', href: '/TheBook/chapter2'}), - new Link({rel: 'start', baseHref: 'http://localhost:3000/link-header', href: 'http://example.org/'}), - new Link({rel: 'http://example.net/relation/other', baseHref: 'http://localhost:3000/link-header', href: 'http://example.org/'}) + new Link({ + rel: 'next', + baseHref: 'http://localhost:3000/link-header', + href: '/hal2.json' + }), + new Link({ + rel: 'previous', + baseHref: 'http://localhost:3000/link-header', + href: '/TheBook/chapter2' + }), + new Link({ + rel: 'start', + baseHref: 'http://localhost:3000/link-header', + href: 'http://example.org/' + }), + new Link({ + rel: 'http://example.net/relation/other', + baseHref: 'http://localhost:3000/link-header', + href: 'http://example.org/' + }) ]; expect(links).to.eql(expected); }); - it('should throw an exception when no content-type was returned', async() => { + it('should throw an exception when no content-type was returned', async () => { - const resource = await ketting.follow('no-content-type'); + const resource2 = await ketting.follow('no-content-type'); let hadException = false; try { - await resource.get(); + await resource2.get(); } catch (ex) { hadException = true; } diff --git a/test/integration/oauth-auth.ts b/test/integration/oauth-auth.ts index 825be63c..90513071 100644 --- a/test/integration/oauth-auth.ts +++ b/test/integration/oauth-auth.ts @@ -1,11 +1,11 @@ -import Ketting from '../../src/ketting'; import { expect } from 'chai'; +import Ketting from '../../src/ketting'; describe('OAuth2 Authentication', () => { describe('Owner flow', () => { - it('should return 401 if no credentials were passed.', async() => { + it('should return 401 if no credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); const resource = await ketting.follow('auth-oauth'); @@ -64,7 +64,7 @@ describe('OAuth2 Authentication', () => { }); - it('should return 200 OK if correct credentials were passed.', async() => { + it('should return 200 OK if correct credentials were passed.', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { @@ -88,7 +88,7 @@ describe('OAuth2 Authentication', () => { }); - it('should refresh token if 401 is returned and retry request', async() => { + it('should refresh token if 401 is returned and retry request', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { @@ -120,7 +120,7 @@ describe('OAuth2 Authentication', () => { }); - it('should refresh token if 401 is returned and throw error if refresh is invalid', async() => { + it('should refresh token if 401 is returned and throw error if refresh is invalid', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json', { auth: { @@ -150,7 +150,7 @@ describe('OAuth2 Authentication', () => { const resource = await ketting.follow('auth-oauth'); await resource.fetch(); - } catch (error){ + } catch (error) { expect(error).to.be.an('error'); } }); @@ -160,6 +160,7 @@ describe('OAuth2 Authentication', () => { let ex; try { + // tslint:disable-next-line new Ketting('http://localhost:3000/hal1.json', { auth: { type: 'oauth2', diff --git a/test/integration/patch.ts b/test/integration/patch.ts index 911e7c2a..f95bc198 100644 --- a/test/integration/patch.ts +++ b/test/integration/patch.ts @@ -1,32 +1,32 @@ +import { expect } from 'chai'; import Ketting from '../../src/ketting'; import Resource from '../../src/resource'; -import { expect } from 'chai'; describe('Issuing a PATCH request', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); let resource: Resource; - before( async() => { + before( async () => { - resource = await ketting.getResource().follow('echo');; + resource = await ketting.getResource().follow('echo'); // Priming the cache await resource.get(); }); - it('should not fail', async() => { + it('should not fail', async () => { await resource.patch({newData: 'hi!'}); - + }); - it('should have cleared the resource representation', async() => { + it('should have cleared the resource representation', async () => { expect(resource.repr).to.eql(null); - + }); - it('should throw an exception if there was an http error', async() => { + it('should throw an exception if there was an http error', async () => { let ok = false; try { @@ -39,7 +39,7 @@ describe('Issuing a PATCH request', async () => { }); - after( async() => { + after( async () => { await ketting.getResource('/reset').post({}); diff --git a/test/integration/post.ts b/test/integration/post.ts index 6ab89947..889a1e5c 100644 --- a/test/integration/post.ts +++ b/test/integration/post.ts @@ -1,46 +1,46 @@ +import { expect } from 'chai'; import Ketting from '../../src/ketting'; import Resource from '../../src/resource'; -import { expect } from 'chai'; describe('Issuing a POST request', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); - let resource:Resource; - let newResource:Resource; + let resource: Resource; + let newResource: Resource; - before( async() => { + before( async () => { resource = ketting.getResource(); }); - it('should not fail', async() => { + it('should not fail', async () => { - newResource = await resource.post({ + newResource = await resource.post({ title: 'Posted resource' - }); - + }) as Resource; + }); - it('should have returned a new resource', async() => { + it('should have returned a new resource', async () => { expect(newResource).to.be.an.instanceof(Resource); expect(newResource.uri).to.match(/\.json$/); - + }); - it('should have created the new resource', async() => { + it('should have created the new resource', async () => { const newBody = await newResource.get(); expect(newBody).to.eql({title: 'Posted resource'}); - + }); - it('should throw an exception when there was a HTTP error', async() => { + it('should throw an exception when there was a HTTP error', async () => { - const resource = await ketting.follow('error400'); + const resource400 = await ketting.follow('error400'); let exception; try { - await resource.post({foo: 'bar'}); + await resource400.post({foo: 'bar'}); } catch (ex) { exception = ex; } diff --git a/test/integration/put.ts b/test/integration/put.ts index c6127774..9c27b4a2 100644 --- a/test/integration/put.ts +++ b/test/integration/put.ts @@ -1,38 +1,39 @@ +import { expect } from 'chai'; + import Ketting from '../../src/ketting'; import Resource from '../../src/resource'; -import { expect } from 'chai'; describe('Issuing a PUT request', async () => { const ketting = new Ketting('http://localhost:3000/hal1.json'); let resource: Resource; - before( async() => { + before( async () => { - resource = await ketting.getResource().follow('next');; + resource = await ketting.getResource().follow('next'); // Priming the cache await resource.get(); }); - it('should not fail', async() => { + it('should not fail', async () => { await resource.put({newData: 'hi!'}); - + }); - it('should have cleared the resource representation', async() => { - + it('should have cleared the resource representation', async () => { + const newBody = await resource.get(); expect(newBody).to.eql({newData: 'hi!'}); - + }); - it('should have cleared the global cache', async() => { - + it('should have cleared the global cache', async () => { + const newBody = await (await ketting.follow('next')).get(); expect(newBody).to.eql({newData: 'hi!'}); - + }); - it('should throw an exception if there was an http error', async() => { + it('should throw an exception if there was an http error', async () => { let ok = false; try { @@ -45,7 +46,7 @@ describe('Issuing a PUT request', async () => { }); - after( async() => { + after( async () => { await ketting.getResource('/reset').post({}); diff --git a/test/test-entrypoint.ts b/test/test-entrypoint.ts index 811966f2..0721cb55 100644 --- a/test/test-entrypoint.ts +++ b/test/test-entrypoint.ts @@ -2,12 +2,12 @@ * This file aids webpack into getting all tests to load via a single entrypoint. */ // @ts-ignore -var _req = require.context("./unit", true, /^(.*\.(ts$))[^.]*$/im); -_req.keys().forEach(function(key: string){ - _req(key); +let myRequire = require.context('./unit', true, /^(.*\.(ts$))[^.]*$/im); +myRequire.keys().forEach((key: string) => { + myRequire(key); }); // @ts-ignore -var _req = require.context("./integration", true, /^(.*\.(ts$))[^.]*$/im); -_req.keys().forEach(function(key: string){ - _req(key); +myRequire = require.context('./integration', true, /^(.*\.(ts$))[^.]*$/im); +myRequire.keys().forEach((key: string) => { + myRequire(key); }); diff --git a/test/testserver.ts b/test/testserver.ts index afdecc50..60431a14 100644 --- a/test/testserver.ts +++ b/test/testserver.ts @@ -1,22 +1,21 @@ +import fs from 'fs'; import Koa from 'koa'; import { Context as KoaContext } from 'koa'; import bodyParser from 'koa-bodyparser'; +import logger from 'koa-logger'; // @ts-ignore don't have a definition for this. import Route from 'koa-path-match'; -import logger from 'koa-logger'; import koaStatic from 'koa-static'; -import fs from 'fs'; type Context = KoaContext & { params: { [s: string]: string } }; - const app = new Koa(); const route = Route(); let resources: { - [uri: string] : Buffer | string | null + [uri: string]: Buffer | string | null } = {}; // Log to console @@ -42,8 +41,6 @@ staticFile('/', __dirname + '/fixtures/index.html', 'text/html'); staticFile('/mocha.js', __dirname + '/../node_modules/mocha/mocha.js', 'text/javascript'); staticFile('/mocha.css', __dirname + '/../node_modules/mocha/mocha.css', 'text/css'); - - app.use( route('/headers', (ctx: Context) => { ctx.response.status = 200; @@ -64,7 +61,7 @@ app.use( // HTTP errors as a service app.use( route('/error/:code', (ctx: Context) => { - ctx.response.status = parseInt(ctx.params.code); + ctx.response.status = parseInt(ctx.params.code, 10); ctx.response.body = ''; }) ); @@ -80,14 +77,14 @@ app.use( // Return request body as we received it app.use( - route('/echo', (ctx: Context)=> { + route('/echo', (ctx: Context) => { ctx.response.status = 200; ctx.response.type = ctx.request.headers['content-type']; ctx.response.body = { headers: ctx.request.headers, body: ctx.request.body, method: ctx.request.method, - } + }; }) ); @@ -122,8 +119,8 @@ app.use( ctx.response.status = 410; ctx.response.body = { - type: "http://evertpot.com/problem-test", - title: "Some sort of error!" + type: 'http://evertpot.com/problem-test', + title: 'Some sort of error!' }; ctx.response.type = 'application/problem+json'; @@ -134,7 +131,7 @@ app.use( route('/auth/basic') .get((ctx: Context) => { const encoded = 'Basic dXNlcjpwYXNz'; // base64(user:pass) - if (!ctx.request.headers.authorization || ctx.request.headers.authorization!==encoded) { + if (!ctx.request.headers.authorization || ctx.request.headers.authorization !== encoded) { ctx.response.status = 401; ctx.response.body = ''; ctx.response.set('Authorization', 'Basic'); @@ -149,7 +146,7 @@ app.use( route('/auth/bearer') .get((ctx: Context) => { const encoded = 'Bearer foo'; - if (!ctx.request.headers.authorization || ctx.request.headers.authorization!==encoded) { + if (!ctx.request.headers.authorization || ctx.request.headers.authorization !== encoded) { ctx.response.status = 401; ctx.response.body = ''; ctx.response.set('Authorization', 'Bearer'); @@ -164,7 +161,7 @@ app.use( route('/auth/oauth') .get((ctx: Context) => { const encoded = 'Bearer foo'; - if (!ctx.request.headers.authorization || ctx.request.headers.authorization!==encoded) { + if (!ctx.request.headers.authorization || ctx.request.headers.authorization !== encoded) { ctx.response.status = 401; ctx.response.body = ''; ctx.response.set('Authorization', 'Bearer'); @@ -193,7 +190,7 @@ app.use( (requestBody.grant_type === 'refresh_token' && requestBody.refresh_token === 'fooRefresh') ) - ){ + ) { ctx.response.body = { token_type: 'bearer', access_token: 'foo', @@ -212,7 +209,7 @@ app.use( route('/:id') .get((ctx: Context) => { - if (typeof resources[ctx.params.id] === "undefined") { + if (resources[ctx.params.id] === undefined) { resources[ctx.params.id] = fs.readFileSync(__dirname + '/fixtures/' + ctx.params.id); } @@ -262,7 +259,7 @@ app.use( let body = ''; ctx.req.setEncoding('utf-8'); - ctx.req.on('data', (chunk:string) => { + ctx.req.on('data', (chunk: string) => { body += chunk; @@ -282,7 +279,8 @@ app.use( }) ); -var port = 3000; +const port = 3000; app.listen(port); +// tslint:disable no-console console.log('Server is now online. Head to http://localhost:' + port + '/ to run tests in a browser'); diff --git a/test/tsconfig.json b/test/tsconfig.json index 97f98f12..f16b6fc3 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,40 +1,40 @@ { - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "target": "es2017", - "noImplicitAny": true, + compilerOptions: { + module: 'commonjs', + esModuleInterop: true, + target: 'es2017', + noImplicitAny: true, - "strictFunctionTypes": true, - "noImplicitThis": true, - "alwaysStrict": true, - "noUnusedLocals": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, + strictFunctionTypes: true, + noImplicitThis: true, + alwaysStrict: true, + noUnusedLocals: true, + noImplicitReturns: true, + noFallthroughCasesInSwitch: true, - "moduleResolution": "node", - "noEmit": true, - "baseUrl": ".", - "allowJs": true, - "paths": { - "*": [ - "../src/types/*" + moduleResolution: 'node', + noEmit: true, + baseUrl: '.', + allowJs: true, + paths: { + '*': [ + '../src/types/*' ] }, - "lib": [ - "DOM", - "ES5", - "ES2015", - "ES2016", - "ES2017", - "DOM.Iterable" + lib: [ + 'DOM', + 'ES5', + 'ES2015', + 'ES2016', + 'ES2017', + 'DOM.Iterable' ] }, - "include": [ - "**/*", - "../src/**/*" + include: [ + '**/*', + '../src/**/*' ], - "exclude": [ - "../node_modules/**/*" + exclude: [ + '../node_modules/**/*' ] -} +}; diff --git a/test/unit/followable-promise.ts b/test/unit/followable-promise.ts index ad3c4ac5..e05007e1 100644 --- a/test/unit/followable-promise.ts +++ b/test/unit/followable-promise.ts @@ -1,6 +1,7 @@ -import FollowablePromise from '../../src/followable-promise'; import { expect } from 'chai'; +import FollowablePromise from '../../src/followable-promise'; + describe('FollowablePromise', () => { describe('.then()', () => { @@ -17,7 +18,7 @@ describe('FollowablePromise', () => { expect(await p).to.equal('hi'); }); - + it('should work when rejecting', async () => { const p = new FollowablePromise( (res, rej) => { @@ -48,7 +49,7 @@ describe('FollowablePromise', () => { // @ts-ignore: I know what I'm doing res({ - follow: function(rel: string, vars: object) { + follow: (rel: string, vars: object) => { // @ts-ignore: I know what I'm doing return 'follow:' + rel + ':' + vars.B; } @@ -56,7 +57,7 @@ describe('FollowablePromise', () => { }); - expect(await p.follow('A',{B: 'C'}), 'follow:A:C'); + expect(await p.follow('A', {B: 'C'}), 'follow:A:C'); }); @@ -66,8 +67,8 @@ describe('FollowablePromise', () => { // @ts-ignore: I know what I'm doing res({ - follow: function() { - throw "Hi"; + follow() { + throw new Error('Hi'); } }); @@ -79,7 +80,7 @@ describe('FollowablePromise', () => { } catch (e) { result = e; } - expect(result).to.equal('Hi'); + expect(result.message).to.equal('Hi'); }); diff --git a/test/unit/ketting.ts b/test/unit/ketting.ts index 104729ec..57abc09e 100644 --- a/test/unit/ketting.ts +++ b/test/unit/ketting.ts @@ -1,7 +1,8 @@ +import { expect } from 'chai'; + import Ketting from '../../src/ketting'; -import Html from '../../src/representor/html'; import Hal from '../../src/representor/hal'; -import { expect } from 'chai'; +import Html from '../../src/representor/html'; describe('Ketting', () => { @@ -39,5 +40,4 @@ describe('Ketting', () => { }); - }); diff --git a/test/unit/link.ts b/test/unit/link.ts index 23164830..e3db754f 100644 --- a/test/unit/link.ts +++ b/test/unit/link.ts @@ -1,18 +1,20 @@ -import Link from '../../src/link'; import { expect } from 'chai'; +import Link from '../../src/link'; + describe('Link', () => { it('should construct and expose its properties', () => { const link = new Link({ - rel: 'foo', baseHref: 'http://example.org/', href: '/foo/bar', + rel: 'foo', + + name: 'foo-link', type: 'text/css', templated: false, title: 'Foo Link', - name: 'foo-link' }); expect(link.rel).to.equal('foo'); @@ -40,9 +42,9 @@ describe('Link', () => { it('should be able to expand templated links', () => { const link = new Link({ - rel: 'about', baseHref: 'http://example.org/', href: '/foo/{bar}', + rel: 'about', templated: true }); @@ -53,9 +55,9 @@ describe('Link', () => { it('should not error when expanding non-templated links', () => { const link = new Link({ - rel: 'about', baseHref: 'http://example.org/', - href: '/foo/bar' + href: '/foo/bar', + rel: 'about', }); expect(link.expand({ bar: 'zim' })).to.equal('http://example.org/foo/bar'); diff --git a/test/unit/representor/html.ts b/test/unit/representor/html.ts index 01ee46ca..a1ebf489 100644 --- a/test/unit/representor/html.ts +++ b/test/unit/representor/html.ts @@ -1,68 +1,69 @@ -import Html from '../../../src/representor/html'; -import Link from '../../../src/link'; import { expect } from 'chai'; +import Link from '../../../src/link'; +import Html from '../../../src/representor/html'; + describe('HTML representor', () => { type TestTuple = [string] | [string, Link] | [string, Link, Link]; - const tests:TestTuple[] = [ + const tests: TestTuple[] = [ [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'stylesheet', baseHref: '/index.html', href: 'foo.css', type: 'text/css'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'me', baseHref: '/index.html', href: 'https://evertpot.com/'}) ], [ - ``, + '', new Link({rel: 'icon', baseHref: '/index.html', href: 'favicon.ico'}), new Link({rel: 'favicon', baseHref: '/index.html', href: 'favicon.ico'}), ], [ // Ignoring links without rel - ``, + '', ], [ // Ignoring links without href - ``, + '', ] ]; diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..11c5fcb2 --- /dev/null +++ b/tslint.json @@ -0,0 +1,22 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": {}, + "rules": { + "arrow-parens": false, + "interface-name": false, + "interface-over-type-literal": false, + "max-classes-per-file": false, + "max-line-length": false, + "member-access": false, + "no-consecutive-blank-lines": [true, 2], + "no-angle-bracket-type-assertion": false, + "object-literal-shorthand": false, + "object-literal-sort-keys": false, + "quotemark": [true, "single", "avoid-template", "avoid-escape"], + "trailing-comma": "never" + }, + "rulesDirectory": [] +}