From 12c6124147d22620be04e7d45982ab475992453a Mon Sep 17 00:00:00 2001 From: Monil Patel Date: Tue, 21 Nov 2023 12:03:01 -0800 Subject: [PATCH] fix build + fix ssh bug with spaces --- dist/index.js | 90 ++++++++++++++++---------------- dist/index.mjs | 90 ++++++++++++++++---------------- package.json | 12 +++-- src/index.js | 83 +++++++++++++++--------------- test/index.mjs | 137 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 277 insertions(+), 135 deletions(-) diff --git a/dist/index.js b/dist/index.js index 111a11a..eec5fe1 100755 --- a/dist/index.js +++ b/dist/index.js @@ -286,53 +286,55 @@ function normalizeUrl(urlString, options) { * - `parse_failed` (Boolean): Whether the parsing failed or not. */ const parseUrl = (url, normalize = false) => { - - // Constants - const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/; - - const throwErr = msg => { - const err = new Error(msg); - err.subject_url = url; - throw err - }; - - if (typeof url !== "string" || !url.trim()) { - throwErr("Invalid url."); - } - - if (url.length > parseUrl.MAX_INPUT_LENGTH) { - throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH."); - } - - if (normalize) { - if (typeof normalize !== "object") { - normalize = { - stripHash: false - }; - } - url = normalizeUrl(url, normalize); + // Constants + // const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/ + const GIT_RE = + /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:](([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/; + const throwErr = (msg) => { + const err = new Error(msg); + err.subject_url = url; + throw err; + }; + + if (typeof url !== "string" || !url.trim()) { + throwErr("Invalid url."); + } + + if (url.length > parseUrl.MAX_INPUT_LENGTH) { + throwErr( + "Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH." + ); + } + + if (normalize) { + if (typeof normalize !== "object") { + normalize = { + stripHash: false, + }; } - - const parsed = parsePath__default["default"](url); - - // Potential git-ssh urls - if (parsed.parse_failed) { - const matched = parsed.href.match(GIT_RE); - - if (matched) { - parsed.protocols = ["ssh"]; - parsed.protocol = "ssh"; - parsed.resource = matched[2]; - parsed.host = matched[2]; - parsed.user = matched[1]; - parsed.pathname = `/${matched[3]}`; - parsed.parse_failed = false; - } else { - throwErr("URL parsing failed."); - } + url = normalizeUrl(url, normalize); + } + + const parsed = parsePath__default["default"](url); + + // Potential git-ssh urls + if (parsed.parse_failed) { + const matched = parsed.href.match(GIT_RE); + + if (matched) { + parsed.protocols = ["ssh"]; + parsed.protocol = "ssh"; + parsed.resource = matched[2]; + parsed.host = matched[2]; + parsed.user = matched[1]; + parsed.pathname = `/${matched[3]}`; + parsed.parse_failed = false; + } else { + throwErr("URL parsing failed."); } + } - return parsed; + return parsed; }; parseUrl.MAX_INPUT_LENGTH = 2048; diff --git a/dist/index.mjs b/dist/index.mjs index 4fd7be5..ea62183 100755 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -280,53 +280,55 @@ function normalizeUrl(urlString, options) { * - `parse_failed` (Boolean): Whether the parsing failed or not. */ const parseUrl = (url, normalize = false) => { - - // Constants - const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/; - - const throwErr = msg => { - const err = new Error(msg); - err.subject_url = url; - throw err - }; - - if (typeof url !== "string" || !url.trim()) { - throwErr("Invalid url."); - } - - if (url.length > parseUrl.MAX_INPUT_LENGTH) { - throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH."); - } - - if (normalize) { - if (typeof normalize !== "object") { - normalize = { - stripHash: false - }; - } - url = normalizeUrl(url, normalize); + // Constants + // const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/ + const GIT_RE = + /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:](([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/; + const throwErr = (msg) => { + const err = new Error(msg); + err.subject_url = url; + throw err; + }; + + if (typeof url !== "string" || !url.trim()) { + throwErr("Invalid url."); + } + + if (url.length > parseUrl.MAX_INPUT_LENGTH) { + throwErr( + "Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH." + ); + } + + if (normalize) { + if (typeof normalize !== "object") { + normalize = { + stripHash: false, + }; } - - const parsed = parsePath(url); - - // Potential git-ssh urls - if (parsed.parse_failed) { - const matched = parsed.href.match(GIT_RE); - - if (matched) { - parsed.protocols = ["ssh"]; - parsed.protocol = "ssh"; - parsed.resource = matched[2]; - parsed.host = matched[2]; - parsed.user = matched[1]; - parsed.pathname = `/${matched[3]}`; - parsed.parse_failed = false; - } else { - throwErr("URL parsing failed."); - } + url = normalizeUrl(url, normalize); + } + + const parsed = parsePath(url); + + // Potential git-ssh urls + if (parsed.parse_failed) { + const matched = parsed.href.match(GIT_RE); + + if (matched) { + parsed.protocols = ["ssh"]; + parsed.protocol = "ssh"; + parsed.resource = matched[2]; + parsed.host = matched[2]; + parsed.user = matched[1]; + parsed.pathname = `/${matched[3]}`; + parsed.parse_failed = false; + } else { + throwErr("URL parsing failed."); } + } - return parsed; + return parsed; }; parseUrl.MAX_INPUT_LENGTH = 2048; diff --git a/package.json b/package.json index 9418eb4..3d6579c 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,14 @@ "module": "./dist/index.mjs", "types": "./index.d.ts", "exports": { - "types": { - "require": "./index.d.ts", - "import": "./index.d.mts" + "require": { + "types": "./index.d.ts", + "default": "./dist/index.js" }, - "require": "./dist/index.js", - "import": "./dist/index.mjs" + "import": { + "types": "./index.d.mts", + "default": "./dist/index.mjs" + } }, "directories": { "example": "example", diff --git a/src/index.js b/src/index.js index b165cc7..ab2a2ce 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ // Dependencies -import parsePath from "parse-path"; + import normalizeUrl from "normalize-url"; +import parsePath from "parse-path"; /** * parseUrl @@ -33,54 +34,56 @@ import normalizeUrl from "normalize-url"; * - `parse_failed` (Boolean): Whether the parsing failed or not. */ const parseUrl = (url, normalize = false) => { + // Constants + // const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/ + const GIT_RE = + /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:](([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/; + const throwErr = (msg) => { + const err = new Error(msg); + err.subject_url = url; + throw err; + }; - // Constants - const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/ - - const throwErr = msg => { - const err = new Error(msg) - err.subject_url = url - throw err - } - - if (typeof url !== "string" || !url.trim()) { - throwErr("Invalid url.") - } + if (typeof url !== "string" || !url.trim()) { + throwErr("Invalid url."); + } - if (url.length > parseUrl.MAX_INPUT_LENGTH) { - throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.") - } + if (url.length > parseUrl.MAX_INPUT_LENGTH) { + throwErr( + "Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH." + ); + } - if (normalize) { - if (typeof normalize !== "object") { - normalize = { - stripHash: false - } - } - url = normalizeUrl(url, normalize) + if (normalize) { + if (typeof normalize !== "object") { + normalize = { + stripHash: false, + }; } + url = normalizeUrl(url, normalize); + } - const parsed = parsePath(url) + const parsed = parsePath(url); - // Potential git-ssh urls - if (parsed.parse_failed) { - const matched = parsed.href.match(GIT_RE) + // Potential git-ssh urls + if (parsed.parse_failed) { + const matched = parsed.href.match(GIT_RE); - if (matched) { - parsed.protocols = ["ssh"] - parsed.protocol = "ssh" - parsed.resource = matched[2] - parsed.host = matched[2] - parsed.user = matched[1] - parsed.pathname = `/${matched[3]}` - parsed.parse_failed = false - } else { - throwErr("URL parsing failed.") - } + if (matched) { + parsed.protocols = ["ssh"]; + parsed.protocol = "ssh"; + parsed.resource = matched[2]; + parsed.host = matched[2]; + parsed.user = matched[1]; + parsed.pathname = `/${matched[3]}` + parsed.parse_failed = false; + } else { + throwErr("URL parsing failed."); } + } - return parsed; -} + return parsed; +}; parseUrl.MAX_INPUT_LENGTH = 2048 diff --git a/test/index.mjs b/test/index.mjs index 90b04b0..8ac2da1 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -1,7 +1,8 @@ // Dependencies + +import normalizeUrl from "normalize-url"; import parseUrl from "../dist/index.js"; import tester from "tester"; -import normalizeUrl from "normalize-url"; const INPUTS = [ [ @@ -165,9 +166,141 @@ const INPUTS = [ , query: {} , parse_failed: false } - ] + ], + [ + [ + "git@ssh.dev.azure.com:v3/ORG/My-Project/repo", + false, + ], + { + protocols: ["ssh"], + protocol: "ssh", + port: "", + resource: "ssh.dev.azure.com", + host: "ssh.dev.azure.com", + user: "git", + password: "", + pathname: "/v3/ORG/My-Project/repo", + hash: "", + search: "", + query: {}, + parse_failed: false, + }, + ], + [ + [ + "git@ssh.dev.azure.com:v3/ORG/My%20Project/repo", + false, + ], + { + protocols: ["ssh"], + protocol: "ssh", + port: "", + resource: "ssh.dev.azure.com", + host: "ssh.dev.azure.com", + user: "git", + password: "", + pathname: "/v3/ORG/My%20Project/repo", + hash: "", + search: "", + query: {}, + parse_failed: false, + }, + ], + [ + [ + "git@ssh.dev.azure.com:v3/ORG/My Project/repo", + false, + ], + { + protocols: ["ssh"], + protocol: "ssh", + port: "", + resource: "ssh.dev.azure.com", + host: "ssh.dev.azure.com", + user: "git", + password: "", + pathname: "/v3/ORG/My Project/repo", + hash: "", + search: "", + query: {}, + parse_failed: false, + }, + ], + [ + [ + "git@ssh.dev.azure.com:v3/ORG/My-Project/repo", + false, + ], + { + protocols: ["ssh"], + protocol: "ssh", + port: "", + resource: "ssh.dev.azure.com", + host: "ssh.dev.azure.com", + user: "git", + password: "", + pathname: "/v3/ORG/My-Project/repo", + hash: "", + search: "", + query: {}, + parse_failed: false, + }, + ], + [ + [ + "https://ORG@dev.azure.com/ORG/My%20Project/_git/repo", + false, + ], + { + protocols: ["https"], + protocol: "https", + port: "", + resource: "dev.azure.com", + host: "dev.azure.com", + user: "ORG", + password: "", + pathname: "/ORG/My%20Project/_git/repo", + hash: "", + search: "", + query: {}, + parse_failed: false, + }, + ], + [ + [ + "https://ORG@dev.azure.com/ORG/My-Project/_git/repo", + false, + ], + { + protocols: ["https"], + protocol: "https", + port: "", + resource: "dev.azure.com", + host: "dev.azure.com", + user: "ORG", + password: "", + pathname: "/ORG/My-Project/_git/repo", + hash: "", + search: "", + query: {}, + parse_failed: false, + }, + ], ]; + + + + +// test('SSH URL with URL-encoded spaces', 'git@ssh.dev.azure.com:v3/ORG/My%20project/repo'); +// test('SSH URL with non URL-encoded spaces', 'git@ssh.dev.azure.com:v3/ORG/My project/repo'); +// test('SSH URL without spaces', 'git@ssh.dev.azure.com:v3/ORG/My-project/repo'); +// test('HTTPS URL with URL-encoded spaces', 'https://ORG@dev.azure.com/ORG/My%20project/_git/repo'); +// test('HTTPS URL with non URL-encoded spaces', 'https://ORG@dev.azure.com/ORG/My project/_git/repo'); +// test('HTTPS URL without spaces', 'https://ORG@dev.azure.com/ORG/My-project/_git/repo'); + + tester.describe("check urls", test => { INPUTS.forEach(function (c) { let url = Array.isArray(c[0]) ? c[0][0] : c[0]