rolldown-plugin-dts 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Unit Test](https://github.com/sxzz/rolldown-plugin-dts/actions/workflows/unit-test.yml/badge.svg)](https://github.com/sxzz/rolldown-plugin-dts/actions/workflows/unit-test.yml)
4
4
 
5
- A Rolldown plugin to bundle dts files.
5
+ A Rolldown plugin to generate and bundle dts files.
6
6
 
7
7
  ## Install
8
8
 
@@ -18,24 +18,59 @@ Add the plugin to your `rolldown.config.js`:
18
18
  // rolldown.config.js
19
19
  import { dts } from 'rolldown-plugin-dts'
20
20
 
21
- const config = [
22
- {
23
- input: './index.d.ts',
24
- plugins: [dts()],
25
- output: [
26
- {
27
- file: 'dist/index.d.ts',
28
- format: 'es',
29
- },
30
- ],
31
- },
32
- ]
33
-
34
- export default config
21
+ export default {
22
+ input: './src/index.ts',
23
+ plugins: [dts()],
24
+ output: [{ dir: 'dist', format: 'es' }],
25
+ }
35
26
  ```
36
27
 
37
- > [!NOTE]
38
- > Namespaces are not supported yet.
28
+ You can find a real demo in [here](./rolldown.config.ts).
29
+
30
+ ## Options
31
+
32
+ ````ts
33
+ interface Options {
34
+ /**
35
+ * When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
36
+ *
37
+ * If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
38
+ */
39
+ dtsInput?: boolean
40
+
41
+ isolatedDeclaration?: Omit<IsolatedDeclarationsOptions, 'sourcemap'>
42
+
43
+ /**
44
+ * dts file name alias `{ [filename]: path }`
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * inputAlias: {
49
+ * 'foo.d.ts': 'foo/index.d.ts',
50
+ * }
51
+ */
52
+ inputAlias?: Record<string, string>
53
+
54
+ /**
55
+ * Determines whether the module imported by `.d.ts` files should be treated as external or not.
56
+ */
57
+ external?: (
58
+ id: string,
59
+ importer: string,
60
+ extraOptions: ResolveIdExtraOptions,
61
+ ) => boolean | void
62
+ }
63
+ ````
64
+
65
+ ## Caveats
66
+
67
+ - The plugin uses Oxc's `isolatedDeclarations` to generate `.d.ts` files,
68
+ which means you need to set `isolatedDeclarations: true` in your `tsconfig.json` and ensure there are no errors.
69
+
70
+ - Namespaces are not supported yet.
71
+ - `export * as ns from './ns'`
72
+ - `import * as ns from './ns'` and then `export { ns }`
73
+ - `type ns = import('./ns')`
39
74
 
40
75
  ## Credits
41
76
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,40 @@
1
- import { Plugin } from "rolldown";
1
+ import { IsolatedDeclarationsOptions } from "oxc-transform";
2
+ import { FunctionPluginHooks, Plugin } from "rolldown";
2
3
 
3
- //#region dist/.tsdown-types-es/index.d.ts
4
- declare function dts(): Plugin;
4
+ //#region src/fake-js.d.ts
5
+ declare function createFakeJsPlugin({ dtsInput }: Pick<Options, "dtsInput">): Plugin;
5
6
 
6
7
  //#endregion
7
- export { dts };
8
+ //#region src/generate.d.ts
9
+ declare function createGeneratePlugin({ isolatedDeclaration, inputAlias, external }: Pick<Options, "external" | "isolatedDeclaration" | "inputAlias">): Plugin;
10
+
11
+ //#endregion
12
+ //#region src/index.d.ts
13
+ type ResolveIdExtraOptions = Parameters<FunctionPluginHooks["resolveId"]>[2];
14
+ interface Options {
15
+ /**
16
+ * When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
17
+ *
18
+ * If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
19
+ */
20
+ dtsInput?: boolean;
21
+ isolatedDeclaration?: Omit<IsolatedDeclarationsOptions, "sourcemap">;
22
+ /**
23
+ * dts file name alias `{ [filename]: path }`
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * inputAlias: {
28
+ * 'foo.d.ts': 'foo/index.d.ts',
29
+ * }
30
+ */
31
+ inputAlias?: Record<string, string>;
32
+ /**
33
+ * Determines whether the module imported by `.d.ts` files should be treated as external or not.
34
+ */
35
+ external?: (id: string, importer: string, extraOptions: ResolveIdExtraOptions) => boolean | void;
36
+ }
37
+ declare function dts(options?: Options): Plugin[];
38
+
39
+ //#endregion
40
+ export { Options, createFakeJsPlugin, createGeneratePlugin, dts };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
- import path from "node:path";
2
1
  import { MagicStringAST } from "magic-string-ast";
3
2
  import { parseAsync } from "oxc-parser";
3
+ import path, { basename } from "node:path";
4
+ import { isolatedDeclaration } from "oxc-transform";
4
5
 
5
6
  //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js
6
7
  var WalkerBase = class {
@@ -110,10 +111,10 @@ var SyncWalker = class extends WalkerBase {
110
111
  if (value && typeof value === "object") {
111
112
  if (Array.isArray(value)) {
112
113
  const nodes = value;
113
- for (let i$1 = 0; i$1 < nodes.length; i$1 += 1) {
114
- const item = nodes[i$1];
114
+ for (let i = 0; i < nodes.length; i += 1) {
115
+ const item = nodes[i];
115
116
  if (isNode(item)) {
116
- if (!this.visit(item, node, key, i$1)) i$1--;
117
+ if (!this.visit(item, node, key, i)) i--;
117
118
  }
118
119
  }
119
120
  } else if (isNode(value)) this.visit(value, node, key, null);
@@ -163,25 +164,49 @@ function getIdentifierRange(node, offset = 0) {
163
164
  return [node.start + offset, node.end + offset];
164
165
  }
165
166
 
167
+ //#endregion
168
+ //#region src/utils/filename.ts
169
+ const RE_JS = /\.([cm]?)js$/;
170
+ const RE_TS = /\.([cm]?)ts$/;
171
+ const RE_DTS = /\.d\.([cm]?)ts$/;
172
+ const RE_NODE_MODULES = /node_modules/;
173
+ function filename_js_to_dts(id) {
174
+ return id.replace(RE_JS, ".d.$1ts");
175
+ }
176
+ function filename_ts_to_dts(id) {
177
+ return id.replace(RE_TS, ".d.$1ts");
178
+ }
179
+ function filename_dts_to(id, ext) {
180
+ return id.replace(RE_DTS, `.$1${ext}`);
181
+ }
182
+ function isRelative(id) {
183
+ return path.isAbsolute(id) || id[0] === ".";
184
+ }
185
+
166
186
  //#endregion
167
187
  //#region src/utils/magic-string.ts
168
- function overwriteOrAppend(s, range, replacement) {
188
+ function overwriteOrAppend(s, range, replacement, suffix) {
169
189
  if (range[0] === range[1]) {
170
190
  s.appendLeft(range[0], ` ${replacement}`);
171
191
  return;
172
192
  }
173
- s.overwrite(range[0], range[1], replacement);
193
+ const original = s.slice(range[0], range[1]);
194
+ if (original !== replacement) s.overwrite(range[0], range[1], replacement + (suffix || ""));
174
195
  }
175
196
 
176
197
  //#endregion
177
- //#region src/index.ts
198
+ //#region src/fake-js.ts
178
199
  const RE_TYPE = /\btype\b/;
179
- function dts() {
180
- let i$1 = 0;
200
+ function createFakeJsPlugin({ dtsInput }) {
201
+ let symbolIdx = 0;
202
+ let identifierIdx = 0;
181
203
  const symbolMap = new Map();
182
- const commentMap = new Map();
204
+ const preserveMap = new Map();
205
+ function getIdentifierIndex() {
206
+ return identifierIdx++;
207
+ }
183
208
  function register(info) {
184
- const symbolId = i$1++;
209
+ const symbolId = symbolIdx++;
185
210
  symbolMap.set(symbolId, info);
186
211
  return symbolId;
187
212
  }
@@ -189,8 +214,8 @@ function dts() {
189
214
  return symbolMap.get(symbolId);
190
215
  }
191
216
  return {
192
- name: "rolldown-plugin-dts",
193
- options({ onLog,...options }) {
217
+ name: "rolldown-plugin-dts:fake-js",
218
+ options: dtsInput ? (options) => {
194
219
  return {
195
220
  ...options,
196
221
  resolve: {
@@ -205,85 +230,87 @@ function dts() {
205
230
  ".cjs": [".d.cts"]
206
231
  },
207
232
  ...options.resolve
208
- },
209
- onLog(level, log, defaultHandler) {
210
- if (level === "warn" && log.code === "CIRCULAR_DEPENDENCY") return;
211
- if (onLog) onLog(level, log, defaultHandler);
212
- else defaultHandler(level, log);
213
- },
214
- treeshake: {
215
- moduleSideEffects: "no-external",
216
- unknownGlobalSideEffects: false
217
233
  }
218
234
  };
219
- },
235
+ } : void 0,
220
236
  outputOptions(options) {
221
237
  return {
222
- chunkFileNames: "[name]-[hash].d.ts",
223
- entryFileNames: "[name].ts",
224
- format: "es",
225
- exports: "named",
226
- ...options
227
- };
228
- },
229
- resolveId(id, importer) {
230
- if (importer && !path.isAbsolute(id) && id[0] !== ".") return {
231
- id,
232
- external: true
238
+ ...options,
239
+ entryFileNames: options.entryFileNames ?? (dtsInput ? "[name].ts" : void 0),
240
+ chunkFileNames(chunk) {
241
+ const original = (typeof options.chunkFileNames === "function" ? options.chunkFileNames(chunk) : options.chunkFileNames) || "[name]-[hash].js";
242
+ if (chunk.name.endsWith(".d")) return filename_js_to_dts(original);
243
+ return original;
244
+ }
233
245
  };
234
246
  },
235
- async transform(code, id) {
236
- const { program, comments } = await parseAsync(id, code);
237
- const preserveComments = collectReferenceDirectives(comments);
238
- commentMap.set(id, preserveComments);
239
- const s = new MagicStringAST(code);
240
- for (let node of program.body) {
241
- if (rewriteImportExport(s, node)) continue;
242
- const stmt = node;
243
- const isDefaultExport = node.type === "ExportDefaultDeclaration";
244
- if ((node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration") && node.declaration) node = node.declaration;
245
- if (node.type === "VariableDeclaration" && node.declarations.length !== 1) throw new Error("Only one declaration is supported");
246
- if (node.type === "TSDeclareFunction" || node.type.endsWith("Declaration")) {
247
- const binding = node.type === "VariableDeclaration" ? node.declarations[0].id : node.id;
248
- const code$1 = s.sliceNode(node);
249
- const jsdoc = comments.find((c) => c.type === "Block" && c.value[0] === "*" && stmt.start - c.end <= 1);
250
- const offset = node.start;
251
- let bindingRange;
252
- if (binding) bindingRange = getIdentifierRange(binding, -offset);
253
- else if (isDefaultExport) {
254
- const idx = s.sliceNode(node).indexOf("function") + 8;
255
- bindingRange = [idx, idx];
256
- } else continue;
257
- const deps = collectDependencies(s, node);
258
- const depsString = stringifyDependencies(s, deps);
259
- const depsRanges = deps.map((dep) => [dep.start - offset, dep.end - offset]);
260
- const needDeclare = (node.type === "TSEnumDeclaration" || node.type === "ClassDeclaration" || node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction" || node.type === "TSModuleDeclaration" || node.type === "VariableDeclaration") && !node.declare;
261
- const symbolId = register({
262
- code: code$1,
263
- binding: bindingRange,
264
- deps: depsRanges,
265
- needDeclare,
266
- jsdoc: jsdoc ? s.sliceNode(jsdoc) : void 0
267
- });
268
- const runtime = `[${symbolId}, ${depsString}]`;
269
- const bindingName = binding ? s.sliceNode(binding) : "export_default";
270
- if (isDefaultExport) s.overwriteNode(stmt, `var ${bindingName} = ${runtime};export { ${bindingName} as default }`);
271
- else s.overwriteNode(node, `var ${bindingName} = [${symbolId}, ${depsString}]`);
247
+ transform: {
248
+ filter: { id: {
249
+ include: [RE_DTS],
250
+ exclude: [RE_NODE_MODULES]
251
+ } },
252
+ async handler(code, id) {
253
+ const { program, comments } = await parseAsync(id, code);
254
+ const preserved = collectReferenceDirectives(comments);
255
+ preserveMap.set(id, preserved);
256
+ const s = new MagicStringAST(code);
257
+ for (let node of program.body) {
258
+ if (node.type === "ExportAllDeclaration" && node.exported && isRelative(node.source.value)) throw new Error("`export * as foo from './...'` is not supported");
259
+ if (rewriteImportExport(s, node)) continue;
260
+ const sideEffect = node.type === "TSModuleDeclaration" && node.kind !== "namespace";
261
+ const stmt = node;
262
+ const isDefaultExport = node.type === "ExportDefaultDeclaration";
263
+ if ((node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration") && node.declaration) node = node.declaration;
264
+ if (node.type === "VariableDeclaration" && node.declarations.length !== 1) throw new Error("Only one declaration is supported");
265
+ if (node.type === "TSDeclareFunction" || node.type.endsWith("Declaration")) {
266
+ const binding = node.type === "VariableDeclaration" ? node.declarations[0].id : node.id;
267
+ const code$1 = s.sliceNode(node);
268
+ const jsdoc = comments.find((c) => c.type === "Block" && c.value[0] === "*" && c.start < node.start && stmt.start - c.end <= 1);
269
+ const offset = node.start;
270
+ let bindingRange;
271
+ if (sideEffect) bindingRange = [0, 0];
272
+ else if (binding) bindingRange = getIdentifierRange(binding, -offset);
273
+ else if (isDefaultExport) {
274
+ const idx = s.sliceNode(node).indexOf("function") + 8;
275
+ bindingRange = [idx, idx];
276
+ } else continue;
277
+ const depsNodes = collectDependencies(s, node, getIdentifierIndex);
278
+ const depsString = stringifyDependencies(s, depsNodes);
279
+ const depsSymbols = depsNodes.map((dep) => [
280
+ dep.start - offset,
281
+ dep.end - offset,
282
+ dep._suffix
283
+ ]);
284
+ const needDeclare = (node.type === "TSEnumDeclaration" || node.type === "ClassDeclaration" || node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction" || node.type === "TSModuleDeclaration" || node.type === "VariableDeclaration") && !node.declare;
285
+ const symbolId = register({
286
+ code: code$1,
287
+ binding: bindingRange,
288
+ deps: depsSymbols,
289
+ needDeclare,
290
+ jsdoc: jsdoc ? s.sliceNode(jsdoc) : void 0,
291
+ preserveName: sideEffect
292
+ });
293
+ const runtime = `[${symbolId}, ${depsString}${depsString && sideEffect ? ", " : ""}${sideEffect ? "sideEffect()" : ""}]`;
294
+ const bindingName = sideEffect ? `_${identifierIdx++}` : binding ? s.sliceNode(binding) : "export_default";
295
+ if (isDefaultExport) s.overwriteNode(stmt, `var ${bindingName} = ${runtime};export { ${bindingName} as default }`);
296
+ else s.overwriteNode(node, `var ${bindingName} = ${runtime};`);
297
+ }
272
298
  }
299
+ if (!s.hasChanged()) return;
300
+ const str = s.toString();
301
+ return str;
273
302
  }
274
- if (!s.hasChanged()) return;
275
- const str = s.toString();
276
- return str;
277
303
  },
278
304
  async renderChunk(code, chunk) {
305
+ if (!RE_DTS.test(chunk.fileName)) return;
279
306
  const { program } = await parseAsync(chunk.fileName, code);
280
307
  const s = new MagicStringAST(code);
281
308
  const comments = new Set();
282
309
  for (const id of chunk.moduleIds) {
283
- const preserveComments = commentMap.get(id);
310
+ const preserveComments = preserveMap.get(id);
284
311
  if (preserveComments) {
285
312
  preserveComments.forEach((c) => comments.add(c));
286
- commentMap.delete(id);
313
+ preserveMap.delete(id);
287
314
  }
288
315
  }
289
316
  if (comments.size) s.prepend(`${[...comments].join("\n")}\n`);
@@ -301,14 +328,14 @@ function dts() {
301
328
  continue;
302
329
  }
303
330
  const symbolId = symbolIdNode.value;
304
- const { code: code$1, binding, deps, needDeclare, jsdoc } = retrieve(symbolId);
305
- const depsRaw = depsNodes.map((dep) => {
306
- if (dep.type !== "ArrowFunctionExpression") throw new Error("Expected ArrowFunctionExpression");
307
- return s.sliceNode(dep.body);
308
- });
331
+ const { code: code$1, binding, deps, needDeclare, jsdoc, preserveName } = retrieve(symbolId);
332
+ const depsRaw = depsNodes.filter((node$1) => node$1?.type === "ArrowFunctionExpression").map((dep) => s.sliceNode(dep.body));
309
333
  const ss = new MagicStringAST(code$1);
310
- overwriteOrAppend(ss, binding, s.sliceNode(decl.id));
311
- for (const dep of deps) overwriteOrAppend(ss, dep, depsRaw.shift());
334
+ if (!preserveName) overwriteOrAppend(ss, binding, s.sliceNode(decl.id));
335
+ for (const dep of deps) {
336
+ const [start, end, suffix] = dep;
337
+ overwriteOrAppend(ss, [start, end], depsRaw.shift(), suffix);
338
+ }
312
339
  if (needDeclare) ss.prepend("declare ");
313
340
  if (jsdoc) ss.prepend(`${jsdoc}\n`);
314
341
  s.overwriteNode(node, ss.toString());
@@ -323,10 +350,19 @@ const REFERENCE_RE = /\/\s*<reference\s+(?:path|types)=/;
323
350
  function collectReferenceDirectives(comment) {
324
351
  return comment.filter((c) => REFERENCE_RE.test(c.value)).map((c) => `//${c.value}`);
325
352
  }
326
- function collectDependencies(s, node) {
353
+ function collectDependencies(s, node, getIdentifierIndex) {
327
354
  const deps = new Set();
328
355
  walk(node, { leave(node$1) {
329
- if (node$1.type === "TSInterfaceDeclaration" && node$1.extends) for (const heritage of node$1.extends || []) addDependency(heritage.expression);
356
+ if (node$1.type === "ExportNamedDeclaration") {
357
+ for (const specifier of node$1.specifiers) if (specifier.type === "ExportSpecifier") {
358
+ let _suffix;
359
+ if (specifier.local.start === specifier.exported.start && specifier.local.end === specifier.exported.end) _suffix = ` as ${s.sliceNode(specifier.local)}`;
360
+ addDependency({
361
+ ...specifier.local,
362
+ _suffix
363
+ });
364
+ }
365
+ } else if (node$1.type === "TSInterfaceDeclaration" && node$1.extends) for (const heritage of node$1.extends || []) addDependency(heritage.expression);
330
366
  else if (node$1.type === "ClassDeclaration") {
331
367
  if (node$1.superClass) addDependency(node$1.superClass);
332
368
  if (node$1.implements) for (const implement of node$1.implements) addDependency(implement.expression);
@@ -340,7 +376,7 @@ function collectDependencies(s, node) {
340
376
  if (!node$1.qualifier) throw new Error("Import namespace is not supported");
341
377
  const source = node$1.argument.literal.value;
342
378
  const imported = s.sliceNode(node$1.qualifier);
343
- const local = importNamespace(s, source, imported);
379
+ const local = importNamespace(s, source, imported, getIdentifierIndex);
344
380
  addDependency({
345
381
  type: "Identifier",
346
382
  name: local,
@@ -365,10 +401,9 @@ function patchVariableDeclarator(s, node, decl) {
365
401
  if (decl.init && !decl.id.typeAnnotation) s.overwriteNode(node, `type ${s.sliceNode(decl.id)} = ${s.sliceNode(decl.init)}`);
366
402
  else if (!node.declare) s.prependLeft(node.start, "declare ");
367
403
  }
368
- const RE_D_TS = /\.d\.([cm]?)ts$/;
369
404
  function patchImportSource(s, node) {
370
- if ((node.type === "ImportDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportNamedDeclaration") && node.source?.value && RE_D_TS.test(node.source.value)) {
371
- s.overwriteNode(node.source, JSON.stringify(node.source.value.replace(RE_D_TS, ".$1js")));
405
+ if ((node.type === "ImportDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportNamedDeclaration") && node.source?.value && RE_DTS.test(node.source.value)) {
406
+ s.overwriteNode(node.source, JSON.stringify(filename_dts_to(node.source.value, "js")));
372
407
  return true;
373
408
  }
374
409
  }
@@ -393,12 +428,89 @@ function rewriteImportExport(s, node) {
393
428
  return true;
394
429
  }
395
430
  }
396
- let i = 0;
397
- function importNamespace(s, source, imported) {
398
- const local = `_${i++}`;
431
+ function importNamespace(s, source, imported, getIdentifierIndex) {
432
+ const local = `_${getIdentifierIndex()}`;
399
433
  s.prepend(`import { ${imported} as ${local} } from ${JSON.stringify(source)};\n`);
400
434
  return local;
401
435
  }
402
436
 
403
437
  //#endregion
404
- export { dts };
438
+ //#region src/generate.ts
439
+ function createGeneratePlugin({ isolatedDeclaration: isolatedDeclaration$1, inputAlias, external }) {
440
+ const dtsMap = new Map();
441
+ return {
442
+ name: "rolldown-plugin-dts:generate",
443
+ transform: {
444
+ order: "pre",
445
+ filter: { id: {
446
+ include: [RE_TS],
447
+ exclude: [RE_DTS, RE_NODE_MODULES]
448
+ } },
449
+ handler(code, id) {
450
+ const { code: dtsCode, errors } = isolatedDeclaration(id, code, isolatedDeclaration$1);
451
+ if (errors.length) return this.error(errors[0]);
452
+ const dtsId = filename_ts_to_dts(id);
453
+ dtsMap.set(dtsId, dtsCode);
454
+ const mod = this.getModuleInfo(id);
455
+ if (mod?.isEntry) {
456
+ let fileName = basename(dtsId);
457
+ if (inputAlias?.[fileName]) fileName = inputAlias[fileName];
458
+ this.emitFile({
459
+ type: "chunk",
460
+ id: dtsId,
461
+ fileName
462
+ });
463
+ }
464
+ }
465
+ },
466
+ async resolveId(id, importer, extraOptions) {
467
+ if (dtsMap.has(id)) return {
468
+ id,
469
+ meta: { dtsFile: true }
470
+ };
471
+ const importerMod = importer ? this.getModuleInfo(importer) : null;
472
+ if (importerMod?.meta.dtsFile) {
473
+ if (!isRelative(id) || external?.(id, importer, extraOptions) === true) return {
474
+ id,
475
+ external: true
476
+ };
477
+ const resolution = await this.resolve(id, filename_dts_to(importer, "ts"));
478
+ if (!resolution || resolution.external) return;
479
+ const dtsId = filename_ts_to_dts(resolution.id);
480
+ if (dtsMap.has(dtsId)) return {
481
+ id: dtsId,
482
+ meta: { dtsFile: true }
483
+ };
484
+ await this.load(resolution);
485
+ if (dtsMap.has(dtsId)) return {
486
+ id: dtsId,
487
+ meta: { dtsFile: true }
488
+ };
489
+ }
490
+ },
491
+ load: {
492
+ filter: { id: {
493
+ include: [RE_DTS],
494
+ exclude: [RE_NODE_MODULES]
495
+ } },
496
+ handler(id) {
497
+ if (dtsMap.has(id)) return {
498
+ code: dtsMap.get(id),
499
+ moduleSideEffects: false
500
+ };
501
+ }
502
+ }
503
+ };
504
+ }
505
+
506
+ //#endregion
507
+ //#region src/index.ts
508
+ function dts(options = {}) {
509
+ const plugins = [];
510
+ if (!options.dtsInput) plugins.push(createGeneratePlugin(options));
511
+ plugins.push(createFakeJsPlugin(options));
512
+ return plugins;
513
+ }
514
+
515
+ //#endregion
516
+ export { createFakeJsPlugin, createGeneratePlugin, dts };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rolldown-plugin-dts",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A Rolldown plugin to bundle dts files",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -29,24 +29,25 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "magic-string-ast": "^0.9.1",
32
- "oxc-parser": "^0.62.0"
32
+ "oxc-parser": "^0.62.0",
33
+ "oxc-transform": "^0.62.0"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@sxzz/eslint-config": "^6.1.1",
36
37
  "@sxzz/prettier-config": "^2.2.1",
37
38
  "@sxzz/test-utils": "^0.5.4",
38
39
  "@types/diff": "^7.0.2",
39
- "@types/node": "^22.13.17",
40
+ "@types/node": "^22.14.0",
40
41
  "bumpp": "^10.1.0",
41
42
  "diff": "^7.0.0",
42
- "eslint": "^9.23.0",
43
+ "eslint": "^9.24.0",
43
44
  "estree-walker": "^3.0.3",
44
45
  "prettier": "^3.5.3",
45
46
  "rolldown": "1.0.0-beta.7",
46
47
  "rollup-plugin-dts": "^6.2.1",
47
- "tsdown": "^0.7.3",
48
+ "tsdown": "^0.8.0-beta.1",
48
49
  "tsx": "^4.19.3",
49
- "typescript": "^5.8.2",
50
+ "typescript": "^5.8.3",
50
51
  "vitest": "^3.1.1"
51
52
  },
52
53
  "engines": {