Skip to content

Commit

Permalink
fix: makes an effort to also match teh ts config base URL
Browse files Browse the repository at this point in the history
  • Loading branch information
sverweij committed Dec 3, 2023
1 parent d960347 commit 9255feb
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 21 deletions.
93 changes: 73 additions & 20 deletions src/extract/resolve/module-classifiers.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isAbsolute, resolve as path_resolve } from "node:path";
/* eslint-disable max-lines */
import { isAbsolute, join, resolve as path_resolve, relative } from "node:path";
import { isMatch } from "picomatch";
import getExtension from "#utl/get-extension.mjs";

Expand Down Expand Up @@ -131,7 +132,6 @@ function isWebPackAliased(pModuleName, pAliasObject) {
*/
// eslint-disable-next-line max-lines-per-function
function isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest) {
// console.error(...arguments);
// reference: https://docs.npmjs.com/cli/v10/using-npm/workspaces
if (pManifest?.workspaces) {
// workspaces are an array of globs that match the (sub) workspace
Expand Down Expand Up @@ -184,27 +184,85 @@ function isWorkspaceAliased(pModuleName, pResolvedModuleName, pManifest) {
}

/**
*
* @param {string} pModuleName
* @param {Record<string, string[]>} pPaths
* @returns
*/

function matchesATSConfigPath(pModuleName, pPaths) {
// "paths patterns can contain a single * wildcard, which matches any string.
// The * token can then be used in the file path values to substitute the
// matched string."
// https://www.typescriptlang.org/docs/handbook/modules/reference.html#wildcard-substitutions
//
// So, just like with subpath imports, the LHS of a path pattern is not a glob
// and the '*' functions as a string replacement only.
//
// TODO: 'any string' - does this include the empty string as well?
return Object.keys(pPaths).some((pPathLHS) => {
// eslint-disable-next-line security/detect-non-literal-regexp
const lMatchRE = new RegExp(`^${pPathLHS.replace(/\*/g, ".+")}$`);
return Boolean(pModuleName.match(lMatchRE));
});
}

function stripExtension(pModulePath) {
const lExtension = getExtension(pModulePath);
return lExtension ? pModulePath.slice(0, -lExtension.length) : pModulePath;
}

/**
*
* https://www.typescriptlang.org/docs/handbook/modules/reference.html#baseurl
*
* @param {string} pModuleName
* @param {string} pResolvedModuleName
* @param {any} pTSConfigExpanded
* @param {string} pBaseDirectory
* @returns {boolean}
* @param {string} pTSConfigBaseURL
*/
function isLikelyTSAliased(
function matchesTSConfigBaseURL(
pModuleName,
pResolvedModuleName,
pTSConfigExpanded,
pBaseDirectory,
pTSConfigBaseURL,
) {
return (
(pTSConfigExpanded?.options?.baseUrl ||
Object.keys(pTSConfigExpanded?.options?.paths ?? {}).length > 0) &&
!isRelativeModuleName(pModuleName) &&
pResolvedModuleName &&
!isExternalModule(pResolvedModuleName, ["node_modules"], pBaseDirectory)
if (!pTSConfigBaseURL) {
return false;
}
// "If baseUrl is set, TypeScript will resolve non-relative module names
// relative to the baseUrl."
// https://www.typescriptlang.org/docs/handbook/modules.html#base-url
// console.error(
// ...arguments,
// stripExtension(join(pTSConfigBaseURL, pModuleName)),
// stripExtension(pResolvedModuleName)
// );
return stripExtension(join(pTSConfigBaseURL, pModuleName)).endsWith(
stripExtension(pResolvedModuleName),
);
}

/**
* @param {string} pModuleName
* @param {string} pResolvedModuleName
* @param {any} pTSConfigExpanded
* @param {string} pBaseDirectory
* @returns {boolean}
*/
function isTSAliased(pModuleName, pResolvedModuleName, pTSConfigExpanded) {
// we should probably test whether the module name is relative here as well,
// but because we test that before we call this function we can skip that
const lMatchesBaseUrl = matchesTSConfigBaseURL(
pModuleName,
pResolvedModuleName,
pTSConfigExpanded?.options?.baseUrl,
);
const lMatchesPaths = matchesATSConfigPath(
pModuleName,
pTSConfigExpanded?.options?.paths ?? {},
);
return lMatchesBaseUrl || lMatchesPaths;
}

/**
* @param {string} pModuleName
* @param {string} pResolvedModuleName
Expand All @@ -229,12 +287,7 @@ export function getAliasTypes(
return ["aliased", "aliased-webpack"];
}
if (
isLikelyTSAliased(
pModuleName,
pResolvedModuleName,
pTranspileOptions?.tsConfig,
pResolveOptions.baseDirectory,
)
isTSAliased(pModuleName, pResolvedModuleName, pTranspileOptions?.tsConfig)
) {
return ["aliased", "aliased-tsconfig"];
}
Expand Down
2 changes: 1 addition & 1 deletion src/utl/get-extension.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const EXTENSION_RE = /(?<extension>((\.d\.(c|m)?ts)|\.coffee\.md)$)/;
* @param {string} pFileName path to the file to be parsed
* @return {string} extension
*/
export default function getExtensions(pFileName) {
export default function getExtension(pFileName) {
const lMatchResult = pFileName.match(EXTENSION_RE);

return lMatchResult?.groups?.extension ?? extname(pFileName);
Expand Down

0 comments on commit 9255feb

Please sign in to comment.