Skip to content

Commit

Permalink
feat(typescript): export replaceTscContent for downstream usage (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
so1ve authored Aug 17, 2024
1 parent 1ef4bba commit 9b7d91e
Showing 1 changed file with 57 additions and 37 deletions.
94 changes: 57 additions & 37 deletions packages/typescript/lib/quickstart/runTsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export function runTsc(
},
_getLanguagePlugins: typeof getLanguagePlugins
) {

getLanguagePlugins = _getLanguagePlugins;

const proxyApiPath = require.resolve('../node/proxyCreateProgram');
Expand All @@ -35,43 +34,8 @@ export function runTsc(
extraSupportedExtensions = options.extraSupportedExtensions;
extraExtensionsToRemove = options.extraExtensionsToRemove;
}
const needPatchExtenstions = extraSupportedExtensions.filter(ext => !extraExtensionsToRemove.includes(ext));

// Add allow extensions
if (extraSupportedExtensions.length) {
const extsText = extraSupportedExtensions.map(ext => `"${ext}"`).join(', ');
tsc = replace(tsc, /supportedTSExtensions = .*(?=;)/, s => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`);
tsc = replace(tsc, /supportedJSExtensions = .*(?=;)/, s => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`);
tsc = replace(tsc, /allSupportedExtensions = .*(?=;)/, s => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`);
}
// Use to emit basename.xxx to basename.d.ts instead of basename.xxx.d.ts
if (extraExtensionsToRemove.length) {
const extsText = extraExtensionsToRemove.map(ext => `"${ext}"`).join(', ');
tsc = replace(tsc, /extensionsToRemove = .*(?=;)/, s => s + `.concat([${extsText}])`);
}
// Support for basename.xxx to basename.xxx.d.ts
if (needPatchExtenstions.length) {
const extsText = needPatchExtenstions.map(ext => `"${ext}"`).join(', ');
tsc = replace(tsc, /function changeExtension\(/, s => `function changeExtension(path, newExtension) {
return [${extsText}].some(ext => path.endsWith(ext))
? path + newExtension
: _changeExtension(path, newExtension)
}\n` + s.replace('changeExtension', '_changeExtension'));
}

// proxy createProgram
tsc = replace(tsc, /function createProgram\(.+\) {/, s =>
`var createProgram = require(${JSON.stringify(proxyApiPath)}).proxyCreateProgram(`
+ [
`new Proxy({}, { get(_target, p, _receiver) { return eval(p); } } )`,
`_createProgram`,
`require(${JSON.stringify(__filename)}).getLanguagePlugins`,
].join(', ')
+ `);\n`
+ s.replace('createProgram', '_createProgram')
);

return tsc;
return transformTscContent(tsc, proxyApiPath, extraSupportedExtensions, extraExtensionsToRemove);
}
return (readFileSync as any)(...args);
};
Expand All @@ -84,6 +48,62 @@ export function runTsc(
}
}

/**
* Replaces the code of typescript to add support for additional extensions and language plugins.
*
* @param tsc - The original code of typescript.
* @param proxyApiPath - The path to the proxy API.
* @param extraSupportedExtensions - An array of additional supported extensions.
* @param extraExtensionsToRemove - An array of extensions to remove.
* @param getLanguagePluginsFile - The file to get language plugins from.
* @returns The modified typescript code.
*/
export function transformTscContent(
tsc: string,
proxyApiPath: string,
extraSupportedExtensions: string[],
extraExtensionsToRemove: string[],
getLanguagePluginsFile = __filename
) {
const neededPatchExtenstions = extraSupportedExtensions.filter(ext => !extraExtensionsToRemove.includes(ext));

// Add allow extensions
if (extraSupportedExtensions.length) {
const extsText = extraSupportedExtensions.map(ext => `"${ext}"`).join(', ');
tsc = replace(tsc, /supportedTSExtensions = .*(?=;)/, s => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`);
tsc = replace(tsc, /supportedJSExtensions = .*(?=;)/, s => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`);
tsc = replace(tsc, /allSupportedExtensions = .*(?=;)/, s => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`);
}
// Use to emit basename.xxx to basename.d.ts instead of basename.xxx.d.ts
if (extraExtensionsToRemove.length) {
const extsText = extraExtensionsToRemove.map(ext => `"${ext}"`).join(', ');
tsc = replace(tsc, /extensionsToRemove = .*(?=;)/, s => s + `.concat([${extsText}])`);
}
// Support for basename.xxx to basename.xxx.d.ts
if (neededPatchExtenstions.length) {
const extsText = neededPatchExtenstions.map(ext => `"${ext}"`).join(', ');
tsc = replace(tsc, /function changeExtension\(/, s => `function changeExtension(path, newExtension) {
return [${extsText}].some(ext => path.endsWith(ext))
? path + newExtension
: _changeExtension(path, newExtension)
}\n` + s.replace('changeExtension', '_changeExtension'));
}

// proxy createProgram
tsc = replace(tsc, /function createProgram\(.+\) {/, s =>
`var createProgram = require(${JSON.stringify(proxyApiPath)}).proxyCreateProgram(`
+ [
`new Proxy({}, { get(_target, p, _receiver) { return eval(p); } } )`,
`_createProgram`,
`require(${JSON.stringify(getLanguagePluginsFile)}).getLanguagePlugins`,
].join(', ')
+ `);\n`
+ s.replace('createProgram', '_createProgram')
);

return tsc;
}

function replace(text: string, ...[search, replace]: Parameters<String['replace']>) {
const before = text;
text = text.replace(search, replace);
Expand Down

0 comments on commit 9b7d91e

Please sign in to comment.