rolldown-plugin-dts-snapshot 0.3.2 → 0.4.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
@@ -50,7 +50,7 @@ export interface Options {
50
50
  include?: FilterPattern
51
51
  exclude?: FilterPattern
52
52
  /**
53
- * @default false
53
+ * @default true
54
54
  */
55
55
  includeNonExport?: boolean
56
56
  /**
@@ -0,0 +1,86 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { createFromBuffer } from "@dprint/formatter";
3
+ import { getPath } from "@dprint/typescript";
4
+ import { walk } from "estree-walker";
5
+ import MagicString from "magic-string";
6
+ import { parseSync } from "rolldown/utils";
7
+
8
+ //#region src/utils.ts
9
+ function sortObjectKeys(obj) {
10
+ return Object.fromEntries(Object.entries(obj).toSorted(([a], [b]) => a.localeCompare(b)));
11
+ }
12
+
13
+ //#endregion
14
+ //#region src/api.ts
15
+ const multilineCommentsRE = /\/\*.*?\*\//gs;
16
+ const singlelineCommentsRE = /\/\/.*$/gm;
17
+ async function snapshot(code, fileName = "dummy.d.ts", { applyExportRename = true } = {}) {
18
+ code = code.replaceAll(multilineCommentsRE, "").replaceAll(singlelineCommentsRE, "");
19
+ const s = new MagicString(code);
20
+ const slice = (node) => s.slice(node.start, node.end);
21
+ const { program } = parseSync(fileName, code);
22
+ walk(program, { enter(node, parent, key) {
23
+ if (key === "params" && (node.type === "Identifier" || node.type === "ObjectPattern" || node.type === "ArrayPattern")) {
24
+ const end = node.typeAnnotation?.start ?? node.end;
25
+ s.overwrite(node.start, end, "_");
26
+ }
27
+ } });
28
+ const result = Object.create(null);
29
+ if (!tsFormatter) await initFormatter();
30
+ for (const stmt of program.body) {
31
+ let decl;
32
+ if ((stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration") && stmt.declaration) decl = stmt.declaration;
33
+ else decl = stmt;
34
+ const register = (symbol, node) => {
35
+ let code;
36
+ if (node.type === "VariableDeclarator") {
37
+ const typeAnnotation = node.id.typeAnnotation?.typeAnnotation;
38
+ if (typeAnnotation) code = s.slice(typeAnnotation.start, node.end);
39
+ else if (node.init) code = slice(node.init);
40
+ }
41
+ code ||= slice(node);
42
+ result[symbol] = format(code);
43
+ };
44
+ if (decl.type === "VariableDeclaration") for (const node of decl.declarations) register(nodeToString(node.id), node);
45
+ else if ("id" in decl && decl.id) register(nodeToString(decl.id), decl);
46
+ else if (decl.type === "ExportDefaultDeclaration" && "id" in decl.declaration && decl.declaration.id) register("default", decl.declaration);
47
+ }
48
+ if (applyExportRename) {
49
+ for (const stmt of program.body) if (stmt.type === "ExportNamedDeclaration" && stmt.declaration === null && stmt.specifiers.length) for (const specifier of stmt.specifiers) {
50
+ const exported = nodeToString(specifier.exported);
51
+ const local = nodeToString(specifier.local);
52
+ if (local !== exported) result[exported] = result[local];
53
+ }
54
+ }
55
+ return sortObjectKeys(result);
56
+ function nodeToString(node) {
57
+ return node.type === "Identifier" ? node.name : node.type === "Literal" ? node.value : slice(node);
58
+ }
59
+ }
60
+ let tsFormatter;
61
+ async function initFormatter() {
62
+ const globalConfig = {
63
+ indentWidth: 1,
64
+ lineWidth: 1e8
65
+ };
66
+ tsFormatter = createFromBuffer(await readFile(getPath()));
67
+ tsFormatter.setConfig(globalConfig, {
68
+ semiColons: "asi",
69
+ preferSingleLine: true,
70
+ "arrowFunction.useParentheses": "force",
71
+ quoteStyle: "alwaysSingle",
72
+ singleBodyPosition: "sameLine",
73
+ bracePosition: "sameLine",
74
+ operatorPosition: "sameLine",
75
+ preferHanging: true
76
+ });
77
+ }
78
+ function format(code) {
79
+ return tsFormatter.formatText({
80
+ filePath: "dummy.d.ts",
81
+ fileText: code
82
+ }).trim().replaceAll("\n\n", "\n");
83
+ }
84
+
85
+ //#endregion
86
+ export { sortObjectKeys as n, snapshot as t };
package/dist/api.d.mts CHANGED
@@ -3,6 +3,6 @@ declare function snapshot(code: string, fileName?: string, {
3
3
  applyExportRename
4
4
  }?: {
5
5
  applyExportRename?: boolean;
6
- }): Record<string, string>;
6
+ }): Promise<Record<string, string>>;
7
7
  //#endregion
8
8
  export { snapshot };
package/dist/api.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as snapshot } from "./api-DMJmjM2B.mjs";
1
+ import { t as snapshot } from "./api-C9zdW5Yc.mjs";
2
2
 
3
3
  export { snapshot };
package/dist/index.d.mts CHANGED
@@ -9,7 +9,7 @@ interface Options {
9
9
  include?: FilterPattern;
10
10
  exclude?: FilterPattern;
11
11
  /**
12
- * @default false
12
+ * @default true
13
13
  */
14
14
  includeNonExport?: boolean;
15
15
  /**
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as sortObjectKeys, t as snapshot } from "./api-DMJmjM2B.mjs";
1
+ import { n as sortObjectKeys, t as snapshot } from "./api-C9zdW5Yc.mjs";
2
2
  import { writeFile } from "node:fs/promises";
3
3
  import { createFilter } from "unplugin-utils";
4
4
 
@@ -14,7 +14,7 @@ function DtsSnapshot({ include = RE_DTS, exclude, includeNonExport = true, saveT
14
14
  const result = Object.create(null);
15
15
  for (const chunk of Object.values(bundle)) {
16
16
  if (chunk.type === "asset" || !filter(chunk.fileName)) continue;
17
- const map = result[chunk.preliminaryFileName] = snapshot(chunk.code, chunk.fileName, { applyExportRename: chunk.isEntry });
17
+ const map = result[chunk.preliminaryFileName] = await snapshot(chunk.code, chunk.fileName, { applyExportRename: chunk.isEntry });
18
18
  if (chunk.isEntry) {
19
19
  if (!includeNonExport) {
20
20
  for (const key of Object.keys(map)) if (key !== "#exports" && !chunk.exports.includes(key)) delete map[key];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rolldown-plugin-dts-snapshot",
3
3
  "type": "module",
4
- "version": "0.3.2",
4
+ "version": "0.4.0",
5
5
  "description": "DTS snapshot plugin for Rolldown",
6
6
  "author": "Kevin Deng <sxzz@sxzz.moe>",
7
7
  "license": "MIT",
@@ -19,9 +19,6 @@
19
19
  "./api": "./dist/api.mjs",
20
20
  "./package.json": "./package.json"
21
21
  },
22
- "main": "./dist/index.mjs",
23
- "module": "./dist/index.mjs",
24
- "types": "./dist/index.d.mts",
25
22
  "files": [
26
23
  "dist"
27
24
  ],
@@ -32,28 +29,29 @@
32
29
  "node": ">=20.19.0"
33
30
  },
34
31
  "peerDependencies": {
35
- "rolldown": "^1.0.0-beta.56"
32
+ "rolldown": "^1.0.0-rc.2"
36
33
  },
37
34
  "dependencies": {
38
- "@dprint/formatter": "^0.4.1",
39
- "@dprint/typescript": "^0.95.13",
35
+ "@dprint/formatter": "^0.5.1",
36
+ "@dprint/typescript": "^0.95.15",
37
+ "estree-walker": "^3.0.3",
40
38
  "magic-string": "^0.30.21",
41
39
  "unplugin-utils": "^0.3.1"
42
40
  },
43
41
  "devDependencies": {
44
- "@oxc-project/types": "^0.105.0",
45
- "@sxzz/eslint-config": "^7.4.4",
46
- "@sxzz/prettier-config": "^2.2.6",
47
- "@types/node": "^25.0.3",
48
- "@typescript/native-preview": "7.0.0-dev.20251223.1",
49
- "bumpp": "^10.3.2",
50
- "eslint": "^9.39.2",
51
- "estree-walker": "^3.0.3",
52
- "prettier": "^3.7.4",
53
- "rolldown": "^1.0.0-beta.57",
54
- "tsdown": "^0.18.3",
42
+ "@oxc-project/types": "^0.115.0",
43
+ "@sxzz/eslint-config": "^7.8.2",
44
+ "@sxzz/prettier-config": "^2.3.1",
45
+ "@types/node": "^25.3.2",
46
+ "@typescript/native-preview": "7.0.0-dev.20260227.1",
47
+ "bumpp": "^10.4.1",
48
+ "eslint": "^10.0.2",
49
+ "prettier": "^3.8.1",
50
+ "rolldown": "^1.0.0-rc.6",
51
+ "tsdown": "^0.21.0-beta.2",
52
+ "tsdown-preset-sxzz": "^0.4.0",
55
53
  "typescript": "^5.9.3",
56
- "vitest": "^4.0.16"
54
+ "vitest": "^4.0.18"
57
55
  },
58
56
  "prettier": "@sxzz/prettier-config",
59
57
  "scripts": {
@@ -1,267 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import { createFromBuffer } from "@dprint/formatter";
3
- import { getPath } from "@dprint/typescript";
4
- import MagicString from "magic-string";
5
- import { parseSync } from "rolldown/experimental";
6
-
7
- //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js
8
- /**
9
- * @typedef { import('estree').Node} Node
10
- * @typedef {{
11
- * skip: () => void;
12
- * remove: () => void;
13
- * replace: (node: Node) => void;
14
- * }} WalkerContext
15
- */
16
- var WalkerBase = class {
17
- constructor() {
18
- /** @type {boolean} */
19
- this.should_skip = false;
20
- /** @type {boolean} */
21
- this.should_remove = false;
22
- /** @type {Node | null} */
23
- this.replacement = null;
24
- /** @type {WalkerContext} */
25
- this.context = {
26
- skip: () => this.should_skip = true,
27
- remove: () => this.should_remove = true,
28
- replace: (node) => this.replacement = node
29
- };
30
- }
31
- /**
32
- * @template {Node} Parent
33
- * @param {Parent | null | undefined} parent
34
- * @param {keyof Parent | null | undefined} prop
35
- * @param {number | null | undefined} index
36
- * @param {Node} node
37
- */
38
- replace(parent, prop, index, node) {
39
- if (parent && prop) if (index != null)
40
- /** @type {Array<Node>} */ parent[prop][index] = node;
41
- else
42
- /** @type {Node} */ parent[prop] = node;
43
- }
44
- /**
45
- * @template {Node} Parent
46
- * @param {Parent | null | undefined} parent
47
- * @param {keyof Parent | null | undefined} prop
48
- * @param {number | null | undefined} index
49
- */
50
- remove(parent, prop, index) {
51
- if (parent && prop) if (index !== null && index !== void 0)
52
- /** @type {Array<Node>} */ parent[prop].splice(index, 1);
53
- else delete parent[prop];
54
- }
55
- };
56
-
57
- //#endregion
58
- //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/sync.js
59
- /**
60
- * @typedef { import('estree').Node} Node
61
- * @typedef { import('./walker.js').WalkerContext} WalkerContext
62
- * @typedef {(
63
- * this: WalkerContext,
64
- * node: Node,
65
- * parent: Node | null,
66
- * key: string | number | symbol | null | undefined,
67
- * index: number | null | undefined
68
- * ) => void} SyncHandler
69
- */
70
- var SyncWalker = class extends WalkerBase {
71
- /**
72
- *
73
- * @param {SyncHandler} [enter]
74
- * @param {SyncHandler} [leave]
75
- */
76
- constructor(enter, leave) {
77
- super();
78
- /** @type {boolean} */
79
- this.should_skip = false;
80
- /** @type {boolean} */
81
- this.should_remove = false;
82
- /** @type {Node | null} */
83
- this.replacement = null;
84
- /** @type {WalkerContext} */
85
- this.context = {
86
- skip: () => this.should_skip = true,
87
- remove: () => this.should_remove = true,
88
- replace: (node) => this.replacement = node
89
- };
90
- /** @type {SyncHandler | undefined} */
91
- this.enter = enter;
92
- /** @type {SyncHandler | undefined} */
93
- this.leave = leave;
94
- }
95
- /**
96
- * @template {Node} Parent
97
- * @param {Node} node
98
- * @param {Parent | null} parent
99
- * @param {keyof Parent} [prop]
100
- * @param {number | null} [index]
101
- * @returns {Node | null}
102
- */
103
- visit(node, parent, prop, index) {
104
- if (node) {
105
- if (this.enter) {
106
- const _should_skip = this.should_skip;
107
- const _should_remove = this.should_remove;
108
- const _replacement = this.replacement;
109
- this.should_skip = false;
110
- this.should_remove = false;
111
- this.replacement = null;
112
- this.enter.call(this.context, node, parent, prop, index);
113
- if (this.replacement) {
114
- node = this.replacement;
115
- this.replace(parent, prop, index, node);
116
- }
117
- if (this.should_remove) this.remove(parent, prop, index);
118
- const skipped = this.should_skip;
119
- const removed = this.should_remove;
120
- this.should_skip = _should_skip;
121
- this.should_remove = _should_remove;
122
- this.replacement = _replacement;
123
- if (skipped) return node;
124
- if (removed) return null;
125
- }
126
- /** @type {keyof Node} */
127
- let key;
128
- for (key in node) {
129
- /** @type {unknown} */
130
- const value = node[key];
131
- if (value && typeof value === "object") {
132
- if (Array.isArray(value)) {
133
- const nodes = value;
134
- for (let i = 0; i < nodes.length; i += 1) {
135
- const item = nodes[i];
136
- if (isNode(item)) {
137
- if (!this.visit(item, node, key, i)) i--;
138
- }
139
- }
140
- } else if (isNode(value)) this.visit(value, node, key, null);
141
- }
142
- }
143
- if (this.leave) {
144
- const _replacement = this.replacement;
145
- const _should_remove = this.should_remove;
146
- this.replacement = null;
147
- this.should_remove = false;
148
- this.leave.call(this.context, node, parent, prop, index);
149
- if (this.replacement) {
150
- node = this.replacement;
151
- this.replace(parent, prop, index, node);
152
- }
153
- if (this.should_remove) this.remove(parent, prop, index);
154
- const removed = this.should_remove;
155
- this.replacement = _replacement;
156
- this.should_remove = _should_remove;
157
- if (removed) return null;
158
- }
159
- }
160
- return node;
161
- }
162
- };
163
- /**
164
- * Ducktype a node.
165
- *
166
- * @param {unknown} value
167
- * @returns {value is Node}
168
- */
169
- function isNode(value) {
170
- return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string";
171
- }
172
-
173
- //#endregion
174
- //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/index.js
175
- /**
176
- * @typedef {import('estree').Node} Node
177
- * @typedef {import('./sync.js').SyncHandler} SyncHandler
178
- * @typedef {import('./async.js').AsyncHandler} AsyncHandler
179
- */
180
- /**
181
- * @param {Node} ast
182
- * @param {{
183
- * enter?: SyncHandler
184
- * leave?: SyncHandler
185
- * }} walker
186
- * @returns {Node | null}
187
- */
188
- function walk(ast, { enter, leave }) {
189
- return new SyncWalker(enter, leave).visit(ast, null);
190
- }
191
-
192
- //#endregion
193
- //#region src/utils.ts
194
- function sortObjectKeys(obj) {
195
- return Object.fromEntries(Object.entries(obj).toSorted(([a], [b]) => a.localeCompare(b)));
196
- }
197
-
198
- //#endregion
199
- //#region src/api.ts
200
- const multilineCommentsRE = /\/\*.*?\*\//gs;
201
- const singlelineCommentsRE = /\/\/.*$/gm;
202
- function snapshot(code, fileName = "dummy.d.ts", { applyExportRename = true } = {}) {
203
- code = code.replaceAll(multilineCommentsRE, "").replaceAll(singlelineCommentsRE, "");
204
- const s = new MagicString(code);
205
- const slice = (node) => s.slice(node.start, node.end);
206
- const { program } = parseSync(fileName, code);
207
- walk(program, { enter(node, parent, key) {
208
- if (key === "params" && (node.type === "Identifier" || node.type === "ObjectPattern" || node.type === "ArrayPattern")) {
209
- const end = node.typeAnnotation?.start ?? node.end;
210
- s.overwrite(node.start, end, "_");
211
- }
212
- } });
213
- const result = Object.create(null);
214
- for (const stmt of program.body) {
215
- let decl;
216
- if ((stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration") && stmt.declaration) decl = stmt.declaration;
217
- else decl = stmt;
218
- const register = (symbol, node) => {
219
- let code$1;
220
- if (node.type === "VariableDeclarator") {
221
- const typeAnnotation = node.id.typeAnnotation?.typeAnnotation;
222
- if (typeAnnotation) code$1 = s.slice(typeAnnotation.start, node.end);
223
- else if (node.init) code$1 = slice(node.init);
224
- }
225
- code$1 ||= slice(node);
226
- result[symbol] = format(code$1);
227
- };
228
- if (decl.type === "VariableDeclaration") for (const node of decl.declarations) register(nodeToString(node.id), node);
229
- else if ("id" in decl && decl.id) register(nodeToString(decl.id), decl);
230
- else if (decl.type === "ExportDefaultDeclaration" && "id" in decl.declaration && decl.declaration.id) register("default", decl.declaration);
231
- }
232
- if (applyExportRename) {
233
- for (const stmt of program.body) if (stmt.type === "ExportNamedDeclaration" && stmt.declaration === null && stmt.specifiers.length) for (const specifier of stmt.specifiers) {
234
- const exported = nodeToString(specifier.exported);
235
- const local = nodeToString(specifier.local);
236
- if (local !== exported) result[exported] = result[local];
237
- }
238
- }
239
- return sortObjectKeys(result);
240
- function nodeToString(node) {
241
- return node.type === "Identifier" ? node.name : node.type === "Literal" ? node.value : slice(node);
242
- }
243
- }
244
- const globalConfig = {
245
- indentWidth: 1,
246
- lineWidth: 1e8
247
- };
248
- const tsFormatter = createFromBuffer(await readFile(getPath()));
249
- tsFormatter.setConfig(globalConfig, {
250
- semiColons: "asi",
251
- preferSingleLine: true,
252
- "arrowFunction.useParentheses": "force",
253
- quoteStyle: "alwaysSingle",
254
- singleBodyPosition: "sameLine",
255
- bracePosition: "sameLine",
256
- operatorPosition: "sameLine",
257
- preferHanging: true
258
- });
259
- function format(code) {
260
- return tsFormatter.formatText({
261
- filePath: "dummy.d.ts",
262
- fileText: code
263
- }).trim().replaceAll("\n\n", "\n");
264
- }
265
-
266
- //#endregion
267
- export { sortObjectKeys as n, snapshot as t };