forked from withfig/autocomplete
-
Notifications
You must be signed in to change notification settings - Fork 0
/
compiler.ts
135 lines (117 loc) · 3.38 KB
/
compiler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import fs from "fs";
import ts from "typescript";
import path from "path";
import { specTransformer } from "./transformer";
import SpecLogger, { Level } from "./log";
import ProgressBar from "progress";
import { DESTINATION_FOLDER_NAME, SOURCE_FOLDER_NAME } from "./constants";
import { exec } from "child_process";
import chokidar from "chokidar";
// The options for the TypeScript compiler
const options: ts.TranspileOptions = {
compilerOptions: {
module: ts.ModuleKind.ESNext,
},
transformers: {
before: [specTransformer],
},
};
function invalidateCache() {
exec(
"fig settings autocomplete.developerModeNPMInvalidateCache true",
(error, stdout, stderr) => {
if (error) {
SpecLogger.log(
`node error setting Fig to NPM dev mode: ${error.message}`,
Level.ERROR
);
return;
}
if (stderr) {
SpecLogger.log(
`shell error setting Fig to NPM dev mode: ${stderr}`,
Level.ERROR
);
return;
}
}
);
}
if (process.argv[2] == "INVALIDATE_CACHE") {
invalidateCache();
}
function walkDir(dir: string, callback: (path: string) => void) {
fs.readdirSync(dir).forEach((currentFilePath) => {
const dirPath = path.join(dir, currentFilePath);
const isDirectory = fs.statSync(dirPath).isDirectory();
if (isDirectory) {
walkDir(dirPath, callback);
} else {
callback(path.join(dir, currentFilePath));
}
});
}
/**
* Process a spec by transpiling it with the TypeScript
* compiler.
* @param filePath The file to process
*/
const processSpec = (filePath: string) => {
const source = fs.readFileSync(filePath).toString();
const result = ts.transpileModule(source, options);
const relativeFilePath = filePath
.replace(`${SOURCE_FOLDER_NAME}/`, "")
.replace(".ts", ".js");
const outFilePath = path.resolve(DESTINATION_FOLDER_NAME, relativeFilePath);
const outDirname = path.dirname(outFilePath);
if (!fs.existsSync(outDirname)) {
fs.mkdirSync(outDirname);
}
// Remove unessesary export at the end of js files
const jsOutput = result.outputText.replace("export {};", "");
fs.writeFileSync(outFilePath, jsOutput);
};
/**
* Transpiles all passed files and prints the progress
* @param specs Array of filepaths
*/
function processFiles(specs: string[]) {
// Process all the files in the specs directory
SpecLogger.log(`Processing ${specs.length} specs...`);
const bar = new ProgressBar(":bar :percent", {
total: specs.length,
complete: "=",
head: ">",
incomplete: " ",
});
// Make sure that the destination folder exists
if (!fs.existsSync(DESTINATION_FOLDER_NAME)) {
// if not create it
fs.mkdirSync(DESTINATION_FOLDER_NAME);
}
specs.forEach((spec) => {
processSpec(spec);
bar.tick({ spec });
});
SpecLogger.log(
`Specs compiled successfully to /${DESTINATION_FOLDER_NAME} folder!`,
Level.SUCCESS
);
}
const isWatching = process.argv.includes("--watch");
if (isWatching) {
const watcher = chokidar.watch(SOURCE_FOLDER_NAME);
// Process the changed file
watcher.on("change", (filePath: string) => {
processFiles([filePath]);
invalidateCache();
});
} else {
// Get all files from the the source folder recursively
const specs: string[] = [];
walkDir(SOURCE_FOLDER_NAME, (path) => {
if (path === ".DS_STORE") return;
specs.push(path);
});
processFiles(specs);
}