Skip to content

Commit

Permalink
add function to extract ADO information from URL
Browse files Browse the repository at this point in the history
  • Loading branch information
jonchurch committed Apr 22, 2024
1 parent c21746e commit a5185a7
Showing 1 changed file with 65 additions and 15 deletions.
80 changes: 65 additions & 15 deletions packages/ado-npm-auth/src/utils/get-organization-from-feed-url.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
/**
* Extracts the organization and project details from a given Azure DevOps URL.
* The function differentiates between the "new style" URLs that use 'dev.azure.com'
* and "old style" URLs that use a subdomain of 'visualstudio.com'.
*
* @param {string} url - The Azure DevOps URL from which to extract details.
* @returns {Object} An object containing the `organization` and `project` extracted from the URL.
* @throws {Error} Throws an error if the URL is invalid, not in the expected format,
* or does not contain the necessary information for extraction.
*
* @example
* // New style URL
* extractAdoDetails("https://dev.azure.com/contoso/WebsiteRedesign");
* // returns { organization: "contoso", project: "WebsiteRedesign" }
*
* // Old style URL
* extractAdoDetails("https://contoso.visualstudio.com/WebsiteRedesign");
* // returns { organization: "contoso", project: "WebsiteRedesign" }
*
* // Invalid URL
* extractAdoDetails("https://invalid.url.com");
* // throws Error
*/
const extractAdoDetails = (url: string) => {
try {
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname;
const pathname = parsedUrl.pathname;

// Check for new style URLs (dev.azure.com)
if (hostname.endsWith("dev.azure.com")) {
const pathSegments = pathname.split('/').filter(Boolean); // Remove empty strings from the split result
if (pathSegments.length >= 2) {
return {
organization: pathSegments[0],
project: pathSegments[1]
};
} else {
throw new Error("Not enough segments in path for a valid organization and project extraction.");
}
}

// Check for old style URLs (visualstudio.com)
if (hostname.endsWith("visualstudio.com")) {
const subdomain = hostname.split('.')[0];
const pathSegments = pathname.split('/').filter(Boolean);
if (subdomain && pathSegments.length >= 1) {
return {
organization: subdomain,
project: pathSegments[0]
};
} else {
throw new Error("Not enough segments in path or missing subdomain for a valid organization and project extraction.");
}
}

// If the URL does not match expected formats
throw new Error("URL format not recognized or does not contain enough information.");
} catch (error) {
throw new Error("Invalid URL or unsupported format");
}
};

/**
* Get the ADO Org for a npm feed
* @param {string} feedUrl URL of the feed to get the ADO organization from
Expand All @@ -6,21 +69,8 @@
*/
export const getOrganizationFromFeedUrl = (feedUrl: string, defaultOrg = "") => {
try {
const url = new URL(feedUrl);
const packagingIndex = url.pathname.indexOf("/_packaging");

if (packagingIndex > 0) {
// sometimes org is included in the path as the first item in the path
// after the initial "/"
// ex. "https://pkgs.dev.azure.com/foo/bar/_packaging/baz/npm/registry/" -> "foo"
// these are project-scoped feeds
return url.pathname.split("/")[1];
}

// otherwise feed is the first item in the host
// ex. "https://foo.pkgs.visualstudio.com/_packaging/npm-mirror/npm/registry" -> "foo"
// these are org-wide feeds
return url.host.split(".")[0];
const { organization } = extractAdoDetails(feedUrl)
return organization
} catch (error) {
return defaultOrg;
}
Expand Down

0 comments on commit a5185a7

Please sign in to comment.