diff --git a/README.md b/README.md index a5ff07f37..11a8999a2 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,12 @@ This will upload `path-to-openapi.json` to your project and return an ID and URL rdme openapi [path-to-file.json] ``` +If you want to bypass the prompt to create or update an API definition, you can pass the `--create` flag: + +```sh +rdme openapi [path-to-file.json] --version={project-version} --create +``` + #### Editing (Re-Syncing) an Existing API Definition This will edit (re-sync) an existing API definition (identified by `--id`) within your ReadMe project. diff --git a/__tests__/__snapshots__/index.test.ts.snap b/__tests__/__snapshots__/index.test.ts.snap index 1aad8feed..c15bd494d 100644 --- a/__tests__/__snapshots__/index.test.ts.snap +++ b/__tests__/__snapshots__/index.test.ts.snap @@ -15,6 +15,7 @@ Options uploading an existing API definition. --version string Project version. If running command in a CI environment and this option is not passed, the main project version will be used. + --create Bypasses the create/update prompt and creates a new API definition. --useSpecVersion Uses the version listed in the \`info.version\` field in the API definition for the project version parameter. --workingDirectory string Working directory (for usage with relative external references) @@ -42,6 +43,7 @@ Options uploading an existing API definition. --version string Project version. If running command in a CI environment and this option is not passed, the main project version will be used. + --create Bypasses the create/update prompt and creates a new API definition. --useSpecVersion Uses the version listed in the \`info.version\` field in the API definition for the project version parameter. --workingDirectory string Working directory (for usage with relative external references) @@ -69,6 +71,7 @@ Options uploading an existing API definition. --version string Project version. If running command in a CI environment and this option is not passed, the main project version will be used. + --create Bypasses the create/update prompt and creates a new API definition. --useSpecVersion Uses the version listed in the \`info.version\` field in the API definition for the project version parameter. --workingDirectory string Working directory (for usage with relative external references) diff --git a/__tests__/cmds/openapi/index.test.ts b/__tests__/cmds/openapi/index.test.ts index f51b2e104..1150246be 100644 --- a/__tests__/cmds/openapi/index.test.ts +++ b/__tests__/cmds/openapi/index.test.ts @@ -169,6 +169,66 @@ describe('rdme openapi', () => { return mock.done(); }); + it('should create a new spec via `--create` flag', async () => { + const registryUUID = getRandomRegistryId(); + + const mock = getAPIMock() + .get(`/api/v1/version/${version}`) + .basicAuth({ user: key }) + .reply(200, [{ version }]) + .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .post('/api/v1/api-specification', { registryUUID }) + .delayConnection(1000) + .basicAuth({ user: key }) + .reply(201, { _id: 1 }, { location: exampleRefLocation }); + + const spec = './__tests__/__fixtures__/ref-oas/petstore.json'; + + await expect( + openapi.run({ + key, + version, + spec, + create: true, + }) + ).resolves.toBe(successfulUpload(spec)); + + return mock.done(); + }); + + it('should create a new spec via `--create` flag and ignore `--id`', async () => { + const registryUUID = getRandomRegistryId(); + + const mock = getAPIMock() + .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .post('/api/v1/api-specification', { registryUUID }) + .delayConnection(1000) + .basicAuth({ user: key }) + .reply(201, { _id: 1 }, { location: exampleRefLocation }); + + const spec = './__tests__/__fixtures__/ref-oas/petstore.json'; + + await expect( + openapi.run({ + key, + spec, + id: 'some-id', + create: true, + }) + ).resolves.toBe(successfulUpload(spec)); + + expect(console.warn).toHaveBeenCalledTimes(1); + expect(console.info).toHaveBeenCalledTimes(0); + + const output = getCommandOutput(); + + expect(output).toMatch(/the `--id` parameter will be ignored/i); + + return mock.done(); + }); + it('should bundle and upload the expected content', async () => { let requestBody; const registryUUID = getRandomRegistryId(); diff --git a/src/cmds/openapi/index.ts b/src/cmds/openapi/index.ts index b2a7df832..4322bb6d0 100644 --- a/src/cmds/openapi/index.ts +++ b/src/cmds/openapi/index.ts @@ -20,6 +20,7 @@ export type Options = { id?: string; spec?: string; version?: string; + create?: boolean; useSpecVersion?: boolean; workingDirectory?: string; }; @@ -53,6 +54,11 @@ export default class OpenAPICommand extends Command { type: String, defaultOption: true, }, + { + name: 'create', + type: Boolean, + description: 'Bypasses the create/update prompt and creates a new API definition.', + }, { name: 'useSpecVersion', type: Boolean, @@ -70,7 +76,7 @@ export default class OpenAPICommand extends Command { async run(opts: CommandOptions) { super.run(opts); - const { key, id, spec, useSpecVersion, version, workingDirectory } = opts; + const { key, id, spec, create, useSpecVersion, version, workingDirectory } = opts; let selectedVersion = version; let isUpdate: boolean; @@ -86,6 +92,10 @@ export default class OpenAPICommand extends Command { ); } + if (create && id) { + Command.warn("We'll be using the `--create` option , so the `--id` parameter will be ignored."); + } + // Reason we're hardcoding in command here is because `swagger` command // relies on this and we don't want to use `swagger` in this function const { bundledSpec, specPath, specType, specVersion } = await prepareOas(spec, 'openapi'); @@ -214,6 +224,8 @@ export default class OpenAPICommand extends Command { }); } + if (create) return createSpec(); + if (!id) { Command.debug('no id parameter, retrieving list of API specs'); const apiSettings = await getSpecs('/api/v1/api-specification');