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
3 changes: 2 additions & 1 deletion src/domains/models/SpecificationFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ export async function fileExists(name: string): Promise<boolean> {
return true;
}

const extension = name.split('.')[1];
// Bug fix #1940: Use path.extname() for multi-dot filenames (e.g., my.asyncapi.yaml)
const extension = path.extname(name).slice(1);

const allowedExtenstion = ['yml', 'yaml', 'json'];

Expand Down
3 changes: 2 additions & 1 deletion src/domains/services/validation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@

// Handle GitHub web URLs like: https://github.com/owner/repo/blob/branch/path
// eslint-disable-next-line no-useless-escape
const githubWebPattern = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/blob\/([^\/]+)\/(.+)$/;
// Bug fix #1940: Support slash-based branch names (e.g., feature/new-validation)
const githubWebPattern = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/blob\/(.+?)\/(.+)$/;

Check warning on line 74 in src/domains/services/validation.service.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unnecessary escape character: \/.

See more on https://sonarcloud.io/project/issues?id=asyncapi_cli&issues=AZ2zENDKJ1vf44kmcub2&open=AZ2zENDKJ1vf44kmcub2&pullRequest=2131

Check warning on line 74 in src/domains/services/validation.service.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unnecessary escape character: \/.

See more on https://sonarcloud.io/project/issues?id=asyncapi_cli&issues=AZ2zENDKJ1vf44kmcub3&open=AZ2zENDKJ1vf44kmcub3&pullRequest=2131
const match = urlWithoutFragment.match(githubWebPattern);

if (match) {
Expand Down
41 changes: 41 additions & 0 deletions test/unit/services/validation.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,5 +253,46 @@ describe('ValidationService', () => {
expect(result.data?.diagnostics).to.be.an('array');
}
});

it('should handle GitHub URLs with slash-based branch names (e.g., feature/new-validation)', async () => {
// Test AsyncAPI document with slash-based branch name reference
const asyncAPIWithSlashBranch = `{
"asyncapi": "2.6.0",
"info": {
"title": "Test Service with Slash Branch",
"version": "1.0.0"
},
"channels": {
"user/event": {
"publish": {
"message": {
"payload": {
"$ref": "https://github.com/asyncapi/spec/blob/feature/new-validation/examples/streetlights.yml#/channels/light/measured/message/payload"
}
}
}
}
}
}`;

const specFile = new Specification(asyncAPIWithSlashBranch);
const options = {
'diagnostics-format': 'stylish' as const
};

const result = await validationService.validateDocument(specFile, options);

// Validation should execute successfully (may be invalid due to 404, but URL parsing works)
expect(result.success).to.equal(true);
if (result.success) {
expect(result.data).to.have.property('status');
expect(result.data).to.have.property('diagnostics');
// Should not have URL parsing errors - the branch name should be correctly extracted
const urlParseErrors = result.data?.diagnostics?.filter((d: any) =>
d.message?.includes('Failed to parse URL') || d.message?.includes('Invalid URL')
);
expect(urlParseErrors).to.have.lengthOf(0);
}
});
});
});
Loading