svelte-typecheck 0.0.0 → 0.1.1
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 +218 -2
- package/cli.js +73 -0
- package/index.d.ts +196 -0
- package/index.js +1 -0
- package/package.json +35 -3
- package/shared-58j2f7by.js +2 -0
- package/shared-7zm6g9d3.js +83 -0
- package/shared-9c39v7dt.js +1 -0
- package/shims/shims.d.ts +398 -0
- package/shims/svelte3-elements.d.ts +1651 -0
- package/index.ts +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,221 @@
|
|
|
1
1
|
# svelte-typecheck
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Type-check Svelte components with the checker of your choice: `bun check`, tsrs, tsgo or `tsc`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
svelte-typecheck turns each component into TypeScript, runs a type checker on it, and maps every error back to its line and column in the `.svelte` file. It reports what svelte-check reports, up to 11× faster, with about half the memory.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bun add -d svelte-typecheck
|
|
9
|
+
bunx svelte-typecheck
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Runs on Bun and on Node 22+ (`npx svelte-typecheck`). It checks with your project's own TypeScript, so the errors match your editor and build; TypeScript 7's `tsc` is native and fast. `--checker bun` or `--checker tsrs` is faster still.
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
/my-app/src/Errors.svelte:11:8
|
|
16
|
+
Error: Type '"tertiary"' is not assignable to type '"primary" | "ghost" | undefined'. (ts)
|
|
17
|
+
|
|
18
|
+
/my-app/src/Errors.svelte:13:33
|
|
19
|
+
Error: Property 'nope' does not exist on type '{ text: "primary" | "ghost"; }'. (ts)
|
|
20
|
+
|
|
21
|
+
====================================
|
|
22
|
+
svelte-typecheck found 2 errors and 0 warnings in 1 file
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Why
|
|
26
|
+
|
|
27
|
+
| | svelte-check | svelte-typecheck |
|
|
28
|
+
| :------------- | :------------------------------ | :---------------------------------------------------------------- |
|
|
29
|
+
| Type checker | TypeScript's JS API (TS 5 or 6) | Any checker that reads a tsconfig: `bun check`, tsrs, tsgo, `tsc` |
|
|
30
|
+
| TypeScript 7 | Needs `typescript@~6` beside it | Works: never imports `typescript` |
|
|
31
|
+
| Dependencies | 6, plus `typescript` (24 MB) | None: [sveast](https://github.com/metonym/sveast) is bundled |
|
|
32
|
+
| Svelte 3, 4, 5 | Yes | Yes, runes included |
|
|
33
|
+
| SvelteKit | `./$types`, typed `load`, hooks | The same |
|
|
34
|
+
|
|
35
|
+
The fastest of 5 cold runs on an 8-core Apple M2, each factor against
|
|
36
|
+
svelte-check's default mode. svelte-check's own TypeScript 7 modes are
|
|
37
|
+
in for comparison: the same tsgo, driven differently.
|
|
38
|
+
|
|
39
|
+
| Tool | Checker | carbon-components-svelte | bits-ui | realworld |
|
|
40
|
+
| :------------------------------------- | :-------------------- | :----------------------- | :----------- | :------------ |
|
|
41
|
+
| svelte-check | TypeScript 6 | 40.5 s | 6.6 s | 1.76 s |
|
|
42
|
+
| svelte-check `--tsgo-experimental-api` | TypeScript 7 | 11.6 s (3.5×) | 2.8 s (2.3×) | 1.17 s (1.5×) |
|
|
43
|
+
| svelte-typecheck | TypeScript 6 (`tsc`) | 18.9 s (2.1×) | 5.7 s (1.2×) | 1.24 s (1.4×) |
|
|
44
|
+
| svelte-typecheck | TypeScript 7 (`tsgo`) | 7.9 s (5.1×) | 1.6 s (4.2×) | 0.79 s (2.2×) |
|
|
45
|
+
| svelte-typecheck | tsrs | 3.7 s (11.1×) | 1.6 s (4.1×) | 0.70 s (2.5×) |
|
|
46
|
+
| svelte-typecheck | `bun check` | 3.6 s (11.3×) | 1.4 s (4.7×) | 0.67 s (2.6×) |
|
|
47
|
+
|
|
48
|
+
Peak memory falls with it: 0.85 GB against svelte-check's 1.74 GB on
|
|
49
|
+
carbon-components-svelte with `bun check`. There, it also replaced
|
|
50
|
+
svelte-check in CI, where the type tests went from 6 to 30 s to 1 to 3 s.
|
|
51
|
+
|
|
52
|
+
Those are cold runs. After the first, a run regenerates and recompiles
|
|
53
|
+
only the components that changed, the checker reuses its build cache,
|
|
54
|
+
and with nothing changed, the last result comes back without checking
|
|
55
|
+
at all. On carbon-components-svelte, with svelte-check's runs all cold:
|
|
56
|
+
|
|
57
|
+
| Run | `tsc` | tsgo | tsrs | `bun check` |
|
|
58
|
+
| :----------------------------------- | :----- | :----- | :----- | :---------- |
|
|
59
|
+
| Cold | 18.9 s | 7.9 s | 3.7 s | 3.6 s |
|
|
60
|
+
| One component changed | 3.1 s | 0.95 s | 0.72 s | 0.76 s |
|
|
61
|
+
| Nothing changed | 0.09 s | 0.09 s | 0.14 s | 0.09 s |
|
|
62
|
+
| `--watch`, from a save to its result | n/a | 0.68 s | 0.37 s | 0.76 s |
|
|
63
|
+
|
|
64
|
+
`bun check` has no build cache of its own, so it checks the whole
|
|
65
|
+
program again after a change. A run with nothing changed is known by
|
|
66
|
+
each input's size and modification time: the components, the files
|
|
67
|
+
the tsconfig includes and those it extends, the package manifests and
|
|
68
|
+
lockfiles, the Svelte config and the versions, and the files the last
|
|
69
|
+
run's program imported. An edit that none of those see, such as a
|
|
70
|
+
hand-patched package in `node_modules`, needs `--no-incremental`.
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
A drop-in replacement for svelte-check: the same options, the same output in all four formats, the same exit codes.
|
|
75
|
+
|
|
76
|
+
```diff
|
|
77
|
+
- "check": "svelte-check --tsconfig ./tsconfig.json"
|
|
78
|
+
+ "check": "svelte-typecheck --tsconfig ./tsconfig.json"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| svelte-check's options | |
|
|
82
|
+
| :---------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `--workspace <dir>` | Project folder (default: the current one) |
|
|
84
|
+
| `--output <format>` | `human`, `human-verbose` (default), `machine` or `machine-verbose` |
|
|
85
|
+
| `--tsconfig <path>` | tsconfig or jsconfig, relative to the workspace (default: the nearest from the workspace up). The components it includes are checked, and its TS and JS files' errors reported |
|
|
86
|
+
| `--no-tsconfig` | Check every component under the workspace, and no TS or JS files |
|
|
87
|
+
| `--ignore <list>` | With `--no-tsconfig`: paths to skip, comma-separated |
|
|
88
|
+
| `--config <path>` | The vite.config or svelte.config to read preprocessors and `compilerOptions` from |
|
|
89
|
+
| `--diagnostic-sources <list>` | `js`, `svelte` and `css`, comma-separated (default: all) |
|
|
90
|
+
| `--threshold error` | Print errors only |
|
|
91
|
+
| `--compiler-warnings <list>` | `code:ignore` or `code:error`, comma-separated |
|
|
92
|
+
| `--fail-on-warnings` | Exit 1 on a warning too |
|
|
93
|
+
| `--color`, `--no-color` | Force color on or off |
|
|
94
|
+
| `--tsgo` | Check with tsgo |
|
|
95
|
+
|
|
96
|
+
| Its own | |
|
|
97
|
+
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| `--checker <name>` | `tsc` (default: your `typescript`), `tsgo`, `tsrs` or `bun` |
|
|
99
|
+
| `--components <glob>` | Components to check, relative to the workspace, instead of the tsconfig's; repeatable |
|
|
100
|
+
| `--out-dir <dir>` | Where the generated code goes (default: `node_modules/.cache/svelte-typecheck/<workspace>`) |
|
|
101
|
+
| `--no-declarations` | Type component imports only by their own `.svelte.d.ts`, never the generated code |
|
|
102
|
+
| `--svelte <dir>` | The Svelte install to check against, e.g. a Svelte 4 test harness's |
|
|
103
|
+
| `--no-incremental` | Start from nothing: by default, the generated code and the checker's build cache are kept between runs |
|
|
104
|
+
| `--changed` | Report only the files changed from `HEAD` (and untracked ones), and the files that import them; see [Beyond svelte-check](#beyond-svelte-check) |
|
|
105
|
+
| `--since <ref>` | As `--changed`, from where the branch left `<ref>`: `--since origin/main` |
|
|
106
|
+
| `--baseline <file>` | Report only diagnostics the baseline doesn't have; see [Beyond svelte-check](#beyond-svelte-check) |
|
|
107
|
+
| `--update-baseline` | Write the run's diagnostics to `--baseline`'s file |
|
|
108
|
+
|
|
109
|
+
## Beyond svelte-check
|
|
110
|
+
|
|
111
|
+
What svelte-typecheck does that svelte-check doesn't:
|
|
112
|
+
|
|
113
|
+
| | |
|
|
114
|
+
| :------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
115
|
+
| **Any checker, TypeScript 7** | Checks with your project's `tsc`, including TypeScript 7's native one, or tsgo, tsrs or `bun check`; svelte-check needs TypeScript 5 or 6's JS API. See [Bring your own checker](#bring-your-own-checker). |
|
|
116
|
+
| **Baselines** | `--update-baseline --baseline errors.json` records today's diagnostics; `--baseline errors.json` then reports, and fails on, only new ones. A diagnostic is known by its file, code, message and line's text, not its line number, so edits around it don't make it new; fixed ones are counted, to drop with `--update-baseline`. For turning on `strict`, a new rule, or a checker upgrade without fixing everything first. Its paths are the workspace's, so the file is the same on every machine. |
|
|
117
|
+
| **Changed files only** | `--changed` and `--since <ref>` report the files git sees changed and the files that import them, whose errors a change can cause. The whole program is still checked, so the errors are the same ones, fewer to read: for a pre-commit hook, or a PR's CI run. |
|
|
118
|
+
| **Speed and memory** | Up to 11× faster than svelte-check with `bun check` or tsrs, at about half its memory, and 1.2 to 2× with TypeScript 6's own `tsc`: one checker process over files on disk, beside the compiler pass, where svelte-check drives TypeScript's language service file by file. |
|
|
119
|
+
| **Zero dependencies** | One bundle: it uses the project's own Svelte and checker, and installs nothing else. |
|
|
120
|
+
| **Generated code you can read** | The TypeScript it writes and its tsconfig are plain files in `--out-dir`: open them, or run any checker on them yourself. They're kept between runs, with the checker's own build cache, so a run after a change rewrites and rechecks only what it touches (`--no-incremental` starts over). |
|
|
121
|
+
| **No silent passes** | Generated code that doesn't parse fails the run as a svelte-typecheck bug, and a checker error that names no file (a tsconfig option, a root file) is reported on the tsconfig. svelte-check's language service reads past broken generated code. |
|
|
122
|
+
|
|
123
|
+
### Differences from svelte-check
|
|
124
|
+
|
|
125
|
+
- **CSS diagnostics** (`--diagnostic-sources css`): accepted, but nothing is reported. svelte-check runs a CSS language service on `<style>`, a dependency this package leaves out; Svelte's compiler still reports invalid CSS.
|
|
126
|
+
- **`COMPLETED <n> FILES`** counts components, not every file in TypeScript's program.
|
|
127
|
+
- **`--diagnostic-sources svelte`** with a tsconfig reports no type errors, as svelte-check's docs say; svelte-check itself reports them.
|
|
128
|
+
- **`--tsgo-experimental-api`** is accepted, and does what `--tsgo` does.
|
|
129
|
+
- **tsconfig option errors** that only matter to an emitting build, such as a JS file that `tsc` would overwrite, aren't reported: the checker runs with `noEmit`.
|
|
130
|
+
- **A union's members** can print in another order, as TypeScript orders them by when it first meets each type: `Element | Document` where svelte-check has `Document | Element`.
|
|
131
|
+
- **A syntax error in a TS or JS file** stops `tsc` and the other CLI checkers from type-checking at all, so only syntax errors are reported until it's fixed; svelte-check's language service reports the type errors in other files too. A component's syntax errors don't do this.
|
|
132
|
+
- **Svelte 3 and 4 with `lang="ts"` and no preprocessors**: svelte-check strips the types with a fallback preprocessor and reports the compiler's warnings; here the compiler can't read the script, so there are none.
|
|
133
|
+
- **`--out-dir` outside the project** can't find its packages from the generated code; the default is inside `node_modules`.
|
|
134
|
+
|
|
135
|
+
### API
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import {
|
|
139
|
+
applyBaseline,
|
|
140
|
+
compilerDiagnostics,
|
|
141
|
+
createBaseline,
|
|
142
|
+
typecheck,
|
|
143
|
+
} from "svelte-typecheck";
|
|
144
|
+
|
|
145
|
+
const { diagnostics, components, timings } = await typecheck({
|
|
146
|
+
workspace: "src",
|
|
147
|
+
checker: "tsgo",
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Svelte's own warnings and errors (a11y, unused CSS, invalid markup).
|
|
151
|
+
compilerDiagnostics(source, "Button.svelte");
|
|
152
|
+
|
|
153
|
+
// What's new since a baseline, in the files a change reaches.
|
|
154
|
+
const result = await typecheck({ only: ["src/Button.svelte"] });
|
|
155
|
+
const baseline = createBaseline(result.diagnostics, result.workspace);
|
|
156
|
+
applyBaseline(result.diagnostics, baseline, result.workspace).diagnostics; // []
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Bring your own checker
|
|
160
|
+
|
|
161
|
+
svelte-typecheck doesn't bundle or import TypeScript. It writes the generated code and a tsconfig to disk and runs a checker on them as a separate process, so any of these works, at whatever version your project installs:
|
|
162
|
+
|
|
163
|
+
| `--checker` | Install | Runs | Notes |
|
|
164
|
+
| :---------- | :-------------------------------------------- | :------------------------------------------- | :-------------------------------------------------------------------------------------------------- |
|
|
165
|
+
| `tsc` | `typescript` | `tsc -p <generated tsconfig> --pretty false` | The default. TypeScript 7's `tsc` is native; with 6, JS files' JSDoc reads as svelte-check reads it |
|
|
166
|
+
| `tsgo` | `@typescript/native-preview` | `tsgo -p … --pretty false` | TypeScript 7's preview build. `--tsgo` (svelte-check's flag) picks it too |
|
|
167
|
+
| `tsrs` | [`tsrs`](https://github.com/oxc-project/tsrs) | `tsrs -p … --pretty false` | oxc's Rust port of TypeScript 7 |
|
|
168
|
+
| `bun` | [Bun](https://bun.sh) 1.4 | `bun check -p … --no-pretty --all` | Bun's own TypeScript; no build cache, so it checks the whole program after a change |
|
|
169
|
+
|
|
170
|
+
```sh
|
|
171
|
+
svelte-typecheck # your project's typescript: tsc
|
|
172
|
+
svelte-typecheck --checker tsgo # or tsrs, or bun
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const result = await typecheck({ checker: "tsrs" });
|
|
177
|
+
result.checker; // "tsrs"
|
|
178
|
+
result.checkerVersion; // "0.20.1", from its package.json
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### How a checker is found and run
|
|
182
|
+
|
|
183
|
+
| Step | What happens |
|
|
184
|
+
| :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
185
|
+
| Pick | `--checker`, or else the first of `tsc`, `tsgo`, `tsrs`, `bun` that's installed: your project's own TypeScript when it has one |
|
|
186
|
+
| Find | Its package in `node_modules`, from the workspace up, as Node resolves one (a hoisted install counts), then its `bin` in the package's `package.json`; failing that, the command on `PATH` (on Windows, by `PATHEXT`: `tsc.cmd`, `bun.exe`). `bun` is the running Bun, if svelte-typecheck runs on Bun |
|
|
187
|
+
| Launch | A Node launcher (all three packages ship one) runs on the current runtime, Node or Bun, rather than through its shebang, so it works on Windows too; a native binary runs directly; a Windows `.cmd` shim runs through the shell |
|
|
188
|
+
| Configure | The generated tsconfig `extends` yours, so your compiler options (`strict`, `paths`, `lib`, `types`…) apply. It adds the generated code to `files` and `rootDirs`, and sets `noEmit` and its own `incremental` build info, so your files are never written |
|
|
189
|
+
| Read | The checker prints errors as `tsc` does, `file(line,col): error TSxxxx: message`; each one maps back to its `.svelte` line, or to your TS file as it is. An error that names no file (a bad option) is reported on your tsconfig |
|
|
190
|
+
|
|
191
|
+
Any version works as long as it reads a tsconfig and prints `tsc`'s format: to pin one, install it in the project. TypeScript 7 reads JSDoc in JS files more strictly than 6, so a JS codebase's error count can move a little between them.
|
|
192
|
+
|
|
193
|
+
## How it works
|
|
194
|
+
|
|
195
|
+
1. **Find the project.** The tsconfig svelte-check would use (the nearer of tsconfig.json and jsconfig.json from the workspace up), and the components its `include` names.
|
|
196
|
+
2. **Parse.** [sveast](https://github.com/metonym/sveast) parses each component and resolves its scopes: props, `$:` declarations, runes, stores, `{#each}`, `let:` and snippet scopes, every read and write.
|
|
197
|
+
3. **Generate.** Each component becomes TypeScript (or JS with JSDoc) the way svelte2tsx writes it, with a map from each piece back to its source. The code, the helper types it calls (adapted from svelte2tsx's, MIT) and a tsconfig that extends yours go to `node_modules/.cache/svelte-typecheck`.
|
|
198
|
+
4. **Check and compile, at once.** One checker process type-checks the whole program while Svelte's compiler reports its warnings beside it.
|
|
199
|
+
5. **Map and order.** Each error maps back to its `.svelte` line, with svelte-check's rewrites and filters, in the order svelte-check prints them.
|
|
200
|
+
6. **Keep.** What each step learned is kept for the next run.
|
|
201
|
+
|
|
202
|
+
### What makes it fast
|
|
203
|
+
|
|
204
|
+
| Choice | Effect on carbon-components-svelte (1,276 components) |
|
|
205
|
+
| :------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------- |
|
|
206
|
+
| One batch run of a command-line checker, where svelte-check asks TypeScript's language service file by file | 18.9 s against 40.5 s, on the same TypeScript 6 |
|
|
207
|
+
| Native checkers (TypeScript 7, tsrs, `bun check`) on every core | 3.6 s with `bun check`, 11× faster |
|
|
208
|
+
| sveast, a one-pass parser, instead of svelte2tsx and its source maps | Every component parsed and generated in about 0.4 s |
|
|
209
|
+
| Svelte's compiler alongside the checker, not after it | The slower of the two sets the time, not their sum |
|
|
210
|
+
| Only what changed: components regenerated and recompiled, the checker's build cache, the last result when nothing changed | 0.72 s after one change (tsrs), 0.09 s with none |
|
|
211
|
+
|
|
212
|
+
## Limitations
|
|
213
|
+
|
|
214
|
+
- **Type-checking only:** no editor support. Your editor keeps the Svelte language server, which can disagree with it at the edges.
|
|
215
|
+
- **No CSS diagnostics.**
|
|
216
|
+
|
|
217
|
+
The rest of what differs from svelte-check is under [Differences from svelte-check](#differences-from-svelte-check).
|
|
218
|
+
|
|
219
|
+
## Contributing
|
|
220
|
+
|
|
221
|
+
How it's built, the rules a change keeps, and how to check it against svelte-check and benchmark it: [CONTRIBUTING.md](CONTRIBUTING.md).
|
package/cli.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import"./shared-58j2f7by.js";import{EmitError,typecheck2,watch2,createBaseline2,applyBaseline2}from"./shared-7zm6g9d3.js";import{readFileSync as readFileSync2,writeFileSync}from"node:fs";import{resolve}from"node:path";import{parseArgs}from"node:util";import{readFileSync}from"node:fs";import{relative,sep}from"node:path";var OUTPUT_FORMATS=["human","human-verbose","machine","machine-verbose"];function colors(force){let env=process.env,enabled=force??(env.FORCE_COLOR!==void 0?env.FORCE_COLOR!=="0":env.NO_COLOR===void 0&&Boolean(process.stdout.isTTY)&&env.TERM!=="dumb"),paint=(open,close)=>(text)=>enabled?`\x1B[${open}m${text}\x1B[${close}m`:text;return{red:paint(31,39),yellow:paint(33,39),green:paint(32,39),cyan:paint(36,39),magenta:paint(35,39)}}function lineOf(text,line){return text.split(`
|
|
3
|
+
`)[line-1]??""}function codeFrame(d,c){let text;try{text=readFileSync(d.file,"utf-8")}catch{return""}let endLine=d.endLine??d.line,endColumn=d.endColumn??d.column,first=lineOf(text,d.line),last=lineOf(text,endLine),middle=d.line===endLine?first.slice(0,d.column-1)+c.magenta(first.slice(d.column-1,endColumn-1))+first.slice(endColumn-1):first.slice(0,d.column-1)+c.magenta([first.slice(d.column-1),...text.split(`
|
|
4
|
+
`).slice(d.line,endLine-1),last.slice(0,endColumn-1)].join(`
|
|
5
|
+
`))+last.slice(endColumn-1),before=d.line>1?`${lineOf(text,d.line-1)}
|
|
6
|
+
`:"",after=lineOf(text,endLine+1);return`${before}${middle}
|
|
7
|
+
${after}`}function codeOf(d){if(d.code.startsWith("TS"))return Number(d.code.slice(2));return NUMERIC.test(d.code)?Number(d.code):d.code}var NUMERIC=/^-?\d+$/;function sourceOf(d){return d.file.endsWith(".svelte")||d.source==="svelte"?d.source:void 0}var COMPILER_CODE=/^[a-z][\w-]*[-_][\w-]*$/,DASH=/-/g;function codeDescriptionOf(d){if(d.source!=="svelte"||!COMPILER_CODE.test(d.code))return;return{href:`https://svelte.dev/docs/svelte/${d.severity==="warning"?"compiler-warnings":"compiler-errors"}#${d.code.replace(DASH,"_")}`}}function summarize(diagnostics,files){let errors=diagnostics.filter((d)=>d.severity==="error").length;return{files,errors,warnings:diagnostics.length-errors,filesWithProblems:new Set(diagnostics.map((d)=>d.file)).size}}var DRIVE=/^[A-Z]:/;function displayed(workspace){return process.platform==="win32"?workspace.replace(DRIVE,(drive)=>drive.toLowerCase()):workspace}function writer(format,write,c){let machine=format.startsWith("machine"),verbose=format.endsWith("verbose"),log=(message)=>write(`${Date.now()} ${message}
|
|
8
|
+
`);return{start(workspace,clearScreen=!1){if(!machine&&clearScreen&&process.stdout.isTTY)write("\x1B[2J\x1B[3J\x1B[H");if(machine)log(`START ${JSON.stringify(displayed(workspace))}`);else if(verbose)write(`Loading svelte-typecheck in workspace: ${displayed(workspace)}
|
|
9
|
+
Getting Svelte diagnostics...
|
|
10
|
+
|
|
11
|
+
`)},diagnostic(d,workspace){let filename=relative(workspace,d.file),type=d.severity==="error"?"ERROR":"WARNING";if(machine){if(verbose)log(JSON.stringify({type,filename,start:{line:d.line-1,character:d.column-1},end:{line:(d.endLine??d.line)-1,character:(d.endColumn??d.column)-1},message:d.message,code:codeOf(d),codeDescription:codeDescriptionOf(d),source:sourceOf(d)}));else log(`${type} ${JSON.stringify(filename)} ${d.line}:${d.column} ${JSON.stringify(d.message)}`);return}write(`${displayed(workspace)}${sep}${c.green(filename)}:${d.line}:${d.column}
|
|
12
|
+
`);let source=sourceOf(d)?`(${d.source})`:"",message=verbose?`${d.message} ${source}
|
|
13
|
+
${c.cyan(codeFrame(d,c).trimEnd())}`:`${d.message} ${source}`;write(`${d.severity==="error"?c.red("Error"):c.yellow("Warn")}: ${message}
|
|
14
|
+
|
|
15
|
+
`)},note(text){if(!machine)write(`${text}
|
|
16
|
+
`)},completion(summary,watching=!1){let{files,errors,warnings,filesWithProblems}=summary;if(machine){log(`COMPLETED ${files} FILES ${errors} ERRORS ${warnings} WARNINGS ${filesWithProblems} FILES_WITH_PROBLEMS`);return}if(filesWithProblems)write(`====================================
|
|
17
|
+
`);let message=`svelte-typecheck found ${errors} ${errors===1?"error":"errors"} and ${warnings} ${warnings===1?"warning":"warnings"}${filesWithProblems?` in ${filesWithProblems} ${filesWithProblems===1?"file":"files"}`:""}
|
|
18
|
+
`;if(errors)write(c.red(message));else if(warnings)write(c.yellow(message));else write(c.green(message));if(watching)write("Watching for file changes...")},failure(error){if(machine)log(`FAILURE ${JSON.stringify(error.message)}`);else write(`${error.message}
|
|
19
|
+
`)}}}import{spawnSync}from"node:child_process";import{join}from"node:path";var LINE_BREAK=/\r?\n/;function git(args,cwd){let result=spawnSync("git",args,{cwd,encoding:"utf-8"});if(result.status!==0)throw Error(`git ${args.join(" ")} failed: ${(result.stderr||result.error?.message||"").trim()}`);return result.stdout}function changedFiles(cwd,since){let top=git(["rev-parse","--show-toplevel"],cwd).trim(),base=since?git(["merge-base",since,"HEAD"],cwd).trim():"HEAD",lines=[...git(["diff","--name-only",base],cwd).split(LINE_BREAK),...git(["ls-files","--others","--exclude-standard"],top).split(LINE_BREAK)];return[...new Set(lines.filter(Boolean).map((line)=>join(top,line)))]}var HELP=`Usage: svelte-typecheck [options]
|
|
20
|
+
|
|
21
|
+
Type-checks Svelte components, as svelte-check does.
|
|
22
|
+
|
|
23
|
+
svelte-check's options:
|
|
24
|
+
--workspace <dir> Project folder (default: the current one)
|
|
25
|
+
--output <format> human, human-verbose, machine or machine-verbose
|
|
26
|
+
(default: human-verbose)
|
|
27
|
+
--tsconfig <path> tsconfig or jsconfig, relative to the workspace;
|
|
28
|
+
its TS and JS files' errors are reported too
|
|
29
|
+
(default: the nearest from the workspace up)
|
|
30
|
+
--no-tsconfig Check every component under the workspace, and
|
|
31
|
+
no TS or JS files
|
|
32
|
+
--ignore <list> With --no-tsconfig: paths to skip, relative to
|
|
33
|
+
the workspace, comma-separated
|
|
34
|
+
--config <path> vite.config or svelte.config to read preprocessors
|
|
35
|
+
and compilerOptions from (default: the nearest)
|
|
36
|
+
--diagnostic-sources <list>
|
|
37
|
+
js, svelte and css, comma-separated (default: all;
|
|
38
|
+
css reports nothing)
|
|
39
|
+
--threshold <level> error reports errors only (default: warning)
|
|
40
|
+
--compiler-warnings <list>
|
|
41
|
+
code:ignore or code:error, comma-separated
|
|
42
|
+
--fail-on-warnings Exit 1 on a warning too
|
|
43
|
+
--color, --no-color Force color on or off
|
|
44
|
+
--watch Check again when a file changes
|
|
45
|
+
--preserveWatchOutput Don't clear the screen between watch runs
|
|
46
|
+
--incremental Keep generated code between runs, and let the
|
|
47
|
+
checker reuse its last run (the default)
|
|
48
|
+
--no-incremental Start from nothing each run
|
|
49
|
+
--tsgo Check with tsgo (same as --checker tsgo)
|
|
50
|
+
-h, --help Show this help
|
|
51
|
+
-v, --version Show the version
|
|
52
|
+
|
|
53
|
+
svelte-typecheck's own:
|
|
54
|
+
--checker <name> tsc, tsgo, tsrs or bun (default: the project's
|
|
55
|
+
TypeScript, then the first installed)
|
|
56
|
+
--components <glob> Components to check, relative to the workspace,
|
|
57
|
+
instead of the tsconfig's; repeatable
|
|
58
|
+
--out-dir <dir> Where to write the generated code (default:
|
|
59
|
+
node_modules/.cache/svelte-typecheck/<workspace>)
|
|
60
|
+
--no-declarations Resolve component imports to their own
|
|
61
|
+
.svelte.d.ts
|
|
62
|
+
--svelte <dir> Svelte package to check against
|
|
63
|
+
--changed Report only files changed from HEAD (and
|
|
64
|
+
untracked), and the files that import them
|
|
65
|
+
--since <ref> As --changed, from where the branch left <ref>
|
|
66
|
+
--baseline <file> Report only diagnostics the baseline doesn't have
|
|
67
|
+
--update-baseline Write the run's diagnostics to the baseline
|
|
68
|
+
|
|
69
|
+
Exits 1 on an error, or a warning with --fail-on-warnings.`;async function main(argv){let values;try{values=parse(argv).values}catch(error){return console.error(`${error.message}
|
|
70
|
+
|
|
71
|
+
${HELP}`),1}if(values.help)return console.log(HELP),0;if(values.version){let{version}=await import("./shared-9c39v7dt.js");return console.log(version),0}let format=formatOf(values.output),out=writer(format,(text)=>process.stdout.write(text),colors(colorFlag(values.color,values["no-color"]))),options={workspace:values.workspace??".",tsconfig:values["no-tsconfig"]?!1:values.tsconfig,ignore:values.ignore?.split(","),config:values.config,checker:values.checker??(values.tsgo||values["tsgo-experimental-api"]?"tsgo":void 0),components:values.components,outDir:values["out-dir"],declarations:!values["no-declarations"],svelte:values.svelte,diagnosticSources:values["diagnostic-sources"]?.split(",").map((source)=>source.trim()),compilerWarnings:parseCompilerWarnings(values["compiler-warnings"]),incremental:!values["no-incremental"]};if(values.changed||values.since)try{options.only=changedFiles(process.cwd(),values.since)}catch(error){return out.failure(error),1}let baselinePath=values.baseline&&resolve(values.baseline);if(values["update-baseline"]&&!baselinePath)return out.failure(Error("--update-baseline needs --baseline <file>")),1;if(values["update-baseline"]&&(values.changed||values.since))return out.failure(Error("--update-baseline takes every file's: drop --changed")),1;let baseline;if(baselinePath&&!values["update-baseline"])try{baseline=JSON.parse(readFileSync2(baselinePath,"utf-8"))}catch{return out.failure(Error(`No baseline at ${baselinePath}: write one with --update-baseline`)),1}let errorsOnly=values.threshold==="error",failOnWarnings=values["fail-on-warnings"],report=(result,watching)=>{if(result instanceof Error)return out.failure(result instanceof EmitError?Error(`${result.message}
|
|
72
|
+
This is a svelte-typecheck bug; please report it.`):result),1;if(baselinePath&&values["update-baseline"]){let written=createBaseline2(result.diagnostics,result.workspace);return writeFileSync(baselinePath,`${JSON.stringify(written,null,2)}
|
|
73
|
+
`),out.note(`Wrote ${result.diagnostics.length} diagnostics to ${baselinePath}`),0}let known=baseline?applyBaseline2(result.diagnostics,baseline,result.workspace):void 0,shown=known?known.diagnostics:result.diagnostics;out.start(result.workspace,watching&&!values.preserveWatchOutput);for(let d of shown)if(!errorsOnly||d.severity==="error")out.diagnostic(d,result.workspace);for(let f of result.failed)out.failure(Error(`${f.file}: failed to parse: ${f.message}`));let summary=summarize(shown,result.components);if(known?.known)out.note(`${known.known} more in the baseline, not shown`);if(known?.fixed)out.note(`${known.fixed} in the baseline are fixed: --update-baseline drops them`);if(result.skipped>0)out.note(`${result.skipped} more in files the changes don't reach, not shown`);return out.completion(summary,watching),summary.errors>0||result.failed.length>0||failOnWarnings&&summary.warnings>0?1:0};if(values.watch)return watch2(options,(result)=>report(result,!0)),new Promise(()=>{});try{return report(await typecheck2(options),!1)}catch(error){return report(error,!1)}}function formatOf(output){if(output&&OUTPUT_FORMATS.includes(output))return output;return process.env.CLAUDECODE==="1"?"machine":"human-verbose"}function parse(argv){return parseArgs({args:argv,options:{workspace:{type:"string"},output:{type:"string"},tsconfig:{type:"string"},"no-tsconfig":{type:"boolean",default:!1},ignore:{type:"string"},config:{type:"string"},"diagnostic-sources":{type:"string"},threshold:{type:"string"},"compiler-warnings":{type:"string"},"fail-on-warnings":{type:"boolean",default:!1},color:{type:"boolean",default:!1},"no-color":{type:"boolean",default:!1},tsgo:{type:"boolean",default:!1},incremental:{type:"boolean",default:!1},"no-incremental":{type:"boolean",default:!1},watch:{type:"boolean",default:!1},preserveWatchOutput:{type:"boolean",default:!1},"tsgo-experimental-api":{type:"boolean",default:!1},checker:{type:"string"},components:{type:"string",multiple:!0},"out-dir":{type:"string"},"no-declarations":{type:"boolean",default:!1},svelte:{type:"string"},changed:{type:"boolean",default:!1},baseline:{type:"string"},"update-baseline":{type:"boolean",default:!1},since:{type:"string"},help:{type:"boolean",short:"h",default:!1},version:{type:"boolean",short:"v",default:!1}}})}function parseCompilerWarnings(list){if(!list)return;let levels={};for(let entry of list.split(",")){let[code,level]=entry.trim().split(":");if(code&&(level==="ignore"||level==="error"))levels[code]=level}return levels}function colorFlag(on,off){if(on)return!0;if(off)return!1;return}process.exitCode=await main(process.argv.slice(2));
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// The package's public API, as consumers see it: the build copies this file
|
|
2
|
+
// as dist/index.d.ts, so it imports nothing and holds only declarations.
|
|
3
|
+
// tests/api.test.ts fails when an implementation's signature drifts from
|
|
4
|
+
// its declaration here.
|
|
5
|
+
|
|
6
|
+
/** A type checker that reads a tsconfig and prints errors as `tsc` does. */
|
|
7
|
+
export type Checker = "bun" | "tsrs" | "tsgo" | "tsc";
|
|
8
|
+
|
|
9
|
+
export interface TypecheckOptions {
|
|
10
|
+
/** The project root the other paths resolve against. Default: `process.cwd()`. */
|
|
11
|
+
cwd?: string;
|
|
12
|
+
/** The project folder, relative to `cwd`. Default: `"."`. */
|
|
13
|
+
workspace?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The tsconfig or jsconfig, relative to the workspace. With one, the
|
|
16
|
+
* components it includes are checked, and its TS and JS files' errors are
|
|
17
|
+
* reported too. Default: the nearest from the workspace up. `false`: none,
|
|
18
|
+
* so every component under the workspace, and only theirs.
|
|
19
|
+
*/
|
|
20
|
+
tsconfig?: string | false;
|
|
21
|
+
/**
|
|
22
|
+
* With no tsconfig: paths to skip, relative to the workspace, as
|
|
23
|
+
* svelte-check's `--ignore` (a prefix, or `**` at the start or end).
|
|
24
|
+
*/
|
|
25
|
+
ignore?: string[];
|
|
26
|
+
/** The svelte.config to read preprocessors from, relative to the workspace. Default: the nearest. */
|
|
27
|
+
config?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Default: the project's own TypeScript (`tsc`; native in TypeScript 7),
|
|
30
|
+
* then the first of `tsgo`, `tsrs` and `bun` that's installed.
|
|
31
|
+
*/
|
|
32
|
+
checker?: Checker;
|
|
33
|
+
/** Globs of the components to check, relative to the workspace, instead of the tsconfig's. */
|
|
34
|
+
components?: string[];
|
|
35
|
+
/** Where to write the generated code. Default: `node_modules/.cache/svelte-typecheck/<workspace>`. */
|
|
36
|
+
outDir?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Whether an import of a checked component resolves to its generated
|
|
39
|
+
* code (the default). With `false`, it resolves to the component's own
|
|
40
|
+
* `.svelte.d.ts`, as a library's generated declarations are.
|
|
41
|
+
*/
|
|
42
|
+
declarations?: boolean;
|
|
43
|
+
/** The Svelte package to check against. Default: `svelte`, resolved from `cwd`. */
|
|
44
|
+
svelte?: string;
|
|
45
|
+
/**
|
|
46
|
+
* What to report: `js` for type errors (in TS and JS), `svelte` for the
|
|
47
|
+
* compiler's warnings and errors. `css` is accepted, as svelte-check
|
|
48
|
+
* takes it, and reports nothing. Default: all.
|
|
49
|
+
*/
|
|
50
|
+
diagnosticSources?: DiagnosticSource[];
|
|
51
|
+
/** `error` reports errors only. Default: `warning`. */
|
|
52
|
+
threshold?: "warning" | "error";
|
|
53
|
+
/** Compiler warnings to drop (`ignore`) or report as errors, by code. */
|
|
54
|
+
compilerWarnings?: Record<string, "ignore" | "error">;
|
|
55
|
+
/**
|
|
56
|
+
* Keep the generated code between runs: rewrite only what changed, and
|
|
57
|
+
* let `tsc`, tsgo and tsrs reuse their last run. Default `true`.
|
|
58
|
+
*/
|
|
59
|
+
incremental?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Report only these files' diagnostics, and those of the files that
|
|
62
|
+
* import them, relative to `cwd`. The whole program is still checked.
|
|
63
|
+
* `--changed` and `--since` pass git's changed files.
|
|
64
|
+
*/
|
|
65
|
+
only?: string[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** A kind of check, as svelte-check's `--diagnostic-sources` names them. */
|
|
69
|
+
export type DiagnosticSource = "js" | "svelte" | "css";
|
|
70
|
+
|
|
71
|
+
/** An error or warning, at its line and column (both 1-based) in the source. */
|
|
72
|
+
export interface Diagnostic {
|
|
73
|
+
/** An absolute path. */
|
|
74
|
+
file: string;
|
|
75
|
+
line: number;
|
|
76
|
+
column: number;
|
|
77
|
+
/** Where the range ends, when known. */
|
|
78
|
+
endLine?: number;
|
|
79
|
+
endColumn?: number;
|
|
80
|
+
severity: "error" | "warning";
|
|
81
|
+
/** `ts` or `js` for a type error (by the file's language), `svelte` for the compiler. */
|
|
82
|
+
source: "ts" | "js" | "svelte";
|
|
83
|
+
/** `TS2322`, or a compiler code such as `a11y_missing_attribute`. */
|
|
84
|
+
code: string;
|
|
85
|
+
message: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface TypecheckResult {
|
|
89
|
+
diagnostics: Diagnostic[];
|
|
90
|
+
/** The workspace, as an absolute path. */
|
|
91
|
+
workspace: string;
|
|
92
|
+
/** The tsconfig used, if any. */
|
|
93
|
+
tsconfig?: string;
|
|
94
|
+
/** How many components were checked. */
|
|
95
|
+
components: number;
|
|
96
|
+
/** Diagnostics left out by `only`. */
|
|
97
|
+
skipped: number;
|
|
98
|
+
/** Errors in generated code, which map to no source. */
|
|
99
|
+
dropped: Diagnostic[];
|
|
100
|
+
/** Components that failed to parse. */
|
|
101
|
+
failed: { file: string; message: string }[];
|
|
102
|
+
checker: Checker;
|
|
103
|
+
/** The checker's version, when its package says. */
|
|
104
|
+
checkerVersion?: string;
|
|
105
|
+
/** Milliseconds spent emitting, type-checking and compiling. */
|
|
106
|
+
timings: { emit: number; check: number; compile: number };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** A warning or error the Svelte compiler reports for a component. */
|
|
110
|
+
export interface CompilerDiagnostic {
|
|
111
|
+
severity: "error" | "warning";
|
|
112
|
+
code: string;
|
|
113
|
+
message: string;
|
|
114
|
+
line: number;
|
|
115
|
+
column: number;
|
|
116
|
+
endLine?: number;
|
|
117
|
+
endColumn?: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Diagnostics a project accepts for now, to report only new ones. Each is
|
|
122
|
+
* known by its file, code, message and the text of its line, not the
|
|
123
|
+
* line's number, so an edit above it doesn't make it new.
|
|
124
|
+
*/
|
|
125
|
+
export interface Baseline {
|
|
126
|
+
version: 1;
|
|
127
|
+
diagnostics: BaselineEntry[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface BaselineEntry {
|
|
131
|
+
/** Relative to the workspace, `/`-separated. */
|
|
132
|
+
file: string;
|
|
133
|
+
code: string;
|
|
134
|
+
message: string;
|
|
135
|
+
/** The text of the diagnostic's line, trimmed. */
|
|
136
|
+
line: string;
|
|
137
|
+
/** How many such diagnostics there are. */
|
|
138
|
+
count: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** What a baseline leaves of a run's diagnostics. */
|
|
142
|
+
export interface BaselineResult {
|
|
143
|
+
/** The diagnostics the baseline doesn't have. */
|
|
144
|
+
diagnostics: Diagnostic[];
|
|
145
|
+
/** How many it has, and were left out. */
|
|
146
|
+
known: number;
|
|
147
|
+
/** How many it has that the run no longer reports. */
|
|
148
|
+
fixed: number;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Type-checks Svelte components, as svelte-check does: with a tsconfig
|
|
153
|
+
* (given, or the nearest from the workspace up), the components it
|
|
154
|
+
* includes, and its TS and JS files' errors too; with none, every component
|
|
155
|
+
* under the workspace. Each component becomes TypeScript under `outDir`,
|
|
156
|
+
* next to a tsconfig that extends the project's, a checker runs on it, and
|
|
157
|
+
* each error maps back to its `.svelte` line. Errors in generated code are
|
|
158
|
+
* dropped. Svelte's compiler reports its warnings in the same pass.
|
|
159
|
+
*/
|
|
160
|
+
export declare function typecheck(
|
|
161
|
+
options?: TypecheckOptions,
|
|
162
|
+
): Promise<TypecheckResult>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Checks, then checks again whenever a component, TS or JS file, or a
|
|
166
|
+
* config under the workspace changes, as svelte-check `--watch` does. Runs
|
|
167
|
+
* are incremental. Returns a function that stops watching.
|
|
168
|
+
*/
|
|
169
|
+
export declare function watch(
|
|
170
|
+
options: TypecheckOptions,
|
|
171
|
+
onResult: (result: TypecheckResult | Error) => void,
|
|
172
|
+
): () => void;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* What `svelte/compiler` reports for a component (a11y, unused CSS, invalid
|
|
176
|
+
* markup), without generating code. `<!-- svelte-ignore -->` applies, as in
|
|
177
|
+
* a build. A compile error comes back as one `error`.
|
|
178
|
+
*/
|
|
179
|
+
export declare function compilerDiagnostics(
|
|
180
|
+
source: string,
|
|
181
|
+
filename: string,
|
|
182
|
+
options?: { cwd?: string; svelte?: string },
|
|
183
|
+
): CompilerDiagnostic[];
|
|
184
|
+
|
|
185
|
+
/** A baseline of a run's diagnostics, sorted so it diffs well. */
|
|
186
|
+
export declare function createBaseline(
|
|
187
|
+
diagnostics: Diagnostic[],
|
|
188
|
+
workspace: string,
|
|
189
|
+
): Baseline;
|
|
190
|
+
|
|
191
|
+
/** A run's diagnostics less the baseline's: what's new since it. */
|
|
192
|
+
export declare function applyBaseline(
|
|
193
|
+
diagnostics: Diagnostic[],
|
|
194
|
+
baseline: Baseline,
|
|
195
|
+
workspace: string,
|
|
196
|
+
): BaselineResult;
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./shared-58j2f7by.js";import{compilerDiagnostics2,typecheck2,watch2,createBaseline2,applyBaseline2}from"./shared-7zm6g9d3.js";export{applyBaseline2 as applyBaseline,compilerDiagnostics2 as compilerDiagnostics,createBaseline2 as createBaseline,typecheck2 as typecheck,watch2 as watch};
|
package/package.json
CHANGED
|
@@ -1,8 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-typecheck",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Placeholder package reserving the \"svelte-typecheck\" name.",
|
|
3
|
+
"version": "0.1.1",
|
|
5
4
|
"license": "MIT",
|
|
5
|
+
"description": "A drop-in svelte-check replacement that checks with tsc, tsgo, tsrs or bun check. Up to 11x faster, zero dependencies.",
|
|
6
6
|
"author": "Eric Liu (https://github.com/metonym)",
|
|
7
|
-
"
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./index.js",
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"default": "./index.js"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"svelte-typecheck": "cli.js"
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=22"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/metonym/svelte-typecheck.git"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/metonym/svelte-typecheck",
|
|
29
|
+
"bugs": "https://github.com/metonym/svelte-typecheck/issues",
|
|
30
|
+
"keywords": [
|
|
31
|
+
"svelte",
|
|
32
|
+
"typecheck",
|
|
33
|
+
"typescript",
|
|
34
|
+
"svelte-check",
|
|
35
|
+
"tsgo",
|
|
36
|
+
"tsrs",
|
|
37
|
+
"bun",
|
|
38
|
+
"ci"
|
|
39
|
+
]
|
|
8
40
|
}
|