vite-plugin-dts 4.0.0-beta.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.cjs +160 -58
  2. package/dist/index.mjs +160 -59
  3. package/package.json +21 -21
package/dist/index.cjs CHANGED
@@ -9,21 +9,74 @@ const node_os = require('node:os');
9
9
  const languageCore = require('@vue/language-core');
10
10
  const typescript = require('@volar/typescript');
11
11
  const ts = require('typescript');
12
- const pluginutils = require('@rollup/pluginutils');
13
12
  const vueTsc = require('vue-tsc');
13
+ const pluginutils = require('@rollup/pluginutils');
14
14
  const debug = require('debug');
15
15
  const kolorist = require('kolorist');
16
16
  const apiExtractor = require('@microsoft/api-extractor');
17
+ const node_module = require('node:module');
17
18
  const localPkg = require('local-pkg');
18
19
  const compareVersions = require('compare-versions');
19
20
  const MagicString = require('magic-string');
20
21
 
22
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
21
23
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
22
24
 
23
25
  const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
24
26
  const debug__default = /*#__PURE__*/_interopDefaultCompat(debug);
25
27
  const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
26
28
 
29
+ const _createProgram = typescript.proxyCreateProgram(ts__default, ts__default.createProgram, (ts2, options) => {
30
+ const { configFilePath } = options.options;
31
+ const vueOptions = typeof configFilePath === "string" ? languageCore.createParsedCommandLine(ts2, ts2.sys, configFilePath.replace(/\\/g, "/")).vueOptions : languageCore.resolveVueCompilerOptions({});
32
+ if (options.host) {
33
+ const writeFile = options.host.writeFile.bind(options.host);
34
+ options.host.writeFile = (fileName, contents, ...args) => {
35
+ return writeFile(fileName, vueTsc.removeEmitGlobalTypes(contents), ...args);
36
+ };
37
+ }
38
+ const vueLanguagePlugin = languageCore.createVueLanguagePlugin2(
39
+ ts2,
40
+ (id) => id,
41
+ languageCore.createRootFileChecker(
42
+ void 0,
43
+ () => options.rootNames.map((rootName) => rootName.replace(/\\/g, "/")),
44
+ options.host?.useCaseSensitiveFileNames?.() ?? false
45
+ ),
46
+ options.options,
47
+ vueOptions
48
+ );
49
+ return [vueLanguagePlugin];
50
+ });
51
+ const createProgram = (options) => {
52
+ const program = _createProgram(options);
53
+ const emit = program.emit;
54
+ program.emit = (targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) => {
55
+ if (writeFile) {
56
+ return emit(
57
+ targetSourceFile,
58
+ (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
59
+ if (fileName.endsWith(".d.ts")) {
60
+ data = vueTsc.removeEmitGlobalTypes(data);
61
+ }
62
+ return writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
63
+ },
64
+ cancellationToken,
65
+ emitOnlyDtsFiles,
66
+ customTransformers
67
+ );
68
+ }
69
+ return emit(
70
+ targetSourceFile,
71
+ writeFile,
72
+ cancellationToken,
73
+ emitOnlyDtsFiles,
74
+ customTransformers
75
+ );
76
+ };
77
+ return program;
78
+ };
79
+
27
80
  const windowsSlashRE = /\\+/g;
28
81
  function slash(p) {
29
82
  return p.replace(windowsSlashRE, "/");
@@ -147,6 +200,23 @@ function getTsConfig(tsConfigPath, readFileSync) {
147
200
  Object.assign(tsConfig.compilerOptions, baseConfig.compilerOptions);
148
201
  return tsConfig;
149
202
  }
203
+ function getTsLibFolder({ root, entryRoot }) {
204
+ let libFolder;
205
+ try {
206
+ libFolder = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).resolve("typescript").replace(/node_modules\/typescript.*/, "node_modules/typescript");
207
+ } catch {
208
+ libFolder = resolve(root, "node_modules/typescript");
209
+ if (!node_fs.existsSync(libFolder)) {
210
+ if (root !== entryRoot) {
211
+ libFolder = resolve(entryRoot, "node_modules/typescript");
212
+ if (!node_fs.existsSync(libFolder))
213
+ libFolder = void 0;
214
+ }
215
+ libFolder = void 0;
216
+ }
217
+ }
218
+ return libFolder;
219
+ }
150
220
  const BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
151
221
  function base64Encode(number) {
152
222
  if (number >= 0 && number < BASE64_ALPHABET.length) {
@@ -285,6 +355,9 @@ function rollupDeclarationFiles({
285
355
  if (!dtsRE$1.test(fileName)) {
286
356
  fileName += ".d.ts";
287
357
  }
358
+ if (/preserve/i.test(compilerOptions.module)) {
359
+ compilerOptions = { ...compilerOptions, module: "ESNext" };
360
+ }
288
361
  const extractorConfig = apiExtractor.ExtractorConfig.prepare({
289
362
  configObject: {
290
363
  ...rollupConfig,
@@ -410,7 +483,7 @@ function VueResolver() {
410
483
  program.emit(
411
484
  sourceFile,
412
485
  (path, content) => {
413
- outputs.push({ path, content });
486
+ outputs.push({ path, content: vueTsc.removeEmitGlobalTypes(content) });
414
487
  },
415
488
  void 0,
416
489
  true
@@ -501,10 +574,12 @@ function transformCode(options) {
501
574
  return options.cleanVueFileName ? name.replace(/\.vue$/, "") : name;
502
575
  };
503
576
  let indexCount = 0;
577
+ let importCount = 0;
504
578
  walkSourceFile(ast, (node, parent) => {
505
579
  if (ts__default.isImportDeclaration(node)) {
506
580
  if (!node.importClause) {
507
581
  options.clearPureImport && s.remove(node.pos, node.end);
582
+ ++importCount;
508
583
  } else if (ts__default.isStringLiteral(node.moduleSpecifier) && (node.importClause.name || node.importClause.namedBindings && ts__default.isNamedImports(node.importClause.namedBindings))) {
509
584
  const libName = toLibName(node.moduleSpecifier.text);
510
585
  const importSet = importMap.get(libName) ?? importMap.set(libName, /* @__PURE__ */ new Set()).get(libName);
@@ -523,6 +598,7 @@ function transformCode(options) {
523
598
  });
524
599
  }
525
600
  s.remove(node.pos, node.end);
601
+ ++importCount;
526
602
  }
527
603
  return false;
528
604
  }
@@ -565,7 +641,7 @@ function transformCode(options) {
565
641
  return false;
566
642
  }
567
643
  if (ts__default.isModuleDeclaration(node)) {
568
- if (node.body && ts__default.isModuleBlock(node.body) && !node.body.statements.some(
644
+ if (node.modifiers?.[0] && node.modifiers[0].kind === ts__default.SyntaxKind.DeclareKeyword && node.body && ts__default.isModuleBlock(node.body) && !node.body.statements.some(
569
645
  (s2) => ts__default.isExportAssignment(s2) || ts__default.isExportDeclaration(s2) || ts__default.isImportDeclaration(s2)
570
646
  )) {
571
647
  declareModules.push(s.slice(node.pos, node.end + 1));
@@ -578,12 +654,36 @@ function transformCode(options) {
578
654
  prependImports += `import { ${Array.from(importSet).join(", ")} } from '${libName}';
579
655
  `;
580
656
  });
581
- s.prepend(prependImports);
657
+ s.trimStart("\n").prepend(prependImports);
582
658
  return {
583
659
  content: s.toString(),
584
- declareModules
660
+ declareModules,
661
+ diffLineCount: importMap.size && importCount < importMap.size ? importMap.size - importCount : null
585
662
  };
586
663
  }
664
+ function hasNamedExport(content) {
665
+ const ast = ts__default.createSourceFile("a.ts", content, ts__default.ScriptTarget.Latest);
666
+ let has = false;
667
+ walkSourceFile(ast, (node) => {
668
+ if (ts__default.isExportDeclaration(node) && node.exportClause && ts__default.isNamedExports(node.exportClause)) {
669
+ for (const element of node.exportClause.elements) {
670
+ if (element.name.escapedText !== "default") {
671
+ has = true;
672
+ break;
673
+ }
674
+ }
675
+ } else if ("modifiers" in node && Array.isArray(node.modifiers) && node.modifiers.length > 1) {
676
+ for (let i = 0, len = node.modifiers.length; i < len; ++i) {
677
+ if (node.modifiers[i].kind === ts__default.SyntaxKind.ExportKeyword && node.modifiers[i + 1]?.kind !== ts__default.SyntaxKind.DefaultKeyword) {
678
+ has = true;
679
+ break;
680
+ }
681
+ }
682
+ }
683
+ return false;
684
+ });
685
+ return has;
686
+ }
587
687
  function hasExportDefault(content) {
588
688
  const ast = ts__default.createSourceFile("a.ts", content, ts__default.ScriptTarget.Latest);
589
689
  let has = false;
@@ -610,26 +710,6 @@ function hasExportDefault(content) {
610
710
  return has;
611
711
  }
612
712
 
613
- const createProgram = typescript.proxyCreateProgram(ts__default, ts__default.createProgram, (ts2, options) => {
614
- const { configFilePath } = options.options;
615
- const vueOptions = typeof configFilePath === "string" ? languageCore.createParsedCommandLine(ts2, ts2.sys, configFilePath.replace(/\\/g, "/")).vueOptions : languageCore.resolveVueCompilerOptions({});
616
- if (options.host) {
617
- const writeFile2 = options.host.writeFile.bind(options.host);
618
- options.host.writeFile = (fileName, contents, ...args) => {
619
- return writeFile2(fileName, vueTsc.removeEmitGlobalTypes(contents), ...args);
620
- };
621
- }
622
- const vueLanguagePlugin = languageCore.createVueLanguagePlugin(
623
- ts2,
624
- (id) => id,
625
- options.host?.useCaseSensitiveFileNames?.() ?? false,
626
- () => "",
627
- () => options.rootNames.map((rootName) => rootName.replace(/\\/g, "/")),
628
- options.options,
629
- vueOptions
630
- );
631
- return [vueLanguagePlugin];
632
- });
633
713
  const jsRE = /\.(m|c)?jsx?$/;
634
714
  const tsRE = /\.(m|c)?tsx?$/;
635
715
  const dtsRE = /\.d\.(m|c)?tsx?$/;
@@ -997,13 +1077,28 @@ ${logPrefix} Start generate declaration files...`));
997
1077
  }
998
1078
  bundleDebug("emit output patch");
999
1079
  const currentDir = host.getCurrentDirectory();
1080
+ const declarationFiles = /* @__PURE__ */ new Map();
1081
+ const mapFiles = /* @__PURE__ */ new Map();
1082
+ const prependMappings = /* @__PURE__ */ new Map();
1083
+ for (const [filePath, content] of outputFiles.entries()) {
1084
+ if (filePath.endsWith(".map")) {
1085
+ mapFiles.set(filePath, content);
1086
+ } else {
1087
+ declarationFiles.set(filePath, content);
1088
+ }
1089
+ }
1000
1090
  await runParallel(
1001
1091
  node_os.cpus().length,
1002
- Array.from(outputFiles.entries()),
1092
+ Array.from(declarationFiles.entries()),
1003
1093
  async ([filePath, content]) => {
1004
- const isMapFile = filePath.endsWith(".map");
1005
- const baseDir = node_path.dirname(filePath);
1006
- if (!isMapFile && content) {
1094
+ const newFilePath = resolve(
1095
+ outDir,
1096
+ node_path.relative(
1097
+ entryRoot,
1098
+ cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath
1099
+ )
1100
+ );
1101
+ if (content) {
1007
1102
  const result = transformCode({
1008
1103
  filePath,
1009
1104
  content,
@@ -1015,7 +1110,18 @@ ${logPrefix} Start generate declaration files...`));
1015
1110
  });
1016
1111
  content = result.content;
1017
1112
  declareModules.push(...result.declareModules);
1113
+ if (result.diffLineCount) {
1114
+ prependMappings.set(`${newFilePath}.map`, ";".repeat(result.diffLineCount));
1115
+ }
1018
1116
  }
1117
+ await writeOutput(newFilePath, content, outDir);
1118
+ }
1119
+ );
1120
+ await runParallel(
1121
+ node_os.cpus().length,
1122
+ Array.from(mapFiles.entries()),
1123
+ async ([filePath, content]) => {
1124
+ const baseDir = node_path.dirname(filePath);
1019
1125
  filePath = resolve(
1020
1126
  outDir,
1021
1127
  node_path.relative(
@@ -1023,21 +1129,22 @@ ${logPrefix} Start generate declaration files...`));
1023
1129
  cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath
1024
1130
  )
1025
1131
  );
1026
- if (isMapFile) {
1027
- try {
1028
- const sourceMap = JSON.parse(content);
1029
- sourceMap.sources = sourceMap.sources.map((source) => {
1030
- return normalizePath(
1031
- node_path.relative(
1032
- node_path.dirname(filePath),
1033
- resolve(currentDir, node_path.relative(publicRoot, baseDir), source)
1034
- )
1035
- );
1036
- });
1037
- content = JSON.stringify(sourceMap);
1038
- } catch (e) {
1039
- logger.warn(`${logPrefix} ${kolorist.yellow("Processing source map fail:")} ${filePath}`);
1132
+ try {
1133
+ const sourceMap = JSON.parse(content);
1134
+ sourceMap.sources = sourceMap.sources.map((source) => {
1135
+ return normalizePath(
1136
+ node_path.relative(
1137
+ node_path.dirname(filePath),
1138
+ resolve(currentDir, node_path.relative(publicRoot, baseDir), source)
1139
+ )
1140
+ );
1141
+ });
1142
+ if (prependMappings.has(filePath)) {
1143
+ sourceMap.mappings = `${prependMappings.get(filePath)}${sourceMap.mappings}`;
1040
1144
  }
1145
+ content = JSON.stringify(sourceMap);
1146
+ } catch (e) {
1147
+ logger.warn(`${logPrefix} ${kolorist.yellow("Processing source map fail:")} ${filePath}`);
1041
1148
  }
1042
1149
  await writeOutput(filePath, content, outDir);
1043
1150
  }
@@ -1074,27 +1181,23 @@ ${logPrefix} ${kolorist.yellow(
1074
1181
  let fromPath = normalizePath(node_path.relative(node_path.dirname(entryDtsPath), sourceEntry));
1075
1182
  fromPath = fromPath.replace(dtsRE, "");
1076
1183
  fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`;
1077
- let content = `export * from '${fromPath}'
1184
+ let content = "";
1185
+ if (emittedFiles.has(sourceEntry)) {
1186
+ if (hasNamedExport(emittedFiles.get(sourceEntry))) {
1187
+ content += `export * from '${fromPath}'
1078
1188
  `;
1079
- if (emittedFiles.has(sourceEntry) && hasExportDefault(emittedFiles.get(sourceEntry))) {
1080
- content += `import ${libName} from '${fromPath}'
1189
+ }
1190
+ if (hasExportDefault(emittedFiles.get(sourceEntry))) {
1191
+ content += `import ${libName} from '${fromPath}'
1081
1192
  export default ${libName}
1082
1193
  `;
1194
+ }
1083
1195
  }
1084
1196
  await writeOutput(cleanPath(entryDtsPath), content, outDir);
1085
1197
  }
1086
1198
  bundleDebug("insert index");
1087
1199
  if (rollupTypes) {
1088
1200
  logger.info(kolorist.green(`${logPrefix} Start rollup declaration files...`));
1089
- let libFolder = resolve(root, "node_modules/typescript");
1090
- if (!node_fs.existsSync(libFolder)) {
1091
- if (root !== entryRoot) {
1092
- libFolder = resolve(entryRoot, "node_modules/typescript");
1093
- if (!node_fs.existsSync(libFolder))
1094
- libFolder = void 0;
1095
- }
1096
- libFolder = void 0;
1097
- }
1098
1201
  const rollupFiles = /* @__PURE__ */ new Set();
1099
1202
  const compilerOptions2 = configPath ? getTsConfig(configPath, host.readFile).compilerOptions : rawCompilerOptions;
1100
1203
  const rollup = async (path) => {
@@ -1105,7 +1208,7 @@ export default ${libName}
1105
1208
  outDir,
1106
1209
  entryPath: path,
1107
1210
  fileName: node_path.basename(path),
1108
- libFolder,
1211
+ libFolder: getTsLibFolder({ root, entryRoot }),
1109
1212
  rollupConfig,
1110
1213
  rollupOptions
1111
1214
  });
@@ -1130,8 +1233,7 @@ export default ${libName}
1130
1233
  await writeOutput(
1131
1234
  filePath,
1132
1235
  await promises.readFile(filePath, "utf-8") + (declared ? `
1133
- ${declared}
1134
- ` : ""),
1236
+ ${declared}` : ""),
1135
1237
  node_path.dirname(filePath)
1136
1238
  );
1137
1239
  });
package/dist/index.mjs CHANGED
@@ -9,18 +9,70 @@ import { relative, posix, resolve as resolve$1, isAbsolute, dirname, normalize,
9
9
  import { existsSync, readdirSync, lstatSync, rmdirSync } from 'node:fs';
10
10
  import { readFile, mkdir, writeFile, unlink } from 'node:fs/promises';
11
11
  import { cpus } from 'node:os';
12
- import { createParsedCommandLine, resolveVueCompilerOptions, createVueLanguagePlugin } from '@vue/language-core';
12
+ import { createParsedCommandLine, resolveVueCompilerOptions, createVueLanguagePlugin2, createRootFileChecker } from '@vue/language-core';
13
13
  import { proxyCreateProgram } from '@volar/typescript';
14
14
  import ts from 'typescript';
15
- import { createFilter } from '@rollup/pluginutils';
16
15
  import { removeEmitGlobalTypes } from 'vue-tsc';
16
+ import { createFilter } from '@rollup/pluginutils';
17
17
  import debug from 'debug';
18
18
  import { cyan, yellow, green } from 'kolorist';
19
19
  import { ExtractorConfig, Extractor } from '@microsoft/api-extractor';
20
+ import { createRequire } from 'node:module';
20
21
  import { getPackageInfoSync, resolveModule } from 'local-pkg';
21
22
  import { compare } from 'compare-versions';
22
23
  import MagicString from 'magic-string';
23
24
 
25
+ const _createProgram = proxyCreateProgram(ts, ts.createProgram, (ts2, options) => {
26
+ const { configFilePath } = options.options;
27
+ const vueOptions = typeof configFilePath === "string" ? createParsedCommandLine(ts2, ts2.sys, configFilePath.replace(/\\/g, "/")).vueOptions : resolveVueCompilerOptions({});
28
+ if (options.host) {
29
+ const writeFile = options.host.writeFile.bind(options.host);
30
+ options.host.writeFile = (fileName, contents, ...args) => {
31
+ return writeFile(fileName, removeEmitGlobalTypes(contents), ...args);
32
+ };
33
+ }
34
+ const vueLanguagePlugin = createVueLanguagePlugin2(
35
+ ts2,
36
+ (id) => id,
37
+ createRootFileChecker(
38
+ void 0,
39
+ () => options.rootNames.map((rootName) => rootName.replace(/\\/g, "/")),
40
+ options.host?.useCaseSensitiveFileNames?.() ?? false
41
+ ),
42
+ options.options,
43
+ vueOptions
44
+ );
45
+ return [vueLanguagePlugin];
46
+ });
47
+ const createProgram = (options) => {
48
+ const program = _createProgram(options);
49
+ const emit = program.emit;
50
+ program.emit = (targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) => {
51
+ if (writeFile) {
52
+ return emit(
53
+ targetSourceFile,
54
+ (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
55
+ if (fileName.endsWith(".d.ts")) {
56
+ data = removeEmitGlobalTypes(data);
57
+ }
58
+ return writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
59
+ },
60
+ cancellationToken,
61
+ emitOnlyDtsFiles,
62
+ customTransformers
63
+ );
64
+ }
65
+ return emit(
66
+ targetSourceFile,
67
+ writeFile,
68
+ cancellationToken,
69
+ emitOnlyDtsFiles,
70
+ customTransformers
71
+ );
72
+ };
73
+ return program;
74
+ };
75
+
24
76
  const windowsSlashRE = /\\+/g;
25
77
  function slash(p) {
26
78
  return p.replace(windowsSlashRE, "/");
@@ -144,6 +196,23 @@ function getTsConfig(tsConfigPath, readFileSync) {
144
196
  Object.assign(tsConfig.compilerOptions, baseConfig.compilerOptions);
145
197
  return tsConfig;
146
198
  }
199
+ function getTsLibFolder({ root, entryRoot }) {
200
+ let libFolder;
201
+ try {
202
+ libFolder = createRequire(import.meta.url).resolve("typescript").replace(/node_modules\/typescript.*/, "node_modules/typescript");
203
+ } catch {
204
+ libFolder = resolve(root, "node_modules/typescript");
205
+ if (!existsSync(libFolder)) {
206
+ if (root !== entryRoot) {
207
+ libFolder = resolve(entryRoot, "node_modules/typescript");
208
+ if (!existsSync(libFolder))
209
+ libFolder = void 0;
210
+ }
211
+ libFolder = void 0;
212
+ }
213
+ }
214
+ return libFolder;
215
+ }
147
216
  const BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
148
217
  function base64Encode(number) {
149
218
  if (number >= 0 && number < BASE64_ALPHABET.length) {
@@ -282,6 +351,9 @@ function rollupDeclarationFiles({
282
351
  if (!dtsRE$1.test(fileName)) {
283
352
  fileName += ".d.ts";
284
353
  }
354
+ if (/preserve/i.test(compilerOptions.module)) {
355
+ compilerOptions = { ...compilerOptions, module: "ESNext" };
356
+ }
285
357
  const extractorConfig = ExtractorConfig.prepare({
286
358
  configObject: {
287
359
  ...rollupConfig,
@@ -407,7 +479,7 @@ function VueResolver() {
407
479
  program.emit(
408
480
  sourceFile,
409
481
  (path, content) => {
410
- outputs.push({ path, content });
482
+ outputs.push({ path, content: removeEmitGlobalTypes(content) });
411
483
  },
412
484
  void 0,
413
485
  true
@@ -498,10 +570,12 @@ function transformCode(options) {
498
570
  return options.cleanVueFileName ? name.replace(/\.vue$/, "") : name;
499
571
  };
500
572
  let indexCount = 0;
573
+ let importCount = 0;
501
574
  walkSourceFile(ast, (node, parent) => {
502
575
  if (ts.isImportDeclaration(node)) {
503
576
  if (!node.importClause) {
504
577
  options.clearPureImport && s.remove(node.pos, node.end);
578
+ ++importCount;
505
579
  } else if (ts.isStringLiteral(node.moduleSpecifier) && (node.importClause.name || node.importClause.namedBindings && ts.isNamedImports(node.importClause.namedBindings))) {
506
580
  const libName = toLibName(node.moduleSpecifier.text);
507
581
  const importSet = importMap.get(libName) ?? importMap.set(libName, /* @__PURE__ */ new Set()).get(libName);
@@ -520,6 +594,7 @@ function transformCode(options) {
520
594
  });
521
595
  }
522
596
  s.remove(node.pos, node.end);
597
+ ++importCount;
523
598
  }
524
599
  return false;
525
600
  }
@@ -562,7 +637,7 @@ function transformCode(options) {
562
637
  return false;
563
638
  }
564
639
  if (ts.isModuleDeclaration(node)) {
565
- if (node.body && ts.isModuleBlock(node.body) && !node.body.statements.some(
640
+ if (node.modifiers?.[0] && node.modifiers[0].kind === ts.SyntaxKind.DeclareKeyword && node.body && ts.isModuleBlock(node.body) && !node.body.statements.some(
566
641
  (s2) => ts.isExportAssignment(s2) || ts.isExportDeclaration(s2) || ts.isImportDeclaration(s2)
567
642
  )) {
568
643
  declareModules.push(s.slice(node.pos, node.end + 1));
@@ -575,12 +650,36 @@ function transformCode(options) {
575
650
  prependImports += `import { ${Array.from(importSet).join(", ")} } from '${libName}';
576
651
  `;
577
652
  });
578
- s.prepend(prependImports);
653
+ s.trimStart("\n").prepend(prependImports);
579
654
  return {
580
655
  content: s.toString(),
581
- declareModules
656
+ declareModules,
657
+ diffLineCount: importMap.size && importCount < importMap.size ? importMap.size - importCount : null
582
658
  };
583
659
  }
660
+ function hasNamedExport(content) {
661
+ const ast = ts.createSourceFile("a.ts", content, ts.ScriptTarget.Latest);
662
+ let has = false;
663
+ walkSourceFile(ast, (node) => {
664
+ if (ts.isExportDeclaration(node) && node.exportClause && ts.isNamedExports(node.exportClause)) {
665
+ for (const element of node.exportClause.elements) {
666
+ if (element.name.escapedText !== "default") {
667
+ has = true;
668
+ break;
669
+ }
670
+ }
671
+ } else if ("modifiers" in node && Array.isArray(node.modifiers) && node.modifiers.length > 1) {
672
+ for (let i = 0, len = node.modifiers.length; i < len; ++i) {
673
+ if (node.modifiers[i].kind === ts.SyntaxKind.ExportKeyword && node.modifiers[i + 1]?.kind !== ts.SyntaxKind.DefaultKeyword) {
674
+ has = true;
675
+ break;
676
+ }
677
+ }
678
+ }
679
+ return false;
680
+ });
681
+ return has;
682
+ }
584
683
  function hasExportDefault(content) {
585
684
  const ast = ts.createSourceFile("a.ts", content, ts.ScriptTarget.Latest);
586
685
  let has = false;
@@ -607,26 +706,6 @@ function hasExportDefault(content) {
607
706
  return has;
608
707
  }
609
708
 
610
- const createProgram = proxyCreateProgram(ts, ts.createProgram, (ts2, options) => {
611
- const { configFilePath } = options.options;
612
- const vueOptions = typeof configFilePath === "string" ? createParsedCommandLine(ts2, ts2.sys, configFilePath.replace(/\\/g, "/")).vueOptions : resolveVueCompilerOptions({});
613
- if (options.host) {
614
- const writeFile2 = options.host.writeFile.bind(options.host);
615
- options.host.writeFile = (fileName, contents, ...args) => {
616
- return writeFile2(fileName, removeEmitGlobalTypes(contents), ...args);
617
- };
618
- }
619
- const vueLanguagePlugin = createVueLanguagePlugin(
620
- ts2,
621
- (id) => id,
622
- options.host?.useCaseSensitiveFileNames?.() ?? false,
623
- () => "",
624
- () => options.rootNames.map((rootName) => rootName.replace(/\\/g, "/")),
625
- options.options,
626
- vueOptions
627
- );
628
- return [vueLanguagePlugin];
629
- });
630
709
  const jsRE = /\.(m|c)?jsx?$/;
631
710
  const tsRE = /\.(m|c)?tsx?$/;
632
711
  const dtsRE = /\.d\.(m|c)?tsx?$/;
@@ -994,13 +1073,28 @@ ${logPrefix} Start generate declaration files...`));
994
1073
  }
995
1074
  bundleDebug("emit output patch");
996
1075
  const currentDir = host.getCurrentDirectory();
1076
+ const declarationFiles = /* @__PURE__ */ new Map();
1077
+ const mapFiles = /* @__PURE__ */ new Map();
1078
+ const prependMappings = /* @__PURE__ */ new Map();
1079
+ for (const [filePath, content] of outputFiles.entries()) {
1080
+ if (filePath.endsWith(".map")) {
1081
+ mapFiles.set(filePath, content);
1082
+ } else {
1083
+ declarationFiles.set(filePath, content);
1084
+ }
1085
+ }
997
1086
  await runParallel(
998
1087
  cpus().length,
999
- Array.from(outputFiles.entries()),
1088
+ Array.from(declarationFiles.entries()),
1000
1089
  async ([filePath, content]) => {
1001
- const isMapFile = filePath.endsWith(".map");
1002
- const baseDir = dirname(filePath);
1003
- if (!isMapFile && content) {
1090
+ const newFilePath = resolve(
1091
+ outDir,
1092
+ relative(
1093
+ entryRoot,
1094
+ cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath
1095
+ )
1096
+ );
1097
+ if (content) {
1004
1098
  const result = transformCode({
1005
1099
  filePath,
1006
1100
  content,
@@ -1012,7 +1106,18 @@ ${logPrefix} Start generate declaration files...`));
1012
1106
  });
1013
1107
  content = result.content;
1014
1108
  declareModules.push(...result.declareModules);
1109
+ if (result.diffLineCount) {
1110
+ prependMappings.set(`${newFilePath}.map`, ";".repeat(result.diffLineCount));
1111
+ }
1015
1112
  }
1113
+ await writeOutput(newFilePath, content, outDir);
1114
+ }
1115
+ );
1116
+ await runParallel(
1117
+ cpus().length,
1118
+ Array.from(mapFiles.entries()),
1119
+ async ([filePath, content]) => {
1120
+ const baseDir = dirname(filePath);
1016
1121
  filePath = resolve(
1017
1122
  outDir,
1018
1123
  relative(
@@ -1020,21 +1125,22 @@ ${logPrefix} Start generate declaration files...`));
1020
1125
  cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath
1021
1126
  )
1022
1127
  );
1023
- if (isMapFile) {
1024
- try {
1025
- const sourceMap = JSON.parse(content);
1026
- sourceMap.sources = sourceMap.sources.map((source) => {
1027
- return normalizePath(
1028
- relative(
1029
- dirname(filePath),
1030
- resolve(currentDir, relative(publicRoot, baseDir), source)
1031
- )
1032
- );
1033
- });
1034
- content = JSON.stringify(sourceMap);
1035
- } catch (e) {
1036
- logger.warn(`${logPrefix} ${yellow("Processing source map fail:")} ${filePath}`);
1128
+ try {
1129
+ const sourceMap = JSON.parse(content);
1130
+ sourceMap.sources = sourceMap.sources.map((source) => {
1131
+ return normalizePath(
1132
+ relative(
1133
+ dirname(filePath),
1134
+ resolve(currentDir, relative(publicRoot, baseDir), source)
1135
+ )
1136
+ );
1137
+ });
1138
+ if (prependMappings.has(filePath)) {
1139
+ sourceMap.mappings = `${prependMappings.get(filePath)}${sourceMap.mappings}`;
1037
1140
  }
1141
+ content = JSON.stringify(sourceMap);
1142
+ } catch (e) {
1143
+ logger.warn(`${logPrefix} ${yellow("Processing source map fail:")} ${filePath}`);
1038
1144
  }
1039
1145
  await writeOutput(filePath, content, outDir);
1040
1146
  }
@@ -1071,27 +1177,23 @@ ${logPrefix} ${yellow(
1071
1177
  let fromPath = normalizePath(relative(dirname(entryDtsPath), sourceEntry));
1072
1178
  fromPath = fromPath.replace(dtsRE, "");
1073
1179
  fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`;
1074
- let content = `export * from '${fromPath}'
1180
+ let content = "";
1181
+ if (emittedFiles.has(sourceEntry)) {
1182
+ if (hasNamedExport(emittedFiles.get(sourceEntry))) {
1183
+ content += `export * from '${fromPath}'
1075
1184
  `;
1076
- if (emittedFiles.has(sourceEntry) && hasExportDefault(emittedFiles.get(sourceEntry))) {
1077
- content += `import ${libName} from '${fromPath}'
1185
+ }
1186
+ if (hasExportDefault(emittedFiles.get(sourceEntry))) {
1187
+ content += `import ${libName} from '${fromPath}'
1078
1188
  export default ${libName}
1079
1189
  `;
1190
+ }
1080
1191
  }
1081
1192
  await writeOutput(cleanPath(entryDtsPath), content, outDir);
1082
1193
  }
1083
1194
  bundleDebug("insert index");
1084
1195
  if (rollupTypes) {
1085
1196
  logger.info(green(`${logPrefix} Start rollup declaration files...`));
1086
- let libFolder = resolve(root, "node_modules/typescript");
1087
- if (!existsSync(libFolder)) {
1088
- if (root !== entryRoot) {
1089
- libFolder = resolve(entryRoot, "node_modules/typescript");
1090
- if (!existsSync(libFolder))
1091
- libFolder = void 0;
1092
- }
1093
- libFolder = void 0;
1094
- }
1095
1197
  const rollupFiles = /* @__PURE__ */ new Set();
1096
1198
  const compilerOptions2 = configPath ? getTsConfig(configPath, host.readFile).compilerOptions : rawCompilerOptions;
1097
1199
  const rollup = async (path) => {
@@ -1102,7 +1204,7 @@ export default ${libName}
1102
1204
  outDir,
1103
1205
  entryPath: path,
1104
1206
  fileName: basename(path),
1105
- libFolder,
1207
+ libFolder: getTsLibFolder({ root, entryRoot }),
1106
1208
  rollupConfig,
1107
1209
  rollupOptions
1108
1210
  });
@@ -1127,8 +1229,7 @@ export default ${libName}
1127
1229
  await writeOutput(
1128
1230
  filePath,
1129
1231
  await readFile(filePath, "utf-8") + (declared ? `
1130
- ${declared}
1131
- ` : ""),
1232
+ ${declared}` : ""),
1132
1233
  dirname(filePath)
1133
1234
  );
1134
1235
  });
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "vite-plugin-dts",
3
- "version": "4.0.0-beta.1",
3
+ "version": "4.0.0",
4
4
  "type": "module",
5
+ "packageManager": "pnpm@8.3.0",
5
6
  "license": "MIT",
6
7
  "author": "qmhc",
7
- "packageManager": "pnpm@8.3.0",
8
8
  "scripts": {
9
9
  "build": "tsx scripts/build.ts",
10
10
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s --commit-path .",
11
11
  "dev": "unbuild --stub",
12
- "lint": "eslint --ext .js,.jsx,.ts,.tsx \"{src,tests}/**\"",
13
12
  "_postinstall": "is-ci || husky install",
14
- "postpublish": "pinst --enable",
13
+ "lint": "eslint --ext .js,.jsx,.ts,.tsx \"{src,tests}/**\"",
15
14
  "precommit": "lint-staged -c ./.husky/.lintstagedrc -q",
16
15
  "prepublishOnly": "pinst --disable",
17
16
  "prettier": "pretty-quick --staged && pnpm run lint",
17
+ "postpublish": "pinst --enable",
18
18
  "release": "tsx scripts/release.ts",
19
19
  "test": "vitest run",
20
20
  "test:dev": "vitest",
@@ -39,13 +39,6 @@
39
39
  "engines": {
40
40
  "node": "^14.18.0 || >=16.0.0"
41
41
  },
42
- "repository": {
43
- "type": "git",
44
- "url": "git+https://github.com/qmhc/vite-plugin-dts.git"
45
- },
46
- "bugs": {
47
- "url": "https://github.com/qmhc/vite-plugin-dts/issues"
48
- },
49
42
  "keywords": [
50
43
  "vite",
51
44
  "vite-plugin",
@@ -57,17 +50,24 @@
57
50
  "vue-tsc",
58
51
  "volar"
59
52
  ],
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "git+https://github.com/qmhc/vite-plugin-dts.git"
56
+ },
57
+ "bugs": {
58
+ "url": "https://github.com/qmhc/vite-plugin-dts/issues"
59
+ },
60
60
  "dependencies": {
61
- "@microsoft/api-extractor": "7.47.2",
61
+ "@microsoft/api-extractor": "7.47.4",
62
62
  "@rollup/pluginutils": "^5.1.0",
63
63
  "@volar/typescript": "^2.3.4",
64
- "@vue/language-core": "2.0.19",
64
+ "@vue/language-core": "2.0.29",
65
65
  "compare-versions": "^6.1.1",
66
- "debug": "^4.3.5",
66
+ "debug": "^4.3.6",
67
67
  "kolorist": "^1.8.0",
68
68
  "local-pkg": "^0.5.0",
69
- "magic-string": "^0.30.10",
70
- "vue-tsc": "2.0.19"
69
+ "magic-string": "^0.30.11",
70
+ "vue-tsc": "2.0.29"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@commitlint/cli": "^19.3.0",
@@ -78,7 +78,7 @@
78
78
  "@types/semver": "^7.5.8",
79
79
  "@vexip-ui/commitlint-config": "^0.5.0",
80
80
  "@vexip-ui/eslint-config": "^0.12.1",
81
- "@vexip-ui/prettier-config": "^0.2.0",
81
+ "@vexip-ui/prettier-config": "^1.0.0",
82
82
  "@vue/eslint-config-standard": "^8.0.1",
83
83
  "@vue/eslint-config-typescript": "^13.0.0",
84
84
  "conventional-changelog-cli": "^5.0.0",
@@ -95,10 +95,10 @@
95
95
  "rimraf": "^6.0.1",
96
96
  "semver": "^7.6.3",
97
97
  "tsx": "^4.16.2",
98
- "typescript": "5.5.3",
98
+ "typescript": "5.5.4",
99
99
  "unbuild": "^2.0.0",
100
- "vite": "^5.3.4",
101
- "vitest": "^2.0.3"
100
+ "vite": "^5.3.5",
101
+ "vitest": "^2.0.4"
102
102
  },
103
103
  "peerDependencies": {
104
104
  "typescript": "*",
@@ -111,7 +111,7 @@
111
111
  },
112
112
  "pnpm": {
113
113
  "patchedDependencies": {
114
- "@microsoft/api-extractor@7.47.2": "patches/@microsoft__api-extractor@7.47.2.patch"
114
+ "@microsoft/api-extractor@7.47.4": "patches/@microsoft__api-extractor@7.47.4.patch"
115
115
  }
116
116
  }
117
117
  }