From aa5ccefe2e933bffb994fff808136d72af2dfa9b Mon Sep 17 00:00:00 2001 From: lightning-sagar Date: Mon, 27 Oct 2025 21:33:59 +0530 Subject: [PATCH 01/17] fix(config): - use 'node:' prefix for built-in modules - replace if-assignment with nullish coalescing (??=) - use String#replaceAll and String.raw in wildcardToRegex --- src/domains/services/config.service.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/domains/services/config.service.ts b/src/domains/services/config.service.ts index b5cf3497948..29ca563e1b1 100644 --- a/src/domains/services/config.service.ts +++ b/src/domains/services/config.service.ts @@ -1,6 +1,6 @@ -import path from 'path'; -import os from 'os'; -import { promises as fs } from 'fs'; +import path from 'node:path'; +import os from 'node:os'; +import { promises as fs } from 'node:fs'; const CONFIG_DIR = path.join(os.homedir(), '.asyncapi'); const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json'); @@ -51,9 +51,7 @@ export class ConfigService { */ static async addAuthEntry(entry: AuthEntry): Promise { const config = await this.loadConfig(); - if (!config.auth) { - config.auth = []; - } + config.auth ??= []; config.auth.push(entry); await this.saveConfig(config); } @@ -96,13 +94,11 @@ export class ConfigService { * @param pattern - wildcard pattern */ private static wildcardToRegex(pattern: string): RegExp { - const escaped = pattern.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&'); + const escaped = String.raw`${pattern}`.replaceAll(/[-/\\^$+?.()|[\]{}]/g, '\\$&'); const regexStr = escaped - .replace(/\*\*/g, '.*') - .replace(/\*/g, '[^/]*'); - - // eslint-disable-next-line security/detect-non-literal-regexp + .replaceAll('**', '.*') + .replaceAll('*', '[^/]*'); return new RegExp(`^${regexStr}`); } } From eb7394e172568521ba77264f1e36e61ed78a6ab0 Mon Sep 17 00:00:00 2001 From: lightning-sagar Date: Mon, 27 Oct 2025 22:25:30 +0530 Subject: [PATCH 02/17] refactor: improve GitHub URL handling and simplify HTTP resolver Use RegExp.exec() instead of String.match() in convertGitHubWebUrl Remove unnecessary try/catch from isValidGitHubBlobUrl Refactor read function in HTTP resolver to reduce cognitive complexity from 16 to 15 --- src/domains/services/validation.service.ts | 79 ++++++++-------------- 1 file changed, 30 insertions(+), 49 deletions(-) diff --git a/src/domains/services/validation.service.ts b/src/domains/services/validation.service.ts index a2fcc4e34ca..2c7e344c0ca 100644 --- a/src/domains/services/validation.service.ts +++ b/src/domains/services/validation.service.ts @@ -50,15 +50,11 @@ interface GitHubFileInfo { * Helper function to validate if a URL is a GitHub blob URL */ const isValidGitHubBlobUrl = (url: string): boolean => { - try { - const parsedUrl = new URL(url); - return ( - parsedUrl.hostname === 'github.com' && - parsedUrl.pathname.split('/')[3] === 'blob' - ); - } catch (error) { - return false; - } + const parsedUrl = new URL(url); + return ( + parsedUrl.hostname === 'github.com' && + parsedUrl.pathname.split('/')[3] === 'blob' + ); }; /** @@ -89,7 +85,7 @@ const createHttpWithAuthResolver = () => ({ order: 1, read: async (uri: any) => { - let url = uri.toString(); + const url = uri.toString(); // Default headers const headers: Record = { @@ -97,55 +93,40 @@ const createHttpWithAuthResolver = () => ({ }; const authInfo = await ConfigService.getAuthForUrl(url); - - if (isValidGitHubBlobUrl(url)) { - url = convertGitHubWebUrl(url); - } - if (authInfo) { headers['Authorization'] = `${authInfo.authType} ${authInfo.token}`; - Object.assign(headers, authInfo.headers); // merge custom headers + Object.assign(headers, authInfo.headers); } - if (url.includes('api.github.com')) { - headers['Accept'] = 'application/vnd.github.v3+json'; - const res = await fetch(url, { headers }); - if (!res.ok) { - throw new Error( - `Failed to fetch GitHub API URL: ${url} - ${res.statusText}` - ); - } - const fileInfo = (await res.json()) as GitHubFileInfo; - - if (fileInfo.download_url) { - const contentRes = await fetch(fileInfo.download_url, { headers }); - if (!contentRes.ok) { - throw new Error( - `Failed to fetch content from download URL: ${fileInfo.download_url} - ${contentRes.statusText}` - ); - } - return await contentRes.text(); - } - throw new Error( - `No download URL found in GitHub API response for: ${url}` - ); - } else if (url.includes('raw.githubusercontent.com')) { - headers['Accept'] = 'application/vnd.github.v3.raw'; - const res = await fetch(url, { headers }); + const finalUrl = isValidGitHubBlobUrl(url) ? convertGitHubWebUrl(url) : url; + + // Helper to fetch and throw on error + const fetchText = async (fetchUrl: string, customHeaders = headers) => { + const res = await fetch(fetchUrl, { headers: customHeaders }); if (!res.ok) { - throw new Error( - `Failed to fetch GitHub URL: ${url} - ${res.statusText}` - ); + throw new Error(`Failed to fetch URL: ${fetchUrl} - ${res.statusText}`); } return await res.text(); - } else { - const res = await fetch(url, { headers }); - if (!res.ok) { - throw new Error(`Failed to fetch URL: ${url} - ${res.statusText}`); + }; + if (finalUrl.includes('api.github.com')) { + headers['Accept'] = 'application/vnd.github.v3+json'; + const fileInfo = (await fetch(finalUrl, { headers }).then(res => { + if (!res.ok) throw new Error(`Failed to fetch GitHub API URL: ${finalUrl} - ${res.statusText}`); + return res.json(); + })) as GitHubFileInfo; + + if (!fileInfo.download_url) { + throw new Error(`No download URL found in GitHub API response for: ${finalUrl}`); } - return await res.text(); + + return fetchText(fileInfo.download_url); } + if (finalUrl.includes('raw.githubusercontent.com')) { + headers['Accept'] = 'application/vnd.github.v3.raw'; + } + return fetchText(finalUrl); }, + }); const { writeFile } = promises; From 8a23b57fed3fc5a007cd6b4358d9a2c986f695ff Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Mon, 27 Oct 2025 17:03:43 +0000 Subject: [PATCH 03/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .changeset/1884.md diff --git a/.changeset/1884.md b/.changeset/1884.md new file mode 100644 index 00000000000..f613416eae1 --- /dev/null +++ b/.changeset/1884.md @@ -0,0 +1,19 @@ +--- +'@asyncapi/cli': patch +--- + +Fix: fixed all sonar cloud issue + +- aa5ccef: fix(config): +- use 'node:' prefix for built-in modules +- replace if-assignment with nullish coalescing (??=) +- use String#replaceAll and String.raw in wildcardToRegex +- eb7394e: refactor: improve GitHub URL handling and simplify HTTP resolver + +Use RegExp.exec() instead of String.match() in convertGitHubWebUrl + +Remove unnecessary try/catch from isValidGitHubBlobUrl + +Refactor read function in HTTP resolver to reduce cognitive complexity from 16 to 15 + + From a16698c6710292d91a78887b7bfabe39c9e8f6d8 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Mon, 27 Oct 2025 17:03:55 +0000 Subject: [PATCH 04/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/1884.md b/.changeset/1884.md index f613416eae1..71a0b57c516 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -2,7 +2,7 @@ '@asyncapi/cli': patch --- -Fix: fixed all sonar cloud issue +fix: fixed all sonar cloud issue - aa5ccef: fix(config): - use 'node:' prefix for built-in modules From 35b917d0a414f69e86639a27c6dde44c717dc090 Mon Sep 17 00:00:00 2001 From: lightning-sagar Date: Tue, 28 Oct 2025 09:11:00 +0530 Subject: [PATCH 05/17] Refactor URL conversion to use RegExp.exec() instead of match() --- src/domains/services/validation.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/domains/services/validation.service.ts b/src/domains/services/validation.service.ts index 2c7e344c0ca..deda7833704 100644 --- a/src/domains/services/validation.service.ts +++ b/src/domains/services/validation.service.ts @@ -67,7 +67,7 @@ const convertGitHubWebUrl = (url: string): string => { // 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\/([^\/]+)\/(.+)$/; - const match = urlWithoutFragment.match(githubWebPattern); + const match = githubWebPattern.exec(urlWithoutFragment); if (match) { const [, owner, repo, branch, filePath] = match; From 910f75f8b82e4b1d045f8b469b565f9121998779 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Tue, 28 Oct 2025 03:43:06 +0000 Subject: [PATCH 06/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/1884.md b/.changeset/1884.md index 71a0b57c516..3e7f8ecb813 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -15,5 +15,6 @@ Use RegExp.exec() instead of String.match() in convertGitHubWebUrl Remove unnecessary try/catch from isValidGitHubBlobUrl Refactor read function in HTTP resolver to reduce cognitive complexity from 16 to 15 +- 35b917d: Refactor URL conversion to use RegExp.exec() instead of match() From 05be198cf61c7a068c02dbb67aa4298e16489586 Mon Sep 17 00:00:00 2001 From: Sagar Seth Date: Thu, 13 Nov 2025 18:57:02 +0530 Subject: [PATCH 07/17] chore: updated the validation.service.ts --- src/domains/services/validation.service.ts | 117 +++++++++++++++------ 1 file changed, 84 insertions(+), 33 deletions(-) diff --git a/src/domains/services/validation.service.ts b/src/domains/services/validation.service.ts index deda7833704..f89d430f92d 100644 --- a/src/domains/services/validation.service.ts +++ b/src/domains/services/validation.service.ts @@ -50,11 +50,17 @@ interface GitHubFileInfo { * Helper function to validate if a URL is a GitHub blob URL */ const isValidGitHubBlobUrl = (url: string): boolean => { - const parsedUrl = new URL(url); - return ( - parsedUrl.hostname === 'github.com' && - parsedUrl.pathname.split('/')[3] === 'blob' - ); + try { + const parsedUrl = new URL(url); + return ( + parsedUrl.hostname === 'github.com' && + parsedUrl.pathname.split('/')[3] === 'blob' + ); + } catch (error) { + // This is expected for non-URL strings, just log and return false + console.debug(`Invalid URL format for GitHub blob check: ${url}`); + return false; + } }; /** @@ -77,6 +83,67 @@ const convertGitHubWebUrl = (url: string): string => { return url; }; +/** + * Helper function to fetch URL and handle errors + */ +const fetchWithErrorHandling = async ( + url: string, + headers: Record, + errorMessage: string +): Promise => { + const res = await fetch(url, { headers }); + if (!res.ok) { + throw new Error(`${errorMessage}: ${url} - ${res.statusText}`); + } + return res; +}; + +/** + * Handle GitHub API URLs + */ +const handleGitHubApiUrl = async ( + url: string, + headers: Record +): Promise => { + headers['Accept'] = 'application/vnd.github.v3+json'; + const res = await fetchWithErrorHandling(url, headers, 'Failed to fetch GitHub API URL'); + const fileInfo = (await res.json()) as GitHubFileInfo; + + if (!fileInfo.download_url) { + throw new Error(`No download URL found in GitHub API response for: ${url}`); + } + + const contentRes = await fetchWithErrorHandling( + fileInfo.download_url, + headers, + 'Failed to fetch content from download URL' + ); + return await contentRes.text(); +}; + +/** + * Handle raw GitHub content URLs + */ +const handleRawGitHubUrl = async ( + url: string, + headers: Record +): Promise => { + headers['Accept'] = 'application/vnd.github.v3.raw'; + const res = await fetchWithErrorHandling(url, headers, 'Failed to fetch GitHub URL'); + return await res.text(); +}; + +/** + * Handle regular HTTP/HTTPS URLs + */ +const handleRegularUrl = async ( + url: string, + headers: Record +): Promise => { + const res = await fetchWithErrorHandling(url, headers, 'Failed to fetch URL'); + return await res.text(); +}; + /** * Custom resolver for private repositories */ @@ -85,7 +152,7 @@ const createHttpWithAuthResolver = () => ({ order: 1, read: async (uri: any) => { - const url = uri.toString(); + let url = uri.toString(); // Default headers const headers: Record = { @@ -93,40 +160,24 @@ const createHttpWithAuthResolver = () => ({ }; const authInfo = await ConfigService.getAuthForUrl(url); + + if (isValidGitHubBlobUrl(url)) { + url = convertGitHubWebUrl(url); + } + if (authInfo) { headers['Authorization'] = `${authInfo.authType} ${authInfo.token}`; - Object.assign(headers, authInfo.headers); + Object.assign(headers, authInfo.headers); } - const finalUrl = isValidGitHubBlobUrl(url) ? convertGitHubWebUrl(url) : url; - - // Helper to fetch and throw on error - const fetchText = async (fetchUrl: string, customHeaders = headers) => { - const res = await fetch(fetchUrl, { headers: customHeaders }); - if (!res.ok) { - throw new Error(`Failed to fetch URL: ${fetchUrl} - ${res.statusText}`); - } - return await res.text(); - }; - if (finalUrl.includes('api.github.com')) { - headers['Accept'] = 'application/vnd.github.v3+json'; - const fileInfo = (await fetch(finalUrl, { headers }).then(res => { - if (!res.ok) throw new Error(`Failed to fetch GitHub API URL: ${finalUrl} - ${res.statusText}`); - return res.json(); - })) as GitHubFileInfo; - - if (!fileInfo.download_url) { - throw new Error(`No download URL found in GitHub API response for: ${finalUrl}`); - } - - return fetchText(fileInfo.download_url); + if (url.includes('api.github.com')) { + return handleGitHubApiUrl(url, headers); } - if (finalUrl.includes('raw.githubusercontent.com')) { - headers['Accept'] = 'application/vnd.github.v3.raw'; + if (url.includes('raw.githubusercontent.com')) { + return handleRawGitHubUrl(url, headers); } - return fetchText(finalUrl); + return handleRegularUrl(url, headers); }, - }); const { writeFile } = promises; From ed1080b4f2fbf428dc4492edf3df4b4dca9c7397 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Nov 2025 13:27:34 +0000 Subject: [PATCH 08/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/1884.md b/.changeset/1884.md index 3e7f8ecb813..b3c3e5a35e0 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -16,5 +16,6 @@ Remove unnecessary try/catch from isValidGitHubBlobUrl Refactor read function in HTTP resolver to reduce cognitive complexity from 16 to 15 - 35b917d: Refactor URL conversion to use RegExp.exec() instead of match() +- 05be198: chore: updated the validation.service.ts From 2bd1f07a1e1b6c69b5c88b47500d7ef79e170872 Mon Sep 17 00:00:00 2001 From: Sagar Seth Date: Thu, 13 Nov 2025 19:18:44 +0530 Subject: [PATCH 09/17] fix: address Sonar S7780 by replacing manual escaping with String.raw --- src/domains/services/config.service.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/domains/services/config.service.ts b/src/domains/services/config.service.ts index 29ca563e1b1..f357cf004d2 100644 --- a/src/domains/services/config.service.ts +++ b/src/domains/services/config.service.ts @@ -94,11 +94,16 @@ export class ConfigService { * @param pattern - wildcard pattern */ private static wildcardToRegex(pattern: string): RegExp { - const escaped = String.raw`${pattern}`.replaceAll(/[-/\\^$+?.()|[\]{}]/g, '\\$&'); - + const rawPattern = String.raw`${pattern}`; + const escaped = rawPattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&'); + // Convert wildcards: + // ** -> match any depth + // * -> match one segment const regexStr = escaped - .replaceAll('**', '.*') - .replaceAll('*', '[^/]*'); - return new RegExp(`^${regexStr}`); + .replace(/\*\*/g, '.*')// ** -> .* + .replace(/\*/g, '[^/]*');// * -> any chars except '/' + + // eslint-disable-next-line security/detect-non-literal-regexp + return new RegExp(`^${regexStr}$`); } } From 19fdb0ffded3526436d452c0dbdeec62c01f0eb0 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Nov 2025 13:54:22 +0000 Subject: [PATCH 10/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/1884.md b/.changeset/1884.md index b3c3e5a35e0..36a01d7cbc3 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -17,5 +17,7 @@ Remove unnecessary try/catch from isValidGitHubBlobUrl Refactor read function in HTTP resolver to reduce cognitive complexity from 16 to 15 - 35b917d: Refactor URL conversion to use RegExp.exec() instead of match() - 05be198: chore: updated the validation.service.ts +- 2bd1f07: fix: address Sonar S7780 by replacing manual escaping with String.raw +- b9cf80a: chore: pull the changes From ba5f736202578ba8e9af83994b11207ed22ed2cd Mon Sep 17 00:00:00 2001 From: Sagar Seth Date: Thu, 13 Nov 2025 19:36:54 +0530 Subject: [PATCH 11/17] replaceAll rule in wildcardToRegex function --- src/domains/services/config.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/domains/services/config.service.ts b/src/domains/services/config.service.ts index f357cf004d2..b83ed11d68c 100644 --- a/src/domains/services/config.service.ts +++ b/src/domains/services/config.service.ts @@ -95,13 +95,13 @@ export class ConfigService { */ private static wildcardToRegex(pattern: string): RegExp { const rawPattern = String.raw`${pattern}`; - const escaped = rawPattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&'); + const escaped = rawPattern.replaceAll(/[.+?^${}()|[\]\\]/g, '\\$&'); // Convert wildcards: // ** -> match any depth // * -> match one segment const regexStr = escaped - .replace(/\*\*/g, '.*')// ** -> .* - .replace(/\*/g, '[^/]*');// * -> any chars except '/' + .replaceAll('**', '.*') // ** -> .* + .replaceAll('*', '[^/]*'); // * -> any chars except '/' // eslint-disable-next-line security/detect-non-literal-regexp return new RegExp(`^${regexStr}$`); From 3d23909591f650ef2ac76f29755cadc48e637743 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Nov 2025 14:07:49 +0000 Subject: [PATCH 12/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/1884.md b/.changeset/1884.md index 36a01d7cbc3..0bed8b76808 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -19,5 +19,6 @@ Refactor read function in HTTP resolver to reduce cognitive complexity from 16 t - 05be198: chore: updated the validation.service.ts - 2bd1f07: fix: address Sonar S7780 by replacing manual escaping with String.raw - b9cf80a: chore: pull the changes +- ba5f736: replaceAll rule in wildcardToRegex function From c3b7224617fb8afd1fb4ac870a7bb58c3f9b23ee Mon Sep 17 00:00:00 2001 From: Sagar Seth Date: Thu, 13 Nov 2025 19:42:33 +0530 Subject: [PATCH 13/17] fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 --- src/domains/services/config.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/domains/services/config.service.ts b/src/domains/services/config.service.ts index b83ed11d68c..dd96b9c5721 100644 --- a/src/domains/services/config.service.ts +++ b/src/domains/services/config.service.ts @@ -95,7 +95,9 @@ export class ConfigService { */ private static wildcardToRegex(pattern: string): RegExp { const rawPattern = String.raw`${pattern}`; - const escaped = rawPattern.replaceAll(/[.+?^${}()|[\]\\]/g, '\\$&'); + // Sonar-safe regex escaping using String.raw + const escapePattern = '[.+?^${}()|[\\]\\\\]'; + const escaped = rawPattern.replaceAll(new RegExp(escapePattern, 'g'), '\\$&'); // Convert wildcards: // ** -> match any depth // * -> match one segment From a6b08cb62e4472a27b57d8e437a886fd433f8e3e Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Nov 2025 14:13:07 +0000 Subject: [PATCH 14/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/1884.md b/.changeset/1884.md index 0bed8b76808..1408a448760 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -20,5 +20,6 @@ Refactor read function in HTTP resolver to reduce cognitive complexity from 16 t - 2bd1f07: fix: address Sonar S7780 by replacing manual escaping with String.raw - b9cf80a: chore: pull the changes - ba5f736: replaceAll rule in wildcardToRegex function +- c3b7224: fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 From 538dea15a138dc6cd09c9e40568472eb003eb2eb Mon Sep 17 00:00:00 2001 From: Sagar Seth Date: Thu, 13 Nov 2025 19:36:54 +0530 Subject: [PATCH 15/17] replaceAll rule in wildcardToRegex function chore: add changeset for PR #1884 fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 --- .changeset/1884.md | 1 + src/domains/services/config.service.ts | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.changeset/1884.md b/.changeset/1884.md index 36a01d7cbc3..0bed8b76808 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -19,5 +19,6 @@ Refactor read function in HTTP resolver to reduce cognitive complexity from 16 t - 05be198: chore: updated the validation.service.ts - 2bd1f07: fix: address Sonar S7780 by replacing manual escaping with String.raw - b9cf80a: chore: pull the changes +- ba5f736: replaceAll rule in wildcardToRegex function diff --git a/src/domains/services/config.service.ts b/src/domains/services/config.service.ts index f357cf004d2..dd96b9c5721 100644 --- a/src/domains/services/config.service.ts +++ b/src/domains/services/config.service.ts @@ -95,13 +95,15 @@ export class ConfigService { */ private static wildcardToRegex(pattern: string): RegExp { const rawPattern = String.raw`${pattern}`; - const escaped = rawPattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&'); + // Sonar-safe regex escaping using String.raw + const escapePattern = '[.+?^${}()|[\\]\\\\]'; + const escaped = rawPattern.replaceAll(new RegExp(escapePattern, 'g'), '\\$&'); // Convert wildcards: // ** -> match any depth // * -> match one segment const regexStr = escaped - .replace(/\*\*/g, '.*')// ** -> .* - .replace(/\*/g, '[^/]*');// * -> any chars except '/' + .replaceAll('**', '.*') // ** -> .* + .replaceAll('*', '[^/]*'); // * -> any chars except '/' // eslint-disable-next-line security/detect-non-literal-regexp return new RegExp(`^${regexStr}$`); From 0fe8c3747770cdf5d6037c624c48b93941ba4c7b Mon Sep 17 00:00:00 2001 From: Sagar Seth Date: Thu, 13 Nov 2025 19:46:34 +0530 Subject: [PATCH 16/17] fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 --- src/domains/services/config.service.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/domains/services/config.service.ts b/src/domains/services/config.service.ts index dd96b9c5721..f8bb88f7ee5 100644 --- a/src/domains/services/config.service.ts +++ b/src/domains/services/config.service.ts @@ -97,7 +97,10 @@ export class ConfigService { const rawPattern = String.raw`${pattern}`; // Sonar-safe regex escaping using String.raw const escapePattern = '[.+?^${}()|[\\]\\\\]'; - const escaped = rawPattern.replaceAll(new RegExp(escapePattern, 'g'), '\\$&'); + const escaped = rawPattern.replaceAll( + new RegExp(escapePattern, 'g'), + String.raw`\$&` + ); // Convert wildcards: // ** -> match any depth // * -> match one segment From 0713671cecd4d828dd0d7b7aea4f180e6dc91c83 Mon Sep 17 00:00:00 2001 From: asyncapi-bot Date: Thu, 13 Nov 2025 14:22:28 +0000 Subject: [PATCH 17/17] chore: add changeset for PR #1884 --- .changeset/1884.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.changeset/1884.md b/.changeset/1884.md index 0bed8b76808..4ab13b8b6a6 100644 --- a/.changeset/1884.md +++ b/.changeset/1884.md @@ -20,5 +20,13 @@ Refactor read function in HTTP resolver to reduce cognitive complexity from 16 t - 2bd1f07: fix: address Sonar S7780 by replacing manual escaping with String.raw - b9cf80a: chore: pull the changes - ba5f736: replaceAll rule in wildcardToRegex function +- c3b7224: fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 +- 538dea1: replaceAll rule in wildcardToRegex function + +chore: add changeset for PR #1884 + +fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 +- 0fe8c37: fix(config): replace unsafe regex literal with safe escapePattern to satisfy Sonar rule S7780 +- b5ee095: chore: pulling from master