Skip to content

Commit 9705f18

Browse files
authored
Merge pull request #15 from ieedan/formatting
feat: formatting
2 parents 00524b7 + f8619ed commit 9705f18

File tree

11 files changed

+71
-40
lines changed

11 files changed

+71
-40
lines changed

.changeset/six-clocks-battle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"sv-strip": minor
3+
---
4+
5+
feat: Remove leading and trailing whitespace from removed nodes.

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,16 @@ const js = strip(ts);
3636
<input bind:value/>
3737
```
3838

39-
## Limitations
39+
## Formatting
40+
41+
By default `sv-strip` will remove leading and trailing whitespace when removing nodes. This will result in an output that is correctly formatted (with a small performance penalty).
42+
43+
If you are doing your own formatting you can disable this behavior with the `format` option like so:
44+
```ts
45+
const js = strip(ts, { format: false });
46+
```
4047

41-
### Formatting
42-
`sv-strip` doesn't format the code so we recommend running the output through a formatter to prevent unnecessary (and ugly) whitespace in your code.
48+
## Limitations
4349

4450
### Unsupported Syntax
4551

package.json

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@
1414
"bugs": {
1515
"url": "https://github.com/ieedan/sv-strip/issues"
1616
},
17-
"keywords": [
18-
"svelte",
19-
"strip",
20-
"types",
21-
"typescript",
22-
"javascript"
23-
],
17+
"keywords": ["svelte", "strip", "types", "typescript", "javascript"],
2418
"packageManager": "pnpm@10.4.1",
2519
"type": "module",
2620
"scripts": {
@@ -32,9 +26,7 @@
3226
"changeset": "changeset",
3327
"ci:release": "unbuild && changeset publish"
3428
},
35-
"files": [
36-
"dist"
37-
],
29+
"files": ["dist"],
3830
"exports": {
3931
".": {
4032
"import": "./dist/index.mjs",

src/index.ts

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { type AST, parse } from 'svelte/compiler';
55
export type Options = {
66
/** Used for debugging hints. */
77
filename?: string;
8+
/** Should the output be formatted. (Turn this off if you are doing your own formatting) @default true */
9+
format?: boolean;
810
};
911

1012
/** Strips the types from the provided Svelte source.
@@ -35,8 +37,11 @@ export type Options = {
3537
* assert(stripped === expected);
3638
* ```
3739
*/
38-
export function strip(source: string, options?: Options): string {
39-
const ast = parse(source, { filename: options?.filename });
40+
export function strip(
41+
source: string,
42+
{ filename = undefined, format = true }: Options = {}
43+
): string {
44+
const ast = parse(source, { filename });
4045

4146
const src = new MagicString(source);
4247

@@ -61,8 +66,14 @@ export function strip(source: string, options?: Options): string {
6166
'TSInterfaceDeclaration',
6267
];
6368
if (tsNodes.includes(node.type)) {
64-
if (parent.type === 'ExportNamedDeclaration') {
65-
src.update(parent.start, parent.end, '');
69+
if (['TSTypeAliasDeclaration', 'TSInterfaceDeclaration'].includes(node.type)) {
70+
let start = node.start;
71+
72+
if (parent.type === 'ExportNamedDeclaration') {
73+
start = parent.start;
74+
}
75+
76+
removeNode(src, start, node.end, format);
6677
return;
6778
}
6879

@@ -74,7 +85,7 @@ export function strip(source: string, options?: Options): string {
7485
if (node.type === 'ImportDeclaration') {
7586
// @ts-expect-error wrong
7687
if (node.importKind === 'type') {
77-
src.update(node.start, node.end, '');
88+
removeNode(src, node.start, node.end, format);
7889
return;
7990
}
8091

@@ -87,7 +98,7 @@ export function strip(source: string, options?: Options): string {
8798

8899
// if all the specifiers were type only remove the entire thing
89100
if (remainingSpecifiers.length === 0) {
90-
src.update(node.start, node.end, '');
101+
removeNode(src, node.start, node.end, format);
91102
return;
92103
}
93104

@@ -106,7 +117,7 @@ export function strip(source: string, options?: Options): string {
106117
if (node.type === 'ExportNamedDeclaration') {
107118
// @ts-expect-error wrong
108119
if (node.exportKind === 'type') {
109-
src.update(node.start, node.end, '');
120+
removeNode(src, node.start, node.end, format);
110121
return;
111122
}
112123

@@ -119,7 +130,7 @@ export function strip(source: string, options?: Options): string {
119130

120131
// if all the specifiers were type only remove the entire thing
121132
if (remainingSpecifiers.length === 0) {
122-
src.update(node.start, node.end, '');
133+
removeNode(src, node.start, node.end, format);
123134
return;
124135
}
125136

@@ -169,3 +180,39 @@ export function strip(source: string, options?: Options): string {
169180

170181
return src.toString();
171182
}
183+
184+
/** Removes the entire node and any leading / trailing whitespace
185+
*
186+
* @param src
187+
* @param start
188+
* @param end
189+
*/
190+
function removeNode(src: MagicString, start: number, end: number, format: boolean) {
191+
let newStart = start;
192+
let newEnd = end;
193+
194+
if (format) {
195+
newStart = 0;
196+
197+
// remove whitespace proceeding the node until the next newline / none whitespace character
198+
for (let i = start - 1; i > -1; i--) {
199+
if (/\S|\n/.test(src.original[i])) {
200+
newStart = i + 1;
201+
break;
202+
}
203+
}
204+
205+
// remove whitespace beyond the node until the proceeding whitespace of the next node
206+
for (let i = end; i < src.original.length; i++) {
207+
if (/\S/.test(src.original[i])) {
208+
break;
209+
}
210+
211+
if (src.original[i] === '\n') {
212+
newEnd = i + 1;
213+
}
214+
}
215+
}
216+
217+
src.update(newStart, newEnd, '');
218+
}
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
<script>
2-
3-
42
let thing = "foo";
53
</script>

tests/cases/strip-func-binding-types/js.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<script>
2-
32
</script>
43

54
<input bind:value={() => {

tests/cases/strip-getter-setter-types/js.svelte

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<script>
2-
3-
42
let value = $state(0);
53
</script>
64

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
<script module>
2-
3-
4-
5-
62
const FIVE = 5;
73
8-
9-
104
export { FIVE };
115
</script>
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
<script>
2-
3-
4-
5-
62
let { ...rest } = $props();
73
</script>

tests/cases/strips-props/js.svelte

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<script>
2-
3-
42
let { value } = $props();
53
</script>
64

0 commit comments

Comments
 (0)