From 97f81ba854ee206fe624a7c64c60794a9e121aa6 Mon Sep 17 00:00:00 2001 From: maqijun Date: Wed, 13 May 2026 18:24:31 +0100 Subject: [PATCH 1/2] fix: handle GitHub URLs with slash-based branches and multi-dot filenames Fixes #1940 1. GitHub URL parsing: Changed from regex with `[^\/]+` for branch capture (which fails on branches like `feature/new-validation`) to capturing everything after `/blob/` and converting to raw.githubusercontent.com URL, which resolves branch/path ambiguity internally. 2. File extension detection: Changed `name.split('.')[1]` to `parts.pop()` to correctly extract the last extension segment. This fixes handling of multi-dot filenames like `my.asyncapi.yaml` (previously extracted `asyncapi` instead of `yaml`) and filenames without extensions. --- src/apps/cli/commands/new/file.ts | 3 ++- src/domains/models/SpecificationFile.ts | 5 +++-- src/domains/services/validation.service.ts | 9 ++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/apps/cli/commands/new/file.ts b/src/apps/cli/commands/new/file.ts index de61abc5d..047de5151 100644 --- a/src/apps/cli/commands/new/file.ts +++ b/src/apps/cli/commands/new/file.ts @@ -175,7 +175,8 @@ export default class NewFile extends Command { if (!fileName.includes('.')) { fileNameToWriteToDisk = `${fileName}.yaml`; } else { - const extension = fileName.split('.')[1]; + const parts = fileName.split('.'); + const extension = parts.length > 1 ? parts.pop()!.toLowerCase() : ''; if (extension === 'yml' || extension === 'yaml' || extension === 'json') { fileNameToWriteToDisk = fileName; diff --git a/src/domains/models/SpecificationFile.ts b/src/domains/models/SpecificationFile.ts index 5370f6e67..3be30f5cc 100644 --- a/src/domains/models/SpecificationFile.ts +++ b/src/domains/models/SpecificationFile.ts @@ -237,11 +237,12 @@ export async function fileExists(name: string): Promise { return true; } - const extension = name.split('.')[1]; + const parts = name.split('.'); + const extension = parts.length > 1 ? parts.pop()!.toLowerCase() : ''; const allowedExtenstion = ['yml', 'yaml', 'json']; - if (!allowedExtenstion.includes(extension)) { + if (!extension || !allowedExtenstion.includes(extension)) { throw new ErrorLoadingSpec('invalid file', name); } diff --git a/src/domains/services/validation.service.ts b/src/domains/services/validation.service.ts index 11ac45fc4..8f394f721 100644 --- a/src/domains/services/validation.service.ts +++ b/src/domains/services/validation.service.ts @@ -69,13 +69,16 @@ const convertGitHubWebUrl = (url: string): string => { const urlWithoutFragment = url.split('#')[0]; // Handle GitHub web URLs like: https://github.com/owner/repo/blob/branch/path + // Branch names can contain slashes (e.g. feature/new-validation), so we capture + // everything after /blob/ and use raw.githubusercontent.com which resolves the + // branch/path split internally. // eslint-disable-next-line no-useless-escape - const githubWebPattern = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/blob\/([^\/]+)\/(.+)$/; + const githubWebPattern = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/blob\/(.+)$/; const match = urlWithoutFragment.match(githubWebPattern); if (match) { - const [, owner, repo, branch, filePath] = match; - return `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}?ref=${branch}`; + const [, owner, repo, branchAndPath] = match; + return `https://raw.githubusercontent.com/${owner}/${repo}/${branchAndPath}`; } return url; From 0511ad6adbbee058c017a782be90902663110f40 Mon Sep 17 00:00:00 2001 From: maqijun Date: Wed, 13 May 2026 19:06:03 +0100 Subject: [PATCH 2/2] add changeset for patch release --- .changeset/fix-url-and-extension-parsing.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-url-and-extension-parsing.md diff --git a/.changeset/fix-url-and-extension-parsing.md b/.changeset/fix-url-and-extension-parsing.md new file mode 100644 index 000000000..556f4be69 --- /dev/null +++ b/.changeset/fix-url-and-extension-parsing.md @@ -0,0 +1,5 @@ +--- +"@asyncapi/cli": patch +--- + +Fix GitHub URL parsing for branches with slashes and file extension detection for multi-dot filenames