pankod/refine

View on GitHub
packages/live-previews/src/utils/replace-imports.ts

Summary

Maintainability
B
5 hrs
Test Coverage
import { packageMap, packageScopeMap } from "@/src/scope/map";
import { isDevelopmentModeByCookie } from "./development-cookie";
import { prettySpaces } from "./pretty-spaces";

const packageRegex =
  /import(?:(?:(?:[ \n\t]+([^ *\n\t\{\},]+)[ \n\t]*(?:,|[ \n\t]+))?([ \n\t]*\{(?:[ \n\t]*[^ \n\t"'\{\}]+[ \n\t]*,?)+\})?[ \n\t]*)|[ \n\t]*\*[ \n\t]*as[ \n\t]+([^ \n\t\{\}]+)[ \n\t]+)from[ \n\t]*(?:['"])([^'"\n]+)(?:['"])(?:;?)/g;
//
const sideEffectRegex = /import[ \n\t](?:['"])([^'"\n]+)(?:['"])(?:;?)/g;

const nameChangeRegex = /((?:\w|\s|_)*)( as )((?:\w|\s|_)*)( |,)?/g;

export const replaceImports = (content: string): string => {
  const matches = content.matchAll(packageRegex);

  const imports = new Set();

  for (const match of matches) {
    const [, defaultImport, namedImports, namespaceImport, packageName] = match;

    const regexMatch = Object.entries(packageScopeMap).find(([key, value]) =>
      // value is regexp, key is package name
      value.test(packageName),
    );
    const regexPackage = regexMatch ? regexMatch[0] : null;

    if (regexPackage && !(packageName in packageMap)) {
      const importName = packageMap[regexPackage];

      if (defaultImport) {
        imports.add(`const { ${defaultImport} } = ${importName};`);
      }

      if (namedImports) {
        imports.add(
          `const${namedImports.replace(
            nameChangeRegex,
            "$1: $3$4",
          )} = ${importName};`,
        );
      }
    }

    if (packageName in packageMap) {
      const importName = packageMap[packageName];

      if (defaultImport) {
        imports.add(`const { default: ${defaultImport} } = ${importName};`);
      }

      if (namedImports) {
        imports.add(
          `const${namedImports.replace(
            nameChangeRegex,
            "$1: $3$4",
          )} = ${importName};`,
        );
      }

      if (namespaceImport) {
        imports.add(`const ${namespaceImport} = ${importName};`);
      }
    }
  }

  const pretty = prettySpaces(`
    ${Array.from(imports).join("\n")}
    ${content
      .replace(packageRegex, "")
      .replace(sideEffectRegex, "")
      .replace(
        "React.createElement(GoogleButton,",
        "React.createElement(MockGoogleButton,",
      )}
    `);

  if (isDevelopmentModeByCookie()) {
    console.log("== Incoming Code ==");
    console.log(content);
    console.log("== ==");
    console.log("== Transformed Code ==");
    console.log(pretty);
    console.log("== ==");
  }

  return pretty;
};