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

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,17 @@ 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 'os';
12
+ import ts from 'typescript';
13
+ import { normalizePath as normalizePath$1, createLogger } from 'vite';
14
+ import { createFilter } from '@rollup/pluginutils';
15
+ import { createParsedCommandLine } from '@vue/language-core';
16
+ import { createProgram } from 'vue-tsc';
17
+ import debug from 'debug';
18
+ import { cyan, yellow, green } from 'kolorist';
22
19
  import { ExtractorConfig, CompilerState } from '@microsoft/api-extractor';
23
20
  import { Collector } from '@microsoft/api-extractor/lib/collector/Collector.js';
24
21
  import { MessageRouter } from '@microsoft/api-extractor/lib/collector/MessageRouter.js';
@@ -26,6 +23,105 @@ import { SourceMapper } from '@microsoft/api-extractor/lib/collector/SourceMappe
26
23
  import { DtsRollupGenerator, DtsRollupKind } from '@microsoft/api-extractor/lib/generators/DtsRollupGenerator.js';
27
24
  import { PackageJsonLookup } from '@rushstack/node-core-library';
28
25
 
26
+ const dtsRE$1 = /\.d\.tsx?$/;
27
+ function rollupDeclarationFiles({
28
+ root,
29
+ compilerOptions,
30
+ outDir,
31
+ entryPath,
32
+ fileName,
33
+ libFolder,
34
+ bundledPackages
35
+ }) {
36
+ const configObjectFullPath = resolve$1(root, "api-extractor.json");
37
+ const packageJsonLookup = new PackageJsonLookup();
38
+ const packageJsonFullPath = packageJsonLookup.tryGetPackageJsonFilePathFor(configObjectFullPath);
39
+ if (!dtsRE$1.test(fileName)) {
40
+ fileName += ".d.ts";
41
+ }
42
+ const extractorConfig = ExtractorConfig.prepare({
43
+ configObject: {
44
+ projectFolder: root,
45
+ mainEntryPointFilePath: entryPath,
46
+ bundledPackages,
47
+ compiler: {
48
+ // tsconfigFilePath: tsConfigPath,
49
+ overrideTsconfig: {
50
+ $schema: "http://json.schemastore.org/tsconfig",
51
+ compilerOptions: {
52
+ ...compilerOptions,
53
+ target: "ESNext"
54
+ }
55
+ }
56
+ },
57
+ apiReport: {
58
+ enabled: false,
59
+ reportFileName: "<unscopedPackageName>.api.md"
60
+ },
61
+ docModel: {
62
+ enabled: false
63
+ },
64
+ dtsRollup: {
65
+ enabled: true,
66
+ publicTrimmedFilePath: resolve$1(outDir, fileName)
67
+ },
68
+ tsdocMetadata: {
69
+ enabled: false
70
+ },
71
+ messages: {
72
+ compilerMessageReporting: {
73
+ default: {
74
+ logLevel: "none"
75
+ }
76
+ },
77
+ extractorMessageReporting: {
78
+ default: {
79
+ logLevel: "none"
80
+ }
81
+ }
82
+ }
83
+ },
84
+ configObjectFullPath,
85
+ packageJsonFullPath
86
+ });
87
+ const compilerState = CompilerState.create(extractorConfig, {
88
+ localBuild: false,
89
+ showVerboseMessages: false,
90
+ typescriptCompilerFolder: libFolder ? resolve$1(libFolder, "..") : void 0
91
+ });
92
+ const sourceMapper = new SourceMapper();
93
+ const messageRouter = new MessageRouter({
94
+ workingPackageFolder: root,
95
+ messageCallback: void 0,
96
+ messagesConfig: extractorConfig.messages,
97
+ showVerboseMessages: false,
98
+ showDiagnostics: false,
99
+ tsdocConfiguration: extractorConfig.tsdocConfiguration,
100
+ sourceMapper
101
+ });
102
+ const collector = new Collector({
103
+ program: compilerState.program,
104
+ messageRouter,
105
+ extractorConfig,
106
+ sourceMapper
107
+ });
108
+ collector.analyze();
109
+ DtsRollupGenerator.writeTypingsFile(
110
+ collector,
111
+ extractorConfig.publicTrimmedFilePath,
112
+ DtsRollupKind.PublicRelease,
113
+ extractorConfig.newlineKind
114
+ );
115
+ }
116
+
117
+ const windowsSlashRE = /\\/g;
118
+ function slash(p) {
119
+ return p.replace(windowsSlashRE, "/");
120
+ }
121
+ const isWindows = platform() === "win32";
122
+ function normalizePath(id) {
123
+ return posix.normalize(isWindows ? slash(id) : id);
124
+ }
29
125
  function isNativeObj(value) {
30
126
  return Object.prototype.toString.call(value) === "[object Object]";
31
127
  }
@@ -35,39 +131,6 @@ function isRegExp(value) {
35
131
  function isPromise(value) {
36
132
  return !!value && typeof value.then === "function" && typeof value.catch === "function";
37
133
  }
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
134
  function ensureAbsolute(path, root) {
72
135
  return path ? isAbsolute(path) ? path : resolve$1(root, path) : root;
73
136
  }
@@ -148,25 +211,6 @@ function removeDirIfEmpty(dir) {
148
211
  }
149
212
  return onlyHasDir;
150
213
  }
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
214
 
171
215
  const globSuffixRE = /^((?:.*\.[^.]+)|(?:\*+))$/;
172
216
  function normalizeGlob(path) {
@@ -239,7 +283,7 @@ function transformAliasImport(filePath, content, aliases, exclude = []) {
239
283
  if (exclude.some((e) => isRegExp(e) ? e.test(matchResult[1]) : String(e) === matchResult[1])) {
240
284
  return str;
241
285
  }
242
- const truthPath = isAbsolute(matchedAlias.replacement) ? normalizePath(relative(dirname(filePath), matchedAlias.replacement)) : normalizePath(matchedAlias.replacement);
286
+ const truthPath = isAbsolute(matchedAlias.replacement) ? normalizePath$1(relative(dirname(filePath), matchedAlias.replacement)) : normalizePath$1(matchedAlias.replacement);
243
287
  return str.replace(
244
288
  isDynamic ? simpleDynamicImportRE : simpleStaticImportRE,
245
289
  `$1'${matchResult[1].replace(
@@ -256,456 +300,67 @@ const pureImportRE = /import\s?['"][^;\n]+?['"];?\n?/g;
256
300
  function removePureImport(content) {
257
301
  return content.replace(pureImportRE, "");
258
302
  }
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
303
 
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
-
614
- const noneExport = "export {};\n";
615
- 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 compilerOptions;
346
+ let rawCompilerOptions;
347
+ let root = ensureAbsolute(options.root ?? "", process.cwd());
652
348
  let entryRoot = options.entryRoot ?? "";
653
- let libName;
654
- let indexName;
655
- let aliases;
656
349
  let entries;
657
- let logger;
658
- let project;
659
- let tsConfigPath;
660
- let outputDirs;
661
- let isBundle = false;
662
350
  let include;
663
351
  let exclude;
664
- 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
- }
352
+ let outDirs;
353
+ let aliases;
354
+ let libName;
355
+ let indexName;
356
+ let logger;
357
+ let bundled = false;
358
+ let program;
702
359
  return {
703
360
  name: "vite:dts",
704
361
  apply: "build",
705
362
  enforce: "pre",
706
363
  config(config) {
707
- if (isBundle)
708
- return;
709
364
  const aliasOptions = config?.resolve?.alias ?? [];
710
365
  if (isNativeObj(aliasOptions)) {
711
366
  aliases = Object.entries(aliasOptions).map(([key, value]) => {
@@ -723,22 +378,18 @@ ${cyan(
723
378
  }
724
379
  },
725
380
  configResolved(config) {
726
- if (isBundle)
727
- return;
728
381
  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 {
382
+ root = ensureAbsolute(options.root ?? "", config.root);
383
+ if (config.build.lib) {
384
+ const input = typeof config.build.lib.entry === "string" ? [config.build.lib.entry] : config.build.lib.entry;
385
+ if (Array.isArray(input)) {
386
+ entries = input.reduce((prev, current) => {
387
+ prev[basename(current)] = current;
388
+ return prev;
389
+ }, {});
390
+ } else {
391
+ entries = { ...input };
392
+ }
742
393
  const filename = config.build.lib.fileName ?? defaultIndex;
743
394
  const entry = typeof config.build.lib.entry === "string" ? config.build.lib.entry : Object.values(config.build.lib.entry)[0];
744
395
  libName = config.build.lib.name || "_default";
@@ -746,199 +397,177 @@ ${cyan(
746
397
  if (!dtsRE.test(indexName)) {
747
398
  indexName = `${indexName.replace(tjsRE, "")}.d.${extPrefix(indexName)}ts`;
748
399
  }
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(
400
+ } else {
401
+ logger.warn(
402
+ yellow(
757
403
  `
758
404
  ${cyan(
759
405
  "[vite:dts]"
760
- )} Can not resolve declaration directory. Please check your vite config and plugin options.
406
+ )} You are building a library that may not need to generate declaration files.
761
407
  `
762
408
  )
763
409
  );
764
- return;
410
+ libName = "_default";
411
+ indexName = defaultIndex;
765
412
  }
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;
413
+ if (!options.outDir) {
414
+ outDirs = [ensureAbsolute(config.build.outDir, root)];
415
+ }
416
+ bundleDebug("parse vite config");
791
417
  },
792
- async buildStart(inputOptions) {
793
- if (Array.isArray(inputOptions.input)) {
794
- entries = inputOptions.input.reduce((prev, current) => {
418
+ options(options2) {
419
+ if (entries)
420
+ return;
421
+ const input = typeof options2.input === "string" ? [options2.input] : options2.input;
422
+ if (Array.isArray(input)) {
423
+ entries = input.reduce((prev, current) => {
795
424
  prev[basename(current)] = current;
796
425
  return prev;
797
426
  }, {});
798
427
  } else {
799
- entries = { ...inputOptions.input };
428
+ entries = { ...input };
800
429
  }
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 });
833
- }
834
- bundleDebug("collect files");
835
- }
836
- },
837
- async transform(_, id) {
838
- await internalTransform(id);
839
- return null;
430
+ logger = logger || console;
431
+ libName = "_default";
432
+ indexName = defaultIndex;
433
+ bundleDebug("parse options");
840
434
  },
841
- async watchChange(id) {
435
+ watchChange(id) {
842
436
  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);
437
+ bundled = false;
438
+ program?.getSourceFile(normalizePath(id));
439
+ }
440
+ },
441
+ async buildStart() {
442
+ if (program)
443
+ return;
444
+ const configPath = tsconfigPath ? ensureAbsolute(tsconfigPath, root) : ts.findConfigFile(root, ts.sys.fileExists);
445
+ const content = configPath && createParsedCommandLine(ts, ts.sys, configPath);
446
+ const config = content ? {
447
+ include: content.raw.include,
448
+ exclude: content.raw.exclude,
449
+ fileNames: content.fileNames,
450
+ raw: content.raw,
451
+ options: {
452
+ ...content.options,
453
+ ...options.compilerOptions || {},
454
+ ...fixedCompilerOptions
848
455
  }
456
+ } : { options: { ...options.compilerOptions || {}, ...fixedCompilerOptions } };
457
+ if (!outDirs) {
458
+ outDirs = options.outDir ? ensureArray(options.outDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.raw?.compilerOptions?.outDir || "dist", root)];
849
459
  }
460
+ include = ensureArray(options.include ?? config.include ?? "**/*").map(normalizeGlob);
461
+ exclude = ensureArray(options.exclude ?? config.exclude ?? "node_modules/**").map(
462
+ normalizeGlob
463
+ );
464
+ compilerOptions = { ...config.options, outDir: outDirs[0] };
465
+ rawCompilerOptions = config.raw?.compilerOptions || {};
466
+ const host = ts.createCompilerHost(compilerOptions, true);
467
+ program = createProgram({
468
+ host,
469
+ rootNames: Object.values(entries).concat(
470
+ config.fileNames?.filter((name) => dtsRE.test(name)) || []
471
+ ),
472
+ options: compilerOptions
473
+ });
474
+ libName = libName || "_default";
475
+ indexName = indexName || defaultIndex;
476
+ const diagnostics = program.getDeclarationDiagnostics();
477
+ if (diagnostics?.length) {
478
+ logger.error(ts.formatDiagnostics(diagnostics, host));
479
+ }
480
+ if (typeof afterDiagnostic === "function") {
481
+ const result = afterDiagnostic(diagnostics);
482
+ isPromise(result) && await result;
483
+ }
484
+ bundleDebug("create ts program");
850
485
  },
851
- async closeBundle() {
852
- if (!outputDirs || !project || isBundle)
486
+ async writeBundle() {
487
+ if (!outDirs || !program || bundled)
853
488
  return;
854
489
  logger.info(green(`
855
490
  ${logPrefix} Start generate declaration files...`));
856
- bundleDebug("start");
857
- isBundle = true;
858
- emittedFiles.clear();
859
- 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));
491
+ bundled = true;
492
+ const outDir = outDirs[0];
493
+ const emittedFiles = /* @__PURE__ */ new Map();
494
+ const filter = createFilter(include, exclude, { resolve: root });
495
+ const service = program.__vue.languageService;
496
+ const sourceFiles = program.getSourceFiles();
497
+ const outputFiles = sourceFiles.map((sourceFile) => {
498
+ if (!filter(sourceFile.fileName))
499
+ return [];
500
+ const output = [];
501
+ if (copyDtsFiles && dtsRE.test(sourceFile.fileName)) {
502
+ output.push({
503
+ path: sourceFile.fileName,
504
+ content: sourceFile.getFullText()
505
+ });
866
506
  }
867
- if (typeof afterDiagnostic === "function") {
868
- const result = afterDiagnostic(diagnostics);
869
- isPromise(result) && await result;
870
- }
871
- bundleDebug("diagnostics");
872
- }
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");
507
+ return output.concat(
508
+ service.getEmitOutput(sourceFile.fileName, true).outputFiles.map((outputFile) => {
509
+ return {
510
+ path: resolve(root, relative(outDir, outputFile.name)),
511
+ content: outputFile.text
512
+ };
513
+ })
514
+ );
515
+ }).flat();
516
+ bundleDebug("emit output");
886
517
  entryRoot = entryRoot || queryPublicPath(outputFiles.map((file) => file.path));
887
518
  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) {
519
+ await runParallel(cpus().length, outputFiles, async ({ path, content }) => {
520
+ const isMapFile = path.endsWith(".map");
521
+ if (!isMapFile && content) {
896
522
  content = clearPureImport ? removePureImport(content) : content;
897
- content = transformAliasImport(filePath, content, aliases, aliasesExclude);
523
+ content = transformAliasImport(path, content, aliases, aliasesExclude);
898
524
  content = staticImport || rollupTypes ? transformDynamicImport(content) : content;
899
525
  }
900
- filePath = resolve(
901
- outputDir,
902
- relative(entryRoot, cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath)
526
+ path = resolve(
527
+ outDir,
528
+ relative(entryRoot, cleanVueFileName ? path.replace(".vue.d.ts", ".d.ts") : path)
903
529
  );
904
530
  content = cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content;
905
531
  if (typeof beforeWriteFile === "function") {
906
- const result = beforeWriteFile(filePath, content);
532
+ const result = beforeWriteFile(path, content);
907
533
  if (result === false)
908
534
  return;
909
535
  if (result && isNativeObj(result)) {
910
- filePath = result.filePath || filePath;
536
+ path = result.filePath || path;
911
537
  content = result.content ?? content;
912
538
  }
913
539
  }
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);
540
+ path = normalizePath(path);
541
+ const dir = dirname(path);
542
+ if (!existsSync(dir)) {
543
+ await mkdir(dir, { recursive: true });
544
+ }
545
+ await writeFile(path, content, "utf-8");
546
+ emittedFiles.set(path, content);
918
547
  });
919
- bundleDebug("output");
548
+ bundleDebug("write output");
920
549
  if (insertTypesEntry || rollupTypes) {
921
550
  const pkgPath = resolve(root, "package.json");
922
- const pkg = fs.existsSync(pkgPath) ? JSON.parse(await fs.readFile(pkgPath, "utf-8")) : {};
551
+ const pkg = existsSync(pkgPath) ? JSON.parse(await readFile(pkgPath, "utf-8")) : {};
923
552
  const entryNames = Object.keys(entries);
924
553
  const types = pkg.types || pkg.typings || pkg.publishConfig?.types || pkg.publishConfig?.typings || (pkg.exports?.["."] || pkg.exports?.["./"])?.types;
925
554
  const multiple = entryNames.length > 1;
926
- const typesPath = types ? resolve(root, types) : resolve(outputDir, indexName);
555
+ const typesPath = types ? resolve(root, types) : resolve(outDir, indexName);
927
556
  for (const name of entryNames) {
928
- let filePath = multiple ? resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`) : typesPath;
929
- if (fs.existsSync(filePath))
557
+ let path = multiple ? resolve(outDir, `${name.replace(tsRE, "")}.d.ts`) : typesPath;
558
+ if (existsSync(path))
930
559
  continue;
931
560
  const index = resolve(
932
- outputDir,
561
+ outDir,
933
562
  relative(entryRoot, `${entries[name].replace(tsRE, "")}.d.ts`)
934
563
  );
935
- let fromPath = normalizePath(relative(dirname(filePath), index));
564
+ let fromPath = normalizePath(relative(dirname(path), index));
936
565
  fromPath = fromPath.replace(dtsRE, "");
937
566
  fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`;
938
567
  let content = `export * from '${fromPath}'
939
568
  `;
940
- if (fs.existsSync(index)) {
941
- const entryCodes = await fs.readFile(index, "utf-8");
569
+ if (existsSync(index)) {
570
+ const entryCodes = await readFile(index, "utf-8");
942
571
  if (entryCodes.includes("export default")) {
943
572
  content += `import ${libName} from '${fromPath}'
944
573
  export default ${libName}
@@ -947,32 +576,41 @@ export default ${libName}
947
576
  }
948
577
  let result;
949
578
  if (typeof beforeWriteFile === "function") {
950
- result = beforeWriteFile(filePath, content);
579
+ result = beforeWriteFile(path, content);
951
580
  if (result && isNativeObj(result)) {
952
- filePath = result.filePath ?? filePath;
581
+ path = result.filePath ?? path;
953
582
  content = result.content ?? content;
954
583
  }
955
584
  }
956
- filePath = normalizePath(filePath);
585
+ path = normalizePath(path);
957
586
  if (result !== false) {
958
- await fs.writeFile(filePath, content, "utf-8");
959
- emittedFiles.set(filePath, content);
587
+ await writeFile(path, content, "utf-8");
588
+ emittedFiles.set(path, content);
960
589
  }
961
590
  }
962
591
  bundleDebug("insert index");
963
592
  if (rollupTypes) {
964
593
  logger.info(green(`${logPrefix} Start rollup declaration files...`));
594
+ let libFolder = resolve(root, "node_modules/typescript");
595
+ if (!existsSync(libFolder)) {
596
+ if (root !== entryRoot) {
597
+ libFolder = resolve(entryRoot, "node_modules/typescript");
598
+ if (!existsSync(libFolder))
599
+ libFolder = void 0;
600
+ }
601
+ libFolder = void 0;
602
+ }
965
603
  const rollupFiles = /* @__PURE__ */ new Set();
966
604
  if (multiple) {
967
605
  for (const name of entryNames) {
968
- const path = resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`);
606
+ const path = resolve(outDir, `${name.replace(tsRE, "")}.d.ts`);
969
607
  rollupDeclarationFiles({
970
608
  root,
971
- compilerOptions,
972
- outputDir,
609
+ compilerOptions: rawCompilerOptions,
610
+ outDir,
973
611
  entryPath: path,
974
612
  fileName: basename(path),
975
- libFolder: libFolderPath,
613
+ libFolder,
976
614
  bundledPackages
977
615
  });
978
616
  emittedFiles.delete(path);
@@ -981,48 +619,47 @@ export default ${libName}
981
619
  } else {
982
620
  rollupDeclarationFiles({
983
621
  root,
984
- compilerOptions,
985
- outputDir,
622
+ compilerOptions: rawCompilerOptions,
623
+ outDir,
986
624
  entryPath: typesPath,
987
625
  fileName: basename(typesPath),
988
- libFolder: libFolderPath,
626
+ libFolder,
989
627
  bundledPackages
990
628
  });
991
629
  emittedFiles.delete(typesPath);
992
630
  rollupFiles.add(typesPath);
993
631
  }
994
- await runParallel(os.cpus().length, Array.from(emittedFiles.keys()), (f) => fs.unlink(f));
995
- removeDirIfEmpty(outputDir);
632
+ await runParallel(cpus().length, Array.from(emittedFiles.keys()), (f) => unlink(f));
633
+ removeDirIfEmpty(outDir);
996
634
  emittedFiles.clear();
997
635
  for (const file of rollupFiles) {
998
- emittedFiles.set(file, await fs.readFile(file, "utf-8"));
636
+ emittedFiles.set(file, await readFile(file, "utf-8"));
999
637
  }
1000
- bundleDebug("rollup");
638
+ bundleDebug("rollup output");
1001
639
  }
1002
640
  }
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
- );
641
+ if (outDirs.length > 1) {
642
+ const dirs = outDirs.slice(1);
643
+ await runParallel(cpus().length, Array.from(emittedFiles), async ([wroteFile, content]) => {
644
+ const relativePath = relative(outDir, wroteFile);
645
+ await Promise.all(
646
+ dirs.map(async (dir) => {
647
+ const path = resolve(dir, relativePath);
648
+ const dirPath = dirname(path);
649
+ if (!existsSync(dirPath)) {
650
+ await mkdir(dirPath, { recursive: true });
651
+ }
652
+ await writeFile(path, content, "utf-8");
653
+ })
654
+ );
655
+ });
1019
656
  }
1020
657
  if (typeof afterBuild === "function") {
1021
658
  const result = afterBuild();
1022
659
  isPromise(result) && await result;
1023
660
  }
1024
661
  bundleDebug("finish");
1025
- logger.info(green(`${logPrefix} Declaration files built in ${Date.now() - startTime}ms.
662
+ logger.info(green(`${logPrefix} Declaration files built.
1026
663
  `));
1027
664
  }
1028
665
  };