UNPKG

3.94 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const fs = require("fs");
4const path = require("path");
5const debug_1 = require("./debug");
6// eslint-disable-next-line new-cap
7const debug = debug_1.default();
8const tsconfigs = {};
9const rootDirs = [];
10const typeRoots = [`${__dirname}/../node_modules/@types`];
11function loadTSConfig(root) {
12 const tsconfigPath = path.join(root, 'tsconfig.json');
13 let typescript;
14 try {
15 typescript = require('typescript');
16 }
17 catch (_a) {
18 try {
19 typescript = require(root + '/node_modules/typescript');
20 }
21 catch (_b) { }
22 }
23 if (fs.existsSync(tsconfigPath) && typescript) {
24 const tsconfig = typescript.parseConfigFileTextToJson(tsconfigPath, fs.readFileSync(tsconfigPath, 'utf8')).config;
25 if (!tsconfig || !tsconfig.compilerOptions) {
26 throw new Error(`Could not read and parse tsconfig.json at ${tsconfigPath}, or it ` +
27 'did not contain a "compilerOptions" section.');
28 }
29 return tsconfig;
30 }
31}
32function registerTSNode(root) {
33 if (process.env.OCLIF_TS_NODE === '0')
34 return;
35 if (tsconfigs[root])
36 return;
37 const tsconfig = loadTSConfig(root);
38 if (!tsconfig)
39 return;
40 debug('registering ts-node at', root);
41 const tsNodePath = require.resolve('ts-node', { paths: [root, __dirname] });
42 const tsNode = require(tsNodePath);
43 tsconfigs[root] = tsconfig;
44 typeRoots.push(`${root}/node_modules/@types`);
45 if (tsconfig.compilerOptions.rootDirs) {
46 rootDirs.push(...tsconfig.compilerOptions.rootDirs.map(r => path.join(root, r)));
47 }
48 else {
49 rootDirs.push(`${root}/src`);
50 }
51 const cwd = process.cwd();
52 try {
53 process.chdir(root);
54 tsNode.register({
55 skipProject: true,
56 transpileOnly: true,
57 // cache: false,
58 // typeCheck: true,
59 compilerOptions: {
60 esModuleInterop: tsconfig.compilerOptions.esModuleInterop,
61 target: tsconfig.compilerOptions.target || 'es2017',
62 experimentalDecorators: tsconfig.compilerOptions.experimentalDecorators || false,
63 emitDecoratorMetadata: tsconfig.compilerOptions.emitDecoratorMetadata || false,
64 module: 'commonjs',
65 sourceMap: true,
66 rootDirs,
67 typeRoots,
68 jsx: 'react',
69 },
70 });
71 }
72 finally {
73 process.chdir(cwd);
74 }
75}
76function tsPath(root, orig) {
77 if (!orig)
78 return orig;
79 orig = path.join(root, orig);
80 try {
81 registerTSNode(root);
82 const tsconfig = tsconfigs[root];
83 if (!tsconfig)
84 return orig;
85 const { rootDir, rootDirs, outDir } = tsconfig.compilerOptions;
86 const rootDirPath = rootDir || (rootDirs || [])[0];
87 if (!rootDirPath || !outDir)
88 return orig;
89 // rewrite path from ./lib/foo to ./src/foo
90 const lib = path.join(root, outDir); // ./lib
91 const src = path.join(root, rootDirPath); // ./src
92 const relative = path.relative(lib, orig); // ./commands
93 const out = path.join(src, relative); // ./src/commands
94 // this can be a directory of commands or point to a hook file
95 // if it's a directory, we check if the path exists. If so, return the path to the directory.
96 // For hooks, it might point to a module, not a file. Something like "./hooks/myhook"
97 // That file doesn't exist, and the real file is "./hooks/myhook.ts"
98 // In that case we attempt to resolve to the filename. If it fails it will revert back to the lib path
99 if (fs.existsSync(out) || fs.existsSync(out + '.ts'))
100 return out;
101 return orig;
102 }
103 catch (error) {
104 debug(error);
105 return orig;
106 }
107}
108exports.tsPath = tsPath;