rolldown-plugin-dts 0.0.0 → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2025 三咲智子 Kevin Deng (https://github.com/sxzz)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # rolldown-plugin-dts [![npm](https://img.shields.io/npm/v/rolldown-plugin-dts.svg)](https://npmjs.com/package/rolldown-plugin-dts)
2
+
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
+
5
+ A Rolldown plugin to bundle dts files.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm i rolldown-plugin-dts
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Add the plugin to your `rolldown.config.js`:
16
+
17
+ ```js
18
+ // rolldown.config.js
19
+ import { dts } from 'rolldown-plugin-dts'
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
35
+ ```
36
+
37
+ > [!NOTE]
38
+ > Namespaces are not supported yet.
39
+
40
+ ## Credits
41
+
42
+ The project is inspired by [rollup-plugin-dts](https://github.com/Swatinem/rollup-plugin-dts)
43
+ but has been independently implemented.
44
+ We extend our gratitude to the original creators for their contributions.
45
+ Furthermore, the test suite is authorized by them and distributed under the MIT license.
46
+
47
+ ## Sponsors
48
+
49
+ <p align="center">
50
+ <a href="https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg">
51
+ <img src='https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg'/>
52
+ </a>
53
+ </p>
54
+
55
+ ## License
56
+
57
+ [MIT](./LICENSE) License © 2025 [三咲智子 Kevin Deng](https://github.com/sxzz)
@@ -0,0 +1,7 @@
1
+ import { Plugin } from "rolldown";
2
+
3
+ //#region dist/.tsdown-types-es/index.d.ts
4
+ declare function dts(): Plugin;
5
+
6
+ //#endregion
7
+ export { dts };
package/dist/index.js ADDED
@@ -0,0 +1,404 @@
1
+ import path from "node:path";
2
+ import { MagicStringAST } from "magic-string-ast";
3
+ import { parseAsync } from "oxc-parser";
4
+
5
+ //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js
6
+ var WalkerBase = class {
7
+ constructor() {
8
+ /** @type {boolean} */
9
+ this.should_skip = false;
10
+ /** @type {boolean} */
11
+ this.should_remove = false;
12
+ /** @type {Node | null} */
13
+ this.replacement = null;
14
+ /** @type {WalkerContext} */
15
+ this.context = {
16
+ skip: () => this.should_skip = true,
17
+ remove: () => this.should_remove = true,
18
+ replace: (node) => this.replacement = node
19
+ };
20
+ }
21
+ /**
22
+ * @template {Node} Parent
23
+ * @param {Parent | null | undefined} parent
24
+ * @param {keyof Parent | null | undefined} prop
25
+ * @param {number | null | undefined} index
26
+ * @param {Node} node
27
+ */
28
+ replace(parent, prop, index, node) {
29
+ if (parent && prop) if (index != null)
30
+ /** @type {Array<Node>} */ parent[prop][index] = node;
31
+ else
32
+ /** @type {Node} */ parent[prop] = node;
33
+ }
34
+ /**
35
+ * @template {Node} Parent
36
+ * @param {Parent | null | undefined} parent
37
+ * @param {keyof Parent | null | undefined} prop
38
+ * @param {number | null | undefined} index
39
+ */
40
+ remove(parent, prop, index) {
41
+ if (parent && prop) if (index !== null && index !== void 0)
42
+ /** @type {Array<Node>} */ parent[prop].splice(index, 1);
43
+ else delete parent[prop];
44
+ }
45
+ };
46
+
47
+ //#endregion
48
+ //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/sync.js
49
+ var SyncWalker = class extends WalkerBase {
50
+ /**
51
+ *
52
+ * @param {SyncHandler} [enter]
53
+ * @param {SyncHandler} [leave]
54
+ */
55
+ constructor(enter, leave) {
56
+ super();
57
+ /** @type {boolean} */
58
+ this.should_skip = false;
59
+ /** @type {boolean} */
60
+ this.should_remove = false;
61
+ /** @type {Node | null} */
62
+ this.replacement = null;
63
+ /** @type {WalkerContext} */
64
+ this.context = {
65
+ skip: () => this.should_skip = true,
66
+ remove: () => this.should_remove = true,
67
+ replace: (node) => this.replacement = node
68
+ };
69
+ /** @type {SyncHandler | undefined} */
70
+ this.enter = enter;
71
+ /** @type {SyncHandler | undefined} */
72
+ this.leave = leave;
73
+ }
74
+ /**
75
+ * @template {Node} Parent
76
+ * @param {Node} node
77
+ * @param {Parent | null} parent
78
+ * @param {keyof Parent} [prop]
79
+ * @param {number | null} [index]
80
+ * @returns {Node | null}
81
+ */
82
+ visit(node, parent, prop, index) {
83
+ if (node) {
84
+ if (this.enter) {
85
+ const _should_skip = this.should_skip;
86
+ const _should_remove = this.should_remove;
87
+ const _replacement = this.replacement;
88
+ this.should_skip = false;
89
+ this.should_remove = false;
90
+ this.replacement = null;
91
+ this.enter.call(this.context, node, parent, prop, index);
92
+ if (this.replacement) {
93
+ node = this.replacement;
94
+ this.replace(parent, prop, index, node);
95
+ }
96
+ if (this.should_remove) this.remove(parent, prop, index);
97
+ const skipped = this.should_skip;
98
+ const removed = this.should_remove;
99
+ this.should_skip = _should_skip;
100
+ this.should_remove = _should_remove;
101
+ this.replacement = _replacement;
102
+ if (skipped) return node;
103
+ if (removed) return null;
104
+ }
105
+ /** @type {keyof Node} */
106
+ let key;
107
+ for (key in node) {
108
+ /** @type {unknown} */
109
+ const value = node[key];
110
+ if (value && typeof value === "object") {
111
+ if (Array.isArray(value)) {
112
+ const nodes = value;
113
+ for (let i$1 = 0; i$1 < nodes.length; i$1 += 1) {
114
+ const item = nodes[i$1];
115
+ if (isNode(item)) {
116
+ if (!this.visit(item, node, key, i$1)) i$1--;
117
+ }
118
+ }
119
+ } else if (isNode(value)) this.visit(value, node, key, null);
120
+ }
121
+ }
122
+ if (this.leave) {
123
+ const _replacement = this.replacement;
124
+ const _should_remove = this.should_remove;
125
+ this.replacement = null;
126
+ this.should_remove = false;
127
+ this.leave.call(this.context, node, parent, prop, index);
128
+ if (this.replacement) {
129
+ node = this.replacement;
130
+ this.replace(parent, prop, index, node);
131
+ }
132
+ if (this.should_remove) this.remove(parent, prop, index);
133
+ const removed = this.should_remove;
134
+ this.replacement = _replacement;
135
+ this.should_remove = _should_remove;
136
+ if (removed) return null;
137
+ }
138
+ }
139
+ return node;
140
+ }
141
+ };
142
+ /**
143
+ * Ducktype a node.
144
+ *
145
+ * @param {unknown} value
146
+ * @returns {value is Node}
147
+ */
148
+ function isNode(value) {
149
+ return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string";
150
+ }
151
+
152
+ //#endregion
153
+ //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/index.js
154
+ function walk(ast, { enter, leave }) {
155
+ const instance = new SyncWalker(enter, leave);
156
+ return instance.visit(ast, null);
157
+ }
158
+
159
+ //#endregion
160
+ //#region src/utils/ast.ts
161
+ function getIdentifierRange(node, offset = 0) {
162
+ if ("typeAnnotation" in node && node.typeAnnotation) return [node.start + offset, node.typeAnnotation.start + offset];
163
+ return [node.start + offset, node.end + offset];
164
+ }
165
+
166
+ //#endregion
167
+ //#region src/utils/magic-string.ts
168
+ function overwriteOrAppend(s, range, replacement) {
169
+ if (range[0] === range[1]) {
170
+ s.appendLeft(range[0], ` ${replacement}`);
171
+ return;
172
+ }
173
+ s.overwrite(range[0], range[1], replacement);
174
+ }
175
+
176
+ //#endregion
177
+ //#region src/index.ts
178
+ const RE_TYPE = /\btype\b/;
179
+ function dts() {
180
+ let i$1 = 0;
181
+ const symbolMap = new Map();
182
+ const commentMap = new Map();
183
+ function register(info) {
184
+ const symbolId = i$1++;
185
+ symbolMap.set(symbolId, info);
186
+ return symbolId;
187
+ }
188
+ function retrieve(symbolId) {
189
+ return symbolMap.get(symbolId);
190
+ }
191
+ return {
192
+ name: "rolldown-plugin-dts",
193
+ options({ onLog,...options }) {
194
+ return {
195
+ ...options,
196
+ resolve: {
197
+ extensions: [
198
+ ".d.ts",
199
+ ".d.mts",
200
+ ".d.cts"
201
+ ],
202
+ extensionAlias: {
203
+ ".js": [".d.ts"],
204
+ ".mjs": [".d.mts"],
205
+ ".cjs": [".d.cts"]
206
+ },
207
+ ...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
+ }
218
+ };
219
+ },
220
+ outputOptions(options) {
221
+ 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
233
+ };
234
+ },
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}]`);
272
+ }
273
+ }
274
+ if (!s.hasChanged()) return;
275
+ const str = s.toString();
276
+ return str;
277
+ },
278
+ async renderChunk(code, chunk) {
279
+ const { program } = await parseAsync(chunk.fileName, code);
280
+ const s = new MagicStringAST(code);
281
+ const comments = new Set();
282
+ for (const id of chunk.moduleIds) {
283
+ const preserveComments = commentMap.get(id);
284
+ if (preserveComments) {
285
+ preserveComments.forEach((c) => comments.add(c));
286
+ commentMap.delete(id);
287
+ }
288
+ }
289
+ if (comments.size) s.prepend(`${[...comments].join("\n")}\n`);
290
+ for (const node of program.body) {
291
+ if (patchImportSource(s, node)) continue;
292
+ if (node.type !== "VariableDeclaration" || node.declarations.length !== 1) continue;
293
+ const [decl] = node.declarations;
294
+ if (decl.init?.type !== "ArrayExpression" || !decl.init.elements[0]) {
295
+ patchVariableDeclarator(s, node, decl);
296
+ continue;
297
+ }
298
+ const [symbolIdNode, ...depsNodes] = decl.init.elements;
299
+ if (symbolIdNode?.type !== "Literal" || typeof symbolIdNode.value !== "number") {
300
+ patchVariableDeclarator(s, node, decl);
301
+ continue;
302
+ }
303
+ 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
+ });
309
+ 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());
312
+ if (needDeclare) ss.prepend("declare ");
313
+ if (jsdoc) ss.prepend(`${jsdoc}\n`);
314
+ s.overwriteNode(node, ss.toString());
315
+ }
316
+ const str = s.toString();
317
+ if (str.trim().length === 0) return "export {}";
318
+ return str;
319
+ }
320
+ };
321
+ }
322
+ const REFERENCE_RE = /\/\s*<reference\s+(?:path|types)=/;
323
+ function collectReferenceDirectives(comment) {
324
+ return comment.filter((c) => REFERENCE_RE.test(c.value)).map((c) => `//${c.value}`);
325
+ }
326
+ function collectDependencies(s, node) {
327
+ const deps = new Set();
328
+ walk(node, { leave(node$1) {
329
+ if (node$1.type === "TSInterfaceDeclaration" && node$1.extends) for (const heritage of node$1.extends || []) addDependency(heritage.expression);
330
+ else if (node$1.type === "ClassDeclaration") {
331
+ if (node$1.superClass) addDependency(node$1.superClass);
332
+ if (node$1.implements) for (const implement of node$1.implements) addDependency(implement.expression);
333
+ } else if (node$1.type === "MethodDefinition" || node$1.type === "PropertyDefinition" || node$1.type === "TSPropertySignature") {
334
+ if (node$1.computed && isReferenceId(node$1.key)) addDependency(node$1.key);
335
+ if ("value" in node$1 && isReferenceId(node$1.value)) addDependency(node$1.value);
336
+ } else if (node$1.type === "TSTypeReference") addDependency(node$1.typeName);
337
+ else if (node$1.type === "TSTypeQuery") addDependency(node$1.exprName);
338
+ else if (node$1.type === "TSImportType") {
339
+ if (node$1.argument.type !== "TSLiteralType" || node$1.argument.literal.type !== "Literal" || typeof node$1.argument.literal.value !== "string") return;
340
+ if (!node$1.qualifier) throw new Error("Import namespace is not supported");
341
+ const source = node$1.argument.literal.value;
342
+ const imported = s.sliceNode(node$1.qualifier);
343
+ const local = importNamespace(s, source, imported);
344
+ addDependency({
345
+ type: "Identifier",
346
+ name: local,
347
+ start: node$1.start + (node$1.isTypeOf ? 7 : 0),
348
+ end: node$1.qualifier.end
349
+ });
350
+ }
351
+ } });
352
+ return Array.from(deps);
353
+ function addDependency(node$1) {
354
+ if (node$1.type === "Identifier" && node$1.name === "this") return;
355
+ deps.add(node$1);
356
+ }
357
+ }
358
+ function isReferenceId(node) {
359
+ return !!node && (node.type === "Identifier" || node.type === "MemberExpression");
360
+ }
361
+ function stringifyDependencies(s, deps) {
362
+ return deps.map((node) => `() => ${node.type === "Identifier" ? node.name : s.sliceNode(node)}`).join(", ");
363
+ }
364
+ function patchVariableDeclarator(s, node, decl) {
365
+ if (decl.init && !decl.id.typeAnnotation) s.overwriteNode(node, `type ${s.sliceNode(decl.id)} = ${s.sliceNode(decl.init)}`);
366
+ else if (!node.declare) s.prependLeft(node.start, "declare ");
367
+ }
368
+ const RE_D_TS = /\.d\.([cm]?)ts$/;
369
+ 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")));
372
+ return true;
373
+ }
374
+ }
375
+ function rewriteImportExport(s, node) {
376
+ if (node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" && !node.declaration) {
377
+ for (const specifier of node.specifiers) if (specifier.type === "ImportSpecifier" && specifier.importKind === "type" || specifier.type === "ExportSpecifier" && specifier.exportKind === "type") s.overwriteNode(specifier, s.sliceNode(specifier).replace(RE_TYPE, ""));
378
+ const firstSpecifier = node.specifiers[0];
379
+ const kind = node.type === "ImportDeclaration" ? node.importKind : node.exportKind;
380
+ if (kind === "type" && firstSpecifier) s.overwrite(node.start, firstSpecifier.start, s.slice(node.start, firstSpecifier.start).replace(RE_TYPE, ""));
381
+ return true;
382
+ } else if (node.type === "ExportAllDeclaration") {
383
+ if (node.exportKind === "type") s.overwrite(node.start, node.source.start, s.slice(node.start, node.source.start).replace(RE_TYPE, ""));
384
+ return true;
385
+ } else if (node.type === "TSImportEqualsDeclaration") {
386
+ if (node.moduleReference.type === "TSExternalModuleReference") s.overwriteNode(node, `import ${s.sliceNode(node.id)} from ${s.sliceNode(node.moduleReference.expression)}`);
387
+ return true;
388
+ } else if (node.type === "TSExportAssignment") {
389
+ s.overwriteNode(node, `export default ${s.sliceNode(node.expression)}`);
390
+ return true;
391
+ } else if (node.type === "ExportDefaultDeclaration" && node.declaration.type === "Identifier") {
392
+ s.overwriteNode(node, `export { ${s.sliceNode(node.declaration)} as default }`);
393
+ return true;
394
+ }
395
+ }
396
+ let i = 0;
397
+ function importNamespace(s, source, imported) {
398
+ const local = `_${i++}`;
399
+ s.prepend(`import { ${imported} as ${local} } from ${JSON.stringify(source)};\n`);
400
+ return local;
401
+ }
402
+
403
+ //#endregion
404
+ export { dts };
package/package.json CHANGED
@@ -1,12 +1,66 @@
1
1
  {
2
2
  "name": "rolldown-plugin-dts",
3
- "version": "0.0.0",
4
- "description": "",
5
- "main": "index.js",
6
- "keywords": [],
7
- "author": "",
8
- "license": "ISC",
3
+ "version": "0.1.0",
4
+ "description": "A Rolldown plugin to bundle dts files",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/sxzz/rolldown-plugin-dts#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/sxzz/rolldown-plugin-dts/issues"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/sxzz/rolldown-plugin-dts.git"
14
+ },
15
+ "author": "三咲智子 Kevin Deng <sxzz@sxzz.moe>",
16
+ "funding": "https://github.com/sponsors/sxzz",
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "main": "./dist/index.js",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": "./dist/index.js",
25
+ "./package.json": "./package.json"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "dependencies": {
31
+ "magic-string-ast": "^0.9.1",
32
+ "oxc-parser": "^0.62.0"
33
+ },
34
+ "devDependencies": {
35
+ "@sxzz/eslint-config": "^6.1.1",
36
+ "@sxzz/prettier-config": "^2.2.1",
37
+ "@sxzz/test-utils": "^0.5.4",
38
+ "@types/diff": "^7.0.2",
39
+ "@types/node": "^22.13.17",
40
+ "bumpp": "^10.1.0",
41
+ "diff": "^7.0.0",
42
+ "eslint": "^9.23.0",
43
+ "estree-walker": "^3.0.3",
44
+ "prettier": "^3.5.3",
45
+ "rolldown": "1.0.0-beta.7",
46
+ "rollup-plugin-dts": "^6.2.1",
47
+ "tsdown": "^0.7.3",
48
+ "tsx": "^4.19.3",
49
+ "typescript": "^5.8.2",
50
+ "vitest": "^3.1.1"
51
+ },
52
+ "engines": {
53
+ "node": ">=20.18.0"
54
+ },
55
+ "prettier": "@sxzz/prettier-config",
9
56
  "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1"
57
+ "lint": "eslint --cache .",
58
+ "lint:fix": "pnpm run lint --fix",
59
+ "build": "tsdown",
60
+ "dev": "tsdown --watch",
61
+ "test": "vitest",
62
+ "typecheck": "tsc --noEmit",
63
+ "format": "prettier --cache --write .",
64
+ "release": "bumpp && pnpm publish"
11
65
  }
12
66
  }
@@ -1,5 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "rolldown"
4
- ]
5
- }