Skip to content

Commit 8c36b09

Browse files
committed
feat: Added typescript-transform-paths/register script
1 parent 7313ad8 commit 8c36b09

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

register.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let tsNode;
2+
try {
3+
tsNode = require('ts-node');
4+
} catch {}
5+
6+
if (!tsNode) throw new Error(`Cannot register transformer without ts-node.`);
7+
8+
tsNode.register();
9+
require('./').register();

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
import transformer from "./transformer";
22
export default transformer;
3+
4+
export { TsTransformPathsConfig } from "./types";
5+
export { register } from "./register";

src/register.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import type TSNode from "ts-node";
2+
import type { REGISTER_INSTANCE } from "ts-node";
3+
import ts from "typescript";
4+
import transformer from "./transformer";
5+
6+
/* ****************************************************************************************************************** */
7+
// region: Helpers
8+
/* ****************************************************************************************************************** */
9+
10+
function getProjectTransformerConfig(pcl: ts.ParsedCommandLine) {
11+
const plugins = pcl.options.plugins as Record<string, string>[] | undefined;
12+
if (!plugins) return;
13+
14+
const res: { afterDeclarations?: Record<string, string>; before?: Record<string, string> } = {};
15+
for (const plugin of plugins) {
16+
if (plugin.transform === "typescript-transform-paths" && !plugin.after)
17+
res[plugin.afterDeclarations ? "afterDeclarations" : "before"] = plugin;
18+
}
19+
20+
return res;
21+
}
22+
23+
function getTransformers(
24+
program?: ts.Program,
25+
beforeConfig?: Record<string, string>,
26+
afterDeclarationsConfig?: Record<string, string>
27+
): ts.CustomTransformers {
28+
return {
29+
...(beforeConfig && { before: [transformer(program, beforeConfig)] }),
30+
...(afterDeclarationsConfig && { afterDeclarations: [transformer(program, afterDeclarationsConfig)] }),
31+
} as ts.CustomTransformers;
32+
}
33+
34+
export function mergeTransformers(
35+
baseTransformers: ts.CustomTransformers,
36+
transformers: ts.CustomTransformers
37+
): ts.CustomTransformers {
38+
const res = {
39+
...((baseTransformers.before || transformers.before) && {
40+
before: [...(transformers.before ?? []), ...(baseTransformers.before ?? [])],
41+
}),
42+
...((baseTransformers.afterDeclarations || transformers.afterDeclarations) && {
43+
afterDeclarations: [...(transformers.afterDeclarations ?? []), ...(baseTransformers.afterDeclarations ?? [])],
44+
}),
45+
};
46+
47+
const remainingBaseTransformers = { ...baseTransformers };
48+
delete remainingBaseTransformers.before;
49+
delete remainingBaseTransformers.afterDeclarations;
50+
51+
return Object.assign(res, remainingBaseTransformers);
52+
}
53+
54+
// endregion
55+
56+
/* ****************************************************************************************************************** */
57+
// region: TsNode Registration Utility
58+
/* ****************************************************************************************************************** */
59+
60+
export function register(): TSNode.RegisterOptions | undefined {
61+
const { tsNodeInstance, tsNode } = register.initialize();
62+
63+
const transformerConfig = getProjectTransformerConfig(tsNodeInstance.config);
64+
if (!transformerConfig) return;
65+
66+
const { before: beforeConfig, afterDeclarations: afterDeclarationsConfig } = transformerConfig;
67+
68+
const registerOptions: TSNode.RegisterOptions = Object.assign({}, tsNodeInstance.options);
69+
if (registerOptions.transformers) {
70+
if (typeof registerOptions.transformers === "function") {
71+
let oldTransformersFactory = registerOptions.transformers;
72+
registerOptions.transformers = (program) => {
73+
const transformers = getTransformers(program, beforeConfig, afterDeclarationsConfig);
74+
const baseTransformers = oldTransformersFactory(program);
75+
return mergeTransformers(baseTransformers, transformers);
76+
};
77+
} else {
78+
registerOptions.transformers = mergeTransformers(
79+
registerOptions.transformers,
80+
getTransformers(undefined, beforeConfig, afterDeclarationsConfig)
81+
);
82+
}
83+
} else {
84+
registerOptions.transformers = getTransformers(undefined, beforeConfig, afterDeclarationsConfig);
85+
}
86+
87+
// Re-register with new transformers
88+
tsNode.register(registerOptions);
89+
return registerOptions;
90+
}
91+
92+
export namespace register {
93+
export function initialize(): {
94+
tsNode: typeof TSNode;
95+
instanceSymbol: typeof REGISTER_INSTANCE;
96+
tsNodeInstance: TSNode.Service;
97+
} {
98+
let tsNode: typeof TSNode;
99+
try {
100+
tsNode = require("ts-node");
101+
} catch {
102+
throw new Error(
103+
`Cannot resolve ts-node. Make sure ts-node is installed before using typescript-transform-paths/register`
104+
);
105+
}
106+
107+
const instanceSymbol: typeof REGISTER_INSTANCE = tsNode["REGISTER_INSTANCE"];
108+
109+
let tsNodeInstance = global.process[instanceSymbol];
110+
if (!tsNodeInstance) {
111+
tsNode.register(); // Register initially
112+
tsNodeInstance = global.process[instanceSymbol];
113+
}
114+
if (!tsNodeInstance) throw new Error(`Could not register ts-node instance!`);
115+
116+
return { tsNode, instanceSymbol, tsNodeInstance };
117+
}
118+
}
119+
120+
export default register;
121+
122+
// endregion

0 commit comments

Comments
 (0)