typia
Version:
Superfast runtime validators with only one line
67 lines (56 loc) • 1.81 kB
text/typescript
import path from "path";
import ts from "typescript";
export namespace ImportTransformer {
export const transform =
(from: string) =>
(to: string) =>
(context: ts.TransformationContext) =>
(file: ts.SourceFile) =>
transform_file(from)(to)(context)(file);
const transform_file =
(top: string) =>
(to: string) =>
(context: ts.TransformationContext) =>
(file: ts.SourceFile): ts.SourceFile => {
if (file.isDeclarationFile) return file;
const from: string = get_directory_path(
path.resolve(file.getSourceFile().fileName),
);
to = from.replace(top, to);
return ts.visitEachChild(
file,
(node) => transform_node(top)(from)(to)(node),
context,
);
};
const transform_node =
(top: string) => (from: string) => (to: string) => (node: ts.Node) => {
if (
!ts.isImportDeclaration(node) ||
!ts.isStringLiteral(node.moduleSpecifier)
)
return node;
const text: string = node.moduleSpecifier.text;
if (text[0] !== ".") return node;
const location: string = path.resolve(from, text);
if (location.indexOf(top) === 0) return node;
const replaced: string = (() => {
const simple: string = path
.relative(to, location)
.split(path.sep)
.join("/");
return simple[0] === "." ? simple : `./${simple}`;
})();
return ts.factory.createImportDeclaration(
undefined,
node.importClause,
ts.factory.createStringLiteral(replaced),
node.assertClause,
);
};
}
const get_directory_path = (file: string): string => {
const splitted: string[] = path.resolve(file).split(path.sep);
splitted.pop();
return path.resolve(splitted.join(path.sep));
};