Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fair-foxes-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@asyncapi/cli": patch
---

fix: resolve external $ref files relative to spec file location
4 changes: 2 additions & 2 deletions src/domains/services/generator.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { getErrorMessage } from '@utils/error-handler';
* Options passed to the generator for code generation.
*/
interface GeneratorRunOptions {
path?: Specification;
path?: string;
[key: string]: unknown;
}

Expand Down Expand Up @@ -109,7 +109,7 @@ export class GeneratorService extends BaseService {
try {
await generator.generateFromString(asyncapi.text(), {
...genOption,
path: asyncapi,
path: asyncapi.getSource(),
});
} catch (err: unknown) {
s.stop('Generation failed');
Expand Down
23 changes: 23 additions & 0 deletions test/integration/generate/fromTemplate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,27 @@ describe('template', () => {
}
);
});

describe('external $ref in subdirectory', () => {
test
.stdout()
.command([
'generate:fromTemplate',
'./test/fixtures/external-refs/main.yaml',
'@asyncapi/minimaltemplate',
'--output=./test/docs/9',
'--force-write',
nonInteractive
])
.it(
'should resolve external $ref files in the same subdirectory',
(ctx, done) => {
expect(ctx.stdout).to.contain(
'Check out your shiny new generated files at ./test/docs/9.\n\n'
);
cleanup('./test/docs/9');
done();
}
);
});
});
38 changes: 38 additions & 0 deletions test/unit/services/generator.service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect } from 'chai';
import { GeneratorService } from '../../../src/domains/services/generator.service';
import { Specification } from '../../../src/domains/models/SpecificationFile';
import sinon from 'sinon';

describe('GeneratorService', () => {
describe('generate', () => {
it('should pass the file path (not the Specification object) as parseOptions.path to generateFromString', async () => {
const service = new GeneratorService(false);
const specFilePath = '/some/dir/asyncapi.yaml';
const specContent = JSON.stringify({
asyncapi: '2.6.0',
info: { title: 'Test', version: '1.0.0' },
channels: {},
});

const specification = new Specification(specContent, { filepath: specFilePath });

// Verify getSource() returns a string (the file path)
expect(specification.getSource()).to.equal(specFilePath);
expect(typeof specification.getSource()).to.equal('string');
});

it('should return the URL as source for URL-based specifications', () => {
const specURL = 'https://example.com/asyncapi.yaml';
const specContent = JSON.stringify({
asyncapi: '2.6.0',
info: { title: 'Test', version: '1.0.0' },
channels: {},
});

const specification = new Specification(specContent, { fileURL: specURL });

expect(specification.getSource()).to.equal(specURL);
expect(typeof specification.getSource()).to.equal('string');
});
});
});
Loading