Skip to content

Commit 3b063e0

Browse files
committed
fix: resolve API alias paths correctly for config files located outside the root folder
1 parent 4523355 commit 3b063e0

File tree

10 files changed

+132
-45
lines changed

10 files changed

+132
-45
lines changed

.changeset/silly-chairs-applaud.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@redocly/cli": patch
3+
---
4+
5+
Fixed an issue where an API alias's root path might be resolved incorrectly for configuration files located outside the root folder.

__tests__/commands.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,20 @@ describe('E2E', () => {
613613
const result = getCommandOutput(args, testPath);
614614
(<any>expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(testPath, 'snapshot.js'));
615615
});
616+
617+
test('apply a decorator to a specific api (without specifying the api)', () => {
618+
const testPath = join(folderPath, 'apply-per-api-decorators');
619+
const args = getParams('../../../packages/cli/src/index.ts', 'bundle');
620+
const result = getCommandOutput(args, testPath);
621+
(<any>expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(testPath, 'snapshot.js'));
622+
});
623+
624+
test('apply a decorator to a specific api (when the api is specified as an alias)', () => {
625+
const testPath = join(folderPath, 'apply-per-api-decorators');
626+
const args = getParams('../../../packages/cli/src/index.ts', 'bundle', ['test@v1']);
627+
const result = getCommandOutput(args, testPath);
628+
(<any>expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(testPath, 'snapshot.js'));
629+
});
616630
});
617631

618632
describe('build-docs', () => {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Test
4+
paths: {}
5+
components:
6+
schemas:
7+
Unused:
8+
type: string
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = sparkle;
2+
3+
function sparkle() {
4+
return {
5+
Info: {
6+
leave(target) {
7+
target.version = '1.0.0';
8+
},
9+
},
10+
};
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const version = require('./decorators/version.js');
2+
3+
module.exports = function testPlugin() {
4+
return {
5+
id: 'test',
6+
decorators: {
7+
oas3: {
8+
version,
9+
},
10+
},
11+
};
12+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apis:
2+
test@v1:
3+
root: openapi.yaml
4+
decorators:
5+
test/version: on
6+
remove-unused-components: on
7+
plugins:
8+
- plugins/test.js
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`E2E miscellaneous apply a decorator to a specific api (when the api is specified as an alias) 1`] = `
4+
openapi: 3.1.0
5+
info:
6+
title: Test
7+
version: 1.0.0
8+
paths: {}
9+
components:
10+
schemas:
11+
Unused:
12+
type: string
13+
14+
bundling ./__tests__/miscellaneous/apply-per-api-decorators/openapi.yaml...
15+
📦 Created a bundle for ./__tests__/miscellaneous/apply-per-api-decorators/openapi.yaml at stdout <test>ms.
16+
17+
`;
18+
19+
exports[`E2E miscellaneous apply a decorator to a specific api (without specifying the api) 1`] = `
20+
openapi: 3.1.0
21+
info:
22+
title: Test
23+
version: 1.0.0
24+
paths: {}
25+
components:
26+
schemas:
27+
Unused:
28+
type: string
29+
30+
bundling ./__tests__/miscellaneous/apply-per-api-decorators/openapi.yaml...
31+
📦 Created a bundle for ./__tests__/miscellaneous/apply-per-api-decorators/openapi.yaml at stdout <test>ms.
32+
33+
`;

packages/cli/src/commands/login.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { blue, green, gray } from 'colorette';
22
import { RedoclyClient } from '@redocly/openapi-core';
3-
import { promptUser } from '../utils/miscellaneous';
3+
import { exitWithError, promptUser } from '../utils/miscellaneous';
44

55
import type { CommandArgs } from '../wrapper';
66
import type { Region } from '@redocly/openapi-core';
@@ -21,10 +21,14 @@ export type LoginOptions = {
2121
};
2222

2323
export async function handleLogin({ argv, config }: CommandArgs<LoginOptions>) {
24-
const region = argv.region || config.region;
25-
const client = new RedoclyClient(region);
26-
const clientToken = await promptClientToken(client.domain);
27-
process.stdout.write(gray('\n Logging in...\n'));
28-
await client.login(clientToken, argv.verbose);
29-
process.stdout.write(green(' Authorization confirmed. ✅\n\n'));
24+
try {
25+
const region = argv.region || config.region;
26+
const client = new RedoclyClient(region);
27+
const clientToken = await promptClientToken(client.domain);
28+
process.stdout.write(gray('\n Logging in...\n'));
29+
await client.login(clientToken, argv.verbose);
30+
process.stdout.write(green(' Authorization confirmed. ✅\n\n'));
31+
} catch (err) {
32+
exitWithError(' ' + err?.message);
33+
}
3034
}

packages/cli/src/utils/miscellaneous.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ function getAliasOrPath(config: ConfigApis, aliasOrPath: string): Entrypoint {
9292
const aliasApi = config.apis[aliasOrPath];
9393
return aliasApi
9494
? {
95-
path: aliasApi.root,
95+
path: resolve(getConfigDirectory(config), aliasApi.root),
9696
alias: aliasOrPath,
97-
output: aliasApi.output,
97+
output: aliasApi.output && resolve(getConfigDirectory(config), aliasApi.output),
9898
}
9999
: {
100100
path: aliasOrPath,

packages/core/src/config/config-resolvers.ts

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -370,19 +370,19 @@ export async function resolveApis({
370370
return resolvedApis;
371371
}
372372

373-
async function resolveAndMergeNestedStyleguideConfig(
374-
{
375-
styleguideConfig,
376-
configPath = '',
377-
resolver = new BaseResolver(),
378-
}: {
379-
styleguideConfig?: StyleguideRawConfig;
380-
configPath?: string;
381-
resolver?: BaseResolver;
382-
},
383-
parentConfigPaths: string[] = [],
384-
extendPaths: string[] = []
385-
): Promise<ResolvedStyleguideConfig> {
373+
async function resolveAndMergeNestedStyleguideConfig({
374+
styleguideConfig,
375+
configPath = '',
376+
resolver = new BaseResolver(),
377+
parentConfigPaths = [],
378+
extendPaths = [],
379+
}: {
380+
styleguideConfig?: StyleguideRawConfig;
381+
configPath?: string;
382+
resolver?: BaseResolver;
383+
parentConfigPaths?: string[];
384+
extendPaths?: string[];
385+
}): Promise<ResolvedStyleguideConfig> {
386386
if (parentConfigPaths.includes(configPath)) {
387387
throw new Error(`Circular dependency in config file: "${configPath}"`);
388388
}
@@ -414,15 +414,13 @@ async function resolveAndMergeNestedStyleguideConfig(
414414
? new URL(presetItem, configPath).href
415415
: path.resolve(path.dirname(configPath), presetItem);
416416
const extendedStyleguideConfig = await loadExtendStyleguideConfig(pathItem, resolver);
417-
return await resolveAndMergeNestedStyleguideConfig(
418-
{
419-
styleguideConfig: extendedStyleguideConfig,
420-
configPath: pathItem,
421-
resolver: resolver,
422-
},
423-
[...parentConfigPaths, resolvedConfigPath],
424-
extendPaths
425-
);
417+
return await resolveAndMergeNestedStyleguideConfig({
418+
styleguideConfig: extendedStyleguideConfig,
419+
configPath: pathItem,
420+
resolver,
421+
parentConfigPaths: [...parentConfigPaths, resolvedConfigPath],
422+
extendPaths,
423+
});
426424
}) || []
427425
);
428426

@@ -446,20 +444,14 @@ async function resolveAndMergeNestedStyleguideConfig(
446444
};
447445
}
448446

449-
export async function resolveStyleguideConfig(
450-
opts: {
451-
styleguideConfig?: StyleguideRawConfig;
452-
configPath?: string;
453-
resolver?: BaseResolver;
454-
},
455-
parentConfigPaths: string[] = [],
456-
extendPaths: string[] = []
457-
): Promise<ResolvedStyleguideConfig> {
458-
const resolvedStyleguideConfig = await resolveAndMergeNestedStyleguideConfig(
459-
opts,
460-
parentConfigPaths,
461-
extendPaths
462-
);
447+
export async function resolveStyleguideConfig(opts: {
448+
styleguideConfig?: StyleguideRawConfig;
449+
configPath?: string;
450+
resolver?: BaseResolver;
451+
parentConfigPaths?: string[];
452+
extendPaths?: string[];
453+
}): Promise<ResolvedStyleguideConfig> {
454+
const resolvedStyleguideConfig = await resolveAndMergeNestedStyleguideConfig(opts);
463455

464456
return {
465457
...resolvedStyleguideConfig,

0 commit comments

Comments
 (0)