Index: frontend/node_modules/sucrase/ts-node-plugin/index.js
===================================================================
--- frontend/node_modules/sucrase/ts-node-plugin/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/sucrase/ts-node-plugin/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -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;
