diff --git a/lib/prompts.js b/lib/prompts.js index cc0b8dad4..f9b22055f 100644 --- a/lib/prompts.js +++ b/lib/prompts.js @@ -1,45 +1,86 @@ -exports.generatePrompts = versionList => [ - { - type: 'select', - name: 'option', - message: - "We couldn't find a version in ReadMe matching the version in your OAS file. Would you like to use an existing version or create a new one?", - choices: [ - { title: 'Use existing', value: 'update' }, - { title: 'Create a new version', value: 'create' }, - ], - }, - { - type: prev => (prev === 'update' ? 'select' : null), - name: 'versionSelection', - message: 'Select your desired version', - choices: versionList.map(v => { - return { - title: v.version, - // eslint-disable-next-line - value: v._id, - }; - }), - }, -]; +const { prompt } = require('enquirer'); -exports.createVersionPrompt = versionList => [ - { - type: 'select', - name: 'fork', - message: 'Which version would you like to fork from?', - choices: versionList.map(v => { - return { - title: v.version, - // eslint-disable-next-line - value: v._id, - }; - }), - }, - { - type: 'select', - name: 'main', - message: 'Would you like to make this version the main version?', - choices: [{ title: 'Yes', value: true }, { title: 'No', value: false }], - }, -]; +exports.generatePrompts = async versionList => + prompt([ + { + type: 'select', + name: 'option', + message: + "We couldn't find a version in ReadMe matching the version in your OAS file. Would you like to use an existing version or create a new one?", + choices: [ + { message: 'Use existing', value: 'update' }, + { message: 'Create a new version', value: 'create' }, + ], + }, + { + type: 'select', + name: 'versionSelection', + message: 'Select your desired version', + skip() { + return this.enquirer.answers.option !== 'update'; + }, + choices: versionList.map(v => { + return { + message: v.version, + // eslint-disable-next-line + value: v._id, + }; + }), + }, + ]); + +exports.createVersionPrompt = async (versionList, opts, isUpdate) => + prompt([ + { + type: 'select', + name: 'from', + message: 'Which version would you like to fork from?', + skip() { + return opts.fork || isUpdate; + }, + choices: versionList.map(v => { + return { + message: v.version, + // eslint-disable-next-line + value: v.version, + }; + }), + }, + { + type: 'input', + name: 'newVersion', + message: "What's your new version?", + skip() { + return opts.newVersion || !isUpdate; + }, + hint: '1.0.0', + }, + { + type: 'confirm', + name: 'is_stable', + message: 'Would you like to make this version the main version for this project?', + skip: () => opts.main, + }, + { + type: 'confirm', + name: 'is_beta', + message: 'Should this version be in beta?', + skip: () => opts.beta, + }, + { + type: 'confirm', + name: 'is_hidden', + message: 'Would you like to make this version public?', + skip() { + return opts.isPublic || opts.main || this.enquirer.answers.is_stable; + }, + }, + { + type: 'confirm', + name: 'is_deprecated', + message: 'Would you like to deprecate this version?', + skip() { + return opts.deprecated || opts.main || !isUpdate || this.enquirer.answers.is_stable; + }, + }, + ]); diff --git a/lib/versions/create.js b/lib/versions/create.js index 14f08e1b5..c1bdf0c97 100644 --- a/lib/versions/create.js +++ b/lib/versions/create.js @@ -1,6 +1,5 @@ const request = require('request-promise-native'); const config = require('config'); -const prompts = require('prompts'); const promptOpts = require('../prompts'); exports.desc = 'Create a new version for your project'; @@ -10,7 +9,8 @@ exports.action = 'versions:create'; exports.run = async function({ opts }) { let { key } = opts; - const { version, codename } = opts; + let versionList; + const { version, codename, fork, main, beta, isPublic } = opts; if (!key && opts.token) { console.warn( @@ -29,22 +29,24 @@ exports.run = async function({ opts }) { ); } - const versionList = await request - .get(`${config.host}/api/v1/version`, { - json: true, - auth: { user: key }, - }) - .catch(err => Promise.reject(new Error(err))); - - const promptSelection = promptOpts.createVersionPrompt(versionList); - const { fork, main } = await prompts(promptSelection); + if (!fork) { + versionList = await request + .get(`${config.host}/api/v1/version`, { + json: true, + auth: { user: key }, + }) + .catch(err => Promise.reject(new Error(err))); + } + const promptResponse = await promptOpts.createVersionPrompt(versionList, opts); const options = { json: { version, - fork, codename: codename || '', - is_stable: main, + is_stable: main || promptResponse.is_stable, + is_beta: beta || promptResponse.is_beta, + from: fork || promptResponse.from, + is_hidden: promptResponse.is_stable ? false : !(isPublic || promptResponse.is_hidden), }, auth: { user: key }, }; diff --git a/lib/versions/update.js b/lib/versions/update.js index e69de29bb..0df31d37d 100644 --- a/lib/versions/update.js +++ b/lib/versions/update.js @@ -0,0 +1,57 @@ +const request = require('request-promise-native'); +const config = require('config'); +const promptOpts = require('../prompts'); + +exports.desc = 'Update an existing version for your project'; +exports.category = 'services'; +exports.weight = 4; +exports.action = 'versions:update'; + +exports.run = async function({ opts }) { + let { key } = opts; + let versionList; + const { version, codename, fork, newVersion, main, beta, isPublic, deprecated } = opts; + + if (!key && opts.token) { + console.warn( + 'Using `rdme` with --token has been deprecated. Please use --key and --id instead.', + ); + [key] = opts.token.split('-'); + } + + if (!key) { + return Promise.reject(new Error('No api key provided. Please use --key')); + } + + if (!version) { + return Promise.reject( + new Error('No version provided. Please specify a semantic version using --version'), + ); + } + + if (!fork) { + versionList = await request + .get(`${config.host}/api/v1/version`, { + json: true, + auth: { user: key }, + }) + .catch(err => Promise.reject(new Error(err))); + } + + const promptResponse = await promptOpts.createVersionPrompt(versionList, opts, true); + const options = { + json: { + codename: codename || '', + version: newVersion || promptResponse.newVersion, + is_stable: main || promptResponse.is_stable, + is_beta: beta || promptResponse.is_beta, + is_deprecated: deprecated || promptResponse.is_deprecated, + is_hidden: promptResponse.is_stable ? false : !(isPublic || promptResponse.is_hidden), + }, + auth: { user: key }, + }; + + return request + .put(`${config.host}/api/v1/version/${version}`, options) + .catch(err => Promise.reject(new Error(err))); +}; diff --git a/package-lock.json b/package-lock.json index abbd60f59..5fa4a1f08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -733,6 +733,11 @@ "json-schema-traverse": "^0.3.0" } }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" + }, "ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", @@ -1980,6 +1985,14 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.0.tgz", + "integrity": "sha512-RNGUbRVlfnjmpxV+Ed+7CGu0rg3MK7MmlW+DW0v7V2zdAUBC1s4BxCRiIAozbYB2UJ+q4D+8tW9UFb11kF72/g==", + "requires": { + "ansi-colors": "^3.2.1" + } + }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", @@ -5458,7 +5471,8 @@ "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true }, "lazy-cache": { "version": "1.0.4", @@ -6677,6 +6691,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==", + "dev": true, "requires": { "kleur": "^3.0.2", "sisteransi": "^1.0.0" @@ -7286,7 +7301,8 @@ "sisteransi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", - "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==" + "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", + "dev": true }, "slash": { "version": "2.0.0", diff --git a/package.json b/package.json index af93dbe2e..8e6b58ca2 100644 --- a/package.json +++ b/package.json @@ -31,12 +31,12 @@ "config": "^3.1.0", "configstore": "^5.0.0", "editor": "^1.0.0", + "enquirer": "^2.3.0", "gray-matter": "^4.0.1", "isemail": "^3.1.3", "minimist": "^1.2.0", "oas": "0.8.15", "opn": "^6.0.0", - "prompts": "^2.1.0", "read": "^1.0.7", "request": "^2.88.0", "request-promise-native": "^1.0.5"