Skip to content

Commit

Permalink
fix: resolve apis.root correctly for external urls (#1837)
Browse files Browse the repository at this point in the history
* fix: resolve apis.root correctly for external urls

* chore: fix output formatting

* chore: fix tests

* chore: fix eslint errors

* Update .changeset/cuddly-glasses-add.md

---------

Co-authored-by: Jacek Łękawa <[email protected]>
  • Loading branch information
tatomyr and JLekawa authored Jan 3, 2025
1 parent cd768f9 commit ef2f412
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-glasses-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@redocly/cli": patch
---

Fixed an issue where `apis`' root in `redocly.yaml` was not resolved properly when the value of `root` was a URL.
12 changes: 11 additions & 1 deletion __tests__/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,17 @@ describe('E2E', () => {
const testPath = join(folderPath, 'apply-per-api-decorators');
const args = getParams('../../../packages/cli/src/index.ts', 'bundle', [
'--config=nested/redocly.yaml',
'test@v1',
'test@fs',
]);
const result = getCommandOutput(args, testPath);
(<any>expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(testPath, 'snapshot.js'));
});

test('lint a specific api (when the api is specified as an alias and it points to an external URL)', () => {
const testPath = join(folderPath, 'apply-per-api-decorators');
const args = getParams('../../../packages/cli/src/index.ts', 'lint', [
'--config=nested/redocly.yaml',
'test@external-url',
]);
const result = getCommandOutput(args, testPath);
(<any>expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(testPath, 'snapshot.js'));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
apis:
test@v1:
test@fs:
root: openapi/main.yaml
decorators:
test/version: on
remove-unused-components: on
test@external-url:
root: https://raw.githubusercontent.com/Redocly/redocly-cli/refs/heads/main/__tests__/miscellaneous/apply-per-api-decorators/nested/openapi/main.yaml
rules:
info-contact: error
plugins:
- plugins/test.js
34 changes: 34 additions & 0 deletions __tests__/miscellaneous/apply-per-api-decorators/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,46 @@ info:
title: Test
version: 1.0.0
paths: {}
components:
schemas:
Unused:
type: string
openapi: 3.1.0
info:
title: Test
paths: {}
components:
schemas:
Unused:
type: string
bundling nested/openapi/main.yaml...
📦 Created a bundle for nested/openapi/main.yaml at stdout <test>ms.
bundling https://raw.githubusercontent.com/Redocly/redocly-cli/refs/heads/main/__tests__/miscellaneous/apply-per-api-decorators/nested/openapi/main.yaml...
📦 Created a bundle for https://raw.githubusercontent.com/Redocly/redocly-cli/refs/heads/main/__tests__/miscellaneous/apply-per-api-decorators/nested/openapi/main.yaml at stdout <test>ms.
`;

exports[`E2E miscellaneous lint a specific api (when the api is specified as an alias and it points to an external URL) 1`] = `
validating https://raw.githubusercontent.com/Redocly/redocly-cli/refs/heads/main/__tests__/miscellaneous/apply-per-api-decorators/nested/openapi/main.yaml...
[1] https://raw.githubusercontent.com/Redocly/redocly-cli/refs/heads/main/__tests__/miscellaneous/apply-per-api-decorators/nested/openapi/main.yaml:2:1 at #/info/contact
Info object should contain \`contact\` field.
1 | openapi: 3.1.0
2 | info:
| ^^^^
3 | title: Test
4 | paths: {}
Error was generated by the info-contact rule.
https://raw.githubusercontent.com/Redocly/redocly-cli/refs/heads/main/__tests__/miscellaneous/apply-per-api-decorators/nested/openapi/main.yaml: validated in <test>ms
❌ Validation failed with 1 error.
run \`redocly lint --generate-ignore-file\` to add all problems to the ignore file.
`;
10 changes: 5 additions & 5 deletions packages/cli/src/commands/bundle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { relative } from 'path';
import { performance } from 'perf_hooks';
import { blue, gray, green, yellow } from 'colorette';
import { writeFileSync } from 'fs';
Expand All @@ -13,6 +12,7 @@ import {
saveBundle,
sortTopLevelKeysForOas,
checkForDeprecatedOptions,
formatPath,
} from '../utils/miscellaneous';

import type { OutputExtensions, Skips, Totals, VerifyConfigOptions } from '../types';
Expand Down Expand Up @@ -55,7 +55,7 @@ export async function handleBundle({
styleguide.skipPreprocessors(argv['skip-preprocessor']);
styleguide.skipDecorators(argv['skip-decorator']);

process.stderr.write(gray(`bundling ${relative(process.cwd(), path)}...\n`));
process.stderr.write(gray(`bundling ${formatPath(path)}...\n`));

const {
bundle: result,
Expand Down Expand Up @@ -118,20 +118,20 @@ export async function handleBundle({
if (fileTotals.errors > 0) {
if (argv.force) {
process.stderr.write(
`❓ Created a bundle for ${blue(relative(process.cwd(), path))} at ${blue(
`❓ Created a bundle for ${blue(formatPath(path))} at ${blue(
outputFile || 'stdout'
)} with errors ${green(elapsed)}.\n${yellow('Errors ignored because of --force')}.\n`
);
} else {
process.stderr.write(
`❌ Errors encountered while bundling ${blue(
relative(process.cwd(), path)
formatPath(path)
)}: bundle not created (use --force to ignore errors).\n`
);
}
} else {
process.stderr.write(
`📦 Created a bundle for ${blue(relative(process.cwd(), path))} at ${blue(
`📦 Created a bundle for ${blue(formatPath(path))} at ${blue(
outputFile || 'stdout'
)} ${green(elapsed)}.\n`
);
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/commands/lint.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { relative } from 'path';
import { blue, gray } from 'colorette';
import { performance } from 'perf_hooks';
import {
Expand All @@ -13,6 +12,7 @@ import { pluralize } from '@redocly/openapi-core/lib/utils';
import {
checkIfRulesetExist,
exitWithError,
formatPath,
getExecutionTime,
getFallbackApisOrExit,
handleError,
Expand Down Expand Up @@ -75,7 +75,7 @@ export async function handleLint({
)} configuration by default.\n\n`
);
}
process.stderr.write(gray(`validating ${relative(process.cwd(), path)}...\n`));
process.stderr.write(gray(`validating ${formatPath(path)}...\n`));
const results = await lint({
ref: path,
config: resolvedConfig,
Expand All @@ -102,7 +102,7 @@ export async function handleLint({
}

const elapsed = getExecutionTime(startedAt);
process.stderr.write(gray(`${relative(process.cwd(), path)}: validated in ${elapsed}\n\n`));
process.stderr.write(gray(`${formatPath(path)}: validated in ${elapsed}\n\n`));
} catch (e) {
handleError(e, path);
}
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/utils/__mocks__/miscellaneous.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export const getAndValidateFileExtension = jest.fn((fileName: string) => fileNam
export const writeToFileByExtension = jest.fn();
export const checkForDeprecatedOptions = jest.fn();
export const saveBundle = jest.fn();
export const formatPath = jest.fn((path: string) => path);
11 changes: 9 additions & 2 deletions packages/cli/src/utils/miscellaneous.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export async function getFallbackApisOrExit(
if (isNotEmptyArray(filteredInvalidEntrypoints)) {
for (const { path } of filteredInvalidEntrypoints) {
process.stderr.write(
yellow(`\n${relative(process.cwd(), path)} ${red(`does not exist or is invalid.\n\n`)}`)
yellow(`\n${formatPath(path)} ${red(`does not exist or is invalid.\n\n`)}`)
);
}
exitWithError('Please provide a valid path.');
Expand Down Expand Up @@ -92,7 +92,7 @@ function getAliasOrPath(config: ConfigApis, aliasOrPath: string): Entrypoint {
const aliasApi = config.apis[aliasOrPath];
return aliasApi
? {
path: isAbsolute(aliasApi.root)
path: isAbsoluteUrl(aliasApi.root)
? aliasApi.root
: resolve(getConfigDirectory(config), aliasApi.root),
alias: aliasOrPath,
Expand Down Expand Up @@ -702,3 +702,10 @@ export function notifyAboutIncompatibleConfigOptions(
}
}
}

export function formatPath(path: string) {
if (isAbsoluteUrl(path)) {
return path;
}
return relative(process.cwd(), path);
}

1 comment on commit ef2f412

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.61% 5046/6419
🟡 Branches 67.24% 2055/3056
🟡 Functions 73.13% 833/1139
🟡 Lines 78.9% 4760/6033

Test suite run success

833 tests passing in 120 suites.

Report generated by 🧪jest coverage report action from ef2f412

Please sign in to comment.