@travetto/compiler 3.0.0-rc.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -14
- package/__index__.ts +4 -1
- package/bin/trv.js +57 -63
- package/package.json +8 -6
- package/src/compiler.ts +74 -113
- package/src/log.ts +18 -0
- package/src/state.ts +160 -166
- package/src/types.ts +14 -0
- package/src/util.ts +32 -87
- package/src/watch.ts +142 -0
- package/support/compiler-entry.ts +2 -0
- package/support/launcher.ts +152 -0
- package/support/lock-pinger.ts +25 -0
- package/support/lock.ts +234 -0
- package/support/log.ts +51 -0
- package/support/transpile.ts +210 -0
- package/tsconfig.trv.json +1 -0
- package/bin/transpile.d.ts +0 -32
- package/bin/transpile.js +0 -227
- package/support/bin/compiler-bootstrap.ts +0 -151
- package/support/bin/utils.ts +0 -116
- package/support/main.output.ts +0 -11
package/src/state.ts
CHANGED
|
@@ -1,39 +1,61 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { mkdirSync, readFileSync, writeFile } from 'fs';
|
|
3
2
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
ManifestModuleUtil, ManifestDelta, ManifestModule,
|
|
7
|
-
ManifestModuleFileType, ManifestRoot, ManifestState
|
|
8
|
-
} from '@travetto/manifest';
|
|
3
|
+
import { path, ManifestModuleUtil, ManifestModule, ManifestRoot, ManifestIndex } from '@travetto/manifest';
|
|
4
|
+
import { TransformerManager } from '@travetto/transformer';
|
|
9
5
|
|
|
10
|
-
import { CompilerUtil
|
|
6
|
+
import { CompilerUtil } from './util';
|
|
7
|
+
import { TranspileUtil } from '../support/transpile';
|
|
8
|
+
import { CompileStateEntry } from './types';
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
function folderMapper(root: string, prefix: string): { dir: string, translate: (val: string) => string } {
|
|
11
|
+
let matched: string = '~~';
|
|
12
|
+
prefix = `/${prefix}`;
|
|
13
|
+
const final = path.resolve(root).replace(/\/[^\/]+/, m => {
|
|
14
|
+
matched = m;
|
|
15
|
+
return prefix;
|
|
16
|
+
});
|
|
17
|
+
return { dir: final, translate: (file: string) => file.replace(prefix, matched) };
|
|
18
|
+
}
|
|
13
19
|
|
|
14
|
-
export class CompilerState {
|
|
20
|
+
export class CompilerState implements ts.CompilerHost {
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
static async get(idx: ManifestIndex): Promise<CompilerState> {
|
|
23
|
+
return new CompilerState().init(idx);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private constructor() { }
|
|
27
|
+
|
|
28
|
+
#rootDir: string;
|
|
29
|
+
#inputPathToSource: (file: string) => string;
|
|
30
|
+
#outputPath: string;
|
|
31
|
+
#inputFiles = new Set<string>();
|
|
20
32
|
#inputDirectoryToSource = new Map<string, string>();
|
|
21
|
-
#
|
|
33
|
+
#inputToEntry = new Map<string, CompileStateEntry>();
|
|
34
|
+
#sourceToEntry = new Map<string, CompileStateEntry>();
|
|
35
|
+
#outputToEntry = new Map<string, CompileStateEntry>();
|
|
22
36
|
|
|
23
37
|
#sourceContents = new Map<string, string | undefined>();
|
|
24
38
|
#sourceFileObjects = new Map<string, ts.SourceFile>();
|
|
25
|
-
#sourceHashes = new Map<string, number>();
|
|
26
39
|
|
|
40
|
+
#manifestIndex: ManifestIndex;
|
|
27
41
|
#manifest: ManifestRoot;
|
|
28
|
-
#delta: ManifestDelta;
|
|
29
42
|
#modules: ManifestModule[];
|
|
43
|
+
#transformerManager: TransformerManager;
|
|
44
|
+
#compilerOptions: ts.CompilerOptions;
|
|
45
|
+
|
|
46
|
+
async init(idx: ManifestIndex): Promise<this> {
|
|
47
|
+
this.#manifestIndex = idx;
|
|
48
|
+
this.#manifest = idx.manifest;
|
|
49
|
+
const mapper = folderMapper(this.#manifest.workspacePath, '##');
|
|
50
|
+
this.#rootDir = mapper.dir;
|
|
51
|
+
this.#inputPathToSource = mapper.translate;
|
|
30
52
|
|
|
31
|
-
|
|
32
|
-
this.#manifest = manifest;
|
|
33
|
-
this.#delta = delta;
|
|
53
|
+
this.#outputPath = path.resolve(this.#manifest.workspacePath, this.#manifest.outputFolder);
|
|
34
54
|
this.#modules = Object.values(this.#manifest.modules);
|
|
35
|
-
|
|
36
|
-
|
|
55
|
+
|
|
56
|
+
// Register all inputs
|
|
57
|
+
for (const x of this.#modules) {
|
|
58
|
+
const files = [
|
|
37
59
|
...x.files.bin ?? [],
|
|
38
60
|
...x.files.src ?? [],
|
|
39
61
|
...x.files.support ?? [],
|
|
@@ -41,45 +63,98 @@ export class CompilerState {
|
|
|
41
63
|
...x.files.test ?? [],
|
|
42
64
|
...x.files.$index ?? [],
|
|
43
65
|
...x.files.$package ?? []
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
.
|
|
47
|
-
|
|
66
|
+
];
|
|
67
|
+
for (const [file, type] of files) {
|
|
68
|
+
if (CompilerUtil.validFile(type) || type === 'typings') {
|
|
69
|
+
this.registerInput(x, file);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.#transformerManager = await TransformerManager.create(this.#manifestIndex);
|
|
75
|
+
|
|
76
|
+
this.#compilerOptions = {
|
|
77
|
+
...await TranspileUtil.getCompilerOptions(this.#manifest),
|
|
78
|
+
rootDir: this.#rootDir,
|
|
79
|
+
outDir: this.#outputPath
|
|
80
|
+
};
|
|
48
81
|
|
|
49
82
|
return this;
|
|
50
83
|
}
|
|
51
84
|
|
|
85
|
+
get manifest(): ManifestRoot {
|
|
86
|
+
return this.#manifest;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get manifestIndex(): ManifestIndex {
|
|
90
|
+
return this.#manifestIndex;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
resolveOutputFile(file: string): string {
|
|
94
|
+
return path.resolve(this.#manifest.workspacePath, this.#manifest.outputFolder, file);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getArbitraryInputFile(): string {
|
|
98
|
+
return this.getBySource(this.#manifestIndex.getModule('@travetto/manifest')!.files.src[0].sourceFile)!.input;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
createProgram(oldProgram?: ts.Program): ts.Program {
|
|
102
|
+
const prog = ts.createProgram({ rootNames: this.getAllFiles(), host: this, options: this.#compilerOptions, oldProgram });
|
|
103
|
+
this.#transformerManager.init(prog.getTypeChecker());
|
|
104
|
+
return prog;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
writeInputFile(program: ts.Program, inputFile: string): ts.EmitResult | undefined {
|
|
108
|
+
if (inputFile.endsWith('.json')) {
|
|
109
|
+
this.writeFile(this.#inputToEntry.get(inputFile)!.output!, this.readFile(inputFile)!, false);
|
|
110
|
+
} else if (inputFile.endsWith('.js')) {
|
|
111
|
+
this.writeFile(this.#inputToEntry.get(inputFile)!.output!, ts.transpile(this.readFile(inputFile)!, this.#compilerOptions), false);
|
|
112
|
+
} else if (inputFile.endsWith('.ts')) {
|
|
113
|
+
return program.emit(
|
|
114
|
+
program.getSourceFile(inputFile)!,
|
|
115
|
+
(...args) => this.writeFile(...args), undefined, false,
|
|
116
|
+
this.#transformerManager.get()
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
getBySource(sourceFile: string): CompileStateEntry | undefined {
|
|
122
|
+
return this.#sourceToEntry.get(sourceFile);
|
|
123
|
+
}
|
|
124
|
+
|
|
52
125
|
registerInput(module: ManifestModule, moduleFile: string): string {
|
|
53
|
-
const relativeInput = `${module.
|
|
54
|
-
const sourceFile =
|
|
126
|
+
const relativeInput = `${module.outputFolder}/${moduleFile}`;
|
|
127
|
+
const sourceFile = path.toPosix(path.resolve(this.#manifest.workspacePath, module.sourceFolder, moduleFile));
|
|
55
128
|
const sourceFolder = path.dirname(sourceFile);
|
|
56
|
-
const inputFile = path.resolve(relativeInput);
|
|
129
|
+
const inputFile = path.resolve(this.#rootDir, relativeInput); // Ensure input is isolated
|
|
57
130
|
const inputFolder = path.dirname(inputFile);
|
|
58
131
|
const fileType = ManifestModuleUtil.getFileType(moduleFile);
|
|
59
132
|
const outputFile = fileType === 'typings' ?
|
|
60
133
|
undefined :
|
|
61
|
-
path.resolve(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
(fileType === 'ts' ? relativeInput.replace(/[.]ts$/, '.js') : relativeInput)
|
|
65
|
-
);
|
|
134
|
+
path.resolve(this.#outputPath, CompilerUtil.inputToOutput(relativeInput));
|
|
135
|
+
|
|
136
|
+
const entry = { source: sourceFile, input: inputFile, output: outputFile, module, relativeInput };
|
|
66
137
|
|
|
67
|
-
this.#
|
|
68
|
-
this.#
|
|
69
|
-
this.#inputToOutput.set(inputFile, outputFile);
|
|
138
|
+
this.#inputToEntry.set(inputFile, entry);
|
|
139
|
+
this.#sourceToEntry.set(sourceFile, entry);
|
|
70
140
|
this.#inputDirectoryToSource.set(inputFolder, sourceFolder);
|
|
71
|
-
|
|
141
|
+
|
|
142
|
+
if (outputFile) {
|
|
143
|
+
this.#outputToEntry.set(outputFile, entry);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.#inputFiles.add(inputFile);
|
|
72
147
|
|
|
73
148
|
return inputFile;
|
|
74
149
|
}
|
|
75
150
|
|
|
76
151
|
removeInput(inputFile: string): void {
|
|
77
|
-
const source = this.#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.#
|
|
82
|
-
this.#
|
|
152
|
+
const { output, source } = this.#inputToEntry.get(inputFile)!;
|
|
153
|
+
if (output) {
|
|
154
|
+
this.#outputToEntry.delete(output);
|
|
155
|
+
}
|
|
156
|
+
this.#sourceToEntry.delete(source);
|
|
157
|
+
this.#inputToEntry.delete(inputFile);
|
|
83
158
|
this.#inputFiles.delete(inputFile);
|
|
84
159
|
}
|
|
85
160
|
|
|
@@ -88,138 +163,57 @@ export class CompilerState {
|
|
|
88
163
|
this.#sourceContents.delete(inputFile);
|
|
89
164
|
}
|
|
90
165
|
|
|
91
|
-
|
|
92
|
-
return this.#
|
|
166
|
+
getAllFiles(): string[] {
|
|
167
|
+
return [...this.#inputFiles];
|
|
93
168
|
}
|
|
94
169
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
170
|
+
/* Start Compiler Host */
|
|
171
|
+
getCanonicalFileName(file: string): string { return file; }
|
|
172
|
+
getCurrentDirectory(): string { return this.#rootDir; }
|
|
173
|
+
getDefaultLibFileName(opts: ts.CompilerOptions): string { return ts.getDefaultLibFileName(opts); }
|
|
174
|
+
getNewLine(): string { return ts.sys.newLine; }
|
|
175
|
+
useCaseSensitiveFileNames(): boolean { return ts.sys.useCaseSensitiveFileNames; }
|
|
176
|
+
getDefaultLibLocation(): string { return path.dirname(ts.getDefaultLibFilePath(this.#compilerOptions)); }
|
|
98
177
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const files: string[] = [];
|
|
102
|
-
for (const [modName, events] of Object.entries(this.#delta)) {
|
|
103
|
-
const mod = this.#manifest.modules[modName];
|
|
104
|
-
for (const { file } of events) {
|
|
105
|
-
const fileType = ManifestModuleUtil.getFileType(file);
|
|
106
|
-
if (validFile(fileType)) {
|
|
107
|
-
files.push(path.resolve(mod.output, file));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return files;
|
|
112
|
-
} else {
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
178
|
+
fileExists(inputFile: string): boolean {
|
|
179
|
+
return this.#inputToEntry.has(inputFile) || ts.sys.fileExists(this.#inputPathToSource(inputFile));
|
|
115
180
|
}
|
|
116
181
|
|
|
117
|
-
|
|
118
|
-
return
|
|
182
|
+
directoryExists(inputDir: string): boolean {
|
|
183
|
+
return this.#inputDirectoryToSource.has(inputDir) || ts.sys.directoryExists(this.#inputPathToSource(inputDir));
|
|
119
184
|
}
|
|
120
185
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (validFile(fileType)) {
|
|
139
|
-
const hash = CompilerUtil.naiveHash(readFileSync(sourceFile, 'utf8'));
|
|
140
|
-
const input = this.registerInput(mod, moduleFile);
|
|
141
|
-
this.#sourceHashes.set(sourceFile, hash);
|
|
142
|
-
handler.create(input);
|
|
143
|
-
}
|
|
144
|
-
break;
|
|
145
|
-
}
|
|
146
|
-
case 'update': {
|
|
147
|
-
const io = this.#sourceInputOutput.get(sourceFile);
|
|
148
|
-
if (io) {
|
|
149
|
-
const hash = CompilerUtil.naiveHash(readFileSync(sourceFile, 'utf8'));
|
|
150
|
-
if (this.#sourceHashes.get(sourceFile) !== hash) {
|
|
151
|
-
this.resetInputSource(io.input);
|
|
152
|
-
this.#sourceHashes.set(sourceFile, hash);
|
|
153
|
-
handler.update(io.input);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case 'delete': {
|
|
159
|
-
const io = this.#sourceInputOutput.get(sourceFile);
|
|
160
|
-
if (io) {
|
|
161
|
-
this.removeInput(io.input);
|
|
162
|
-
if (io.output) {
|
|
163
|
-
handler.delete(io.output);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
186
|
+
writeFile(
|
|
187
|
+
outputFile: string,
|
|
188
|
+
text: string,
|
|
189
|
+
bom: boolean,
|
|
190
|
+
onError?: (message: string) => void,
|
|
191
|
+
sourceFiles?: readonly ts.SourceFile[],
|
|
192
|
+
data?: ts.WriteFileCallbackData
|
|
193
|
+
): void {
|
|
194
|
+
if (outputFile.endsWith('package.json')) {
|
|
195
|
+
text = CompilerUtil.rewritePackageJSON(this.#manifest, text);
|
|
196
|
+
} else if (!this.#compilerOptions.inlineSourceMap && this.#compilerOptions.sourceMap && outputFile.endsWith('.map')) {
|
|
197
|
+
text = CompilerUtil.rewriteSourceMap(this.#manifest, text, f => this.#outputToEntry.get(f.replace(/[.]map$/, ''))!);
|
|
198
|
+
} else if (this.#compilerOptions.inlineSourceMap && CompilerUtil.isSourceMapUrlPosData(data)) {
|
|
199
|
+
text = CompilerUtil.rewriteInlineSourceMap(this.#manifest, text, f => this.#outputToEntry.get(f)!, data);
|
|
200
|
+
}
|
|
201
|
+
ts.sys.writeFile(outputFile, text, bom);
|
|
202
|
+
}
|
|
168
203
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
),
|
|
176
|
-
JSON.stringify(this.#manifest),
|
|
177
|
-
() => { });
|
|
178
|
-
};
|
|
204
|
+
readFile(inputFile: string): string | undefined {
|
|
205
|
+
const res = this.#sourceContents.get(inputFile) ?? ts.sys.readFile(
|
|
206
|
+
this.#inputToEntry.get(inputFile)?.source ?? this.#inputPathToSource(inputFile)
|
|
207
|
+
);
|
|
208
|
+
this.#sourceContents.set(inputFile, res);
|
|
209
|
+
return res;
|
|
179
210
|
}
|
|
180
211
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
getNewLine: (): string => ts.sys.newLine,
|
|
188
|
-
useCaseSensitiveFileNames: (): boolean => ts.sys.useCaseSensitiveFileNames,
|
|
189
|
-
getDefaultLibLocation: (): string => path.dirname(ts.getDefaultLibFilePath(options)),
|
|
190
|
-
fileExists: (inputFile: string): boolean => this.#inputToSource.has(inputFile) || ts.sys.fileExists(inputFile),
|
|
191
|
-
directoryExists: (inputFolder: string): boolean => this.#inputDirectoryToSource.has(inputFolder) || ts.sys.directoryExists(inputFolder),
|
|
192
|
-
readFile: (inputFile: string): string | undefined => {
|
|
193
|
-
const res = this.#sourceContents.get(inputFile) ?? ts.sys.readFile(this.#inputToSource.get(inputFile) ?? inputFile);
|
|
194
|
-
this.#sourceContents.set(inputFile, res);
|
|
195
|
-
return res;
|
|
196
|
-
},
|
|
197
|
-
writeFile: (
|
|
198
|
-
outputFile: string,
|
|
199
|
-
text: string,
|
|
200
|
-
bom: boolean,
|
|
201
|
-
onError?: (message: string) => void,
|
|
202
|
-
sourceFiles?: readonly ts.SourceFile[],
|
|
203
|
-
data?: ts.WriteFileCallbackData
|
|
204
|
-
): void => {
|
|
205
|
-
mkdirSync(path.dirname(outputFile), { recursive: true });
|
|
206
|
-
if (outputFile.endsWith('package.json')) {
|
|
207
|
-
text = CompilerUtil.rewritePackageJSON(this.manifest, text, options);
|
|
208
|
-
} else if (!options.inlineSourceMap && options.sourceMap && outputFile.endsWith('.map')) {
|
|
209
|
-
text = CompilerUtil.rewriteSourceMap(text, f => this.#relativeInputToSource.get(f));
|
|
210
|
-
} else if (options.inlineSourceMap && CompilerUtil.isSourceMapUrlPosData(data)) {
|
|
211
|
-
text = CompilerUtil.rewriteInlineSourceMap(text, f => this.#relativeInputToSource.get(f), data);
|
|
212
|
-
}
|
|
213
|
-
ts.sys.writeFile(outputFile, text, bom);
|
|
214
|
-
},
|
|
215
|
-
getSourceFile: (inputFile: string, language: ts.ScriptTarget, __onErr?: unknown): ts.SourceFile => {
|
|
216
|
-
if (!this.#sourceFileObjects.has(inputFile)) {
|
|
217
|
-
const content = host.readFile(inputFile)!;
|
|
218
|
-
this.#sourceFileObjects.set(inputFile, ts.createSourceFile(inputFile, content ?? '', language));
|
|
219
|
-
}
|
|
220
|
-
return this.#sourceFileObjects.get(inputFile)!;
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
return host;
|
|
212
|
+
getSourceFile(inputFile: string, language: ts.ScriptTarget): ts.SourceFile {
|
|
213
|
+
if (!this.#sourceFileObjects.has(inputFile)) {
|
|
214
|
+
const content = this.readFile(inputFile)!;
|
|
215
|
+
this.#sourceFileObjects.set(inputFile, ts.createSourceFile(inputFile, content ?? '', language));
|
|
216
|
+
}
|
|
217
|
+
return this.#sourceFileObjects.get(inputFile)!;
|
|
224
218
|
}
|
|
225
219
|
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type ts from 'typescript';
|
|
2
|
+
|
|
3
|
+
import type { ManifestModule } from '@travetto/manifest';
|
|
4
|
+
|
|
5
|
+
export type CompileEmitError = Error | readonly ts.Diagnostic[];
|
|
6
|
+
export type CompileEmitter = (file: string, newProgram?: boolean) => Promise<CompileEmitError | undefined>;
|
|
7
|
+
export type CompileEmitEvent = { file: string, i: number, total: number, err?: CompileEmitError };
|
|
8
|
+
export type CompileStateEntry = { source: string, input: string, relativeInput: string, output?: string, module: ManifestModule };
|
|
9
|
+
|
|
10
|
+
export type CompileWatcherHandler = {
|
|
11
|
+
create: (inputFile: string) => void;
|
|
12
|
+
update: (inputFile: string) => void;
|
|
13
|
+
delete: (outputFile: string) => void;
|
|
14
|
+
};
|
package/src/util.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import fs from 'fs/promises';
|
|
3
|
-
import { readdirSync } from 'fs';
|
|
4
2
|
|
|
5
|
-
import {
|
|
3
|
+
import { ManifestContext, ManifestModuleFileType, ManifestRoot, Package, path } from '@travetto/manifest';
|
|
6
4
|
|
|
7
|
-
type
|
|
5
|
+
type OutputToSource = (outputFile: string) => ({ source: string } | undefined);
|
|
8
6
|
export type FileWatchEvent = { type: 'create' | 'delete' | 'update', path: string };
|
|
9
7
|
|
|
10
8
|
const nativeCwd = process.cwd();
|
|
@@ -14,6 +12,20 @@ const nativeCwd = process.cwd();
|
|
|
14
12
|
*/
|
|
15
13
|
export class CompilerUtil {
|
|
16
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Determine if this is a manifest file we care about
|
|
17
|
+
*/
|
|
18
|
+
static validFile = (type: ManifestModuleFileType): boolean => type === 'ts' || type === 'package-json' || type === 'js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Map input file to output format, generally converting ts extensions to js
|
|
22
|
+
* @param file
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
static inputToOutput(file: string): string {
|
|
26
|
+
return file.replace(/[.][tj]s$/, '.js');
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
/**
|
|
18
30
|
* Determines if write callback data has sourcemap information
|
|
19
31
|
* @param data
|
|
@@ -27,35 +39,35 @@ export class CompilerUtil {
|
|
|
27
39
|
* Rewrite's sourcemap locations to real folders
|
|
28
40
|
* @returns
|
|
29
41
|
*/
|
|
30
|
-
static rewriteSourceMap(text: string,
|
|
31
|
-
const data: { sourceRoot
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (file
|
|
36
|
-
data.sourceRoot
|
|
37
|
-
data.sources = [file
|
|
42
|
+
static rewriteSourceMap(ctx: ManifestContext, text: string, outputToSource: OutputToSource): string {
|
|
43
|
+
const data: { sourceRoot?: string, sources: string[] } = JSON.parse(text);
|
|
44
|
+
const output = this.inputToOutput(path.resolve(ctx.workspacePath, ctx.outputFolder, data.sources[0]));
|
|
45
|
+
const { source: file } = outputToSource(output) ?? {};
|
|
46
|
+
|
|
47
|
+
if (file) {
|
|
48
|
+
delete data.sourceRoot;
|
|
49
|
+
data.sources = [file];
|
|
38
50
|
text = JSON.stringify(data);
|
|
39
51
|
}
|
|
40
|
-
|
|
41
52
|
return text;
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
/**
|
|
45
56
|
* Rewrite's inline sourcemap locations to real folders
|
|
46
57
|
* @param text
|
|
47
|
-
* @param
|
|
58
|
+
* @param outputToSource
|
|
48
59
|
* @param writeData
|
|
49
60
|
* @returns
|
|
50
61
|
*/
|
|
51
62
|
static rewriteInlineSourceMap(
|
|
63
|
+
ctx: ManifestContext,
|
|
52
64
|
text: string,
|
|
53
|
-
|
|
65
|
+
outputToSource: OutputToSource,
|
|
54
66
|
{ sourceMapUrlPos }: ts.WriteFileCallbackData & { sourceMapUrlPos: number }
|
|
55
67
|
): string {
|
|
56
68
|
const sourceMapUrl = text.substring(sourceMapUrlPos);
|
|
57
69
|
const [prefix, sourceMapData] = sourceMapUrl.split('base64,');
|
|
58
|
-
const rewritten = this.rewriteSourceMap(Buffer.from(sourceMapData, 'base64url').toString('utf8'),
|
|
70
|
+
const rewritten = this.rewriteSourceMap(ctx, Buffer.from(sourceMapData, 'base64url').toString('utf8'), outputToSource);
|
|
59
71
|
return [
|
|
60
72
|
text.substring(0, sourceMapUrlPos),
|
|
61
73
|
prefix,
|
|
@@ -71,15 +83,15 @@ export class CompilerUtil {
|
|
|
71
83
|
* @param text
|
|
72
84
|
* @returns
|
|
73
85
|
*/
|
|
74
|
-
static rewritePackageJSON(manifest: ManifestRoot, text: string
|
|
86
|
+
static rewritePackageJSON(manifest: ManifestRoot, text: string): string {
|
|
75
87
|
const pkg: Package = JSON.parse(text);
|
|
76
88
|
if (pkg.files) {
|
|
77
|
-
pkg.files = pkg.files.map(x =>
|
|
89
|
+
pkg.files = pkg.files.map(x => this.inputToOutput(x));
|
|
78
90
|
}
|
|
79
91
|
if (pkg.main) {
|
|
80
|
-
pkg.main = pkg.main
|
|
92
|
+
pkg.main = this.inputToOutput(pkg.main);
|
|
81
93
|
}
|
|
82
|
-
pkg.type =
|
|
94
|
+
pkg.type = manifest.moduleType;
|
|
83
95
|
for (const key of ['devDependencies', 'dependencies', 'peerDependencies'] as const) {
|
|
84
96
|
if (key in pkg) {
|
|
85
97
|
for (const dep of Object.keys(pkg[key] ?? {})) {
|
|
@@ -92,20 +104,6 @@ export class CompilerUtil {
|
|
|
92
104
|
return JSON.stringify(pkg, null, 2);
|
|
93
105
|
}
|
|
94
106
|
|
|
95
|
-
/**
|
|
96
|
-
* Read the given tsconfig.json values for the project
|
|
97
|
-
* @param path
|
|
98
|
-
* @returns
|
|
99
|
-
*/
|
|
100
|
-
static async readTsConfigOptions(file: string): Promise<ts.CompilerOptions> {
|
|
101
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
102
|
-
const { options } = ts.parseJsonSourceFileConfigFileContent(
|
|
103
|
-
ts.readJsonConfigFile(file, ts.sys.readFile), ts.sys, nativeCwd
|
|
104
|
-
);
|
|
105
|
-
options.target = ts.ScriptTarget.ESNext;
|
|
106
|
-
return options;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
107
|
/**
|
|
110
108
|
* Build transpilation error
|
|
111
109
|
* @param filename The name of the file
|
|
@@ -133,59 +131,6 @@ export class CompilerUtil {
|
|
|
133
131
|
return new Error(`Transpiling ${filename.replace(nativeCwd, '.')} failed: \n${errors.join('\n')}`);
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
/**
|
|
137
|
-
* Allows for watching of explicit folders
|
|
138
|
-
*
|
|
139
|
-
* @param onEvent
|
|
140
|
-
* @returns
|
|
141
|
-
*/
|
|
142
|
-
static async fileWatcher(
|
|
143
|
-
folders: string[],
|
|
144
|
-
onEvent: (ev: FileWatchEvent, folder: string) => void
|
|
145
|
-
): Promise<() => Promise<void>> {
|
|
146
|
-
const watcher = await import('@parcel/watcher');
|
|
147
|
-
const subs: (() => Promise<void>)[] = [];
|
|
148
|
-
for (const folder of folders) {
|
|
149
|
-
const sub = await watcher.subscribe(folder, (err, events) => {
|
|
150
|
-
for (const ev of events) {
|
|
151
|
-
onEvent(ev, folder);
|
|
152
|
-
}
|
|
153
|
-
}, { ignore: ['node_modules', ...readdirSync(folder).filter(x => x.startsWith('.') && x.length > 2)] });
|
|
154
|
-
subs.push(() => sub.unsubscribe());
|
|
155
|
-
}
|
|
156
|
-
const readiedSubs = await Promise.all(subs);
|
|
157
|
-
return () => Promise.all(readiedSubs.map(s => s())).then(() => { });
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Get loaded compiler options
|
|
162
|
-
*/
|
|
163
|
-
static async getCompilerOptions(outputFolder: string, bootTsConfig: string, workspace: string): Promise<ts.CompilerOptions> {
|
|
164
|
-
const opts: Partial<ts.CompilerOptions> = {};
|
|
165
|
-
const rootDir = nativeCwd;
|
|
166
|
-
const projTsconfig = path.resolve('tsconfig.json');
|
|
167
|
-
// Fallback to base tsconfig if not found in local folder
|
|
168
|
-
const config = (await fs.stat(projTsconfig).catch(() => false)) ? projTsconfig : bootTsConfig;
|
|
169
|
-
const base = await this.readTsConfigOptions(config);
|
|
170
|
-
|
|
171
|
-
const { type } = PackageUtil.readPackage(workspace);
|
|
172
|
-
|
|
173
|
-
if (type !== undefined) {
|
|
174
|
-
base.module = `${type}`.toLowerCase() === 'commonjs' ? ts.ModuleKind.CommonJS : ts.ModuleKind.ESNext;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
...base,
|
|
179
|
-
resolveJsonModule: true,
|
|
180
|
-
allowJs: true,
|
|
181
|
-
outDir: outputFolder,
|
|
182
|
-
sourceRoot: rootDir,
|
|
183
|
-
...opts,
|
|
184
|
-
rootDir,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
134
|
/**
|
|
190
135
|
* Naive hashing
|
|
191
136
|
*/
|