diff --git a/__tests__/cmds/docs.test.js b/__tests__/cmds/docs.test.js index 66b4dd07b..32a659097 100644 --- a/__tests__/cmds/docs.test.js +++ b/__tests__/cmds/docs.test.js @@ -87,7 +87,11 @@ describe('rdme docs', () => { ...simpleDoc.doc.data, }) .basicAuth({ user: key }) - .reply(200) + .reply(200, { + category, + slug: simpleDoc.slug, + body: simpleDoc.doc.content, + }) .put('/api/v1/docs/another-doc', { category, slug: anotherDoc.slug, @@ -96,17 +100,24 @@ describe('rdme docs', () => { ...anotherDoc.doc.data, }) .basicAuth({ user: key }) - .reply(200); + .reply(200, { category, slug: anotherDoc.slug, body: anotherDoc.doc.content }); const versionMock = nock(config.host) .get(`/api/v1/version/${version}`) .basicAuth({ user: key }) .reply(200, { version }); - return docs.run({ folder: './__tests__/__fixtures__/existing-docs', key, version }).then(skippedDocs => { + return docs.run({ folder: './__tests__/__fixtures__/existing-docs', key, version }).then(updatedDocs => { // All docs should have been updated because their hashes from the GET request were different from what they // are currently. - expect(skippedDocs).toHaveLength(0); + expect(updatedDocs).toStrictEqual([ + { + category, + slug: simpleDoc.slug, + body: simpleDoc.doc.content, + }, + { category, slug: anotherDoc.slug, body: anotherDoc.doc.content }, + ]); getMocks.done(); updateMocks.done(); @@ -161,7 +172,7 @@ describe('rdme docs', () => { const postMock = getNockWithVersionHeader(version) .post(`/api/v1/docs`, { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) .basicAuth({ user: key }) - .reply(201); + .reply(201, { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); const versionMock = nock(config.host) .get(`/api/v1/version/${version}`) @@ -207,12 +218,6 @@ describe('rdme docs', () => { }); const postMocks = getNockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(400, { - error: 'DOC_INVALID', - message: "We couldn't save this doc (Path `category` is required.).", - }) .post('/api/v1/docs', { slug: slugTwo, body: docTwo.content, ...docTwo.data, lastUpdatedHash: hashTwo }) .basicAuth({ user: key }) .reply(201, { @@ -230,6 +235,12 @@ describe('rdme docs', () => { slug: slugTwo, body: 'Body', category, + }) + .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) + .basicAuth({ user: key }) + .reply(400, { + error: 'DOC_INVALID', + message: "We couldn't save this doc (Path `category` is required.).", }); const versionMock = nock(config.host) @@ -305,7 +316,7 @@ describe('rdme docs:edit', () => { body: `${body}${edits}`, }) .basicAuth({ user: key }) - .reply(200); + .reply(200, { category, slug }); const versionMock = nock(config.host) .get(`/api/v1/version/${version}`) diff --git a/__tests__/cmds/openapi.test.js b/__tests__/cmds/openapi.test.js index f170683ab..a96464661 100644 --- a/__tests__/cmds/openapi.test.js +++ b/__tests__/cmds/openapi.test.js @@ -5,7 +5,7 @@ const promptHandler = require('../../src/lib/prompts'); const swagger = require('../../src/cmds/swagger'); const openapi = require('../../src/cmds/openapi'); -const key = 'Xmw4bGctRVIQz7R7dQXqH9nQe5d0SPQs'; +const key = 'API_KEY'; const version = '1.0.0'; jest.mock('../../src/lib/prompts'); @@ -87,9 +87,14 @@ describe('rdme openapi', () => { help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', }); - return expect(openapi.run({ spec: './__tests__/__fixtures__/swagger.json', key, version })) - .rejects.toThrow('The version you specified') - .then(() => mock.done()); + return openapi.run({ spec: './__tests__/__fixtures__/swagger.json', key, version }).then(() => { + expect(console.log).toHaveBeenCalledTimes(1); + + const output = getCommandOutput(); + expect(output).toMatch(/The version you specified/); + + mock.done(); + }); }); it('should POST to the swagger api if no id provided', () => { @@ -135,9 +140,14 @@ describe('rdme openapi', () => { help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', }); - return expect(openapi.run({ spec: './__tests__/__fixtures__/invalid-swagger.json', key, version })) - .rejects.toThrow('README VALIDATION ERROR "x-samples-languages" must be of type "Array"') - .then(() => mock.done()); + return openapi.run({ spec: './__tests__/__fixtures__/invalid-swagger.json', key, version }).then(() => { + expect(console.log).toHaveBeenCalledTimes(1); + + const output = getCommandOutput(); + expect(output).toMatch(/Unknown error \(README VALIDATION ERROR "x-samples-languages" /); + + mock.done(); + }); }); it.todo('should return a 404 if version flag not found'); diff --git a/__tests__/cmds/versions.test.js b/__tests__/cmds/versions.test.js index 491188d00..b6173b0d0 100644 --- a/__tests__/cmds/versions.test.js +++ b/__tests__/cmds/versions.test.js @@ -7,7 +7,7 @@ const createVersion = require('../../src/cmds/versions/create'); const deleteVersion = require('../../src/cmds/versions/delete'); const updateVersion = require('../../src/cmds/versions/update'); -const key = 'Xmw4bGctRVIQz7R7dQXqH9nQe5d0SPQs'; +const key = 'API_KEY'; const version = '1.0.0'; const version2 = '2.0.0'; diff --git a/package-lock.json b/package-lock.json index 6e5bdf26c..73f50c393 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "configstore": "^5.0.0", "editor": "^1.0.0", "enquirer": "^2.3.0", + "form-data": "^2.3.3", "gray-matter": "^4.0.1", "isemail": "^3.1.3", + "node-fetch": "^2.6.1", "oas": "^14.0.0", "oas-normalize": "^3.0.4", "open": "^8.2.1", "read": "^1.0.7", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", "semver": "^7.0.0", "table-layout": "^1.0.0" }, @@ -2628,6 +2628,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2810,22 +2811,6 @@ "node": ">=0.10.0" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -2846,19 +2831,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" - }, "node_modules/axe-core": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz", @@ -3079,14 +3051,6 @@ } ] }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3267,11 +3231,6 @@ "cdl": "bin/cdl.js" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4024,7 +3983,8 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -4096,17 +4056,6 @@ "node": ">=8" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -4328,15 +4277,6 @@ "node": ">=8" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/editor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/editor/-/editor-1.0.0.tgz", @@ -5654,11 +5594,6 @@ "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -5672,18 +5607,11 @@ "node": ">=4" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-diff": { "version": "1.2.0", @@ -5710,7 +5638,8 @@ "node_modules/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=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -5819,14 +5748,6 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -6163,14 +6084,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/git-raw-commits": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", @@ -6358,26 +6271,6 @@ "uglify-js": "^3.1.4" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dependencies": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -6486,20 +6379,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/http2-client": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", @@ -7166,11 +7045,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "node_modules/istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -10247,11 +10121,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, "node_modules/jsdom": { "version": "16.6.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", @@ -10362,11 +10231,6 @@ "integrity": "sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q==", "dev": true }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, "node_modules/json-schema-compare": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", @@ -10391,7 +10255,8 @@ "node_modules/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==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -10402,7 +10267,8 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "node_modules/json2yaml": { "version": "1.1.0", @@ -10468,20 +10334,6 @@ "node": "*" } }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "node_modules/jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -11438,14 +11290,6 @@ "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -11804,11 +11648,6 @@ "node": ">=4" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, "node_modules/picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -12011,7 +11850,8 @@ "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true }, "node_modules/punycode": { "version": "2.1.1", @@ -12031,14 +11871,6 @@ "teleport": ">=0.2.0" } }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -12192,65 +12024,6 @@ "node": "*" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/request/node_modules/safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12388,7 +12161,8 @@ "node_modules/safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true }, "node_modules/safe-regex": { "version": "2.1.1", @@ -12707,25 +12481,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", @@ -12747,14 +12502,6 @@ "node": ">=8" } }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -13227,18 +12974,6 @@ "node": ">=8.0" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tr46": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", @@ -13314,22 +13049,6 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, "node_modules/type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -13445,6 +13164,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -13458,6 +13178,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true, "bin": { "uuid": "bin/uuid" } @@ -13541,19 +13262,6 @@ "node": ">= 0.10" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -15800,6 +15508,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -15936,19 +15645,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -15966,16 +15662,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" - }, "axe-core": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz", @@ -16136,14 +15822,6 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -16272,11 +15950,6 @@ "redeyed": "~2.1.0" } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -16877,7 +16550,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cross-spawn": { "version": "7.0.3", @@ -16939,14 +16613,6 @@ "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -17120,15 +16786,6 @@ "is-obj": "^2.0.0" } }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "editor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/editor/-/editor-1.0.0.tgz", @@ -18135,11 +17792,6 @@ } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -18150,15 +17802,11 @@ "tmp": "^0.0.33" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "fast-diff": { "version": "1.2.0", @@ -18182,7 +17830,8 @@ "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=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -18270,11 +17919,6 @@ "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -18526,14 +18170,6 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "git-raw-commits": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", @@ -18672,20 +18308,6 @@ "wordwrap": "^1.0.0" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -18764,16 +18386,6 @@ } } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "http2-client": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", @@ -19232,11 +18844,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -21585,11 +21192,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, "jsdom": { "version": "16.6.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", @@ -21673,11 +21275,6 @@ "integrity": "sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, "json-schema-compare": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", @@ -21699,7 +21296,8 @@ "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==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -21710,7 +21308,8 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "json2yaml": { "version": "1.1.0", @@ -21749,17 +21348,6 @@ "through": ">=2.2.7 <3" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "jsx-ast-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", @@ -22541,11 +22129,6 @@ "yaml": "^1.10.0" } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -22807,11 +22390,6 @@ "pify": "^2.0.0" } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -22962,7 +22540,8 @@ "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true }, "punycode": { "version": "2.1.1", @@ -22975,11 +22554,6 @@ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -23097,58 +22671,6 @@ "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==" }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -23256,7 +22778,8 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true }, "safe-regex": { "version": "2.1.1", @@ -23536,22 +23059,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", @@ -23569,11 +23076,6 @@ } } }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -23950,15 +23452,6 @@ "is-number": "^7.0.0" } }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "tr46": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", @@ -24018,19 +23511,6 @@ "tslib": "^1.8.1" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -24112,6 +23592,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -24124,7 +23605,8 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true }, "v8-compile-cache": { "version": "2.2.0", @@ -24198,16 +23680,6 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz", "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/package.json b/package.json index 0e335287b..101191fd0 100644 --- a/package.json +++ b/package.json @@ -38,14 +38,14 @@ "configstore": "^5.0.0", "editor": "^1.0.0", "enquirer": "^2.3.0", + "form-data": "^2.3.3", "gray-matter": "^4.0.1", "isemail": "^3.1.3", + "node-fetch": "^2.6.1", "oas": "^14.0.0", "oas-normalize": "^3.0.4", "open": "^8.2.1", "read": "^1.0.7", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", "semver": "^7.0.0", "table-layout": "^1.0.0" }, diff --git a/src/cmds/docs/edit.js b/src/cmds/docs/edit.js index 96322681b..d2d77d8a7 100644 --- a/src/cmds/docs/edit.js +++ b/src/cmds/docs/edit.js @@ -1,10 +1,11 @@ -const request = require('request-promise-native'); const config = require('config'); const fs = require('fs'); const editor = require('editor'); const { promisify } = require('util'); const APIError = require('../../lib/apiError'); const { getProjectVersion } = require('../../lib/versionSelect'); +const { handleRes } = require('../../lib/handleRes'); +const fetch = require('node-fetch'); const writeFile = promisify(fs.writeFile); const readFile = promisify(fs.readFile); @@ -51,19 +52,16 @@ exports.run = async function (opts) { }); const filename = `${slug}.md`; - const options = { - auth: { user: key }, + const encodedString = Buffer.from(`${key}:`).toString('base64'); + + const existingDoc = await fetch(`${config.host}/api/v1/docs/${slug}`, { + method: 'get', headers: { 'x-readme-version': selectedVersion, + Authorization: `Basic ${encodedString}`, + Accept: 'application/json', }, - }; - - const existingDoc = await request - .get(`${config.host}/api/v1/docs/${slug}`, { - json: true, - ...options, - }) - .catch(err => Promise.reject(new APIError(err))); + }).then(res => handleRes(res)); await writeFile(filename, existingDoc.body); @@ -72,19 +70,28 @@ exports.run = async function (opts) { if (code !== 0) return reject(new Error('Non zero exit code from $EDITOR')); const updatedDoc = await readFile(filename, 'utf8'); - return request - .put(`${config.host}/api/v1/docs/${slug}`, { - json: Object.assign(existingDoc, { + return fetch(`${config.host}/api/v1/docs/${slug}`, { + method: 'put', + headers: { + 'x-readme-version': selectedVersion, + Authorization: `Basic ${encodedString}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify( + Object.assign(existingDoc, { body: updatedDoc, - }), - ...options, - }) - .then(async () => { + }) + ), + }) + .then(res => res.json()) + .then(async res => { + if (res.error) { + return reject(new APIError(res)); + } console.log(`Doc successfully updated. Cleaning up local file.`); await unlink(filename); return resolve(); - }) - .catch(err => reject(new APIError(err))); + }); }); }); }; diff --git a/src/cmds/docs/index.js b/src/cmds/docs/index.js index 3d1f0f7bd..f59934a8c 100644 --- a/src/cmds/docs/index.js +++ b/src/cmds/docs/index.js @@ -1,13 +1,13 @@ require('colors'); -const request = require('request-promise-native'); const fs = require('fs'); const path = require('path'); const config = require('config'); const crypto = require('crypto'); const frontMatter = require('gray-matter'); const { promisify } = require('util'); -const APIError = require('../../lib/apiError'); const { getProjectVersion } = require('../../lib/versionSelect'); +const { handleRes } = require('../../lib/handleRes'); +const fetch = require('node-fetch'); const readFile = promisify(fs.readFile); @@ -70,22 +70,25 @@ exports.run = async function (opts) { return Promise.reject(new Error(`We were unable to locate Markdown files in ${folder}.`)); } - const options = { - auth: { user: key }, - headers: { - 'x-readme-version': selectedVersion, - }, - }; + const encodedString = Buffer.from(`${key}:`).toString('base64'); function createDoc(slug, file, hash, err) { - if (err.statusCode !== 404) return Promise.reject(err.error); - - return request - .post(`${config.host}/api/v1/docs`, { - json: { slug, body: file.content, ...file.data, lastUpdatedHash: hash }, - ...options, - }) - .catch(err => Promise.reject(new APIError(err))); + if (err.error !== 'DOC_NOTFOUND') return Promise.reject(err); + + return fetch(`${config.host}/api/v1/docs`, { + method: 'post', + headers: { + 'x-readme-version': selectedVersion, + Authorization: `Basic ${encodedString}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + slug, + body: file.content, + ...file.data, + lastUpdatedHash: hash, + }), + }).then(res => handleRes(res)); } function updateDoc(slug, file, hash, existingDoc) { @@ -93,16 +96,21 @@ exports.run = async function (opts) { return `\`${slug}\` was not updated because there were no changes.`; } - return request - .put(`${config.host}/api/v1/docs/${slug}`, { - json: Object.assign(existingDoc, { + return fetch(`${config.host}/api/v1/docs/${slug}`, { + method: 'put', + headers: { + 'x-readme-version': selectedVersion, + Authorization: `Basic ${encodedString}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify( + Object.assign(existingDoc, { body: file.content, ...file.data, lastUpdatedHash: hash, - }), - ...options, - }) - .catch(err => Promise.reject(new APIError(err))); + }) + ), + }).then(res => handleRes(res)); } const updatedDocs = await Promise.allSettled( @@ -114,12 +122,21 @@ exports.run = async function (opts) { const slug = path.basename(filename).replace(path.extname(filename), '').toLowerCase(); const hash = crypto.createHash('sha1').update(file).digest('hex'); - return request - .get(`${config.host}/api/v1/docs/${slug}`, { - json: true, - ...options, + return fetch(`${config.host}/api/v1/docs/${slug}`, { + method: 'get', + headers: { + 'x-readme-version': selectedVersion, + Authorization: `Basic ${encodedString}`, + Accept: 'application/json', + }, + }) + .then(res => res.json()) + .then(res => { + if (res.error) { + return createDoc(slug, matter, hash, res); + } + return updateDoc(slug, matter, hash, res); }) - .then(updateDoc.bind(null, slug, matter, hash), createDoc.bind(null, slug, matter, hash)) .catch(err => { console.log(`\n\`${slug}\` failed to upload. ${err.message}\n`.red); }); diff --git a/src/cmds/login.js b/src/cmds/login.js index 6298291c1..5dfed438c 100644 --- a/src/cmds/login.js +++ b/src/cmds/login.js @@ -1,10 +1,10 @@ -const request = require('request-promise-native'); const config = require('config'); const { validate: isEmail } = require('isemail'); const { promisify } = require('util'); const read = promisify(require('read')); const configStore = require('../lib/configstore'); const APIError = require('../lib/apiError'); +const fetch = require('node-fetch'); const testing = process.env.NODE_ENV === 'testing'; @@ -54,16 +54,26 @@ exports.run = async function (opts) { return Promise.reject(new Error('You must provide a valid email address.')); } - return request - .post(`${config.host}/api/v1/login`, { - json: { email, password, project, token }, - }) + return fetch(`${config.host}/api/v1/login`, { + method: 'post', + headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, + body: JSON.stringify({ + email, + password, + project, + token, + }), + }) + .then(res => res.json()) .then(res => { + if (res.error) { + return Promise.reject(new APIError(res)); + } + configStore.set('apiKey', res.apiKey); configStore.set('email', email); configStore.set('project', project); return `Successfully logged in as ${email.green} to the ${project.blue} project.`; - }) - .catch(err => Promise.reject(new APIError(err))); + }); }; diff --git a/src/cmds/openapi.js b/src/cmds/openapi.js index 58792ea16..17fae13f0 100644 --- a/src/cmds/openapi.js +++ b/src/cmds/openapi.js @@ -1,5 +1,4 @@ require('colors'); -const request = require('request-promise-native'); const fs = require('fs'); const config = require('config'); const { prompt } = require('enquirer'); @@ -7,6 +6,8 @@ const OASNormalize = require('oas-normalize'); const promptOpts = require('../lib/prompts'); const APIError = require('../lib/apiError'); const { getProjectVersion } = require('../lib/versionSelect'); +const fetch = require('node-fetch'); +const FormData = require('form-data'); exports.command = 'openapi'; exports.usage = 'openapi [file] [options]'; @@ -59,31 +60,35 @@ exports.run = async function (opts) { return Promise.reject(new Error('No project API key provided. Please use `--key`.')); } + const encodedString = Buffer.from(`${key}:`).toString('base64'); + async function callApi(specPath, versionCleaned) { // @todo Tailor messaging to what is actually being handled here. If the user is uploading an OpenAPI file, never mention that they uploaded/updated a Swagger file. - function success(data) { + async function success(data) { const message = !isUpdate ? "You've successfully uploaded a new Swagger file to your ReadMe project!" : "You've successfully updated a Swagger file on your ReadMe project!"; + const body = await data.json(); + console.log( [ message, '', - `\t${`${data.headers.location}`.green}`, + `\t${`${data.headers.get('location')}`.green}`, '', 'To update your Swagger or OpenAPI file, run the following:', '', // eslint-disable-next-line no-underscore-dangle - `\trdme openapi FILE --key=${key} --id=${JSON.parse(data.body)._id}`.green, + `\trdme openapi FILE --key=${key} --id=${body._id}`.green, ].join('\n') ); } - function error(err) { + async function error(err) { try { - const parsedError = JSON.parse(err.error); + const parsedError = await err.json(); return Promise.reject(new APIError(parsedError)); } catch (e) { if (e.message.includes('Unexpected token < in JSON')) { @@ -112,26 +117,38 @@ exports.run = async function (opts) { return Promise.reject(err); }); + const formData = new FormData(); + formData.append('spec', bundledSpec); + const options = { - formData: { - spec: bundledSpec, - }, headers: { 'x-readme-version': versionCleaned, 'x-readme-source': 'cli', + Authorization: `Basic ${encodedString}`, + Accept: 'application/json', }, - auth: { user: key }, - resolveWithFullResponse: true, + body: formData, }; function createSpec() { - return request.post(`${config.host}/api/v1/api-specification`, options).then(success, error); + options.method = 'post'; + return fetch(`${config.host}/api/v1/api-specification`, options) + .then(res => { + if (res.ok) return success(res); + return error(res); + }) + .catch(err => console.log(`\n ${err.message}\n`.red)); } function updateSpec(specId) { isUpdate = true; - - return request.put(`${config.host}/api/v1/api-specification/${specId}`, options).then(success, error); + options.method = 'put'; + return fetch(`${config.host}/api/v1/api-specification/${specId}`, options) + .then(res => { + if (res.ok) return success(res); + return error(res); + }) + .catch(err => console.log(`\n ${err.message}\n`.red)); } /* @@ -143,13 +160,13 @@ exports.run = async function (opts) { */ if (!id) { - const apiSettings = await request.get(`${config.host}/api/v1/api-specification`, { + const apiSettings = await fetch(`${config.host}/api/v1/api-specification`, { + method: 'get', headers: { 'x-readme-version': versionCleaned, + Authorization: `Basic ${encodedString}`, }, - json: true, - auth: { user: key }, - }); + }).then(res => res.json()); if (!apiSettings.length) return createSpec(); diff --git a/src/cmds/versions/create.js b/src/cmds/versions/create.js index d726a5022..0ca1020db 100644 --- a/src/cmds/versions/create.js +++ b/src/cmds/versions/create.js @@ -1,9 +1,10 @@ -const request = require('request-promise-native'); const config = require('config'); const semver = require('semver'); const { prompt } = require('enquirer'); const promptOpts = require('../../lib/prompts'); const APIError = require('../../lib/apiError'); +const { handleRes } = require('../../lib/handleRes'); +const fetch = require('node-fetch'); exports.command = 'versions:create'; exports.usage = 'versions:create --version= [options]'; @@ -53,6 +54,7 @@ exports.args = [ exports.run = async function (opts) { let versionList; const { key, version, codename, fork, main, beta, isPublic } = opts; + const encodedString = Buffer.from(`${key}:`).toString('base64'); if (!key) { return Promise.reject(new Error('No project API key provided. Please use `--key`.')); @@ -65,12 +67,12 @@ exports.run = async function (opts) { } if (!fork) { - versionList = await request - .get(`${config.host}/api/v1/version`, { - json: true, - auth: { user: key }, - }) - .catch(err => Promise.reject(new APIError(err))); + versionList = await fetch(`${config.host}/api/v1/version`, { + method: 'get', + headers: { + Authorization: `Basic ${encodedString}`, + }, + }).then(res => handleRes(res)); } const versionPrompt = promptOpts.createVersionPrompt(versionList || [{}], { @@ -79,20 +81,28 @@ exports.run = async function (opts) { }); const promptResponse = await prompt(versionPrompt); - const options = { - json: { + + return fetch(`${config.host}/api/v1/version`, { + method: 'post', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Basic ${encodedString}`, + }, + body: JSON.stringify({ version, codename: codename || '', is_stable: main === 'true' || promptResponse.is_stable, is_beta: beta === 'true' || promptResponse.is_beta, from: fork || promptResponse.from, is_hidden: promptResponse.is_stable ? false : !(isPublic === 'true' || promptResponse.is_hidden), - }, - auth: { user: key }, - }; - - return request - .post(`${config.host}/api/v1/version`, options) - .then(() => Promise.resolve(`Version ${version} created successfully.`)) - .catch(err => Promise.reject(new APIError(err))); + }), + }) + .then(res => res.json()) + .then(res => { + if (res.error) { + return Promise.reject(new APIError(res)); + } + return Promise.resolve(`Version ${version} created successfully.`); + }); }; diff --git a/src/cmds/versions/delete.js b/src/cmds/versions/delete.js index 8d7eebe95..79ea6c3f3 100644 --- a/src/cmds/versions/delete.js +++ b/src/cmds/versions/delete.js @@ -1,7 +1,7 @@ -const request = require('request-promise-native'); const config = require('config'); const APIError = require('../../lib/apiError'); const { getProjectVersion } = require('../../lib/versionSelect'); +const fetch = require('node-fetch'); exports.command = 'versions:delete'; exports.usage = 'versions:delete --version= [options]'; @@ -25,6 +25,7 @@ exports.args = [ exports.run = async function (opts) { const { key, version } = opts; + const encodedString = Buffer.from(`${key}:`).toString('base64'); if (!key) { return Promise.reject(new Error('No project API key provided. Please use `--key`.')); @@ -34,11 +35,15 @@ exports.run = async function (opts) { return Promise.reject(e); }); - return request - .delete(`${config.host}/api/v1/version/${selectedVersion}`, { - json: true, - auth: { user: key }, - }) - .then(() => Promise.resolve(`Version ${selectedVersion} deleted successfully.`)) - .catch(err => Promise.reject(new APIError(err))); + return fetch(`${config.host}/api/v1/version/${selectedVersion}`, { + method: 'delete', + headers: { + Authorization: `Basic ${encodedString}`, + }, + }).then(res => { + if (res.error) { + return Promise.reject(new APIError(res)); + } + return Promise.resolve(`Version ${selectedVersion} deleted successfully.`); + }); }; diff --git a/src/cmds/versions/index.js b/src/cmds/versions/index.js index 5ec9b4b6d..002346320 100644 --- a/src/cmds/versions/index.js +++ b/src/cmds/versions/index.js @@ -1,8 +1,8 @@ -const request = require('request-promise-native'); const Table = require('cli-table'); const config = require('config'); const versionsCreate = require('./create'); const APIError = require('../../lib/apiError'); +const fetch = require('node-fetch'); exports.command = 'versions'; exports.usage = 'versions [options]'; @@ -82,6 +82,7 @@ const getVersionFormatted = version => { exports.run = function (opts) { const { key, version, raw } = opts; + const encodedString = Buffer.from(`${key}:`).toString('base64'); if (!key) { return Promise.reject(new Error('No project API key provided. Please use `--key`.')); @@ -89,12 +90,18 @@ exports.run = function (opts) { const uri = version ? `${config.host}/api/v1/version/${version}` : `${config.host}/api/v1/version`; - return request - .get(uri, { - json: true, - auth: { user: key }, - }) + return fetch(uri, { + method: 'get', + headers: { + Authorization: `Basic ${encodedString}`, + }, + }) + .then(res => res.json()) .then(data => { + if (data.error) { + return Promise.reject(new APIError(data)); + } + if (raw) { return Promise.resolve(data); } @@ -117,6 +124,5 @@ exports.run = function (opts) { } return Promise.resolve(getVersionFormatted(versions[0])); - }) - .catch(err => Promise.reject(new APIError(err))); + }); }; diff --git a/src/cmds/versions/update.js b/src/cmds/versions/update.js index c4e80d438..1f1b80ee6 100644 --- a/src/cmds/versions/update.js +++ b/src/cmds/versions/update.js @@ -1,9 +1,10 @@ -const request = require('request-promise-native'); const config = require('config'); const { prompt } = require('enquirer'); const promptOpts = require('../../lib/prompts'); const APIError = require('../../lib/apiError'); const { getProjectVersion } = require('../../lib/versionSelect'); +const fetch = require('node-fetch'); +const { handleRes } = require('../../lib/handleRes'); exports.command = 'versions:update'; exports.usage = 'versions:update --version= [options]'; @@ -46,6 +47,7 @@ exports.args = [ exports.run = async function (opts) { const { key, version, codename, newVersion, main, beta, isPublic, deprecated } = opts; + const encodedString = Buffer.from(`${key}:`).toString('base64'); if (!key) { return Promise.reject(new Error('No project API key provided. Please use `--key`.')); @@ -55,28 +57,36 @@ exports.run = async function (opts) { return Promise.reject(e); }); - const foundVersion = await request - .get(`${config.host}/api/v1/version/${selectedVersion}`, { - json: true, - auth: { user: key }, - }) - .catch(err => Promise.reject(new APIError(err))); + const foundVersion = await fetch(`${config.host}/api/v1/version/${selectedVersion}`, { + method: 'get', + headers: { + Authorization: `Basic ${encodedString}`, + }, + }).then(res => handleRes(res)); const promptResponse = await prompt(promptOpts.createVersionPrompt([{}], opts, foundVersion)); - const options = { - json: { + + return fetch(`${config.host}/api/v1/version/${selectedVersion}`, { + method: 'put', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Basic ${encodedString}`, + }, + body: JSON.stringify({ codename: codename || '', version: newVersion || promptResponse.newVersion, is_stable: foundVersion.is_stable || main === 'true' || promptResponse.is_stable, is_beta: beta === 'true' || promptResponse.is_beta, is_deprecated: deprecated || promptResponse.is_deprecated, is_hidden: promptResponse.is_stable ? false : !(isPublic === 'true' || promptResponse.is_hidden), - }, - auth: { user: key }, - }; - - return request - .put(`${config.host}/api/v1/version/${selectedVersion}`, options) - .then(() => Promise.resolve(`Version ${selectedVersion} updated successfully.`)) - .catch(err => Promise.reject(new APIError(err))); + }), + }) + .then(res => res.json()) + .then(res => { + if (res.error) { + return Promise.reject(new APIError(res)); + } + return Promise.resolve(`Version ${selectedVersion} updated successfully.`); + }); }; diff --git a/src/lib/handleRes.js b/src/lib/handleRes.js new file mode 100644 index 000000000..e29ede3fd --- /dev/null +++ b/src/lib/handleRes.js @@ -0,0 +1,11 @@ +const APIError = require('./apiError'); + +async function handleRes(res) { + const body = await res.json(); + if (body.error) { + return Promise.reject(new APIError(body)); + } + return body; +} + +module.exports = { handleRes }; diff --git a/src/lib/versionSelect.js b/src/lib/versionSelect.js index 0526f1b1d..07364b265 100644 --- a/src/lib/versionSelect.js +++ b/src/lib/versionSelect.js @@ -1,29 +1,41 @@ const { prompt } = require('enquirer'); const promptOpts = require('./prompts'); -const request = require('request-promise-native'); +const fetch = require('node-fetch'); const config = require('config'); const APIError = require('./apiError'); async function getProjectVersion(versionFlag, key, allowNewVersion) { - const options = { json: {}, auth: { user: key } }; + const encodedString = Buffer.from(`${key}:`).toString('base64'); try { if (versionFlag) { - options.json.version = versionFlag; - const foundVersion = await request.get(`${config.host}/api/v1/version/${versionFlag}`, options); - - return foundVersion.version; + return await fetch(`${config.host}/api/v1/version/${versionFlag}`, { + method: 'get', + headers: { Authorization: `Basic ${encodedString}` }, + }) + .then(res => res.json()) + .then(res => res.version); } - const versionList = await request.get(`${config.host}/api/v1/version`, options); + const versionList = await fetch(`${config.host}/api/v1/version`, { + method: 'get', + headers: { Authorization: `Basic ${encodedString}` }, + }).then(res => res.json()); if (allowNewVersion) { const { option, versionSelection, newVersion } = await prompt(promptOpts.generatePrompts(versionList)); if (option === 'update') return versionSelection; - options.json = { from: versionList[0].version, version: newVersion, is_stable: false }; - await request.post(`${config.host}/api/v1/version`, options); + await fetch(`${config.host}/api/v1/version`, { + method: 'post', + headers: { Authorization: `Basic ${encodedString}`, 'Content-Type': 'application/json' }, + body: JSON.stringify({ + from: versionList[0].version, + version: newVersion, + is_stable: false, + }), + }); return newVersion; }