MCPcopy Index your code
hub / github.com/TypeStrong/ts-node / createEsmHooks

Function createEsmHooks

src/esm.ts:121–406  ·  view source on GitHub ↗
(tsNodeService: Service)

Source from the content-addressed store, hash-verified

119}
120
121export function createEsmHooks(tsNodeService: Service) {
122 tsNodeService.enableExperimentalEsmLoaderInterop();
123
124 // Custom implementation that considers additional file extensions and automatically adds file extensions
125 const nodeResolveImplementation = tsNodeService.getNodeEsmResolver();
126 const nodeGetFormatImplementation = tsNodeService.getNodeEsmGetFormat();
127 const extensions = tsNodeService.extensions;
128
129 const hooksAPI = filterHooksByAPIVersion({
130 resolve,
131 load,
132 getFormat,
133 transformSource,
134 });
135
136 function isFileUrlOrNodeStyleSpecifier(parsed: UrlWithStringQuery) {
137 // We only understand file:// URLs, but in node, the specifier can be a node-style `./foo` or `foo`
138 const { protocol } = parsed;
139 return protocol === null || protocol === 'file:';
140 }
141
142 /**
143 * Named "probably" as a reminder that this is a guess.
144 * node does not explicitly tell us if we're resolving the entrypoint or not.
145 */
146 function isProbablyEntrypoint(specifier: string, parentURL: string) {
147 return parentURL === undefined && specifier.startsWith('file://');
148 }
149 // Side-channel between `resolve()` and `load()` hooks
150 const rememberIsProbablyEntrypoint = new Set();
151 const rememberResolvedViaCommonjsFallback = new Set();
152
153 async function resolve(
154 specifier: string,
155 context: { parentURL: string },
156 defaultResolve: typeof resolve
157 ): Promise<{ url: string; format?: NodeLoaderHooksFormat }> {
158 const defer = async () => {
159 const r = await defaultResolve(specifier, context, defaultResolve);
160 return r;
161 };
162 // See: https://github.com/nodejs/node/discussions/41711
163 // nodejs will likely implement a similar fallback. Till then, we can do our users a favor and fallback today.
164 async function entrypointFallback(
165 cb: () => ReturnType<typeof resolve> | Awaited<ReturnType<typeof resolve>>
166 ): ReturnType<typeof resolve> {
167 try {
168 const resolution = await cb();
169 if (
170 resolution?.url &&
171 isProbablyEntrypoint(specifier, context.parentURL)
172 )
173 rememberIsProbablyEntrypoint.add(resolution.url);
174 return resolution;
175 } catch (esmResolverError) {
176 if (!isProbablyEntrypoint(specifier, context.parentURL))
177 throw esmResolverError;
178 try {

Callers 2

loader.mjsFile · 0.50

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…