From 52712b42c12a7be3aa6505510110325b7367cb41 Mon Sep 17 00:00:00 2001
From: Alexander Lesnenko <alxnddr@users.noreply.github.com>
Date: Wed, 8 Dec 2021 23:51:33 +0300
Subject: [PATCH] support ts and tsx in parse-deps (#18329)

* support ts and tsx in parse-deps

* use strip flow types plugin

* remove strip flow types plugin
---
 frontend/parse-deps.js | 75 +++++++++++++++++++++++-------------------
 1 file changed, 42 insertions(+), 33 deletions(-)

diff --git a/frontend/parse-deps.js b/frontend/parse-deps.js
index 0524c39d9ea..a6ad1f1c6b7 100644
--- a/frontend/parse-deps.js
+++ b/frontend/parse-deps.js
@@ -5,11 +5,10 @@ const path = require("path");
 
 const glob = require("glob");
 const minimatch = require("minimatch");
-const parser = require("@babel/parser");
-const traverse = require("@babel/traverse").default;
+const babel = require("@babel/core");
 const readline = require("readline");
 
-const PATTERN = "{enterprise/,}frontend/src/**/*.{js,jsx}";
+const PATTERN = "{enterprise/,}frontend/src/**/*.{js,jsx,ts,tsx}";
 
 // after webpack.config.js
 const ALIAS = {
@@ -24,19 +23,19 @@ function files() {
 }
 
 function dependencies() {
-  const deps = files().map(fileName => {
-    const contents = fs.readFileSync(fileName, "utf-8");
-    const options = {
-      allowImportExportEverywhere: true,
-      allowReturnOutsideFunction: true,
-      decoratorsBeforeExport: true,
-      sourceType: "unambiguous",
-      plugins: ["jsx", "flow", "decorators-legacy", "exportDefaultFrom"],
-    };
+  const deps = files().map(filename => {
+    const contents = fs.readFileSync(filename, "utf-8");
+
     const importList = [];
     try {
-      const ast = parser.parse(contents, options);
-      traverse(ast, {
+      const file = babel.transformSync(contents, {
+        filename,
+        presets: ["@babel/preset-typescript"],
+        ast: true,
+        code: false,
+      });
+
+      babel.traverse(file.ast, {
         enter(path) {
           if (path.node.type === "ImportDeclaration") {
             importList.push(path.node.source.value);
@@ -53,11 +52,11 @@ function dependencies() {
         },
       });
     } catch (e) {
-      console.error(fileName, e.toString());
+      console.error(filename, e.toString());
       process.exit(-1);
       n;
     }
-    const base = path.dirname(fileName) + path.sep;
+    const base = path.dirname(filename) + path.sep;
     const absoluteImportList = importList
       .map(name => {
         const absName = name[0] === "." ? path.normalize(base + name) : name;
@@ -67,29 +66,39 @@ function dependencies() {
         const realName = parts.join(path.sep);
         return realName;
       })
-      .map(name => {
-        if (fs.existsSync(name)) {
-          if (
-            fs.lstatSync(name).isDirectory() &&
-            fs.existsSync(name + "/index.js")
-          ) {
-            return name + "/index.js";
-          }
-          return name;
-        } else if (fs.existsSync(name + ".js")) {
-          return name + ".js";
-        } else if (fs.existsSync(name + ".jsx")) {
-          return name + ".jsx";
-        }
-        return name;
-      })
+      .map(getFilePathFromImportPath)
       .filter(name => minimatch(name, PATTERN));
 
-    return { source: fileName, dependencies: absoluteImportList.sort() };
+    return { source: filename, dependencies: absoluteImportList.sort() };
   });
   return deps;
 }
 
+function getFilePathFromImportPath(name) {
+  const scriptsExtensions = ["js", "ts"];
+  const scriptsExtensionsWithJsx = [...scriptsExtensions, "jsx", "tsx"];
+
+  for (let extension of scriptsExtensionsWithJsx) {
+    const path = `${name}.${extension}`;
+
+    if (fs.existsSync(path)) {
+      return path;
+    }
+  }
+
+  const isDirectory = fs.existsSync(name) && fs.lstatSync(name).isDirectory();
+
+  for (let extension of scriptsExtensions) {
+    const indexScriptPath = `${name}/index.${extension}`;
+
+    if (isDirectory && fs.existsSync(indexScriptPath)) {
+      return indexScriptPath;
+    }
+  }
+
+  return name;
+}
+
 function dependents() {
   let dependents = {};
   dependencies().forEach(dep => {
-- 
GitLab