1 | import path, { resolve, dirname, relative, win32, posix, normalize } from 'path';
|
2 | import { createFilter } from '@rollup/pluginutils';
|
3 | import * as defaultTs from 'typescript';
|
4 | import { DiagnosticCategory } from 'typescript';
|
5 | import resolveId from 'resolve';
|
6 | import fs, { readFileSync } from 'fs';
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | function createFormattingHost(ts, compilerOptions) {
|
16 | return {
|
17 |
|
18 | getCompilationSettings: () => compilerOptions,
|
19 |
|
20 | getCurrentDirectory: () => process.cwd(),
|
21 |
|
22 | getNewLine() {
|
23 | switch (compilerOptions.newLine) {
|
24 | case ts.NewLineKind.CarriageReturnLineFeed:
|
25 | return '\r\n';
|
26 | case ts.NewLineKind.LineFeed:
|
27 | return '\n';
|
28 | default:
|
29 | return ts.sys.newLine;
|
30 | }
|
31 | },
|
32 |
|
33 | getCanonicalFileName: (fileName) => ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase()
|
34 | };
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | function createModuleResolver(ts, host) {
|
43 | const compilerOptions = host.getCompilationSettings();
|
44 | const cache = ts.createModuleResolutionCache(process.cwd(), host.getCanonicalFileName, compilerOptions);
|
45 | const moduleHost = Object.assign(Object.assign({}, ts.sys), host);
|
46 | return (moduleName, containingFile) => {
|
47 | const resolved = ts.nodeModuleNameResolver(moduleName, containingFile, compilerOptions, moduleHost, cache);
|
48 | return resolved.resolvedModule;
|
49 | };
|
50 | }
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | function __rest(s, e) {
|
68 | var t = {};
|
69 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
70 | t[p] = s[p];
|
71 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
72 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
73 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
74 | t[p[i]] = s[p[i]];
|
75 | }
|
76 | return t;
|
77 | }
|
78 |
|
79 | const resolveIdAsync = (file, opts) => new Promise((fulfil, reject) => resolveId(file, opts, (err, contents) => (err || typeof contents === 'undefined' ? reject(err) : fulfil(contents))));
|
80 |
|
81 |
|
82 |
|
83 | function getTsLibPath() {
|
84 | return resolveIdAsync('tslib/tslib.es6.js', { basedir: __dirname });
|
85 | }
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | function getPluginOptions(options) {
|
98 | const { cacheDir, exclude, include, transformers, tsconfig, tslib, typescript } = options, compilerOptions = __rest(options, ["cacheDir", "exclude", "include", "transformers", "tsconfig", "tslib", "typescript"]);
|
99 | const filter = createFilter(include || ['*.ts+(|x)', '**/*.ts+(|x)'], exclude);
|
100 | return {
|
101 | cacheDir,
|
102 | filter,
|
103 | tsconfig,
|
104 | compilerOptions: compilerOptions,
|
105 | typescript: typescript || defaultTs,
|
106 | tslib: tslib || getTsLibPath(),
|
107 | transformers
|
108 | };
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 |
|
114 | function diagnosticToWarning(ts, host, diagnostic) {
|
115 | const pluginCode = `TS${diagnostic.code}`;
|
116 | const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
117 |
|
118 | const warning = {
|
119 | pluginCode,
|
120 | message: `@rollup/plugin-typescript ${pluginCode}: ${message}`
|
121 | };
|
122 | if (diagnostic.file) {
|
123 |
|
124 | const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
125 | warning.loc = {
|
126 | column: character + 1,
|
127 | line: line + 1,
|
128 | file: diagnostic.file.fileName
|
129 | };
|
130 | if (host) {
|
131 |
|
132 | const formatted = ts.formatDiagnosticsWithColorAndContext([diagnostic], host);
|
133 |
|
134 |
|
135 | let frame = formatted.slice(formatted.indexOf(message) + message.length);
|
136 | const newLine = host.getNewLine();
|
137 | if (frame.startsWith(newLine)) {
|
138 | frame = frame.slice(frame.indexOf(newLine) + newLine.length);
|
139 | }
|
140 | warning.frame = frame;
|
141 | }
|
142 | }
|
143 | return warning;
|
144 | }
|
145 |
|
146 | const DEFAULT_COMPILER_OPTIONS = {
|
147 | module: 'esnext',
|
148 | skipLibCheck: true
|
149 | };
|
150 | const FORCED_COMPILER_OPTIONS = {
|
151 |
|
152 | noEmitHelpers: true,
|
153 | importHelpers: true,
|
154 |
|
155 | noEmit: false,
|
156 | emitDeclarationOnly: false,
|
157 |
|
158 | noResolve: false
|
159 | };
|
160 |
|
161 |
|
162 | const DIRECTORY_PROPS = ['outDir', 'declarationDir'];
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 | function makePathsAbsolute(compilerOptions, relativeTo) {
|
171 | for (const pathProp of DIRECTORY_PROPS) {
|
172 | if (compilerOptions[pathProp]) {
|
173 | compilerOptions[pathProp] = resolve(relativeTo, compilerOptions[pathProp]);
|
174 | }
|
175 | }
|
176 | }
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 | function normalizeCompilerOptions(ts, compilerOptions) {
|
183 | let autoSetSourceMap = false;
|
184 | if (compilerOptions.inlineSourceMap) {
|
185 |
|
186 | compilerOptions.sourceMap = true;
|
187 | compilerOptions.inlineSourceMap = false;
|
188 | }
|
189 | else if (typeof compilerOptions.sourceMap !== 'boolean') {
|
190 |
|
191 |
|
192 | compilerOptions.sourceMap = true;
|
193 |
|
194 |
|
195 | compilerOptions.inlineSources = true;
|
196 | autoSetSourceMap = true;
|
197 | }
|
198 | switch (compilerOptions.module) {
|
199 | case ts.ModuleKind.ES2015:
|
200 | case ts.ModuleKind.ESNext:
|
201 | case ts.ModuleKind.CommonJS:
|
202 |
|
203 | return autoSetSourceMap;
|
204 | case ts.ModuleKind.None:
|
205 | case ts.ModuleKind.AMD:
|
206 | case ts.ModuleKind.UMD:
|
207 | case ts.ModuleKind.System: {
|
208 |
|
209 | const moduleType = ts.ModuleKind[compilerOptions.module];
|
210 | throw new Error(`@rollup/plugin-typescript: The module kind should be 'ES2015' or 'ESNext, found: '${moduleType}'`);
|
211 | }
|
212 | default:
|
213 |
|
214 | compilerOptions.module = ts.ModuleKind.ESNext;
|
215 | }
|
216 | return autoSetSourceMap;
|
217 | }
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 | function getTsConfigPath(ts, relativePath) {
|
226 | if (relativePath === false)
|
227 | return null;
|
228 |
|
229 | const tsConfigPath = resolve(process.cwd(), relativePath || 'tsconfig.json');
|
230 | if (!ts.sys.fileExists(tsConfigPath)) {
|
231 | if (relativePath) {
|
232 |
|
233 | throw new Error(`Could not find specified tsconfig.json at ${tsConfigPath}`);
|
234 | }
|
235 | else {
|
236 | return null;
|
237 | }
|
238 | }
|
239 | return tsConfigPath;
|
240 | }
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 | function readTsConfigFile(ts, tsConfigPath) {
|
248 | const { config, error } = ts.readConfigFile(tsConfigPath, (path) => readFileSync(path, 'utf8'));
|
249 | if (error) {
|
250 | throw Object.assign(Error(), diagnosticToWarning(ts, null, error));
|
251 | }
|
252 | return config || {};
|
253 | }
|
254 |
|
255 |
|
256 |
|
257 |
|
258 | function containsEnumOptions(compilerOptions) {
|
259 | const enums = [
|
260 | 'module',
|
261 | 'target',
|
262 | 'jsx',
|
263 | 'moduleResolution',
|
264 | 'newLine'
|
265 | ];
|
266 | return enums.some((prop) => prop in compilerOptions && typeof compilerOptions[prop] === 'number');
|
267 | }
|
268 | const configCache = new Map();
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 | function parseTypescriptConfig(ts, tsconfig, compilerOptions) {
|
281 |
|
282 | const cwd = process.cwd();
|
283 | makePathsAbsolute(compilerOptions, cwd);
|
284 | let parsedConfig;
|
285 |
|
286 |
|
287 | const tsConfigPath = getTsConfigPath(ts, tsconfig) || undefined;
|
288 | const tsConfigFile = tsConfigPath ? readTsConfigFile(ts, tsConfigPath) : {};
|
289 | const basePath = tsConfigPath ? dirname(tsConfigPath) : cwd;
|
290 |
|
291 |
|
292 | if (containsEnumOptions(compilerOptions)) {
|
293 | parsedConfig = ts.parseJsonConfigFileContent(Object.assign(Object.assign({}, tsConfigFile), { compilerOptions: Object.assign(Object.assign({}, DEFAULT_COMPILER_OPTIONS), tsConfigFile.compilerOptions) }), ts.sys, basePath, Object.assign(Object.assign({}, compilerOptions), FORCED_COMPILER_OPTIONS), tsConfigPath, undefined, undefined, configCache);
|
294 | }
|
295 | else {
|
296 | parsedConfig = ts.parseJsonConfigFileContent(Object.assign(Object.assign({}, tsConfigFile), { compilerOptions: Object.assign(Object.assign(Object.assign({}, DEFAULT_COMPILER_OPTIONS), tsConfigFile.compilerOptions), compilerOptions) }), ts.sys, basePath, FORCED_COMPILER_OPTIONS, tsConfigPath, undefined, undefined, configCache);
|
297 | }
|
298 | const autoSetSourceMap = normalizeCompilerOptions(ts, parsedConfig.options);
|
299 | return Object.assign(Object.assign({}, parsedConfig), { autoSetSourceMap });
|
300 | }
|
301 |
|
302 |
|
303 |
|
304 |
|
305 | function emitParsedOptionsErrors(ts, context, parsedOptions) {
|
306 | if (parsedOptions.errors.length > 0) {
|
307 | parsedOptions.errors.forEach((error) => context.warn(diagnosticToWarning(ts, null, error)));
|
308 | context.error(`@rollup/plugin-typescript: Couldn't process compiler options`);
|
309 | }
|
310 | }
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 |
|
320 | function validateSourceMap(context, compilerOptions, outputOptions, autoSetSourceMap) {
|
321 | if (compilerOptions.sourceMap && !outputOptions.sourcemap && !autoSetSourceMap) {
|
322 | context.warn(`@rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.`);
|
323 | }
|
324 | else if (!compilerOptions.sourceMap && outputOptions.sourcemap) {
|
325 | context.warn(`@rollup/plugin-typescript: Typescript 'sourceMap' compiler option must be set to generate source maps.`);
|
326 | }
|
327 | }
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 | function validatePaths(ts, context, compilerOptions, outputOptions) {
|
335 | if (compilerOptions.out) {
|
336 | context.error(`@rollup/plugin-typescript: Deprecated Typescript compiler option 'out' is not supported. Use 'outDir' instead.`);
|
337 | }
|
338 | else if (compilerOptions.outFile) {
|
339 | context.error(`@rollup/plugin-typescript: Typescript compiler option 'outFile' is not supported. Use 'outDir' instead.`);
|
340 | }
|
341 | for (const dirProperty of DIRECTORY_PROPS) {
|
342 | if (compilerOptions[dirProperty] && outputOptions.dir) {
|
343 |
|
344 | const fromRollupDirToTs = relative(outputOptions.dir, compilerOptions[dirProperty]);
|
345 | if (fromRollupDirToTs.startsWith('..')) {
|
346 | context.error(`@rollup/plugin-typescript: Path of Typescript compiler option '${dirProperty}' must be located inside Rollup 'dir' option.`);
|
347 | }
|
348 | }
|
349 | }
|
350 | const tsBuildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(compilerOptions);
|
351 | if (tsBuildInfoPath && compilerOptions.incremental) {
|
352 | if (!outputOptions.dir) {
|
353 | context.error(`@rollup/plugin-typescript: Rollup 'dir' option must be used when Typescript compiler options 'tsBuildInfoFile' or 'incremental' are specified.`);
|
354 | }
|
355 |
|
356 | const fromRollupDirToTs = relative(outputOptions.dir, tsBuildInfoPath);
|
357 | if (fromRollupDirToTs.startsWith('..')) {
|
358 | context.error(`@rollup/plugin-typescript: Path of Typescript compiler option 'tsBuildInfoFile' must be located inside Rollup 'dir' option.`);
|
359 | }
|
360 | }
|
361 | if (compilerOptions.declaration || compilerOptions.declarationMap || compilerOptions.composite) {
|
362 | if (DIRECTORY_PROPS.every((dirProperty) => !compilerOptions[dirProperty])) {
|
363 | context.error(`@rollup/plugin-typescript: You are using one of Typescript's compiler options 'declaration', 'declarationMap' or 'composite'. ` +
|
364 | `In this case 'outDir' or 'declarationDir' must be specified to generate declaration files.`);
|
365 | }
|
366 | }
|
367 | }
|
368 |
|
369 |
|
370 |
|
371 |
|
372 | function isCodeOutputFile(name) {
|
373 | return !isMapOutputFile(name) && !name.endsWith('.d.ts');
|
374 | }
|
375 |
|
376 |
|
377 |
|
378 | function isMapOutputFile(name) {
|
379 | return name.endsWith('.map');
|
380 | }
|
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 | function getEmittedFile(fileName, emittedFiles, tsCache) {
|
389 | let code;
|
390 | if (fileName) {
|
391 | if (emittedFiles.has(fileName)) {
|
392 | code = emittedFiles.get(fileName);
|
393 | }
|
394 | else {
|
395 | code = tsCache.getCached(fileName);
|
396 | }
|
397 | }
|
398 | return code;
|
399 | }
|
400 |
|
401 |
|
402 |
|
403 |
|
404 |
|
405 |
|
406 | function findTypescriptOutput(ts, parsedOptions, id, emittedFiles, tsCache) {
|
407 | const emittedFileNames = ts.getOutputFileNames(parsedOptions, id, !ts.sys.useCaseSensitiveFileNames);
|
408 | const codeFile = emittedFileNames.find(isCodeOutputFile);
|
409 | const mapFile = emittedFileNames.find(isMapOutputFile);
|
410 | return {
|
411 | code: getEmittedFile(codeFile, emittedFiles, tsCache),
|
412 | map: getEmittedFile(mapFile, emittedFiles, tsCache),
|
413 | declarations: emittedFileNames.filter((name) => name !== codeFile && name !== mapFile)
|
414 | };
|
415 | }
|
416 |
|
417 |
|
418 | const CANNOT_COMPILE_ESM = 1204;
|
419 |
|
420 |
|
421 |
|
422 | function emitDiagnostic(ts, context, host, diagnostic) {
|
423 | if (diagnostic.code === CANNOT_COMPILE_ESM)
|
424 | return;
|
425 | const { noEmitOnError } = host.getCompilationSettings();
|
426 |
|
427 | const warning = diagnosticToWarning(ts, host, diagnostic);
|
428 |
|
429 | if (noEmitOnError && diagnostic.category === ts.DiagnosticCategory.Error) {
|
430 | context.error(warning);
|
431 | }
|
432 | else {
|
433 | context.warn(warning);
|
434 | }
|
435 | }
|
436 | function buildDiagnosticReporter(ts, context, host) {
|
437 | return function reportDiagnostics(diagnostic) {
|
438 | emitDiagnostic(ts, context, host, diagnostic);
|
439 | };
|
440 | }
|
441 |
|
442 |
|
443 |
|
444 |
|
445 | function mergeTransformers(builder, ...input) {
|
446 |
|
447 | const transformerTypes = ['after', 'afterDeclarations', 'before'];
|
448 | const accumulator = {
|
449 | after: [],
|
450 | afterDeclarations: [],
|
451 | before: []
|
452 | };
|
453 | let program;
|
454 | let typeChecker;
|
455 | input.forEach((transformers) => {
|
456 | if (!transformers) {
|
457 |
|
458 | return;
|
459 | }
|
460 | transformerTypes.forEach((stage) => {
|
461 | getTransformers(transformers[stage]).forEach((transformer) => {
|
462 | if (!transformer) {
|
463 |
|
464 | return;
|
465 | }
|
466 | if ('type' in transformer) {
|
467 | if (typeof transformer.factory === 'function') {
|
468 |
|
469 | program = program || builder.getProgram();
|
470 | typeChecker = typeChecker || program.getTypeChecker();
|
471 | let factory;
|
472 | if (transformer.type === 'program') {
|
473 | program = program || builder.getProgram();
|
474 | factory = transformer.factory(program);
|
475 | }
|
476 | else {
|
477 | program = program || builder.getProgram();
|
478 | typeChecker = typeChecker || program.getTypeChecker();
|
479 | factory = transformer.factory(typeChecker);
|
480 | }
|
481 |
|
482 | if (factory) {
|
483 | accumulator[stage].push(factory);
|
484 | }
|
485 | }
|
486 | }
|
487 | else {
|
488 |
|
489 | accumulator[stage].push(transformer);
|
490 | }
|
491 | });
|
492 | });
|
493 | });
|
494 | return accumulator;
|
495 | }
|
496 | function getTransformers(transformers) {
|
497 | return transformers || [];
|
498 | }
|
499 |
|
500 |
|
501 | var DiagnosticCode;
|
502 | (function (DiagnosticCode) {
|
503 | DiagnosticCode[DiagnosticCode["FILE_CHANGE_DETECTED"] = 6032] = "FILE_CHANGE_DETECTED";
|
504 | DiagnosticCode[DiagnosticCode["FOUND_1_ERROR_WATCHING_FOR_FILE_CHANGES"] = 6193] = "FOUND_1_ERROR_WATCHING_FOR_FILE_CHANGES";
|
505 | DiagnosticCode[DiagnosticCode["FOUND_N_ERRORS_WATCHING_FOR_FILE_CHANGES"] = 6194] = "FOUND_N_ERRORS_WATCHING_FOR_FILE_CHANGES";
|
506 | })(DiagnosticCode || (DiagnosticCode = {}));
|
507 | function createDeferred(timeout) {
|
508 | let promise;
|
509 | let resolve = () => { };
|
510 | if (timeout) {
|
511 | promise = Promise.race([
|
512 | new Promise((r) => setTimeout(r, timeout, true)),
|
513 | new Promise((r) => (resolve = r))
|
514 | ]);
|
515 | }
|
516 | else {
|
517 | promise = new Promise((r) => (resolve = r));
|
518 | }
|
519 | return { promise, resolve };
|
520 | }
|
521 |
|
522 |
|
523 |
|
524 | class WatchProgramHelper {
|
525 | constructor() {
|
526 | this._startDeferred = null;
|
527 | this._finishDeferred = null;
|
528 | }
|
529 | watch(timeout = 1000) {
|
530 |
|
531 | this._startDeferred = createDeferred(timeout);
|
532 | this._finishDeferred = createDeferred();
|
533 | }
|
534 | handleStatus(diagnostic) {
|
535 |
|
536 | if (diagnostic.category === DiagnosticCategory.Message) {
|
537 | switch (diagnostic.code) {
|
538 | case DiagnosticCode.FILE_CHANGE_DETECTED:
|
539 | this.resolveStart();
|
540 | break;
|
541 | case DiagnosticCode.FOUND_1_ERROR_WATCHING_FOR_FILE_CHANGES:
|
542 | case DiagnosticCode.FOUND_N_ERRORS_WATCHING_FOR_FILE_CHANGES:
|
543 | this.resolveFinish();
|
544 | break;
|
545 | }
|
546 | }
|
547 | }
|
548 | resolveStart() {
|
549 | if (this._startDeferred) {
|
550 | this._startDeferred.resolve(false);
|
551 | this._startDeferred = null;
|
552 | }
|
553 | }
|
554 | resolveFinish() {
|
555 | if (this._finishDeferred) {
|
556 | this._finishDeferred.resolve(false);
|
557 | this._finishDeferred = null;
|
558 | }
|
559 | }
|
560 | async wait() {
|
561 | var _a;
|
562 | if (this._startDeferred) {
|
563 | const timeout = await this._startDeferred.promise;
|
564 |
|
565 | if (timeout) {
|
566 | this._startDeferred = null;
|
567 | this._finishDeferred = null;
|
568 | }
|
569 | await ((_a = this._finishDeferred) === null || _a === void 0 ? void 0 : _a.promise);
|
570 | }
|
571 | }
|
572 | }
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 | function createWatchHost(ts, context, { formatHost, parsedOptions, writeFile, status, resolveModule, transformers }) {
|
580 | const createProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram;
|
581 | const baseHost = ts.createWatchCompilerHost(parsedOptions.fileNames, parsedOptions.options, ts.sys, createProgram, buildDiagnosticReporter(ts, context, formatHost), status, parsedOptions.projectReferences);
|
582 | return Object.assign(Object.assign({}, baseHost), {
|
583 |
|
584 | afterProgramCreate(program) {
|
585 | const origEmit = program.emit;
|
586 |
|
587 | program.emit = (targetSourceFile, _, ...args) => origEmit(targetSourceFile, writeFile,
|
588 |
|
589 | args[0],
|
590 |
|
591 | args[1], mergeTransformers(program, transformers, args[2]));
|
592 | return baseHost.afterProgramCreate(program);
|
593 | },
|
594 |
|
595 | resolveModuleNames(moduleNames, containingFile) {
|
596 | return moduleNames.map((moduleName) => resolveModule(moduleName, containingFile));
|
597 | } });
|
598 | }
|
599 | function createWatchProgram(ts, context, options) {
|
600 | return ts.createWatchProgram(createWatchHost(ts, context, options));
|
601 | }
|
602 |
|
603 |
|
604 | const createFileFolder = (filePath) => {
|
605 | const folderPath = path.dirname(filePath);
|
606 | fs.mkdirSync(folderPath, { recursive: true });
|
607 | };
|
608 | class TSCache {
|
609 | constructor(cacheFolder = '.rollup.cache') {
|
610 | this._cacheFolder = cacheFolder;
|
611 | }
|
612 |
|
613 | cachedFilename(fileName) {
|
614 | return path.join(this._cacheFolder, fileName.replace(/^([A-Z]+):/, '$1'));
|
615 | }
|
616 |
|
617 | cacheCode(fileName, code) {
|
618 | const cachedPath = this.cachedFilename(fileName);
|
619 | createFileFolder(cachedPath);
|
620 | fs.writeFileSync(cachedPath, code);
|
621 | }
|
622 |
|
623 | isCached(fileName) {
|
624 | return fs.existsSync(this.cachedFilename(fileName));
|
625 | }
|
626 |
|
627 | getCached(fileName) {
|
628 | let code;
|
629 | if (this.isCached(fileName)) {
|
630 | code = fs.readFileSync(this.cachedFilename(fileName), { encoding: 'utf-8' });
|
631 | }
|
632 | return code;
|
633 | }
|
634 | }
|
635 |
|
636 | function typescript(options = {}) {
|
637 | const { cacheDir, compilerOptions, filter, transformers, tsconfig, tslib, typescript: ts } = getPluginOptions(options);
|
638 | const tsCache = new TSCache(cacheDir);
|
639 | const emittedFiles = new Map();
|
640 | const watchProgramHelper = new WatchProgramHelper();
|
641 | const parsedOptions = parseTypescriptConfig(ts, tsconfig, compilerOptions);
|
642 | parsedOptions.fileNames = parsedOptions.fileNames.filter(filter);
|
643 | const formatHost = createFormattingHost(ts, parsedOptions.options);
|
644 | const resolveModule = createModuleResolver(ts, formatHost);
|
645 | let program = null;
|
646 | function normalizePath(fileName) {
|
647 | return fileName.split(win32.sep).join(posix.sep);
|
648 | }
|
649 | return {
|
650 | name: 'typescript',
|
651 | buildStart() {
|
652 | emitParsedOptionsErrors(ts, this, parsedOptions);
|
653 |
|
654 | if (!program) {
|
655 | program = createWatchProgram(ts, this, {
|
656 | formatHost,
|
657 | resolveModule,
|
658 | parsedOptions,
|
659 | writeFile(fileName, data) {
|
660 | if (parsedOptions.options.composite || parsedOptions.options.incremental) {
|
661 | tsCache.cacheCode(fileName, data);
|
662 | }
|
663 | emittedFiles.set(fileName, data);
|
664 | },
|
665 | status(diagnostic) {
|
666 | watchProgramHelper.handleStatus(diagnostic);
|
667 | },
|
668 | transformers
|
669 | });
|
670 | }
|
671 | },
|
672 | watchChange(id) {
|
673 | if (!filter(id))
|
674 | return;
|
675 | watchProgramHelper.watch();
|
676 | },
|
677 | buildEnd() {
|
678 | if (this.meta.watchMode !== true) {
|
679 |
|
680 |
|
681 | program === null || program === void 0 ? void 0 : program.close();
|
682 | }
|
683 | },
|
684 | renderStart(outputOptions) {
|
685 | validateSourceMap(this, parsedOptions.options, outputOptions, parsedOptions.autoSetSourceMap);
|
686 | validatePaths(ts, this, parsedOptions.options, outputOptions);
|
687 | },
|
688 | resolveId(importee, importer) {
|
689 | if (importee === 'tslib') {
|
690 | return tslib;
|
691 | }
|
692 | if (!importer)
|
693 | return null;
|
694 |
|
695 | const containingFile = normalizePath(importer);
|
696 | const resolved = resolveModule(importee, containingFile);
|
697 | if (resolved) {
|
698 | if (resolved.extension === '.d.ts')
|
699 | return null;
|
700 | return normalize(resolved.resolvedFileName);
|
701 | }
|
702 | return null;
|
703 | },
|
704 | async load(id) {
|
705 | if (!filter(id))
|
706 | return null;
|
707 | await watchProgramHelper.wait();
|
708 | const fileName = normalizePath(id);
|
709 | if (!parsedOptions.fileNames.includes(fileName)) {
|
710 |
|
711 | parsedOptions.fileNames.push(fileName);
|
712 | }
|
713 | const output = findTypescriptOutput(ts, parsedOptions, id, emittedFiles, tsCache);
|
714 | return output.code != null ? output : null;
|
715 | },
|
716 | generateBundle(outputOptions) {
|
717 | parsedOptions.fileNames.forEach((fileName) => {
|
718 | const output = findTypescriptOutput(ts, parsedOptions, fileName, emittedFiles, tsCache);
|
719 | output.declarations.forEach((id) => {
|
720 | const code = getEmittedFile(id, emittedFiles, tsCache);
|
721 | let baseDir = outputOptions.dir;
|
722 | if (!baseDir && tsconfig) {
|
723 | baseDir = tsconfig.substring(0, tsconfig.lastIndexOf('/'));
|
724 | }
|
725 | if (!code || !baseDir)
|
726 | return;
|
727 | this.emitFile({
|
728 | type: 'asset',
|
729 | fileName: normalizePath(relative(baseDir, id)),
|
730 | source: code
|
731 | });
|
732 | });
|
733 | });
|
734 | const tsBuildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(parsedOptions.options);
|
735 | if (tsBuildInfoPath) {
|
736 | const tsBuildInfoSource = emittedFiles.get(tsBuildInfoPath);
|
737 |
|
738 | if (tsBuildInfoSource) {
|
739 | this.emitFile({
|
740 | type: 'asset',
|
741 | fileName: normalizePath(relative(outputOptions.dir, tsBuildInfoPath)),
|
742 | source: tsBuildInfoSource
|
743 | });
|
744 | }
|
745 | }
|
746 | }
|
747 | };
|
748 | }
|
749 |
|
750 | export default typescript;
|