vite-plugin-dts 2.3.0 → 3.0.0-beta.2

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/dist/index.mjs CHANGED
@@ -5,20 +5,16 @@ import __cjs_mod__ from 'module';
5
5
  const __filename = __cjs_url__.fileURLToPath(import.meta.url);
6
6
  const __dirname = __cjs_path__.dirname(__filename);
7
7
  const require = __cjs_mod__.createRequire(import.meta.url);
8
- import { isAbsolute, resolve as resolve$1, dirname, normalize, sep, relative, basename } from 'node:path';
9
- import fs from 'fs-extra';
10
- import os from 'os';
11
- import { cyan, yellow, red, green } from 'kolorist';
12
- import glob from 'fast-glob';
13
- import debug from 'debug';
14
- import { Project } from 'ts-morph';
15
- import { normalizePath, createLogger } from 'vite';
16
- import { createFilter } from '@rollup/pluginutils';
8
+ import { resolve as resolve$1, posix, isAbsolute, dirname, normalize, sep, relative, basename } from 'node:path';
17
9
  import { existsSync, readdirSync, lstatSync, rmdirSync } from 'node:fs';
18
- import typescript from 'typescript';
19
- import { createRequire } from 'node:module';
20
- import { parse } from '@babel/parser';
21
- import MagicString from 'magic-string';
10
+ import { readFile, writeFile, mkdir, unlink } from 'node:fs/promises';
11
+ import { platform, cpus } from 'node:os';
12
+ import ts from 'typescript';
13
+ import { createFilter } from '@rollup/pluginutils';
14
+ import { createParsedCommandLine } from '@vue/language-core';
15
+ import { createProgram } from 'vue-tsc';
16
+ import debug from 'debug';
17
+ import { cyan, yellow, green } from 'kolorist';
22
18
  import { ExtractorConfig, CompilerState } from '@microsoft/api-extractor';
23
19
  import { Collector } from '@microsoft/api-extractor/lib/collector/Collector.js';
24
20
  import { MessageRouter } from '@microsoft/api-extractor/lib/collector/MessageRouter.js';
@@ -26,6 +22,105 @@ import { SourceMapper } from '@microsoft/api-extractor/lib/collector/SourceMappe
26
22
  import { DtsRollupGenerator, DtsRollupKind } from '@microsoft/api-extractor/lib/generators/DtsRollupGenerator.js';
27
23
  import { PackageJsonLookup } from '@rushstack/node-core-library';
28
24
 
25
+ const dtsRE$1 = /\.d\.tsx?$/;
26
+ function rollupDeclarationFiles({
27
+ root,
28
+ compilerOptions,
29
+ outDir,
30
+ entryPath,
31
+ fileName,
32
+ libFolder,
33
+ bundledPackages
34
+ }) {
35
+ const configObjectFullPath = resolve$1(root, "api-extractor.json");
36
+ const packageJsonLookup = new PackageJsonLookup();
37
+ const packageJsonFullPath = packageJsonLookup.tryGetPackageJsonFilePathFor(configObjectFullPath);
38
+ if (!dtsRE$1.test(fileName)) {
39
+ fileName += ".d.ts";
40
+ }
41
+ const extractorConfig = ExtractorConfig.prepare({
42
+ configObject: {
43
+ projectFolder: root,
44
+ mainEntryPointFilePath: entryPath,
45
+ bundledPackages,
46
+ compiler: {
47
+ // tsconfigFilePath: tsConfigPath,
48
+ overrideTsconfig: {
49
+ $schema: "http://json.schemastore.org/tsconfig",
50
+ compilerOptions: {
51
+ ...compilerOptions,
52
+ target: "ESNext"
53
+ }
54
+ }
55
+ },
56
+ apiReport: {
57
+ enabled: false,
58
+ reportFileName: "<unscopedPackageName>.api.md"
59
+ },
60
+ docModel: {
61
+ enabled: false
62
+ },
63
+ dtsRollup: {
64
+ enabled: true,
65
+ publicTrimmedFilePath: resolve$1(outDir, fileName)
66
+ },
67
+ tsdocMetadata: {
68
+ enabled: false
69
+ },
70
+ messages: {
71
+ compilerMessageReporting: {
72
+ default: {
73
+ logLevel: "none"
74
+ }
75
+ },
76
+ extractorMessageReporting: {
77
+ default: {
78
+ logLevel: "none"
79
+ }
80
+ }
81
+ }
82
+ },
83
+ configObjectFullPath,
84
+ packageJsonFullPath
85
+ });
86
+ const compilerState = CompilerState.create(extractorConfig, {
87
+ localBuild: false,
88
+ showVerboseMessages: false,
89
+ typescriptCompilerFolder: libFolder ? resolve$1(libFolder, "..") : void 0
90
+ });
91
+ const sourceMapper = new SourceMapper();
92
+ const messageRouter = new MessageRouter({
93
+ workingPackageFolder: root,
94
+ messageCallback: void 0,
95
+ messagesConfig: extractorConfig.messages,
96
+ showVerboseMessages: false,
97
+ showDiagnostics: false,
98
+ tsdocConfiguration: extractorConfig.tsdocConfiguration,
99
+ sourceMapper
100
+ });
101
+ const collector = new Collector({
102
+ program: compilerState.program,
103
+ messageRouter,
104
+ extractorConfig,
105
+ sourceMapper
106
+ });
107
+ collector.analyze();
108
+ DtsRollupGenerator.writeTypingsFile(
109
+ collector,
110
+ extractorConfig.publicTrimmedFilePath,
111
+ DtsRollupKind.PublicRelease,
112
+ extractorConfig.newlineKind
113
+ );
114
+ }
115
+
116
+ const windowsSlashRE = /\\/g;
117
+ function slash(p) {
118
+ return p.replace(windowsSlashRE, "/");
119
+ }
120
+ const isWindows = platform() === "win32";
121
+ function normalizePath(id) {
122
+ return posix.normalize(isWindows ? slash(id) : id);
123
+ }
29
124
  function isNativeObj(value) {
30
125
  return Object.prototype.toString.call(value) === "[object Object]";
31
126
  }
@@ -35,39 +130,6 @@ function isRegExp(value) {
35
130
  function isPromise(value) {
36
131
  return !!value && typeof value.then === "function" && typeof value.catch === "function";
37
132
  }
38
- function mergeObjects(sourceObj, targetObj) {
39
- const loop = [
40
- {
41
- source: sourceObj,
42
- target: targetObj
43
- }
44
- ];
45
- while (loop.length) {
46
- const { source, target } = loop.pop();
47
- Object.keys(target).forEach((key) => {
48
- if (isNativeObj(target[key])) {
49
- if (!isNativeObj(source[key])) {
50
- source[key] = {};
51
- }
52
- loop.push({
53
- source: source[key],
54
- target: target[key]
55
- });
56
- } else if (Array.isArray(target[key])) {
57
- if (!Array.isArray(source[key])) {
58
- source[key] = [];
59
- }
60
- loop.push({
61
- source: source[key],
62
- target: target[key]
63
- });
64
- } else {
65
- source[key] = target[key];
66
- }
67
- });
68
- }
69
- return sourceObj;
70
- }
71
133
  function ensureAbsolute(path, root) {
72
134
  return path ? isAbsolute(path) ? path : resolve$1(root, path) : root;
73
135
  }
@@ -148,25 +210,6 @@ function removeDirIfEmpty(dir) {
148
210
  }
149
211
  return onlyHasDir;
150
212
  }
151
- function getTsConfig(tsConfigPath, readFileSync) {
152
- const tsConfig = {
153
- compilerOptions: {},
154
- ...typescript.readConfigFile(tsConfigPath, readFileSync).config ?? {}
155
- };
156
- if (tsConfig.extends) {
157
- ensureArray(tsConfig.extends).forEach((configPath) => {
158
- const config = getTsConfig(ensureAbsolute(configPath, dirname(tsConfigPath)), readFileSync);
159
- Object.assign(tsConfig.compilerOptions, config.compilerOptions);
160
- if (!tsConfig.include) {
161
- tsConfig.include = config.include;
162
- }
163
- if (!tsConfig.exclude) {
164
- tsConfig.exclude = config.exclude;
165
- }
166
- });
167
- }
168
- return tsConfig;
169
- }
170
213
 
171
214
  const globSuffixRE = /^((?:.*\.[^.]+)|(?:\*+))$/;
172
215
  function normalizeGlob(path) {
@@ -256,456 +299,72 @@ const pureImportRE = /import\s?['"][^;\n]+?['"];?\n?/g;
256
299
  function removePureImport(content) {
257
300
  return content.replace(pureImportRE, "");
258
301
  }
259
- const setupFunctionRE = /function setup\([\s\S]+\)\s+?\{[\s\S]+return __returned__\n\}/;
260
- function transferSetupPosition(content) {
261
- const match = content.match(setupFunctionRE);
262
- if (match) {
263
- const setupFunction = match[0];
264
- return content.replace(setupFunction, "").replace("setup})", setupFunction.slice("function ".length) + "\n\r})");
265
- }
266
- return content;
267
- }
268
-
269
- const noScriptContent = "import { defineComponent } from 'vue'\nexport default defineComponent({})";
270
- const _require = createRequire(import.meta.url);
271
- let index = 1;
272
- let compileRoot = null;
273
- let compiler;
274
- let vue;
275
- function requireCompiler() {
276
- if (!compiler) {
277
- if (compileRoot) {
278
- try {
279
- compiler = _require(_require.resolve("vue/compiler-sfc", { paths: [compileRoot] }));
280
- } catch (e) {
281
- try {
282
- compiler = _require(_require.resolve("@vue/compiler-sfc", { paths: [compileRoot] }));
283
- } catch (e2) {
284
- }
285
- }
286
- }
287
- if (!compiler) {
288
- try {
289
- compiler = _require("vue/compiler-sfc");
290
- } catch (e) {
291
- try {
292
- compiler = _require("@vue/compiler-sfc");
293
- } catch (e2) {
294
- throw new Error("@vue/compiler-sfc is not present in the dependency tree.\n");
295
- }
296
- }
297
- }
298
- }
299
- return compiler;
300
- }
301
- function isVue3() {
302
- if (!vue) {
303
- if (compileRoot) {
304
- try {
305
- vue = _require(_require.resolve("vue", { paths: [compileRoot] }));
306
- } catch (e) {
307
- }
308
- }
309
- if (!vue) {
310
- try {
311
- vue = _require("vue");
312
- } catch (e) {
313
- throw new Error("vue is not present in the dependency tree.\n");
314
- }
315
- }
316
- }
317
- return vue.version.startsWith("3");
318
- }
319
- function setCompileRoot(root) {
320
- if (root && root !== compileRoot) {
321
- compileRoot = root;
322
- compiler = null;
323
- }
324
- }
325
- function parseCode(code) {
326
- const { parse: parseVueCode } = requireCompiler();
327
- let descriptor;
328
- if (isVue3()) {
329
- descriptor = parseVueCode(code).descriptor;
330
- } else {
331
- descriptor = parseVueCode({ source: code });
332
- }
333
- return descriptor;
334
- }
335
- function transformJsToTs(script) {
336
- if (!script)
337
- return script;
338
- const lang = !script.lang || script.lang === "js" ? "ts" : script.lang === "jsx" ? "tsx" : script.lang;
339
- return { ...script, lang };
340
- }
341
- function preprocessVueCode(code, setupScript) {
342
- const plugins = ["typescript", "decorators-legacy", "jsx"];
343
- const scriptAst = parse(code, { sourceType: "module", plugins }).program.body;
344
- const source = new MagicString(code);
345
- let propsTypeName;
346
- let propsTypeLiteral;
347
- if (setupScript) {
348
- let processDefineProps = function(node) {
349
- if (node.type === "CallExpression" && node.callee.type === "Identifier") {
350
- if (node.callee.name === "defineProps") {
351
- defineProps = node;
352
- return true;
353
- } else if (node.callee.name === "withDefaults") {
354
- const propsDef = node.arguments[0];
355
- if (propsDef.type === "CallExpression" && propsDef.callee.type === "Identifier" && propsDef.callee.name === "defineProps") {
356
- defineProps = propsDef;
357
- return true;
358
- }
359
- }
360
- }
361
- return false;
362
- };
363
- const setupAst = parse(setupScript.content, { sourceType: "module", plugins }).program.body;
364
- let defineProps;
365
- for (const node of setupAst) {
366
- if (node.type === "ExpressionStatement") {
367
- processDefineProps(node.expression);
368
- } else if (node.type === "VariableDeclaration" && !node.declare) {
369
- for (const decl of node.declarations) {
370
- if (decl.init && processDefineProps(decl.init)) {
371
- break;
372
- }
373
- }
374
- }
375
- if (defineProps) {
376
- const type = defineProps.typeParameters?.params[0];
377
- if (type && type.type === "TSTypeReference" && type.typeName.type === "Identifier") {
378
- propsTypeName = type.typeName.name;
379
- } else if (type?.type === "TSTypeLiteral") {
380
- propsTypeName = "__DTS_Props__";
381
- propsTypeLiteral = setupScript.content.substring(type.start, type.end);
382
- }
383
- break;
384
- }
385
- }
386
- }
387
- const declRecord = /* @__PURE__ */ new Map();
388
- let defaultExport;
389
- let options;
390
- for (const node of scriptAst) {
391
- if (node.type === "VariableDeclaration") {
392
- for (const decl of node.declarations) {
393
- if (decl.id.type === "Identifier" && decl.init) {
394
- let properties;
395
- if (decl.init.type === "ObjectExpression") {
396
- properties = decl.init.properties;
397
- } else if (decl.init.type === "CallExpression" && decl.init.arguments[0]?.type === "ObjectExpression") {
398
- properties = decl.init.arguments[0].properties;
399
- }
400
- if (!properties)
401
- continue;
402
- if (defaultExport && decl.id.name === defaultExport) {
403
- options = properties;
404
- break;
405
- } else {
406
- declRecord.set(decl.id.name, properties);
407
- }
408
- }
409
- }
410
- }
411
- if (node.type === "ExportDefaultDeclaration") {
412
- if (node.declaration.type === "ObjectExpression") {
413
- options = node.declaration.properties;
414
- } else if (node.declaration.type === "CallExpression" && node.declaration.arguments[0]?.type === "ObjectExpression") {
415
- options = node.declaration.arguments[0].properties;
416
- } else if (node.declaration.type === "Identifier") {
417
- if (declRecord.has(node.declaration.name)) {
418
- options = declRecord.get(node.declaration.name);
419
- } else {
420
- defaultExport = node.declaration.name;
421
- }
422
- }
423
- }
424
- if (options) {
425
- for (const option of options) {
426
- if (propsTypeName && option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "props" && option.value.type === "ObjectExpression") {
427
- for (const prop of option.value.properties) {
428
- if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
429
- if (prop.value.type === "ObjectExpression") {
430
- for (const propDef of prop.value.properties) {
431
- if (propDef.type === "ObjectProperty" && propDef.key.type === "Identifier" && propDef.key.name === "type") {
432
- source.prependLeft(
433
- propDef.end,
434
- ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
435
- );
436
- }
437
- }
438
- } else {
439
- source.prependLeft(
440
- prop.end,
441
- ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
442
- );
443
- }
444
- }
445
- }
446
- }
447
- if (option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "components") {
448
- source.overwrite(option.value.start, option.value.end, "undefined");
449
- }
450
- if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
451
- let exposed;
452
- let returned;
453
- for (const node2 of option.body.body) {
454
- if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
455
- exposed = node2.expression.arguments[0];
456
- continue;
457
- }
458
- if (node2.type === "ReturnStatement") {
459
- returned = node2;
460
- break;
461
- }
462
- }
463
- const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
464
- if (newReturned) {
465
- if (returned) {
466
- source.overwrite(returned.start, returned.end, newReturned);
467
- } else if (option.body.body.length) {
468
- source.appendRight(option.body.body.at(-1).end, `
469
- ${newReturned}
470
- `);
471
- }
472
- }
473
- }
474
- }
475
- break;
476
- }
477
- }
478
- if (propsTypeName) {
479
- if (propsTypeLiteral) {
480
- source.prepend(`
481
- type ${propsTypeName} = ${propsTypeLiteral}
482
-
483
- `);
484
- }
485
- source.prepend("import type { PropType as __PropType } from 'vue'\n");
486
- }
487
- return source.toString();
488
- }
489
- function compileVueCode(code) {
490
- const { compileScript, rewriteDefault } = requireCompiler();
491
- const descriptor = parseCode(code);
492
- const { script, scriptSetup } = descriptor;
493
- let error;
494
- let content;
495
- let ext = "js";
496
- if (script || scriptSetup) {
497
- const compiled = compileScript(
498
- {
499
- ...descriptor,
500
- script: transformJsToTs(script),
501
- scriptSetup: transformJsToTs(scriptSetup),
502
- cssVars: []
503
- },
504
- { id: `${index++}` }
505
- );
506
- try {
507
- content = preprocessVueCode(compiled.content, scriptSetup);
508
- } catch (e) {
509
- error = e;
510
- content = compiled.content;
511
- }
512
- content = rewriteDefault(content, "_sfc_main", ["typescript", "decorators-legacy"]);
513
- if (scriptSetup) {
514
- content = transferSetupPosition(content);
515
- ext = scriptSetup.lang || "js";
516
- } else if (script && script.content) {
517
- ext = script.lang || "js";
518
- }
519
- content += "\nexport default _sfc_main\n";
520
- } else {
521
- content = noScriptContent;
522
- ext = "ts";
523
- }
524
- return { error, content, ext };
525
- }
526
-
527
- const dtsRE$1 = /\.d\.tsx?$/;
528
- function rollupDeclarationFiles({
529
- root,
530
- compilerOptions,
531
- outputDir,
532
- entryPath,
533
- fileName,
534
- libFolder,
535
- bundledPackages
536
- }) {
537
- const configObjectFullPath = resolve$1(root, "api-extractor.json");
538
- const packageJsonLookup = new PackageJsonLookup();
539
- const packageJsonFullPath = packageJsonLookup.tryGetPackageJsonFilePathFor(configObjectFullPath);
540
- if (!dtsRE$1.test(fileName)) {
541
- fileName += ".d.ts";
542
- }
543
- const extractorConfig = ExtractorConfig.prepare({
544
- configObject: {
545
- projectFolder: root,
546
- mainEntryPointFilePath: entryPath,
547
- bundledPackages,
548
- compiler: {
549
- overrideTsconfig: {
550
- $schema: "http://json.schemastore.org/tsconfig",
551
- compilerOptions
552
- }
553
- },
554
- apiReport: {
555
- enabled: false,
556
- reportFileName: "<unscopedPackageName>.api.md"
557
- },
558
- docModel: {
559
- enabled: false
560
- },
561
- dtsRollup: {
562
- enabled: true,
563
- publicTrimmedFilePath: resolve$1(outputDir, fileName)
564
- },
565
- tsdocMetadata: {
566
- enabled: false
567
- },
568
- messages: {
569
- compilerMessageReporting: {
570
- default: {
571
- logLevel: "none"
572
- }
573
- },
574
- extractorMessageReporting: {
575
- default: {
576
- logLevel: "none"
577
- }
578
- }
579
- }
580
- },
581
- configObjectFullPath,
582
- packageJsonFullPath
583
- });
584
- const compilerState = CompilerState.create(extractorConfig, {
585
- localBuild: false,
586
- showVerboseMessages: false,
587
- typescriptCompilerFolder: libFolder ? resolve$1(libFolder, "..") : void 0
588
- });
589
- const sourceMapper = new SourceMapper();
590
- const messageRouter = new MessageRouter({
591
- workingPackageFolder: root,
592
- messageCallback: void 0,
593
- messagesConfig: extractorConfig.messages,
594
- showVerboseMessages: false,
595
- showDiagnostics: false,
596
- tsdocConfiguration: extractorConfig.tsdocConfiguration,
597
- sourceMapper
598
- });
599
- const collector = new Collector({
600
- program: compilerState.program,
601
- messageRouter,
602
- extractorConfig,
603
- sourceMapper
604
- });
605
- collector.analyze();
606
- DtsRollupGenerator.writeTypingsFile(
607
- collector,
608
- extractorConfig.publicTrimmedFilePath,
609
- DtsRollupKind.PublicRelease,
610
- extractorConfig.newlineKind
611
- );
612
- }
613
302
 
614
- const noneExport = "export {};\n";
615
303
  const vueRE = /\.vue$/;
616
- const svelteRE = /\.svelte$/;
617
304
  const tsRE = /\.(m|c)?tsx?$/;
618
- const jsRE = /\.(m|c)?jsx?$/;
619
305
  const dtsRE = /\.d\.(m|c)?tsx?$/;
620
306
  const tjsRE = /\.(m|c)?(t|j)sx?$/;
621
307
  const mtjsRE = /\.m(t|j)sx?$/;
622
308
  const ctjsRE = /\.c(t|j)sx?$/;
623
- const watchExtensionRE = /\.(vue|(m|c)?(t|j)sx?)$/;
624
309
  const fullRelativeRE = /^\.\.?\//;
310
+ const watchExtensionRE = /\.(vue|(m|c)?(t|j)sx?)$/;
625
311
  const defaultIndex = "index.d.ts";
312
+ const logPrefix = cyan("[vite:dts]");
313
+ const bundleDebug = debug("vite-plugin-dts:bundle");
314
+ const fixedCompilerOptions = {
315
+ noEmit: false,
316
+ declaration: true,
317
+ emitDeclarationOnly: true,
318
+ noUnusedParameters: false,
319
+ checkJs: false,
320
+ skipLibCheck: true,
321
+ preserveSymlinks: false,
322
+ noEmitOnError: void 0,
323
+ target: ts.ScriptTarget.ESNext
324
+ };
626
325
  const noop = () => {
627
326
  };
628
327
  const extPrefix = (file) => mtjsRE.test(file) ? "m" : ctjsRE.test(file) ? "c" : "";
629
328
  const resolve = (...paths) => normalizePath(resolve$1(...paths));
630
- const logPrefix = cyan("[vite:dts]");
631
- const bundleDebug = debug("vite-plugin-dts:bundle");
632
329
  function dtsPlugin(options = {}) {
633
330
  const {
634
- tsConfigFilePath = "tsconfig.json",
635
- aliasesExclude = [],
636
- cleanVueFileName = false,
331
+ tsconfigPath,
637
332
  staticImport = false,
638
333
  clearPureImport = true,
334
+ cleanVueFileName = false,
639
335
  insertTypesEntry = false,
640
336
  rollupTypes = false,
641
337
  bundledPackages = [],
642
- noEmitOnError = false,
643
- skipDiagnostics = false,
338
+ aliasesExclude = [],
339
+ logLevel,
644
340
  copyDtsFiles = false,
645
- logLevel = void 0,
646
341
  afterDiagnostic = noop,
647
342
  beforeWriteFile = noop,
648
343
  afterBuild = noop
649
344
  } = options;
650
- let compilerOptions = options.compilerOptions ?? {};
651
- let root;
345
+ let root = ensureAbsolute(options.root ?? "", process.cwd());
652
346
  let entryRoot = options.entryRoot ?? "";
653
- let libName;
654
- let indexName;
655
- let aliases;
347
+ let compilerOptions;
348
+ let rawCompilerOptions;
349
+ let outDirs;
656
350
  let entries;
657
- let logger;
658
- let project;
659
- let tsConfigPath;
660
- let outputDirs;
661
- let isBundle = false;
662
351
  let include;
663
352
  let exclude;
353
+ let aliases;
354
+ let libName;
355
+ let indexName;
356
+ let logger;
357
+ let host;
358
+ let program;
664
359
  let filter;
665
- let libFolderPath = options.libFolderPath;
666
- const sourceDtsFiles = /* @__PURE__ */ new Set();
667
- const includedFiles = /* @__PURE__ */ new Set();
668
- const emittedFiles = /* @__PURE__ */ new Map();
669
- let hasJsVue = false;
670
- let allowJs = false;
671
- let transformError = false;
672
- async function internalTransform(id) {
673
- if (!project || !filter(id)) {
674
- return;
675
- }
676
- if (vueRE.test(id)) {
677
- const { error, content, ext } = compileVueCode(await fs.readFile(id, "utf-8"));
678
- if (!transformError && error) {
679
- logger.error(
680
- red(
681
- `
682
- ${cyan(
683
- "[vite:dts]"
684
- )} A error occurred when transform code, maybe there are some inertnal bugs.
685
- `
686
- )
687
- );
688
- transformError = true;
689
- }
690
- if (content) {
691
- if (ext === "js" || ext === "jsx")
692
- hasJsVue = true;
693
- project.createSourceFile(`${id}.${ext || "js"}`, content, { overwrite: true });
694
- }
695
- } else if (!id.includes(".vue?vue") && (tsRE.test(id) || allowJs && jsRE.test(id))) {
696
- project.createSourceFile(id, await fs.readFile(id, "utf-8"), { overwrite: true });
697
- } else if (svelteRE.test(id)) {
698
- const content = "export { SvelteComponentTyped as default } from 'svelte/internal';";
699
- project.createSourceFile(`${id}.ts`, content, { overwrite: true });
700
- }
701
- }
360
+ let bundled = false;
361
+ const rootFiles = /* @__PURE__ */ new Set();
362
+ const outputFiles = /* @__PURE__ */ new Map();
702
363
  return {
703
364
  name: "vite:dts",
704
365
  apply: "build",
705
366
  enforce: "pre",
706
367
  config(config) {
707
- if (isBundle)
708
- return;
709
368
  const aliasOptions = config?.resolve?.alias ?? [];
710
369
  if (isNativeObj(aliasOptions)) {
711
370
  aliases = Object.entries(aliasOptions).map(([key, value]) => {
@@ -722,23 +381,19 @@ ${cyan(
722
381
  );
723
382
  }
724
383
  },
725
- configResolved(config) {
726
- if (isBundle)
727
- return;
728
- logger = logLevel ? createLogger(logLevel, { allowClearScreen: config.clearScreen }) : config.logger;
729
- if (!config.build.lib) {
730
- logger.warn(
731
- yellow(
732
- `
733
- ${cyan(
734
- "[vite:dts]"
735
- )} You are building a library that may not need to generate declaration files.
736
- `
737
- )
738
- );
739
- libName = "_default";
740
- indexName = defaultIndex;
741
- } else {
384
+ async configResolved(config) {
385
+ logger = logLevel ? (await import('vite')).createLogger(logLevel, { allowClearScreen: config.clearScreen }) : config.logger;
386
+ root = ensureAbsolute(options.root ?? "", config.root);
387
+ if (config.build.lib) {
388
+ const input = typeof config.build.lib.entry === "string" ? [config.build.lib.entry] : config.build.lib.entry;
389
+ if (Array.isArray(input)) {
390
+ entries = input.reduce((prev, current) => {
391
+ prev[basename(current)] = current;
392
+ return prev;
393
+ }, {});
394
+ } else {
395
+ entries = { ...input };
396
+ }
742
397
  const filename = config.build.lib.fileName ?? defaultIndex;
743
398
  const entry = typeof config.build.lib.entry === "string" ? config.build.lib.entry : Object.values(config.build.lib.entry)[0];
744
399
  libName = config.build.lib.name || "_default";
@@ -746,199 +401,201 @@ ${cyan(
746
401
  if (!dtsRE.test(indexName)) {
747
402
  indexName = `${indexName.replace(tjsRE, "")}.d.${extPrefix(indexName)}ts`;
748
403
  }
749
- }
750
- root = ensureAbsolute(options.root ?? "", config.root);
751
- tsConfigPath = ensureAbsolute(tsConfigFilePath, root);
752
- libFolderPath = libFolderPath && ensureAbsolute(libFolderPath, root);
753
- outputDirs = options.outputDir ? ensureArray(options.outputDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.build.outDir, root)];
754
- if (!outputDirs[0]) {
755
- logger.error(
756
- red(
404
+ } else {
405
+ logger.warn(
406
+ yellow(
757
407
  `
758
408
  ${cyan(
759
409
  "[vite:dts]"
760
- )} Can not resolve declaration directory. Please check your vite config and plugin options.
410
+ )} You are building a library that may not need to generate declaration files.
761
411
  `
762
412
  )
763
413
  );
764
- return;
414
+ libName = "_default";
415
+ indexName = defaultIndex;
765
416
  }
766
- setCompileRoot(root);
767
- project = new Project({
768
- compilerOptions: mergeObjects(compilerOptions, {
769
- rootDir: compilerOptions.rootDir || root,
770
- noEmitOnError,
771
- outDir: outputDirs[0],
772
- declarationDir: void 0,
773
- noUnusedParameters: false,
774
- declaration: true,
775
- noEmit: false,
776
- emitDeclarationOnly: true,
777
- composite: false
778
- }),
779
- tsConfigFilePath: tsConfigPath,
780
- skipAddingFilesFromTsConfig: true,
781
- libFolderPath
782
- });
783
- allowJs = project.getCompilerOptions().allowJs ?? false;
784
- const tsConfig = getTsConfig(tsConfigPath, project.getFileSystem().readFileSync);
785
- include = ensureArray(options.include ?? tsConfig.include ?? "**/*").map(normalizeGlob);
786
- exclude = ensureArray(options.exclude ?? tsConfig.exclude ?? "node_modules/**").map(
787
- normalizeGlob
788
- );
789
- filter = createFilter(include, exclude, { resolve: root });
790
- compilerOptions = tsConfig.compilerOptions;
417
+ if (!options.outDir) {
418
+ outDirs = [ensureAbsolute(config.build.outDir, root)];
419
+ }
420
+ bundleDebug("parse vite config");
791
421
  },
792
- async buildStart(inputOptions) {
793
- if (Array.isArray(inputOptions.input)) {
794
- entries = inputOptions.input.reduce((prev, current) => {
422
+ options(options2) {
423
+ if (entries)
424
+ return;
425
+ const input = typeof options2.input === "string" ? [options2.input] : options2.input;
426
+ if (Array.isArray(input)) {
427
+ entries = input.reduce((prev, current) => {
795
428
  prev[basename(current)] = current;
796
429
  return prev;
797
430
  }, {});
798
431
  } else {
799
- entries = { ...inputOptions.input };
432
+ entries = { ...input };
800
433
  }
801
- bundleDebug("parse entries");
802
- sourceDtsFiles.clear();
803
- includedFiles.clear();
804
- if (project && include && include.length) {
805
- const files = await glob(include, {
806
- cwd: root,
807
- absolute: true,
808
- ignore: exclude
809
- });
810
- for (const file of files) {
811
- this.addWatchFile(file);
812
- if (dtsRE.test(file)) {
813
- sourceDtsFiles.add(project.addSourceFileAtPath(file));
814
- if (!copyDtsFiles) {
815
- continue;
816
- }
817
- includedFiles.add(file);
818
- continue;
819
- }
820
- includedFiles.add(`${file.replace(tjsRE, "")}.d.${extPrefix(file)}ts`);
821
- }
822
- if (hasJsVue) {
823
- if (!allowJs) {
824
- logger.warn(
825
- yellow(
826
- `${cyan(
827
- "[vite:dts]"
828
- )} Some js files are referenced, but you may not enable the 'allowJs' option.`
829
- )
830
- );
831
- }
832
- project.compilerOptions.set({ allowJs: true });
434
+ logger = logger || console;
435
+ libName = "_default";
436
+ indexName = defaultIndex;
437
+ bundleDebug("parse options");
438
+ },
439
+ async buildStart() {
440
+ if (program)
441
+ return;
442
+ bundleDebug("begin buildStart");
443
+ const configPath = tsconfigPath ? ensureAbsolute(tsconfigPath, root) : ts.findConfigFile(root, ts.sys.fileExists);
444
+ const content = configPath ? createParsedCommandLine(ts, ts.sys, configPath) : void 0;
445
+ const config = content ? {
446
+ include: content.raw.include,
447
+ exclude: content.raw.exclude,
448
+ raw: content.raw,
449
+ options: {
450
+ ...content.options,
451
+ ...options.compilerOptions || {},
452
+ ...fixedCompilerOptions
833
453
  }
834
- bundleDebug("collect files");
454
+ } : { options: { ...options.compilerOptions || {}, ...fixedCompilerOptions } };
455
+ if (!outDirs) {
456
+ outDirs = options.outDir ? ensureArray(options.outDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.raw?.compilerOptions?.outDir || "dist", root)];
457
+ }
458
+ include = ensureArray(options.include ?? config.include ?? "**/*").map(normalizeGlob);
459
+ exclude = ensureArray(options.exclude ?? config.exclude ?? "node_modules/**").map(
460
+ normalizeGlob
461
+ );
462
+ compilerOptions = { ...config.options, outDir: outDirs[0] };
463
+ rawCompilerOptions = config.raw?.compilerOptions || {};
464
+ filter = createFilter(include, exclude, { resolve: root });
465
+ const rootNames = Object.values(entries).concat(content?.fileNames.filter(filter) || []).map(normalizePath);
466
+ host = ts.createCompilerHost(compilerOptions, true);
467
+ program = createProgram({ host, rootNames, options: compilerOptions });
468
+ libName = libName || "_default";
469
+ indexName = indexName || defaultIndex;
470
+ const diagnostics = program.getDeclarationDiagnostics();
471
+ if (diagnostics?.length) {
472
+ logger.error(ts.formatDiagnostics(diagnostics, host));
835
473
  }
474
+ if (typeof afterDiagnostic === "function") {
475
+ const result = afterDiagnostic(diagnostics);
476
+ isPromise(result) && await result;
477
+ }
478
+ rootNames.forEach((file) => {
479
+ this.addWatchFile(file);
480
+ rootFiles.add(file);
481
+ });
482
+ bundleDebug("create ts program");
836
483
  },
837
- async transform(_, id) {
838
- await internalTransform(id);
839
- return null;
484
+ transform(_, id) {
485
+ if (!program || !filter(id) || id.includes(".vue?vue") || !tsRE.test(id) && !vueRE.test(id)) {
486
+ return;
487
+ }
488
+ id = normalizePath(id);
489
+ rootFiles.delete(id);
490
+ let sourceFile = program.getSourceFile(normalizePath(id));
491
+ if (!sourceFile && vueRE.test(id)) {
492
+ sourceFile = program.getSourceFile(id + ".ts") || program.getSourceFile(id + ".js") || program.getSourceFile(id + ".tsx") || program.getSourceFile(id + ".jsx");
493
+ }
494
+ if (!sourceFile)
495
+ return;
496
+ const outDir = outDirs[0];
497
+ const service = program.__vue.languageService;
498
+ for (const outputFile of service.getEmitOutput(sourceFile.fileName, true).outputFiles) {
499
+ outputFiles.set(resolve(root, relative(outDir, outputFile.name)), outputFile.text);
500
+ }
501
+ const dtsId = id.replace(tjsRE, ".d.ts");
502
+ const dtsSourceFile = program.getSourceFile(dtsId);
503
+ dtsSourceFile && filter(dtsSourceFile.fileName) && outputFiles.set(dtsSourceFile.fileName, dtsSourceFile.getFullText());
840
504
  },
841
- async watchChange(id) {
842
- if (watchExtensionRE.test(id)) {
843
- isBundle = false;
844
- if (project) {
845
- const sourceFile = project.getSourceFile(normalizePath(id));
846
- sourceFile && project.removeSourceFile(sourceFile);
847
- await internalTransform(id);
505
+ watchChange(id) {
506
+ if (host && program && watchExtensionRE.test(id)) {
507
+ const sourceFile = host.getSourceFile(normalizePath(id), ts.ScriptTarget.ESNext);
508
+ if (sourceFile && filter(sourceFile.fileName)) {
509
+ !vueRE.test(id) && rootFiles.add(sourceFile.fileName);
510
+ program.__vue.projectVersion++;
511
+ bundled = false;
848
512
  }
849
513
  }
850
514
  },
851
- async closeBundle() {
852
- if (!outputDirs || !project || isBundle)
515
+ async writeBundle() {
516
+ if (!program || bundled)
853
517
  return;
518
+ bundled = true;
519
+ bundleDebug("begin writeBundle");
854
520
  logger.info(green(`
855
521
  ${logPrefix} Start generate declaration files...`));
856
- bundleDebug("start");
857
- isBundle = true;
858
- emittedFiles.clear();
859
522
  const startTime = Date.now();
860
- project.resolveSourceFileDependencies();
861
- bundleDebug("resolve");
862
- if (!skipDiagnostics) {
863
- const diagnostics = project.getPreEmitDiagnostics();
864
- if (diagnostics?.length) {
865
- logger.warn(project.formatDiagnosticsWithColorAndContext(diagnostics));
523
+ const outDir = outDirs[0];
524
+ const emittedFiles = /* @__PURE__ */ new Map();
525
+ const service = program.__vue.languageService;
526
+ const sourceFiles = program.getSourceFiles();
527
+ for (const sourceFile of sourceFiles) {
528
+ if (!filter(sourceFile.fileName))
529
+ continue;
530
+ if (copyDtsFiles && dtsRE.test(sourceFile.fileName)) {
531
+ outputFiles.set(sourceFile.fileName, sourceFile.getFullText());
866
532
  }
867
- if (typeof afterDiagnostic === "function") {
868
- const result = afterDiagnostic(diagnostics);
869
- isPromise(result) && await result;
533
+ if (rootFiles.has(sourceFile.fileName)) {
534
+ for (const outputFile of service.getEmitOutput(sourceFile.fileName, true).outputFiles) {
535
+ outputFiles.set(resolve(root, relative(outDir, outputFile.name)), outputFile.text);
536
+ }
537
+ rootFiles.delete(sourceFile.fileName);
870
538
  }
871
- bundleDebug("diagnostics");
872
539
  }
873
- const outputDir = outputDirs[0];
874
- const dtsOutputFiles = Array.from(sourceDtsFiles).map((sourceFile) => ({
875
- path: sourceFile.getFilePath(),
876
- content: sourceFile.getFullText()
877
- }));
878
- const service = project.getLanguageService();
879
- const outputFiles = project.getSourceFiles().map(
880
- (sourceFile) => service.getEmitOutput(sourceFile, true).getOutputFiles().map((outputFile) => ({
881
- path: resolve(root, relative(outputDir, outputFile.compilerObject.name)),
882
- content: outputFile.getText()
883
- }))
884
- ).flat().concat(dtsOutputFiles);
885
- bundleDebug("emit");
886
- entryRoot = entryRoot || queryPublicPath(outputFiles.map((file) => file.path));
540
+ bundleDebug("emit output patch");
541
+ entryRoot = entryRoot || queryPublicPath(Array.from(outputFiles.keys()));
887
542
  entryRoot = ensureAbsolute(entryRoot, root);
888
- await runParallel(os.cpus().length, outputFiles, async (outputFile) => {
889
- let filePath = outputFile.path;
890
- let content = outputFile.content;
891
- const isMapFile = filePath.endsWith(".map");
892
- if (!includedFiles.has(isMapFile ? filePath.slice(0, -4) : filePath) || clearPureImport && content === noneExport) {
893
- return;
894
- }
895
- if (!isMapFile && content && content !== noneExport) {
896
- content = clearPureImport ? removePureImport(content) : content;
897
- content = transformAliasImport(filePath, content, aliases, aliasesExclude);
898
- content = staticImport || rollupTypes ? transformDynamicImport(content) : content;
899
- }
900
- filePath = resolve(
901
- outputDir,
902
- relative(entryRoot, cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath)
903
- );
904
- content = cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content;
905
- if (typeof beforeWriteFile === "function") {
906
- const result = beforeWriteFile(filePath, content);
907
- if (result === false)
908
- return;
909
- if (result && isNativeObj(result)) {
910
- filePath = result.filePath || filePath;
911
- content = result.content ?? content;
543
+ await runParallel(
544
+ cpus().length,
545
+ Array.from(outputFiles.entries()),
546
+ async ([path, content]) => {
547
+ const isMapFile = path.endsWith(".map");
548
+ if (!isMapFile && content) {
549
+ content = clearPureImport ? removePureImport(content) : content;
550
+ content = transformAliasImport(path, content, aliases, aliasesExclude);
551
+ content = staticImport || rollupTypes ? transformDynamicImport(content) : content;
552
+ }
553
+ path = resolve(
554
+ outDir,
555
+ relative(entryRoot, cleanVueFileName ? path.replace(".vue.d.ts", ".d.ts") : path)
556
+ );
557
+ content = cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content;
558
+ if (typeof beforeWriteFile === "function") {
559
+ const result = beforeWriteFile(path, content);
560
+ if (result === false)
561
+ return;
562
+ if (result && isNativeObj(result)) {
563
+ path = result.filePath || path;
564
+ content = result.content ?? content;
565
+ }
566
+ }
567
+ path = normalizePath(path);
568
+ const dir = dirname(path);
569
+ if (!existsSync(dir)) {
570
+ await mkdir(dir, { recursive: true });
912
571
  }
572
+ await writeFile(path, content, "utf-8");
573
+ emittedFiles.set(path, content);
913
574
  }
914
- filePath = normalizePath(filePath);
915
- await fs.mkdir(dirname(filePath), { recursive: true });
916
- await fs.writeFile(filePath, content, "utf-8");
917
- emittedFiles.set(filePath, content);
918
- });
919
- bundleDebug("output");
575
+ );
576
+ bundleDebug("write output");
920
577
  if (insertTypesEntry || rollupTypes) {
921
578
  const pkgPath = resolve(root, "package.json");
922
- const pkg = fs.existsSync(pkgPath) ? JSON.parse(await fs.readFile(pkgPath, "utf-8")) : {};
579
+ const pkg = existsSync(pkgPath) ? JSON.parse(await readFile(pkgPath, "utf-8")) : {};
923
580
  const entryNames = Object.keys(entries);
924
581
  const types = pkg.types || pkg.typings || pkg.publishConfig?.types || pkg.publishConfig?.typings || (pkg.exports?.["."] || pkg.exports?.["./"])?.types;
925
582
  const multiple = entryNames.length > 1;
926
- const typesPath = types ? resolve(root, types) : resolve(outputDir, indexName);
583
+ const typesPath = types ? resolve(root, types) : resolve(outDir, indexName);
927
584
  for (const name of entryNames) {
928
- let filePath = multiple ? resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`) : typesPath;
929
- if (fs.existsSync(filePath))
585
+ let path = multiple ? resolve(outDir, `${name.replace(tsRE, "")}.d.ts`) : typesPath;
586
+ if (existsSync(path))
930
587
  continue;
931
588
  const index = resolve(
932
- outputDir,
589
+ outDir,
933
590
  relative(entryRoot, `${entries[name].replace(tsRE, "")}.d.ts`)
934
591
  );
935
- let fromPath = normalizePath(relative(dirname(filePath), index));
592
+ let fromPath = normalizePath(relative(dirname(path), index));
936
593
  fromPath = fromPath.replace(dtsRE, "");
937
594
  fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`;
938
595
  let content = `export * from '${fromPath}'
939
596
  `;
940
- if (fs.existsSync(index)) {
941
- const entryCodes = await fs.readFile(index, "utf-8");
597
+ if (existsSync(index)) {
598
+ const entryCodes = await readFile(index, "utf-8");
942
599
  if (entryCodes.includes("export default")) {
943
600
  content += `import ${libName} from '${fromPath}'
944
601
  export default ${libName}
@@ -947,32 +604,41 @@ export default ${libName}
947
604
  }
948
605
  let result;
949
606
  if (typeof beforeWriteFile === "function") {
950
- result = beforeWriteFile(filePath, content);
607
+ result = beforeWriteFile(path, content);
951
608
  if (result && isNativeObj(result)) {
952
- filePath = result.filePath ?? filePath;
609
+ path = result.filePath ?? path;
953
610
  content = result.content ?? content;
954
611
  }
955
612
  }
956
- filePath = normalizePath(filePath);
613
+ path = normalizePath(path);
957
614
  if (result !== false) {
958
- await fs.writeFile(filePath, content, "utf-8");
959
- emittedFiles.set(filePath, content);
615
+ await writeFile(path, content, "utf-8");
616
+ emittedFiles.set(path, content);
960
617
  }
961
618
  }
962
619
  bundleDebug("insert index");
963
620
  if (rollupTypes) {
964
621
  logger.info(green(`${logPrefix} Start rollup declaration files...`));
622
+ let libFolder = resolve(root, "node_modules/typescript");
623
+ if (!existsSync(libFolder)) {
624
+ if (root !== entryRoot) {
625
+ libFolder = resolve(entryRoot, "node_modules/typescript");
626
+ if (!existsSync(libFolder))
627
+ libFolder = void 0;
628
+ }
629
+ libFolder = void 0;
630
+ }
965
631
  const rollupFiles = /* @__PURE__ */ new Set();
966
632
  if (multiple) {
967
633
  for (const name of entryNames) {
968
- const path = resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`);
634
+ const path = resolve(outDir, `${name.replace(tsRE, "")}.d.ts`);
969
635
  rollupDeclarationFiles({
970
636
  root,
971
- compilerOptions,
972
- outputDir,
637
+ compilerOptions: rawCompilerOptions,
638
+ outDir,
973
639
  entryPath: path,
974
640
  fileName: basename(path),
975
- libFolder: libFolderPath,
641
+ libFolder,
976
642
  bundledPackages
977
643
  });
978
644
  emittedFiles.delete(path);
@@ -981,41 +647,40 @@ export default ${libName}
981
647
  } else {
982
648
  rollupDeclarationFiles({
983
649
  root,
984
- compilerOptions,
985
- outputDir,
650
+ compilerOptions: rawCompilerOptions,
651
+ outDir,
986
652
  entryPath: typesPath,
987
653
  fileName: basename(typesPath),
988
- libFolder: libFolderPath,
654
+ libFolder,
989
655
  bundledPackages
990
656
  });
991
657
  emittedFiles.delete(typesPath);
992
658
  rollupFiles.add(typesPath);
993
659
  }
994
- await runParallel(os.cpus().length, Array.from(emittedFiles.keys()), (f) => fs.unlink(f));
995
- removeDirIfEmpty(outputDir);
660
+ await runParallel(cpus().length, Array.from(emittedFiles.keys()), (f) => unlink(f));
661
+ removeDirIfEmpty(outDir);
996
662
  emittedFiles.clear();
997
663
  for (const file of rollupFiles) {
998
- emittedFiles.set(file, await fs.readFile(file, "utf-8"));
664
+ emittedFiles.set(file, await readFile(file, "utf-8"));
999
665
  }
1000
- bundleDebug("rollup");
666
+ bundleDebug("rollup output");
1001
667
  }
1002
668
  }
1003
- if (outputDirs.length > 1) {
1004
- const dirs = outputDirs.slice(1);
1005
- await runParallel(
1006
- os.cpus().length,
1007
- Array.from(emittedFiles),
1008
- async ([wroteFile, content]) => {
1009
- const relativePath = relative(outputDir, wroteFile);
1010
- await Promise.all(
1011
- dirs.map(async (dir) => {
1012
- const filePath = resolve(dir, relativePath);
1013
- await fs.mkdir(dirname(filePath), { recursive: true });
1014
- await fs.writeFile(filePath, content, "utf-8");
1015
- })
1016
- );
1017
- }
1018
- );
669
+ if (outDirs.length > 1) {
670
+ const dirs = outDirs.slice(1);
671
+ await runParallel(cpus().length, Array.from(emittedFiles), async ([wroteFile, content]) => {
672
+ const relativePath = relative(outDir, wroteFile);
673
+ await Promise.all(
674
+ dirs.map(async (dir) => {
675
+ const path = resolve(dir, relativePath);
676
+ const dirPath = dirname(path);
677
+ if (!existsSync(dirPath)) {
678
+ await mkdir(dirPath, { recursive: true });
679
+ }
680
+ await writeFile(path, content, "utf-8");
681
+ })
682
+ );
683
+ });
1019
684
  }
1020
685
  if (typeof afterBuild === "function") {
1021
686
  const result = afterBuild();