diff --git a/.changeset/build-docs-redoc-three.md b/.changeset/build-docs-redoc-three.md new file mode 100644 index 0000000000..1ea8cf596d --- /dev/null +++ b/.changeset/build-docs-redoc-three.md @@ -0,0 +1,10 @@ +--- +'@redocly/cli': minor +--- + +**Breaking**: Updated the `build-docs` command to Redoc 3 and added support for AsyncAPI descriptions and GraphQL schemas. +Added the `--openapi`, `--asyncapi`, `--graphql`, and `--inlineBundle` options. +Removed `--theme.openapi` and `--disableGoogleFont`, pass Redoc options with `--openapi` instead. +Some Redoc 2 options were renamed or removed, see the [`build-docs` documentation](https://redocly.com/docs/cli/commands/build-docs). +The command now applies the [decorators](https://redocly.com/docs/cli/decorators) and [preprocessors](https://redocly.com/docs/cli/configuration/reference/preprocessors) from the configuration file. +Pages built with the `build-docs` command now send [Redoc telemetry](https://redocly.com/docs/redoc/telemetry) from readers' browsers by default. diff --git a/.claude/skills/redocly-cli/SKILL.md b/.claude/skills/redocly-cli/SKILL.md index e34a2ba971..13a26f6500 100644 --- a/.claude/skills/redocly-cli/SKILL.md +++ b/.claude/skills/redocly-cli/SKILL.md @@ -31,7 +31,7 @@ Install: `npm i @redocly/cli@latest`, or run without installing: `npx @redocly/c | `lint` | Validate an API description against the configured rules | API authoring | | `split` | Break a single-file description into a multi-file structure | API authoring | | `introspect-mcp` | Record a live MCP server's tools, prompts, and resources in `x-mcp` [experimental] | API authoring | -| `build-docs` | Render an API description to a zero-dependency HTML page (Redoc) | Docs rendering | +| `build-docs` | Render an OpenAPI, AsyncAPI, or GraphQL description to an HTML page (Redoc) | Docs rendering | | `preview` | Local preview of a Redocly project | Docs rendering | | `recheck` | Lint Markdown structure, prose style, and Markdoc tags; `--fix` repairs most structural findings | Docs linting | | `bundle` | Resolve all `$ref`s into one self-contained file; apply decorators and overlays | CI and delivery | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a209ae4b69..ca5cdebf9e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -160,13 +160,15 @@ Regenerate it there with `scripts/generate-markdoc-schema.mjs` pointed at this c ### Update Redoc -When updating Redoc, recompute the subresource integrity [SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) (`redocStandaloneSri` in [package.ts](./packages/cli/src/utils/package.ts)): +The `build-docs` command loads Redoc from the Redocly CDN at the exact `redoc` version in [`packages/cli/package.json`](./packages/cli/package.json). +When updating Redoc, pin an exact version and check that the CDN serves it: ```bash -openssl dgst -sha384 -binary node_modules/redoc/bundles/redoc.standalone.js | openssl base64 -A +npm install -w packages/cli --save-dev --save-exact redoc@ +curl -I https://cdn.redocly.com/redoc/v/bundles/redoc.standalone.js ``` -The SRI value also appears in [e2e test snapshots](#e2e-tests) — update those too. +Then update the [e2e test snapshots](#e2e-tests) and the [smoke test](#smoke-tests) page. ### Arguments usage diff --git a/docs/@v2/commands/build-docs.md b/docs/@v2/commands/build-docs.md index 362149b2c7..e1115ae3e3 100644 --- a/docs/@v2/commands/build-docs.md +++ b/docs/@v2/commands/build-docs.md @@ -5,17 +5,23 @@ The `build-docs` command builds Redoc into an HTML file that contains your API documentation. The standalone HTML file can be easily shared or hosted on a platform of your choice. -{% admonition type="warning" name="OpenAPI only" %} -The `build-docs` command currently supports only Swagger 2.0 and OpenAPI 3.0/3.1 descriptions. -Support for OpenAPI 3.2 is coming soon. -{% /admonition %} +The command supports Swagger 2.0, OpenAPI 3.0/3.1/3.2, AsyncAPI 2.x/3.x, and GraphQL schemas (`.graphql` or `.gql` files). + +The page is rendered with Redoc 3 and loads the Redoc scripts from the Redocly CDN. +Pass `--inlineBundle` to embed them, so the page works without loading the Redoc scripts from the CDN. +Only the Redocly logo in the sidebar loads from the CDN. + +The page sends [Redoc telemetry](https://redocly.com/docs/redoc/telemetry) from readers' browsers. +To turn it off, build the page with `REDOCLY_TELEMETRY=off` or with `telemetry: off` in the configuration file. + +Redoc options come from the configuration file key that matches the type of your API description: `openapi`, `asyncapi`, or `graphql`. +The command also applies the [decorators](../decorators.md) and [preprocessors](../configuration/reference/preprocessors.md) from the configuration file. -{% admonition type="warning" name="Redoc 3 migration" %} -An upcoming Redocly CLI release switches `build-docs` to Redoc 3, and the command prints a notice about it on every run. -Redoc 3 is faster on large APIs, adds built-in dark mode and support for OpenAPI 3.2, AsyncAPI, GraphQL, and MCP, and is themed with CSS custom properties instead of the Redoc 2 theme object. -Redoc 2 theme options and custom templates may need updates after the switch. -To keep the current Redoc 2 output, use Redocly CLI v1: `npx @redocly/cli@v1-archive build-docs `. +{% admonition type="warning" name="Upgrading from Redoc 2" %} +Redoc 3 renamed or removed some Redoc 2 configuration options and replaced the Redoc 2 theme object with CSS custom properties. +When you upgrade, review your Redoc settings against the [Redoc configuration options](https://redocly.com/docs/realm/config/openapi) and check your custom templates. Read [what's new in Redoc 3](https://redocly.com/blog/redoc-3-whats-new) for details. +To keep the Redoc 2 output, use Redocly CLI v1: `npx @redocly/cli@v1-archive build-docs `. {% /admonition %} ## Usage @@ -23,25 +29,28 @@ Read [what's new in Redoc 3](https://redocly.com/blog/redoc-3-whats-new) for det ```bash redocly build-docs redocly build-docs --output=custom.html -redocly build-docs --theme.openapi.disableSearch +redocly build-docs --inlineBundle +redocly build-docs --openapi.hideDownloadButtons redocly build-docs --template custom.hbs redocly build-docs -t custom.hbs --templateOptions.metaDescription "Page meta description" ``` ## Options -| Option | Type | Description | -| ------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| api | string | Path to the API description filename or alias that you want to generate the build for. Refer to [the API section](#specify-api) for more details. | -| --config | string | Path to the [configuration file](#use-an-alternative-configuration-file). Defaults to `redocly.yaml` in the local folder. | -| --disableGoogleFont | boolean | Disable Google fonts. The default value is `false`. | -| --help | boolean | Show help. | -| --lint-config | string | Specify the severity level for the configuration file. Possible values: `warn`, `error`, `off`. Default value is `warn`. | -| --output, -o | string | Set the path and name of the output file. The default value is `redoc-static.html`. | -| --template, -t | string | Use custom [Handlebars](https://handlebarsjs.com/) templates to render your OpenAPI description. | -| --templateOptions | string | Add template options you want to pass to your custom Handlebars template. To add options, use dot notation. | -| --theme.openapi | string | Customize your output with [Redoc functionality options](https://redocly.com/docs/api-reference-docs/configuration/functionality/) or [Redoc theming options](https://redocly.com/docs/api-reference-docs/configuration/theming/). | -| --title | string | Set the page title. | +| Option | Type | Description | +| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| api | string | Path to the API description filename or alias that you want to generate the build for. Refer to [the API section](#specify-api) for more details. | +| --asyncapi | string | Customize your output with [Redoc AsyncAPI options](https://redocly.com/docs/realm/config/asyncapi). Use dot notation, for example `--asyncapi.jsonSamplesDepth 4`. | +| --config | string | Path to the [configuration file](#use-an-alternative-configuration-file). Defaults to `redocly.yaml` in the local folder. | +| --graphql | string | Customize your output with [Redoc GraphQL options](https://redocly.com/docs/realm/config/graphql). Use dot notation, for example `--graphql.showBuiltInScalars`. | +| --help | boolean | Show help. | +| --inlineBundle | boolean | Embed the Redoc scripts into the output file instead of loading them from the Redocly CDN. The default value is `false`. | +| --lint-config | string | Specify the severity level for the configuration file. Possible values: `warn`, `error`, `off`. Default value is `warn`. | +| --openapi | string | Customize your output with [Redoc OpenAPI options](https://redocly.com/docs/realm/config/openapi). Use dot notation, for example `--openapi.hideDownloadButtons`. | +| --output, -o | string | Set the path and name of the output file. The default value is `redoc-static.html`. | +| --template, -t | string | Use custom [Handlebars](https://handlebarsjs.com/) templates to render your API description. | +| --templateOptions | string | Add template options you want to pass to your custom Handlebars template. To add options, use dot notation. | +| --title | string | Set the page title. | ## Examples @@ -88,12 +97,23 @@ Use the optional `--config` argument to provide an alternative path to a configu redocly build-docs --config=./another/directory/config.yaml ``` -### Hide search +### Configure Redoc + +Each API description type reads its options from its own configuration file key, so one file can configure all three: + +```yaml Configuration file +openapi: + hideDownloadButtons: true +asyncapi: + jsonSamplesDepth: 4 +graphql: + showBuiltInScalars: true +``` -The following command uses the optional `--theme.openapi` argument to build docs with the search box hidden: +The matching command-line argument replaces the options from the configuration file: ```bash -redocly build-docs openapi.yaml --theme.openapi.disableSearch +redocly build-docs openapi.yaml --openapi.hideDownloadButtons ``` ### Use a custom template @@ -121,10 +141,6 @@ Sample custom Handlebars template: } {{{redocHead}}} - {{#unless disableGoogleFont}}{{/unless}} {{{redocHTML}}} diff --git a/docs/@v2/guides/migrate-from-redoc-cli.md b/docs/@v2/guides/migrate-from-redoc-cli.md index 83df8c67c0..c62f60ba6c 100644 --- a/docs/@v2/guides/migrate-from-redoc-cli.md +++ b/docs/@v2/guides/migrate-from-redoc-cli.md @@ -40,23 +40,22 @@ Details and examples of using `bundle` are on the [`bundle` command page](../com Some of the configuration options have been updated. This section shows how to check which of your settings should be changed. -### Renamed fields +### Update renamed and removed options -Two of the configuration settings were renamed for consistency with the rest of the Redocly tools. +The `build-docs` command renders the docs with Redoc 3, which renamed or removed some Redoc 2 options. +Check the options you use against the [Redoc migration guide](https://redocly.com/docs/redoc/config-migration). -- Replace `menu` with `sidebar` -- Replace `codeSample` with `codeBlock` - -In both cases, the child options should work as before. +One of the removed options is `theme`, so `theme.*` settings have no effect. +Customize the appearance with [CSS variables](https://redocly.com/docs/redoc/deployment/html#theme-configuration) in a ` {{{redocHead}}} - {{#unless disableGoogleFont}}{{/unless}} @@ -35,62 +34,78 @@ const DEFAULT_TEMPLATE_SOURCE = ` `; -export function getObjectOrJSON( - openapiOptions: string | Record, - config: Config -): JSON | Record | Config { - switch (typeof openapiOptions) { - case 'object': - return openapiOptions; - case 'string': - try { - if (existsSync(openapiOptions) && lstatSync(openapiOptions).isFile()) { - return JSON.parse(readFileSync(openapiOptions, 'utf-8')); - } else { - return JSON.parse(openapiOptions); - } - } catch (e) { - logger.error( - `Encountered error:\n\n${openapiOptions}\n\nis neither a file with a valid JSON object neither a stringified JSON object.\n` - ); - throw new HandledError(e instanceof Error ? e.message : String(e)); - } - default: { - if (config?.configPath) { - logger.info(`Found ${config.configPath} and using 'openapi' options\n`); - return config.resolvedConfig?.openapi ?? {}; - } - return {}; +export function getRedocOptions( + specOptions: unknown, + config: Config, + specType: SpecType +): Record { + if (specOptions === undefined) { + if (config?.configPath) { + logger.info(`Found ${config.configPath} and using '${specType}' options\n`); + return config.resolvedConfig[specType] ?? {}; } + return {}; } + + const options = + typeof specOptions === 'string' ? parseJsonOrFile(specOptions, specType) : specOptions; + + if (!isPlainObject(options)) { + throw new HandledError(invalidOptionsMessage(specType, specOptions)); + } + + return options; +} + +function parseJsonOrFile(value: string, specType: SpecType): unknown { + try { + return JSON.parse( + existsSync(value) && lstatSync(value).isFile() ? readFileSync(value, 'utf-8') : value + ); + } catch (error) { + const reason = error instanceof Error ? error.message : String(error); + throw new HandledError(`${invalidOptionsMessage(specType, value)}\n${reason}`); + } +} + +function invalidOptionsMessage(specType: SpecType, value: unknown): string { + const shown = typeof value === 'string' ? value : JSON.stringify(value); + return `Expected --${specType} to be a JSON object or a path to a JSON file, got: ${shown}`; } export async function getPageHTML( - api: any, - pathToApi: string, + definition: Record | string, { title, - disableGoogleFont, templateFileName, templateOptions, redocOptions = {}, redocVersion, + disableTelemetry, + inlineBundle, }: BuildDocsOptions, configPath?: string ) { logger.info('Prerendering docs\n'); - const apiUrl = redocOptions.specUrl || (isAbsoluteUrl(pathToApi) ? pathToApi : undefined); - const store = await redoc.createStore(api, apiUrl, redocOptions); + const pageOptions = { ...redocOptions, skipBundle: true }; + const prepared = await prepareApiDocs({ spec: definition, options: pageOptions }); + const app = createElement(RedoclyApiDocsStandalone, { + items: prepared.items, + store: prepared.store, + basePath: '/', + options: prepared.options, + logo: logoFromSpec(prepared.document), + telemetryConfig: { disabled: disableTelemetry }, + spec: prepared.document, + }); const sheet = new ServerStyleSheet(); - - const html = renderToString(sheet.collectStyles(createElement(redoc.Redoc, { store }))); - const state = await store.toJS(); + const html = renderToString(sheet.collectStyles(app)); const css = sheet.getStyleTags(); const customTemplate = templateFileName || - (redocOptions?.htmlTemplate + (typeof redocOptions.htmlTemplate === 'string' ? path.resolve(configPath ? path.dirname(configPath) : '', redocOptions.htmlTemplate) : undefined); @@ -98,32 +113,54 @@ export async function getPageHTML( ? readFileSync(customTemplate, 'utf-8') : DEFAULT_TEMPLATE_SOURCE; const template = handlebars.compile(templateSource); + + const redocBundleUrl = `https://cdn.redocly.com/redoc/v${redocVersion}/bundles/redoc.standalone.js`; + const redocScript = inlineBundle + ? escapeClosingScriptTag(readFileSync(redocStandalonePath, 'utf-8')) + : `import { hydrate } from "${redocBundleUrl}";`; + const redocHead = inlineBundle + ? css + : `` + + css; + + const definitionTitle = + typeof definition === 'string' + ? undefined + : (definition.info as { title?: string } | undefined)?.title; + return template({ redocHTML: ` -
${html || ''}
- `, - redocHead: - `` + - css, - title: title || api.info.title || 'ReDoc documentation', - disableGoogleFont, + redocHead, + title: title || definitionTitle || 'ReDoc documentation', templateOptions, }); } +const redocStandalonePath = fileURLToPath(new URL('./redoc.standalone.js', import.meta.url)); + +function getRedocStandaloneSri(): string { + const hash = createHash('sha384').update(readFileSync(redocStandalonePath)).digest('base64'); + return `sha384-${hash}`; +} + export function sanitizeJSONString(str: string): string { - return escapeClosingScriptTag(escapeUnicode(str)); + return escapeUnicode(str).replace(//g, '<\\/script>'); + return str.replace(/<\/(script)/gi, '<\\/$1'); } // see http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/ diff --git a/packages/cli/src/custom.d.ts b/packages/cli/src/custom.d.ts deleted file mode 100644 index 6550d68047..0000000000 --- a/packages/cli/src/custom.d.ts +++ /dev/null @@ -1 +0,0 @@ -type GenericObject = Record; diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index e67eff7c1b..0f5c3dbfbe 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -836,11 +836,6 @@ yargs(hideBin(process.argv)) describe: 'Page title.', type: 'string', }, - disableGoogleFont: { - describe: 'Disable Google fonts.', - type: 'boolean', - default: false, - }, t: { alias: 'template', describe: @@ -851,9 +846,20 @@ yargs(hideBin(process.argv)) describe: 'Additional options to pass to the template. Use dot notation, e.g. templateOptions.metaDescription', }, - theme: { + openapi: { + describe: 'Redoc configuration. Use dot notation, e.g. openapi.hideDownloadButtons', + }, + asyncapi: { + describe: 'Redoc configuration. Use dot notation, e.g. asyncapi.jsonSamplesDepth', + }, + graphql: { + describe: 'Redoc configuration. Use dot notation, e.g. graphql.showBuiltInScalars', + }, + inlineBundle: { describe: - 'Redoc theme.openapi configuration. Use dot notation, e.g. theme.openapi.nativeScrollbars', + 'Embed the Redoc scripts into the output file instead of loading them from the Redocly CDN.', + type: 'boolean', + default: false, }, config: { describe: 'Path to the config file.', @@ -864,10 +870,21 @@ yargs(hideBin(process.argv)) choices: ['warn', 'error', 'off'] as ReadonlyArray, default: 'warn' as RuleSeverity, }, + // Remove these options and the check below in the first release after January 31, 2027. + theme: { hidden: true }, + disableGoogleFont: { hidden: true, type: 'boolean' }, }) - .check((argv: any) => { - if (argv.theme && !argv.theme?.openapi) - throw new Error('Invalid option: theme.openapi not set.'); + .check((argv) => { + if (argv.theme !== undefined) { + throw new Error( + 'The --theme.openapi option was removed. Pass Redoc options with --openapi instead: https://redocly.com/docs/cli/guides/migrate-to-v2#changes-in-the-build-docs-command' + ); + } + if (argv.disableGoogleFont !== undefined) { + throw new Error( + 'The --disableGoogleFont option was removed because the page no longer loads Google Fonts. Remove the option from your command.' + ); + } return true; }), async (argv) => { diff --git a/packages/cli/src/utils/__tests__/telemetry.test.ts b/packages/cli/src/utils/__tests__/telemetry.test.ts index b63f83cbca..f6c471b4c6 100644 --- a/packages/cli/src/utils/__tests__/telemetry.test.ts +++ b/packages/cli/src/utils/__tests__/telemetry.test.ts @@ -3,10 +3,10 @@ import { RedoclyOAuthClient, getReuniteUrl } from '@redocly/reunite-integration' import * as childProcess from 'node:child_process'; import * as fs from 'node:fs'; import { join } from 'node:path'; -import { it, expect, vi } from 'vitest'; +import { afterEach, describe, it, expect, vi } from 'vitest'; import { respondWithinMs } from '../network-check.js'; -import { sendTelemetry } from '../telemetry.js'; +import { isTelemetryEnabled, sendTelemetry } from '../telemetry.js'; const mockMapToCloudEvent = vi.hoisted(() => vi.fn()); const mockOtelSend = vi.hoisted(() => vi.fn()); @@ -142,3 +142,19 @@ it('sendTelemetry includes the number of overlays a bundle run applied', async ( expect.objectContaining({ data: [expect.objectContaining({ bundle_overlays_count: 2 })] }) ); }); + +describe('isTelemetryEnabled', () => { + afterEach(() => { + vi.unstubAllEnvs(); + }); + + it('is on unless the environment or the configuration turns it off', async () => { + vi.stubEnv('REDOCLY_TELEMETRY', 'on'); + expect(isTelemetryEnabled(await createConfig({}))).toBe(true); + expect(isTelemetryEnabled(undefined)).toBe(true); + expect(isTelemetryEnabled(await createConfig({ telemetry: 'off' }))).toBe(false); + + vi.stubEnv('REDOCLY_TELEMETRY', 'off'); + expect(isTelemetryEnabled(await createConfig({}))).toBe(false); + }); +}); diff --git a/packages/cli/src/utils/package.ts b/packages/cli/src/utils/package.ts index b7b82c8f28..dd6206fdda 100644 --- a/packages/cli/src/utils/package.ts +++ b/packages/cli/src/utils/package.ts @@ -2,12 +2,3 @@ import packageJson from '../../package.json' with { type: 'json' }; export const { version, name, engines } = packageJson; export const redocVersion = packageJson.devDependencies.redoc; - -/** - * Subresource Integrity hash for the redoc.standalone.js bundle loaded from the CDN. - * Must match `redocVersion`. When bumping redoc, recompute with: - * openssl dgst -sha384 -binary node_modules/redoc/bundles/redoc.standalone.js | openssl base64 -A - * The smoke-test snapshot (tests/smoke/basic/pre-built/redoc.html) flags the resulting output change. - */ -export const redocStandaloneSri = - 'sha384-w447zOpYfw/1Tv/5AK9NfHTlQIqE3RVR6KY62jCyy9zNDgO64cMwGGP1Fj0zJVf5'; diff --git a/packages/cli/src/utils/telemetry.ts b/packages/cli/src/utils/telemetry.ts index af9cbaa902..cb0ce247b4 100644 --- a/packages/cli/src/utils/telemetry.ts +++ b/packages/cli/src/utils/telemetry.ts @@ -36,6 +36,10 @@ type ArazzoFailureAction = NonNullable[number] const SECRET_REPLACEMENT = '***'; +export function isTelemetryEnabled(config?: Config): boolean { + return process.env.REDOCLY_TELEMETRY !== 'off' && config?.resolvedConfig.telemetry !== 'off'; +} + export async function sendTelemetry({ config, argv, diff --git a/packages/cli/src/wrapper.ts b/packages/cli/src/wrapper.ts index 675cf49de1..191e7c5094 100644 --- a/packages/cli/src/wrapper.ts +++ b/packages/cli/src/wrapper.ts @@ -26,10 +26,11 @@ import { import type { ExitCode } from './utils/miscellaneous.js'; import { version } from './utils/package.js'; import { - sendTelemetry, - collectXSecurityAuthTypes, - collectSourceDescriptionTypes, collectCriterionObjectTypes, + collectSourceDescriptionTypes, + collectXSecurityAuthTypes, + isTelemetryEnabled, + sendTelemetry, } from './utils/telemetry.js'; export type CollectResults = (results: NormalizedProblem[]) => void; @@ -49,7 +50,6 @@ export function commandWrapper( return async (argv: Arguments) => { const startedAt = performance.now(); let code: ExitCode = 2; - let telemetry; let specVersion: string = 'unknown'; let specKeyword: string | undefined; let specFullVersion: string | undefined; @@ -115,7 +115,6 @@ export function commandWrapper( throw new HandledError('Please provide a valid path to the configuration file.'); } config = await loadAndCheckConfig(argv as Exact, version, options.plugins); - telemetry = config.resolvedConfig.telemetry; code = 1; if (typeof commandHandler === 'function') { await commandHandler({ argv, config, version, collectSpecData, collectResults }); @@ -134,7 +133,7 @@ export function commandWrapper( logger.error('\n'); } } finally { - if (process.env.REDOCLY_TELEMETRY !== 'off' && telemetry !== 'off') { + if (isTelemetryEnabled(config)) { const executionTime = Math.round(performance.now() - startedAt); await sendTelemetry({ config, diff --git a/tests/e2e/build-docs/arazzo-build-docs/cafe-workflows.yaml b/tests/e2e/build-docs/arazzo-build-docs/cafe-workflows.yaml new file mode 100644 index 0000000000..168591080b --- /dev/null +++ b/tests/e2e/build-docs/arazzo-build-docs/cafe-workflows.yaml @@ -0,0 +1,18 @@ +arazzo: 1.0.1 +info: + title: Redocly Cafe ordering workflows + version: 1.0.0 + +sourceDescriptions: + - name: cafe-api + type: openapi + url: ../../../../resources/cafe.yaml + +workflows: + - workflowId: find-beverage + summary: List the beverages on the menu. + steps: + - stepId: list-menu + operationId: cafe-api.listMenuItems + successCriteria: + - condition: $statusCode == 200 diff --git a/tests/e2e/build-docs/arazzo-build-docs/snapshot.txt b/tests/e2e/build-docs/arazzo-build-docs/snapshot.txt new file mode 100644 index 0000000000..6495af02dc --- /dev/null +++ b/tests/e2e/build-docs/arazzo-build-docs/snapshot.txt @@ -0,0 +1,13 @@ + + + ╔════════════════════════════════════════════════════════════════════════════╗ + ā•‘ ā•‘ + ā•‘ build-docs now renders docs with Redoc 3. ā•‘ + ā•‘ Theme options and custom templates may need updates. ā•‘ + ā•‘ To keep the Redoc 2 output: npx @redocly/cli@v1-archive build-docs ā•‘ + ā•‘ Learn more: https://redocly.com/redoc-ce ā•‘ + ā•‘ ā•‘ + ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• + +build-docs renders OpenAPI, AsyncAPI, and GraphQL. This file is Arazzo. + diff --git a/tests/e2e/build-docs/asyncapi-build-docs/asyncapi.yaml b/tests/e2e/build-docs/asyncapi-build-docs/asyncapi.yaml new file mode 100644 index 0000000000..a6cdf59490 --- /dev/null +++ b/tests/e2e/build-docs/asyncapi-build-docs/asyncapi.yaml @@ -0,0 +1,39 @@ +asyncapi: 3.0.0 +info: + title: Simple AsyncAPI 3 Example + version: 1.0.0 + description: A simple AsyncAPI v3 example for testing split command +channels: + userSignedup: + address: user/signedup + messages: + UserSignedUp: + $ref: '#/components/messages/UserSignedUp' +operations: + sendUserSignedup: + action: send + channel: + $ref: '#/channels/userSignedup' + messages: + - $ref: '#/channels/userSignedup/messages/UserSignedUp' +components: + messages: + UserSignedUp: + payload: + type: object + properties: + displayName: + type: string + description: Name of the user + email: + type: string + format: email + description: Email of the user + schemas: + User: + type: object + properties: + id: + type: string + name: + type: string diff --git a/tests/e2e/build-docs/asyncapi-build-docs/config.yaml b/tests/e2e/build-docs/asyncapi-build-docs/config.yaml new file mode 100644 index 0000000000..4aee33ebce --- /dev/null +++ b/tests/e2e/build-docs/asyncapi-build-docs/config.yaml @@ -0,0 +1,4 @@ +openapi: + hideDownloadButtons: true +asyncapi: + jsonSamplesDepth: 4 diff --git a/tests/e2e/build-docs/asyncapi-build-docs/snapshot.txt b/tests/e2e/build-docs/asyncapi-build-docs/snapshot.txt new file mode 100644 index 0000000000..0bb3484ed1 --- /dev/null +++ b/tests/e2e/build-docs/asyncapi-build-docs/snapshot.txt @@ -0,0 +1,14 @@ + + + ╔════════════════════════════════════════════════════════════════════════════╗ + ā•‘ ā•‘ + ā•‘ build-docs now renders docs with Redoc 3. ā•‘ + ā•‘ Theme options and custom templates may need updates. ā•‘ + ā•‘ To keep the Redoc 2 output: npx @redocly/cli@v1-archive build-docs ā•‘ + ā•‘ Learn more: https://redocly.com/redoc-ce ā•‘ + ā•‘ ā•‘ + ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• + +Prerendering docs + +šŸŽ‰ bundled successfully in: redoc-static.html (251 KiB) [ā± ms]. diff --git a/tests/e2e/build-docs/build-docs-with-config-option/index.hbs b/tests/e2e/build-docs/build-docs-with-config-option/index.hbs index 5b224ef2f1..53d78c196a 100644 --- a/tests/e2e/build-docs/build-docs-with-config-option/index.hbs +++ b/tests/e2e/build-docs/build-docs-with-config-option/index.hbs @@ -13,7 +13,7 @@ } {{{redocHead}}} - {{#unless disableGoogleFont}}{{/unless}} + diff --git a/tests/e2e/build-docs/build-docs-with-config-option/snapshot.txt b/tests/e2e/build-docs/build-docs-with-config-option/snapshot.txt index ef4d87815c..f4d66eaa1c 100644 --- a/tests/e2e/build-docs/build-docs-with-config-option/snapshot.txt +++ b/tests/e2e/build-docs/build-docs-with-config-option/snapshot.txt @@ -12,310 +12,408 @@ margin: 0; } - -

Sample API (1.0.0)

Download OpenAPI specification:

Get a greeting message

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}
-

Sample API (1.0.0)

Servers
http://redocly-example.com
+ diff --git a/tests/e2e/build-docs/build-docs-with-disabled-search/config.yaml b/tests/e2e/build-docs/build-docs-with-disabled-search/config.yaml deleted file mode 100644 index 9651912755..0000000000 --- a/tests/e2e/build-docs/build-docs-with-disabled-search/config.yaml +++ /dev/null @@ -1,2 +0,0 @@ -openapi: - disableSearch: true diff --git a/tests/e2e/build-docs/build-docs-with-disabled-search/snapshot.txt b/tests/e2e/build-docs/build-docs-with-disabled-search/snapshot.txt deleted file mode 100644 index d499eb4ab3..0000000000 --- a/tests/e2e/build-docs/build-docs-with-disabled-search/snapshot.txt +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - Sample API - - - - - - - - - -

Sample API (1.0.0)

Download OpenAPI specification:

Test.

-

Test

Responses

Response samples

Content type
application/json
{ }
- - - - diff --git a/tests/e2e/build-docs/build-docs-with-disabled-search/config-with-alias.yaml b/tests/e2e/build-docs/build-docs-with-openapi-options/config-with-alias.yaml similarity index 61% rename from tests/e2e/build-docs/build-docs-with-disabled-search/config-with-alias.yaml rename to tests/e2e/build-docs/build-docs-with-openapi-options/config-with-alias.yaml index 729b032cd5..c44a41bc10 100644 --- a/tests/e2e/build-docs/build-docs-with-disabled-search/config-with-alias.yaml +++ b/tests/e2e/build-docs/build-docs-with-openapi-options/config-with-alias.yaml @@ -2,4 +2,4 @@ apis: alias: root: openapi.yaml openapi: - disableSearch: true + hideDownloadButtons: true diff --git a/tests/e2e/build-docs/build-docs-with-disabled-search/config-with-apis-and-root-option.yaml b/tests/e2e/build-docs/build-docs-with-openapi-options/config-with-apis-and-root-option.yaml similarity index 63% rename from tests/e2e/build-docs/build-docs-with-disabled-search/config-with-apis-and-root-option.yaml rename to tests/e2e/build-docs/build-docs-with-openapi-options/config-with-apis-and-root-option.yaml index 3c90ad89d3..c080ab0c43 100644 --- a/tests/e2e/build-docs/build-docs-with-disabled-search/config-with-apis-and-root-option.yaml +++ b/tests/e2e/build-docs/build-docs-with-openapi-options/config-with-apis-and-root-option.yaml @@ -3,4 +3,4 @@ apis: root: openapi.yaml openapi: - disableSearch: true + hideDownloadButtons: true diff --git a/tests/e2e/build-docs/build-docs-with-openapi-options/config.yaml b/tests/e2e/build-docs/build-docs-with-openapi-options/config.yaml new file mode 100644 index 0000000000..cedfb86c5a --- /dev/null +++ b/tests/e2e/build-docs/build-docs-with-openapi-options/config.yaml @@ -0,0 +1,2 @@ +openapi: + hideDownloadButtons: true diff --git a/tests/e2e/build-docs/build-docs-with-disabled-search/openapi.yaml b/tests/e2e/build-docs/build-docs-with-openapi-options/openapi.yaml similarity index 100% rename from tests/e2e/build-docs/build-docs-with-disabled-search/openapi.yaml rename to tests/e2e/build-docs/build-docs-with-openapi-options/openapi.yaml diff --git a/tests/e2e/build-docs/build-docs-with-script-tags/openapi.yaml b/tests/e2e/build-docs/build-docs-with-script-tags/openapi.yaml new file mode 100644 index 0000000000..568b6122a4 --- /dev/null +++ b/tests/e2e/build-docs/build-docs-with-script-tags/openapi.yaml @@ -0,0 +1,8 @@ +openapi: 3.2.0 +info: + title: Redocly Cafe + description: | + Uppercase and spaced end tags: + A comment that hides the real end tag: (1.0.0)

Download OpenAPI specification:

Get a greeting message

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}
-

Sample API (1.0.0)

Servers
http://redocly-example.com
+