summaryrefslogtreecommitdiff
path: root/node_modules/sucrase/ts-node-plugin/index.js
diff options
context:
space:
mode:
authorPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:54:57 +0100
committerPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:57:48 +0100
commitb1e2c8fd5cb5dfa46bc440a12eafaf56cd844b1c (patch)
tree49d360fd6cbc6a2754efe93524ac47ff0fbe0f7d /node_modules/sucrase/ts-node-plugin/index.js
Docs
Diffstat (limited to 'node_modules/sucrase/ts-node-plugin/index.js')
-rw-r--r--node_modules/sucrase/ts-node-plugin/index.js83
1 files changed, 83 insertions, 0 deletions
diff --git a/node_modules/sucrase/ts-node-plugin/index.js b/node_modules/sucrase/ts-node-plugin/index.js
new file mode 100644
index 0000000..b523fb3
--- /dev/null
+++ b/node_modules/sucrase/ts-node-plugin/index.js
@@ -0,0 +1,83 @@
+const {transform} = require("../dist");
+
+// Enum constants taken from the TypeScript codebase.
+const ModuleKindCommonJS = 1;
+
+const JsxEmitReactJSX = 4;
+const JsxEmitReactJSXDev = 5;
+
+/**
+ * ts-node transpiler plugin
+ *
+ * This plugin hooks into ts-node so that Sucrase can handle all TS-to-JS
+ * conversion while ts-node handles the ESM loader, require hook, REPL
+ * integration, etc. ts-node automatically discovers the relevant tsconfig file,
+ * so the main logic in this integration is translating tsconfig options to the
+ * corresponding Sucrase options.
+ *
+ * Any tsconfig options relevant to Sucrase are translated, but some config
+ * options outside the scope of Sucrase are ignored. For example, we assume the
+ * isolatedModules option, and we ignore target because Sucrase doesn't provide
+ * JS syntax downleveling (at least not in a way that is useful for Node).
+ *
+ * One notable caveat is that importsNotUsedAsValues and preserveValueImports
+ * are ignored right now, since they are deprecated and don't have exact Sucrase
+ * equivalents. To preserve imports and exports, use verbatimModuleSyntax.
+ */
+function create(createOptions) {
+ const {nodeModuleEmitKind} = createOptions;
+ const {
+ module,
+ jsx,
+ jsxFactory,
+ jsxFragmentFactory,
+ jsxImportSource,
+ esModuleInterop,
+ verbatimModuleSyntax,
+ } = createOptions.service.config.options;
+
+ return {
+ transpile(input, transpileOptions) {
+ const {fileName} = transpileOptions;
+ const transforms = [];
+ // Detect JS rather than TS so we bias toward including the typescript
+ // transform, since almost always it doesn't hurt to include.
+ const isJS =
+ fileName.endsWith(".js") ||
+ fileName.endsWith(".jsx") ||
+ fileName.endsWith(".mjs") ||
+ fileName.endsWith(".cjs");
+ if (!isJS) {
+ transforms.push("typescript");
+ }
+ if (module === ModuleKindCommonJS || nodeModuleEmitKind === "nodecjs") {
+ transforms.push("imports");
+ }
+ if (fileName.endsWith(".tsx") || fileName.endsWith(".jsx")) {
+ transforms.push("jsx");
+ }
+
+ const {code, sourceMap} = transform(input, {
+ transforms,
+ disableESTransforms: true,
+ jsxRuntime: jsx === JsxEmitReactJSX || jsx === JsxEmitReactJSXDev ? "automatic" : "classic",
+ production: jsx === JsxEmitReactJSX,
+ jsxImportSource,
+ jsxPragma: jsxFactory,
+ jsxFragmentPragma: jsxFragmentFactory,
+ keepUnusedImports: verbatimModuleSyntax,
+ preserveDynamicImport: nodeModuleEmitKind === "nodecjs",
+ injectCreateRequireForImportRequire: nodeModuleEmitKind === "nodeesm",
+ enableLegacyTypeScriptModuleInterop: !esModuleInterop,
+ sourceMapOptions: {compiledFilename: fileName},
+ filePath: fileName,
+ });
+ return {
+ outputText: code,
+ sourceMapText: JSON.stringify(sourceMap),
+ };
+ },
+ };
+}
+
+exports.create = create;