Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tsconfig.json "paths" prototype #1515

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -100,7 +100,7 @@
"semver": "^7.1.3",
"tslint": "^6.1.0",
"tslint-config-standard": "^9.0.0",
"typescript": "3.8.3",
"typescript": "3.9.7",
"typescript-json-schema": "^0.42.0",
"util.promisify": "^1.0.1"
},
Expand All @@ -112,6 +112,7 @@
"diff": "^4.0.1",
"make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"tsconfig-paths": "^3.9.0",
"yn": "3.1.1"
}
}
4 changes: 4 additions & 0 deletions src/index.ts
Expand Up @@ -4,6 +4,7 @@ import * as ynModule from 'yn'
import { BaseError } from 'make-error'
import * as util from 'util'
import * as _ts from 'typescript'
import { debugIt } from './resolver'

/**
* Does this version of node obey the package.json "type" field
Expand Down Expand Up @@ -382,6 +383,9 @@ export function register (opts: RegisterOptions = {}): Register {
// Register the extensions.
registerExtensions(service.options.preferTsExts, extensions, service, originalJsHandler)

console.dir(service.config, {depth: 10})
debugIt(service.config)

return service
}

Expand Down
98 changes: 98 additions & 0 deletions src/resolver.ts
@@ -0,0 +1,98 @@
import type * as _ts from 'typescript';
import {getAbsoluteMappingEntries, MappingEntry} from 'tsconfig-paths/lib/mapping-entry';
import {builtinModules as builtinModulesArray} from 'module';

const builtinModules = new Set(builtinModulesArray);

export function debugIt(config: _ts.ParsedCommandLine) {
if(config.options.baseUrl != null) {
const mappingEntries = getAbsoluteMappingEntries(config.options.baseUrl!, config.options.paths ?? {}, true);
console.dir(mappingEntries);
console.dir(getPathsToTry(mappingEntries, 'okeydokey'));
}
}

export function getPathsToTry(
absolutePathMappings: ReadonlyArray<MappingEntry>,
requestedModule: string
): ReadonlyArray<string> | undefined {
if (
!absolutePathMappings ||
!requestedModule ||
requestedModule[0] === "."
) {
return undefined;
}

const candidates: Array<string> = [];
for (const entry of absolutePathMappings) {
const starMatch =
entry.pattern === requestedModule
? ""
: matchStar(entry.pattern, requestedModule);
if (starMatch !== undefined) {
for (const physicalPathPattern of entry.paths) {
const physicalPath = physicalPathPattern.replace("*", starMatch);
candidates.push(physicalPath);
}
}
}
return candidates;
}

/**
* Matches pattern with a single star against search.
* Star must match at least one character to be considered a match.
* @param pattern for example "foo*"
* @param search for example "fooawesomebar"
* @returns the part of search that * matches, or undefined if no match.
*/
function matchStar(pattern: string, search: string): string | undefined {
if (search.length < pattern.length) {
return undefined;
}
if (pattern === "*") {
return search;
}
const star = pattern.indexOf("*");
if (star === -1) {
return undefined;
}
const part1 = pattern.substring(0, star);
const part2 = pattern.substring(star + 1);
if (search.substr(0, star) !== part1) {
return undefined;
}
if (search.substr(search.length - part2.length) !== part2) {
return undefined;
}
return search.substr(star, search.length - part2.length);
}

// function createMappings(config: _ts.ParsedCommandLine): ResolverCandidates {
// const ret: ResolverCandidates = {};

// if(config.options.baseUrl != null) {
// ret.pathsAbs = Object.create(null);
// ret.baseUrlAbs = config.options.baseUrl;
// if(config.options.paths) {
// for(const [pattern, candidates] of Object.entries(config.options.paths)) {
// ret.pathsAbs![pattern] = candidates.map(candidate => joinPath(config.options.baseUrl!, candidate));
// }
// }
// }

// config.options.rootDirs = config.options.rootDirs?.slice();

// return ret;
// }

// function joinPath(a: string, b: string) {
// return require('path').join(a, b).replace('\\', '/');
// }

// interface ResolverCandidates {
// baseUrlAbs?: string;
// rootDirsAbs?: string[];
// pathsAbs?: Record<string, Array<string>>;
// }
12 changes: 11 additions & 1 deletion tsconfig.json
Expand Up @@ -12,7 +12,17 @@
"sourceMap": true,
"inlineSources": true,
"types": ["node", "mocha"],
"stripInternal": true
"stripInternal": true,
"baseUrl": "src",
"paths": {
// "*": ["generated/*", "bundled/*"],
"/what-*": ["generated/*", "bundled/*"],
"/*-what": ["generated/*", "bundled/*"]
},
"rootDirs": [
"src",
"generated/src"
]
},
"include": [
"src/**/*"
Expand Down