Skip to content

Commit

Permalink
fix: openapi:refs touch ups (#1103)
Browse files Browse the repository at this point in the history
## 🧰 Changes

Touched up a few things in #1063!

- [x] Documentation copy edits
- [x] Logging touch ups
- [x] Makes sure we're only allowing this to be run against OpenAPI
- [ ] Adds a stricter type in
81607ca
that ends up breaking the build — I believe this is a code smell.
@olehshh can you look into fixing the type errors here?

## 🧬 QA & Testing

Are my changes sound?
  • Loading branch information
kanadgupta authored Dec 5, 2024
1 parent ce09500 commit b224ec6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
12 changes: 11 additions & 1 deletion __tests__/commands/openapi/refs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { describe, beforeAll, beforeEach, afterEach, it, expect, vi } from 'vite
import Command from '../../../src/commands/openapi/refs.js';
import { runCommandAndReturnResult } from '../../helpers/oclif.js';

describe('openapi:solving-circularity-recursiveness', () => {
describe('openapi refs', () => {
let run: (args?: string[]) => Promise<string>;

beforeAll(() => {
Expand Down Expand Up @@ -97,4 +97,14 @@ describe('openapi:solving-circularity-recursiveness', () => {
expect(processedOutput).toStrictEqual(expectedOutput);
});
});

describe('error handling', () => {
it.each([['json'], ['yaml']])('should fail if given a Swagger 2.0 definition (format: %s)', async format => {
const spec = require.resolve(`@readme/oas-examples/2.0/${format}/petstore.${format}`);

await expect(run([spec])).rejects.toStrictEqual(
new Error('Sorry, this ref resolver feature in rdme only supports OpenAPI 3.0+ definitions.'),
);
});
});
});
14 changes: 7 additions & 7 deletions documentation/commands/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,12 @@ FLAGS
DESCRIPTION
Resolves circular and recursive references in OpenAPI by replacing them with object schemas.
This command addresses limitations in ReadMe’s support for circular or recursive references within OpenAPI
specifications. It automatically identifies and replaces these references with simplified object schemas, ensuring
compatibility for seamless display in the ReadMe platform. As a result, instead of displaying an empty form, as would
occur with schemas containing such references, you will receive a flattened representation of the object, showing what
the object can potentially contain, including references to itself. Complex circular references may require manual
inspection and may not be fully resolved.
This command provides a workaround for circular or recursive references within OpenAPI definitions so they can render
properly in ReadMe. It automatically identifies and replaces these references with simplified object schemas, ensuring
compatibility for seamless display in the ReadMe API Reference. As a result, instead of displaying an empty form, as
would occur with schemas containing such references, you will receive a flattened representation of the object,
showing what the object can potentially contain, including references to itself. Complex circular references may
require manual inspection and may not be fully resolved.
EXAMPLES
This will resolve circular and recursive references in the OpenAPI definition at the given file or URL:
Expand All @@ -264,7 +264,7 @@ EXAMPLES
If you wish to automate this command, you can pass in CLI arguments to bypass the prompts:
$ rdme openapi:refs petstore.json -out petstore.openapi.json
$ rdme openapi:refs petstore.json --out petstore.openapi.json
```

## `rdme openapi:validate [SPEC]`
Expand Down
19 changes: 14 additions & 5 deletions src/commands/openapi/refs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import path from 'node:path';

import { Args, Flags } from '@oclif/core';
import chalk from 'chalk';
import ora from 'ora';
import prompts from 'prompts';

import analyzeOas from '../../lib/analyzeOas.js';
import BaseCommand from '../../lib/baseCommand.js';
import { workingDirectoryFlag } from '../../lib/flags.js';
import { info, warn, debug } from '../../lib/logger.js';
import { info, warn, debug, oraOptions } from '../../lib/logger.js';
import prepareOas from '../../lib/prepareOas.js';
import promptTerminal from '../../lib/promptWrapper.js';
import { validateFilePath } from '../../lib/validatePromptInput.js';
Expand All @@ -23,7 +24,7 @@ export default class OpenAPIRefsCommand extends BaseCommand<typeof OpenAPIRefsCo
static summary = 'Resolves circular and recursive references in OpenAPI by replacing them with object schemas.';

static description =
'This command addresses limitations in ReadMe’s support for circular or recursive references within OpenAPI specifications. It automatically identifies and replaces these references with simplified object schemas, ensuring compatibility for seamless display in the ReadMe platform. As a result, instead of displaying an empty form, as would occur with schemas containing such references, you will receive a flattened representation of the object, showing what the object can potentially contain, including references to itself. Complex circular references may require manual inspection and may not be fully resolved.';
'This command provides a workaround for circular or recursive references within OpenAPI definitions so they can render properly in ReadMe. It automatically identifies and replaces these references with simplified object schemas, ensuring compatibility for seamless display in the ReadMe API Reference. As a result, instead of displaying an empty form, as would occur with schemas containing such references, you will receive a flattened representation of the object, showing what the object can potentially contain, including references to itself. Complex circular references may require manual inspection and may not be fully resolved.';

static args = {
spec: Args.string({ description: 'A file/URL to your API definition' }),
Expand Down Expand Up @@ -311,13 +312,22 @@ export default class OpenAPIRefsCommand extends BaseCommand<typeof OpenAPIRefsCo
this.debug(`Switching working directory from ${previousWorkingDirectory} to ${process.cwd()}`);
}

const { preparedSpec, specPath } = await prepareOas(spec, 'openapi:refs', { convertToLatest: true });
const openApiData = JSON.parse(preparedSpec);
const { preparedSpec, specPath, specType } = await prepareOas(spec, 'openapi:refs', { convertToLatest: true });
if (specType !== 'OpenAPI') {
throw new Error('Sorry, this ref resolver feature in rdme only supports OpenAPI 3.0+ definitions.');
}

const openApiData: OASDocument = JSON.parse(preparedSpec);

const spinner = ora({ ...oraOptions() });
spinner.start('Identifying and resolving circular/recursive references in your API definition...');

try {
await OpenAPIRefsCommand.resolveCircularRefs(openApiData, openApiData.components!.schemas!);
spinner.succeed(`${spinner.text} done! ✅`);
} catch (err) {
this.debug(`${err.message}`);
spinner.fail();
throw err;
}

Expand All @@ -335,7 +345,6 @@ export default class OpenAPIRefsCommand extends BaseCommand<typeof OpenAPIRefsCo
const outputPath = promptResults.outputPath;
this.debug(`Saving processed spec to ${outputPath}...`);
fs.writeFileSync(outputPath, JSON.stringify(openApiData, null, 2));
this.debug('Processed spec saved successfully.');

return Promise.resolve(chalk.green(`Your API definition has been processed and saved to ${outputPath}!`));
}
Expand Down

0 comments on commit b224ec6

Please sign in to comment.