svelte-typecheck 0.1.6 → 0.1.8
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 +72 -196
- package/cli.js +2 -2
- package/compile-worker.js +1 -0
- package/index.d.ts +0 -5
- package/index.js +1 -1
- package/package.json +1 -1
- package/shared-2ek7s6xw.js +1 -0
- package/shared-7cvnvjc0.js +2 -0
- package/shared-8badht7e.js +4 -0
- package/shared-atsj8zxq.js +4 -0
- package/shared-ebbnnbmn.js +19 -0
- package/shared-exams0w3.js +6 -0
- package/shared-g75sf85w.js +47 -0
- package/shared-msaa239m.js +263 -0
- package/shared-xcpj2ac7.js +1 -0
- package/shared-2xseck5b.js +0 -1
- package/shared-ky3xz37f.js +0 -2
- package/shared-rv2wrjaa.js +0 -334
package/README.md
CHANGED
|
@@ -1,226 +1,102 @@
|
|
|
1
1
|
# svelte-typecheck
|
|
2
2
|
|
|
3
|
-
> Type-check Svelte components with
|
|
3
|
+
> Type-check Svelte components with `bun check`, tsrs, tsgo or `tsc`. Fast, light, svelte-check compatible.
|
|
4
4
|
|
|
5
|
-
svelte-typecheck
|
|
5
|
+
svelte-typecheck is a zero-dependency, drop-in replacement for svelte-check. It takes the same options and prints the same output, but runs a command-line checker on the components instead of TypeScript's language service, which makes it up to 11 times faster. It runs on Node 22+ or Bun.
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
```diff
|
|
8
|
+
- "check": "svelte-check --tsconfig ./tsconfig.json"
|
|
9
|
+
+ "check": "svelte-typecheck --tsconfig ./tsconfig.json"
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
A cold run on carbon-components-svelte (1,200+ components) takes:
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
| Checker | Time | vs. svelte-check |
|
|
15
|
+
| :-------------------- | :----- | :--------------- |
|
|
16
|
+
| svelte-check | 40.5 s | 1× |
|
|
17
|
+
| TypeScript 6 (`tsc`) | 18.9 s | 2.1× |
|
|
18
|
+
| TypeScript 7 (`tsgo`) | 7.9 s | 5.1× |
|
|
19
|
+
| tsrs | 3.7 s | 11.1× |
|
|
20
|
+
| `bun check` | 3.6 s | 11.3× |
|
|
17
21
|
|
|
18
|
-
/
|
|
19
|
-
Error: Property 'nope' does not exist on type '{ text: "primary" | "ghost"; }'. (ts)
|
|
22
|
+
The [benchmarks](https://github.com/metonym/svelte-typecheck/blob/master/docs/benchmarks.md) have more, including runs after a change.
|
|
20
23
|
|
|
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.
|
|
24
|
+
## Quick start
|
|
75
25
|
|
|
76
|
-
```
|
|
77
|
-
-
|
|
78
|
-
|
|
26
|
+
```sh
|
|
27
|
+
bun add -d svelte-typecheck
|
|
28
|
+
bunx svelte-typecheck
|
|
79
29
|
```
|
|
80
30
|
|
|
81
|
-
|
|
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
|
-
| `--strict-baseline` | Exit 1 when diagnostics in the baseline are fixed, until `--update-baseline` drops them, so the baseline only goes down |
|
|
109
|
-
|
|
110
|
-
## Beyond svelte-check
|
|
111
|
-
|
|
112
|
-
What svelte-typecheck does that svelte-check doesn't:
|
|
113
|
-
|
|
114
|
-
| | |
|
|
115
|
-
| :------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
116
|
-
| **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). |
|
|
117
|
-
| **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`, and `--strict-baseline` fails until they are, so it only goes down. 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. |
|
|
118
|
-
| **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. |
|
|
119
|
-
| **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. |
|
|
120
|
-
| **Zero dependencies** | One bundle: it uses the project's own Svelte and checker, and installs nothing else. |
|
|
121
|
-
| **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). |
|
|
122
|
-
| **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. |
|
|
123
|
-
|
|
124
|
-
### Differences from svelte-check
|
|
125
|
-
|
|
126
|
-
- **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.
|
|
127
|
-
- **`COMPLETED <n> FILES`** counts components, not every file in TypeScript's program.
|
|
128
|
-
- **`--diagnostic-sources svelte`** with a tsconfig reports no type errors, as svelte-check's docs say; svelte-check itself reports them.
|
|
129
|
-
- **`--tsgo-experimental-api`** is accepted, and does what `--tsgo` does.
|
|
130
|
-
- **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`.
|
|
131
|
-
- **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`.
|
|
132
|
-
The same order picks what a generic call infers from a union: `render(cond ? A : B, …)` with two components can be an error in one tool and not the other, as each checks its files, and so meets the types, in its own order.
|
|
133
|
-
- **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.
|
|
134
|
-
- **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.
|
|
135
|
-
- **Svelte 3's element types** are Svelte 4's, read from the project's `svelte/elements`, without svelte2tsx's deprecated `svelte.JSX` namespace: a project that augments or references `svelte.JSX` should move to `svelteHTML` or `svelte/elements`. An ARIA attribute's type prints as `Booleanish` where svelte-check spells out `boolean | "true" | "false"`.
|
|
136
|
-
- **Slot content for a Svelte 5 component without a `children` prop** is reported at the tag's name. svelte-check places the error where svelte2tsx's text rewriting happens to anchor its inserted `children`: an attribute's opening quote, the start of a line, or after an attribute.
|
|
137
|
-
- **`--out-dir` outside the project** can't find its packages from the generated code; the default is inside `node_modules`.
|
|
138
|
-
- **`<svelte:element this={tag}>` whose tag may be any element**, such as a component's generic `Tag extends keyof HTMLElementTagNameMap`: svelte-check reports TypeScript's "union type too complex" and checks none of the element's attributes; here its attributes are checked as an element's. An attribute error on it names the attributes' type with the tag widened: `keyof HTMLElementTagNameMap extends Tag ? string : Tag`.
|
|
139
|
-
|
|
140
|
-
### API
|
|
31
|
+
It exits with 1 when there's an error and 0 otherwise.
|
|
141
32
|
|
|
142
|
-
|
|
143
|
-
import {
|
|
144
|
-
applyBaseline,
|
|
145
|
-
compilerDiagnostics,
|
|
146
|
-
createBaseline,
|
|
147
|
-
typecheck,
|
|
148
|
-
} from "svelte-typecheck";
|
|
149
|
-
|
|
150
|
-
const { diagnostics, components, timings } = await typecheck({
|
|
151
|
-
workspace: "src",
|
|
152
|
-
checker: "tsgo",
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// Svelte's own warnings and errors (a11y, unused CSS, invalid markup).
|
|
156
|
-
compilerDiagnostics(source, "Button.svelte");
|
|
157
|
-
|
|
158
|
-
// What's new since a baseline, in the files a change reaches.
|
|
159
|
-
const result = await typecheck({ only: ["src/Button.svelte"] });
|
|
160
|
-
const baseline = createBaseline(result.diagnostics, result.workspace);
|
|
161
|
-
applyBaseline(result.diagnostics, baseline, result.workspace).diagnostics; // []
|
|
162
|
-
```
|
|
33
|
+
## CLI
|
|
163
34
|
|
|
164
|
-
|
|
35
|
+
```sh
|
|
36
|
+
# Check the project with the nearest tsconfig and the project's TypeScript
|
|
37
|
+
svelte-typecheck
|
|
165
38
|
|
|
166
|
-
|
|
39
|
+
# Check with another checker
|
|
40
|
+
svelte-typecheck --checker tsgo
|
|
41
|
+
svelte-typecheck --checker tsrs
|
|
42
|
+
svelte-typecheck --checker bun
|
|
167
43
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
| `tsrs` | [`tsrs`](https://github.com/oxc-project/tsrs) | `tsrs -p … --pretty false` | oxc's Rust port of TypeScript 7 |
|
|
173
|
-
| `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 |
|
|
44
|
+
# Check part of a project
|
|
45
|
+
svelte-typecheck --workspace packages/ui
|
|
46
|
+
svelte-typecheck --tsconfig ./tsconfig.app.json
|
|
47
|
+
svelte-typecheck --components "src/lib/**/*.svelte"
|
|
174
48
|
|
|
175
|
-
|
|
176
|
-
svelte-typecheck
|
|
177
|
-
svelte-typecheck --checker tsgo # or tsrs, or bun
|
|
178
|
-
```
|
|
49
|
+
# Check every component, without a tsconfig, skipping two folders
|
|
50
|
+
svelte-typecheck --no-tsconfig --ignore dist,build
|
|
179
51
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
52
|
+
# Print one line per diagnostic, which is easier for scripts and agents to read
|
|
53
|
+
svelte-typecheck --output machine
|
|
54
|
+
|
|
55
|
+
# Print errors only, or fail on warnings as well
|
|
56
|
+
svelte-typecheck --threshold error
|
|
57
|
+
svelte-typecheck --fail-on-warnings
|
|
185
58
|
|
|
186
|
-
|
|
59
|
+
# Ignore one compiler warning
|
|
60
|
+
svelte-typecheck --compiler-warnings a11y_missing_attribute:ignore
|
|
187
61
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
| 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 |
|
|
192
|
-
| 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 |
|
|
193
|
-
| 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 |
|
|
194
|
-
| 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 |
|
|
62
|
+
# Report only files changed from HEAD, or since the branch left main, and the files that import them
|
|
63
|
+
svelte-typecheck --changed
|
|
64
|
+
svelte-typecheck --since origin/main
|
|
195
65
|
|
|
196
|
-
|
|
66
|
+
# Record the current diagnostics, then report only new ones
|
|
67
|
+
svelte-typecheck --baseline errors.json --update-baseline
|
|
68
|
+
svelte-typecheck --baseline errors.json
|
|
197
69
|
|
|
198
|
-
|
|
70
|
+
# Also fail when fixed diagnostics are still in the baseline
|
|
71
|
+
svelte-typecheck --baseline errors.json --strict-baseline
|
|
199
72
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
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 and a tsconfig that extends yours go to `node_modules/.cache/svelte-typecheck`. The helpers are svelte-typecheck's own, except the few names a message prints, which keep svelte2tsx's (MIT) so messages read as svelte-check's do.
|
|
203
|
-
4. **Check and compile, at once.** One checker process type-checks the whole program while Svelte's compiler reports its warnings beside it.
|
|
204
|
-
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.
|
|
205
|
-
6. **Keep.** What each step learned is kept for the next run.
|
|
73
|
+
# Check again on every change
|
|
74
|
+
svelte-typecheck --watch
|
|
206
75
|
|
|
207
|
-
|
|
76
|
+
# Ignore the cache from earlier runs
|
|
77
|
+
svelte-typecheck --no-incremental
|
|
78
|
+
```
|
|
208
79
|
|
|
209
|
-
|
|
210
|
-
| :------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------- |
|
|
211
|
-
| 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 |
|
|
212
|
-
| Native checkers (TypeScript 7, tsrs, `bun check`) on every core | 3.6 s with `bun check`, 11× faster |
|
|
213
|
-
| sveast, a one-pass parser, instead of svelte2tsx and its source maps | Every component parsed and generated in about 0.4 s |
|
|
214
|
-
| Svelte's compiler alongside the checker, not after it | The slower of the two sets the time, not their sum |
|
|
215
|
-
| 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 |
|
|
80
|
+
## API
|
|
216
81
|
|
|
217
|
-
|
|
82
|
+
```ts
|
|
83
|
+
import { typecheck } from "svelte-typecheck";
|
|
218
84
|
|
|
219
|
-
|
|
220
|
-
- **No CSS diagnostics.**
|
|
85
|
+
const { diagnostics } = await typecheck({ checker: "tsgo" });
|
|
221
86
|
|
|
222
|
-
|
|
87
|
+
for (const d of diagnostics) {
|
|
88
|
+
// file is absolute; line and column are 1-based, in the .svelte source
|
|
89
|
+
console.log(
|
|
90
|
+
`${d.file}:${d.line}:${d.column} ${d.severity} ${d.code} ${d.message}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
223
94
|
|
|
224
|
-
##
|
|
95
|
+
## Docs
|
|
225
96
|
|
|
226
|
-
|
|
97
|
+
- [CLI options](https://github.com/metonym/svelte-typecheck/blob/master/docs/cli.md)
|
|
98
|
+
- [API](https://github.com/metonym/svelte-typecheck/blob/master/docs/api.md)
|
|
99
|
+
- [Checkers](https://github.com/metonym/svelte-typecheck/blob/master/docs/checkers.md)
|
|
100
|
+
- [Compared with svelte-check](https://github.com/metonym/svelte-typecheck/blob/master/docs/svelte-check.md)
|
|
101
|
+
- [Benchmarks](https://github.com/metonym/svelte-typecheck/blob/master/docs/benchmarks.md)
|
|
102
|
+
- [How it works](https://github.com/metonym/svelte-typecheck/blob/master/docs/architecture.md)
|
package/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import"./shared-
|
|
2
|
+
import"./shared-7cvnvjc0.js";import{EmitError,typecheck2,watch2,createBaseline2,applyBaseline2}from"./shared-msaa239m.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
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
4
|
`).slice(d.line,endLine-1),last.slice(0,endColumn-1)].join(`
|
|
5
5
|
`))+last.slice(endColumn-1),before=d.line>1?`${lineOf(text,d.line-1)}
|
|
@@ -70,6 +70,6 @@ svelte-typecheck's own:
|
|
|
70
70
|
|
|
71
71
|
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}
|
|
72
72
|
|
|
73
|
-
${HELP}`),1}if(values.help)return console.log(HELP),0;if(values.version){let{version}=await import("./shared-
|
|
73
|
+
${HELP}`),1}if(values.help)return console.log(HELP),0;if(values.version){let{version}=await import("./shared-2ek7s6xw.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;let strict=values["strict-baseline"];if(strict&&!baselinePath)return out.failure(Error("--strict-baseline needs --baseline <file>")),1;for(let flag of["update-baseline","strict-baseline"])if(values[flag]&&(values.changed||values.since))return out.failure(Error(`--${flag} 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}
|
|
74
74
|
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)}
|
|
75
75
|
`),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||strict&&(known?.fixed??0)>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},"strict-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));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{compileAll}from"./shared-exams0w3.js";import{parentPort}from"node:worker_threads";parentPort?.on("message",async({id,request})=>{try{parentPort?.postMessage({id,results:await compileAll(request)})}catch(error){parentPort?.postMessage({id,error:error instanceof Error?error.message:String(error)})}});
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
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
1
|
/** A type checker that reads a tsconfig and prints errors as `tsc` does. */
|
|
7
2
|
export type Checker = "bun" | "tsrs" | "tsgo" | "tsc";
|
|
8
3
|
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./shared-
|
|
1
|
+
import"./shared-7cvnvjc0.js";import{typecheck2,watch2,createBaseline2,applyBaseline2}from"./shared-msaa239m.js";import{compilerDiagnostics2}from"./shared-exams0w3.js";export{applyBaseline2 as applyBaseline,compilerDiagnostics2 as compilerDiagnostics,createBaseline2 as createBaseline,typecheck2 as typecheck,watch2 as watch};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-typecheck",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"license": "MIT",
|
|
5
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)",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{version2,package_default}from"./shared-7cvnvjc0.js";export{package_default as default,version2 as version};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var REGEX_LANG_ATTRIBUTE=/<!--[\s\S]*?-->|<script\s+(?:[^>]*|(?:[^=>'"/]+=(?:"[^"]*"|'[^']*'|[^>\s]+)\s+)*)lang=(["'])?([^"' >]+)\1[^>]*>/y;function withoutByteOrderMark(source){return source.charCodeAt(0)===65279?source.slice(1):source}function isDigit(code){return code>=48&&code<=57}function isWhitespace(code){if(code===32||code<=13&&code>=9)return!0;if(code<160)return!1;return code===160||code===5760||code>=8192&&code<=8202||code===8232||code===8233||code===8239||code===8287||code===12288||code===65279}function skipWhitespace(source,from){let index=from;while(index<source.length&&isWhitespace(source.charCodeAt(index)))index++;return index}function isTypeScript(source){let index=source.indexOf("<");while(index!==-1){let next=source.charCodeAt(index+1);if(next===33||next===115){REGEX_LANG_ATTRIBUTE.lastIndex=index;let match=REGEX_LANG_ATTRIBUTE.exec(source);if(match){if(next===115)return match[2]==="ts";index=source.indexOf("<",REGEX_LANG_ATTRIBUTE.lastIndex);continue}}index=source.indexOf("<",index+1)}return!1}function closingScriptTag(source,from){let close=source.indexOf("</script",from);while(close!==-1){if(source.charCodeAt(skipWhitespace(source,close+8))===GT)return close;close=source.indexOf("</script",close+8)}return-1}function closingScriptTagEnd(source,close){return skipWhitespace(source,close+8)+1}var VOID_ELEMENTS=new Set("area base br col command embed hr img input keygen link meta param source track wbr".split(" "));function isVoid(name){return VOID_ELEMENTS.has(name)||name.charCodeAt(0)===33&&name.toLowerCase()==="!doctype"}function styleContentEnd(source,from){let index=from;while(index<source.length){let code=source.charCodeAt(index);if(code===47&&source.charCodeAt(index+1)===42){let end=source.indexOf("*/",index+2);index=end===-1?source.length:end+2}else if(code===34||code===39){index++;while(index<source.length){let next=source.charCodeAt(index);if(next===code||next===10)break;index+=next===92?2:1}index++}else if(code===60&&source.startsWith("</style",index))break;else index++}return Math.min(index,source.length)}var DOUBLE_QUOTE=34,SINGLE_QUOTE=39,SLASH=47,EQUALS=61,GT=62,isQuote=(code)=>code===DOUBLE_QUOTE||code===SINGLE_QUOTE;function nameEnd(source,from,isAttribute){let i=from;for(;i<source.length;i++){let code=source.charCodeAt(i);if(isWhitespace(code)||code===SLASH||code===GT)break;if(isAttribute&&(isQuote(code)||code===EQUALS))break}return i}function endsUnquotedValue(source,i){let code=source.charCodeAt(i);return isWhitespace(code)||isQuote(code)||code===EQUALS||code===60||code===GT||code===96||code===SLASH&&source.charCodeAt(i+1)===GT}var STATEMENT_START=0,OPERATOR=1,BLOCK_OPENER=2,VALUE=3,PAREN=0,HEAD_PAREN=1,BLOCK=2,OBJECT=3,TEMPLATE=4,HEAD=4,IMPORT=5,EXPORT=6,REQUIRE=7,KEYWORDS={await:OPERATOR,case:OPERATOR,default:OPERATOR,delete:OPERATOR,extends:OPERATOR,in:OPERATOR,instanceof:OPERATOR,new:OPERATOR,of:OPERATOR,return:OPERATOR,throw:OPERATOR,typeof:OPERATOR,void:OPERATOR,yield:OPERATOR,do:BLOCK_OPENER,else:BLOCK_OPENER,finally:BLOCK_OPENER,try:BLOCK_OPENER,for:HEAD,if:HEAD,while:HEAD,with:HEAD,import:IMPORT,export:EXPORT,require:REQUIRE},LONGEST_KEYWORD=10,KEYWORDS_BY_KEY=Array(keywordKey(128,0)).fill(null);for(let entry of Object.entries(KEYWORDS)){let key=keywordKey(entry[0].charCodeAt(0),entry[0].length),entries=KEYWORDS_BY_KEY[key]??[];entries.push(entry),KEYWORDS_BY_KEY[key]=entries}function keywordKey(first,length){return first*(LONGEST_KEYWORD+1)+length}function wordKind(source,start,end){let first=source.charCodeAt(start);if(first>=128||end-start>LONGEST_KEYWORD)return VALUE;let key=keywordKey(first,end-start),entries=KEYWORDS_BY_KEY[key];if(entries===null)return VALUE;for(let i=0;i<entries.length;i++)if(source.startsWith(entries[i][0],start))return entries[i][1];return VALUE}var ASCII_WORD=new Uint8Array(128);for(let range of["az","AZ","09","__","$$","\\\\"])for(let code=range.charCodeAt(0);code<=range.charCodeAt(1);code++)ASCII_WORD[code]=1;function isWordCode(code){return code>=128?!isWhitespace(code):ASCII_WORD[code]===1}function scan(source,localExports,parseAt,exportLists=!1){tokenize(source,lastStatementKeyword(source,localExports,exportLists),localExports,exportLists,parseAt,void 0,void 0)}function tokenize(source,last,localExports,exportLists,parseAt,literal,call){let stack=[],pos=source.startsWith("#!")?lineEnd(source,2):0,prev=STATEMENT_START,afterDot=!1,head=!1,decorators=-1,statementEnd=()=>{if(prev=STATEMENT_START,stack.length===0)decorators=-1};while(pos<=last){let code=source.charCodeAt(pos);if(code===32||code===10||isWhitespace(code)){pos++;continue}if(code===47){let end=commentEnd(source,pos);if(end!==-1){pos=end;continue}}let wasAfterDot=afterDot,wasHead=head;if(afterDot=!1,head=!1,isWordCode(code)||code===35){let start=pos;pos=wordEnd(source,pos+1);let kind=wasAfterDot?VALUE:wordKind(source,start,pos);if(call!==void 0&&(kind===IMPORT||kind===REQUIRE))call(start,prev===STATEMENT_START||prev===VALUE);if(parseAt!==void 0&&stack.length===0&&(kind===EXPORT?localExports||isReexport(source,pos,exportLists):kind===IMPORT&&isImportDeclaration(source,pos)))pos=Math.max(pos,parseAt(decorators!==-1&&kind===EXPORT?decorators:start,start)),statementEnd();else if(kind===EXPORT)prev=BLOCK_OPENER;else if(kind===HEAD)head=!0,prev=VALUE;else prev=kind===OPERATOR||kind===BLOCK_OPENER?kind:VALUE;continue}switch(pos++,code){case 34:case 39:{let start=pos-1;pos=stringEnd(source,pos,code),literal?.(start,pos,!1),prev=VALUE;break}case 96:{let start=pos;pos=templateEnd(source,pos,stack),literal?.(start,quasiEnd(source,pos),!0),prev=source.charCodeAt(pos-1)===123?OPERATOR:VALUE;break}case 47:{let end=prev===VALUE?-1:regexEnd(source,pos);if(end===-1)prev=OPERATOR;else pos=wordCodesEnd(source,end),prev=VALUE;break}case 40:stack.push(wasHead?HEAD_PAREN:PAREN),prev=OPERATOR;break;case 41:prev=stack.pop()===HEAD_PAREN?BLOCK_OPENER:VALUE;break;case 123:stack.push(prev===OPERATOR?OBJECT:BLOCK),prev=STATEMENT_START;break;case 125:{let open=stack.pop();if(open===TEMPLATE){let start=pos;pos=templateEnd(source,pos,stack),literal?.(start,quasiEnd(source,pos),!0),prev=source.charCodeAt(pos-1)===123?OPERATOR:VALUE}else if(open===OBJECT)prev=VALUE;else statementEnd();break}case 59:statementEnd();break;case 44:prev=stack[stack.length-1]===OBJECT?STATEMENT_START:OPERATOR;break;case 93:prev=VALUE;break;case 46:if(isDigit(source.charCodeAt(pos)))pos=wordCodesEnd(source,pos),prev=VALUE;else if(source.startsWith("..",pos))pos+=2,prev=OPERATOR;else afterDot=!0,prev=OPERATOR;break;case 63:if(source.charCodeAt(pos)===46&&!isDigit(source.charCodeAt(pos+1)))pos++,afterDot=!0;prev=OPERATOR;break;case 33:prev=prev===VALUE&&!isWhitespace(source.charCodeAt(pos-2))?VALUE:OPERATOR;break;case 43:case 45:if(source.charCodeAt(pos)===code&&prev===VALUE)pos++;else prev=OPERATOR;break;case 61:if(prev=source.charCodeAt(pos)===62?BLOCK_OPENER:OPERATOR,prev===BLOCK_OPENER)pos++;break;case 64:if(stack.length===0&&decorators===-1)decorators=pos-1;prev=OPERATOR;break;default:prev=OPERATOR}}}function closingBracket(source,from,word){let length=source.length,stack=[],pos=from,prev=OPERATOR,afterDot=!1;while(pos<length){let code=source.charCodeAt(pos);if(code===32||code===10||isWhitespace(code)){pos++;continue}if(code===47){let end=commentEnd(source,pos);if(end!==-1){pos=end;continue}}let wasAfterDot=afterDot;if(afterDot=!1,isWordCode(code)||code===35){let start=pos;if(pos=wordEnd(source,pos+1),!wasAfterDot&&word?.(start,pos))return-1;let kind=wasAfterDot?VALUE:wordKind(source,start,pos);prev=kind===OPERATOR||kind===BLOCK_OPENER||kind===HEAD?OPERATOR:VALUE;continue}switch(pos++,code){case 34:case 39:pos=stringEnd(source,pos,code),prev=VALUE;break;case 96:pos=templateEnd(source,pos,stack),prev=source.charCodeAt(pos-1)===123?OPERATOR:VALUE;break;case 47:{let end=prev===VALUE?-1:regexEnd(source,pos);if(end===-1)prev=OPERATOR;else pos=wordCodesEnd(source,end),prev=VALUE;break}case 40:stack.push(PAREN),prev=OPERATOR;break;case 41:if(stack.length===0)return pos-1;stack.pop(),prev=VALUE;break;case 123:stack.push(prev===OPERATOR?OBJECT:BLOCK),prev=STATEMENT_START;break;case 125:{if(stack.length===0)return pos-1;let open=stack.pop();if(open===TEMPLATE)pos=templateEnd(source,pos,stack),prev=source.charCodeAt(pos-1)===123?OPERATOR:VALUE;else prev=open===OBJECT?VALUE:STATEMENT_START;break}case 93:prev=VALUE;break;case 46:if(isDigit(source.charCodeAt(pos)))pos=wordCodesEnd(source,pos),prev=VALUE;else if(source.startsWith("..",pos))pos+=2,prev=OPERATOR;else afterDot=!0,prev=OPERATOR;break;case 63:if(source.charCodeAt(pos)===46&&!isDigit(source.charCodeAt(pos+1)))pos++,afterDot=!0;prev=OPERATOR;break;case 33:prev=prev===VALUE&&!isWhitespace(source.charCodeAt(pos-2))?VALUE:OPERATOR;break;case 43:case 45:if(source.charCodeAt(pos)===code&&prev===VALUE)pos++;else prev=OPERATOR;break;case 61:if(source.charCodeAt(pos)===62)pos++;prev=OPERATOR;break;default:prev=OPERATOR}}return length}function isLineBreak(code){return code===10||code===13||code===8232||code===8233}function lineEnd(source,pos){for(let i=pos;i<source.length;i++)if(isLineBreak(source.charCodeAt(i)))return i;return source.length}function commentEnd(source,slash){let next=source.charCodeAt(slash+1);if(next===47)return lineEnd(source,slash+2);if(next!==42)return-1;let end=source.indexOf("*/",slash+2);return end===-1?source.length:end+2}function wordEnd(source,pos){let i=pos;while(i<source.length){let code=source.charCodeAt(i);if(code===92)i+=2;else if(isWordCode(code))i++;else break}return i}function wordCodesEnd(source,pos){let i=pos;while(i<source.length&&isWordCode(source.charCodeAt(i)))i++;return i}function stringEnd(source,pos,quote){for(let i=pos;i<source.length;i++){let code=source.charCodeAt(i);if(code===quote)return i+1;if(code===92)i+=source.startsWith(`\r
|
|
2
|
+
`,i+1)?2:1;else if(code===10||code===13)return i}return source.length}function templateEnd(source,pos,stack){for(let i=pos;i<source.length;i++){let code=source.charCodeAt(i);if(code===96)return i+1;if(code===92)i++;else if(code===36&&source.charCodeAt(i+1)===123)return stack.push(TEMPLATE),i+2}return source.length}function quasiEnd(source,pos){let code=source.charCodeAt(pos-1);if(code===96)return pos-1;if(code===123&&source.charCodeAt(pos-2)===36)return pos-2;return pos}function regexEnd(source,pos){let inClass=!1;for(let i=pos;i<source.length;i++){let code=source.charCodeAt(i);if(isLineBreak(code))return-1;if(code===92)i++;else if(code===91)inClass=!0;else if(code===93)inClass=!1;else if(code===47&&!inClass)return i+1}return-1}function skipTrivia(source,pos){let i=pos;while(i<source.length){let code=source.charCodeAt(i);if(isWhitespace(code)){i++;continue}let end=code===47?commentEnd(source,i):-1;if(end===-1)return i;i=end}return source.length}function isWordAt(source,pos,word){return source.charCodeAt(pos)===word.charCodeAt(0)&&source.startsWith(word,pos)&&!isWordCode(source.charCodeAt(pos+word.length))}function isImportDeclaration(source,pos){let code=source.charCodeAt(skipTrivia(source,pos));return code!==40&&code!==46}function isReexport(source,pos,lists){let i=skipTrivia(source,pos);if(isWordAt(source,i,"import"))return!0;if(isWordAt(source,i,"type"))i=skipTrivia(source,i+4);let code=source.charCodeAt(i);if(code===42)return!0;if(code!==123)return!1;if(lists)return!0;for(i++;i<source.length;i++){let inner=source.charCodeAt(i);if(inner===125)break;if(inner===34||inner===39)i=stringEnd(source,i+1,inner)-1;else if(inner===47)i=Math.max(i,skipTrivia(source,i)-1)}return isWordAt(source,skipTrivia(source,i+1),"from")}var STATEMENT_KEYWORD=/import|export/g;function lastStatementKeyword(source,localExports,exportLists){let last=-1;STATEMENT_KEYWORD.lastIndex=0;for(let match=STATEMENT_KEYWORD.exec(source);match!==null;match=STATEMENT_KEYWORD.exec(source)){let start=match.index,end=start+6;if(!isWordCode(source.charCodeAt(start-1))&&!isWordCode(source.charCodeAt(end))&&(source.charCodeAt(start)===105?isImportDeclaration(source,end):localExports||isReexport(source,end,exportLists)))last=start}return last}var AUTOCLOSING_CHILDREN={li:["li"],dt:["dt","dd"],dd:["dt","dd"],p:"address article aside blockquote div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav ol p pre section table ul".split(" "),rt:["rt","rp"],rp:["rt","rp"],optgroup:["optgroup"],option:["option","optgroup"],thead:["tbody","tfoot"],tbody:["tbody","tfoot"],tfoot:["tbody"],tr:["tr","tbody"],td:["td","th","tr"],th:["td","th","tr"]};function closingTagOmitted(current,next){return Object.hasOwn(AUTOCLOSING_CHILDREN,current)&&AUTOCLOSING_CHILDREN[current].includes(next)}var BLOCK2="{",LT=60,GT2=62,SLASH2=47,EQUALS2=61,BRACE=123,REGEX_CLOSING_STYLE_TAG_END=/\s*>/y,REGEX_CLOSING_TEXTAREA=/<\/textarea(\s[^>]*)?>/iy,SECTION_TAG_NAMES=["cript","tyle","velte:options"],CLOSING_OPTIONS_TAG="</svelte:options";function lexComponent2(input){let source=withoutByteOrderMark(input).trimEnd();return lex(source,isTypeScript(source),null)}function topLevelTags(source){let found={tags:[],comments:[]};return lex(source,!1,found),found}function lex(source,typescript,found){let component={typescript,instance:null,module:null,css:null,options:null},last=lastSectionTag(source),stack=[],i=0;while(i<=last){let code=source.charCodeAt(i);if(code===LT)i=readTag(source,i,stack,component,found);else if(code===BRACE)i=readMustache(source,i,stack);else i++}return component}function lastSectionTag(source){let last=-1,i=source.indexOf("<s");while(i!==-1){let end=sectionTagNameEnd(source,i+2);if(end!==-1){let code=source.charCodeAt(end);if(end===source.length||isWhitespace(code)||code===SLASH2||code===GT2)last=i}i=source.indexOf("<s",i+2)}return last}function sectionTagNameEnd(source,from){for(let name of SECTION_TAG_NAMES)if(source.startsWith(name,from))return from+name.length;return-1}function expressionEnd(source,from){return Math.min(closingBracket(source,from)+1,source.length)}function readMustache(source,start,stack){let i=skipWhitespace(source,start+1),code=source.charCodeAt(i),next=source.charCodeAt(i+1);if(code===35||code===58||code===64||code===SLASH2&&next!==SLASH2&&next!==42){i++;while(i<source.length){let letter=source.charCodeAt(i);if(letter<97||letter>122)break;i++}if(code===35)stack.push(BLOCK2);else if(code===SLASH2){let open=stack.lastIndexOf(BLOCK2);if(open!==-1)stack.length=open}}return expressionEnd(source,i)}function readTag(source,start,stack,component,found){if(source.startsWith("!--",start+1)){let close=source.indexOf("-->",start+4),end=close===-1?source.length:close+3;if(found&&stack.length===0)found.comments.push(start,end);return end}if(source.charCodeAt(start+1)===SLASH2){let nameStart=start+2,name=source.slice(nameStart,nameEnd(source,nameStart,!1)),open=stack.lastIndexOf(name);if(open!==-1)stack.length=open;return eatGreaterThan(source,skipWhitespace(source,nameStart+name.length))}let name=source.slice(start+1,nameEnd(source,start+1,!1)),i=skipWhitespace(source,start+1+name.length),parent=stack[stack.length-1];if(parent!==void 0&&closingTagOmitted(parent,name))stack.pop();let topLevel=stack.length===0;if(found&&topLevel&&(name==="script"||name==="style"||name==="svelte:options"))found.tags.push(start);if(topLevel&&(name==="script"||name==="style")){let attributes=[];if(i=eatGreaterThan(source,readStaticAttributes(source,i,attributes)),name==="script"){let script=readScript(source,start,i,attributes);if(script.context==="module")component.module??=script;else component.instance??=script;return script.end}let css=readStyle(source,start,i,attributes);return component.css??=css,css.end}let attributes=topLevel&&name==="svelte:options"?[]:null;if(i=readAttributes(source,i,attributes),source.charCodeAt(i)===SLASH2||isVoid(name)){if(source.charCodeAt(i)===SLASH2)i++;i=eatGreaterThan(source,i)}else{if(i=eatGreaterThan(source,i),name==="textarea")return textareaEnd(source,i);if(name==="script"||name==="style"){let closer=`</${name}>`,close=source.indexOf(closer,i);return close===-1?source.length:close+closer.length}if(attributes&&source.startsWith(CLOSING_OPTIONS_TAG,i))i=eatGreaterThan(source,skipWhitespace(source,i+CLOSING_OPTIONS_TAG.length));else return stack.push(name),i}if(attributes)component.options??={start,end:i,attributes};return i}function eatGreaterThan(source,i){return source.charCodeAt(i)===GT2?i+1:i}function readScript(source,start,contentStart,attributes){let close=closingScriptTag(source,contentStart),contentEnd=close===-1?source.length:close,module=attributes.some((attribute)=>attribute.name==="module"||attribute.name==="context");return{start,end:close===-1?source.length:closingScriptTagEnd(source,close),context:module?"module":"default",attributes,content:{start:contentStart,end:contentEnd}}}function readStyle(source,start,contentStart,attributes){let contentEnd=styleContentEnd(source,contentStart),end=contentEnd;if(source.startsWith("</style",end)){end+=7,REGEX_CLOSING_STYLE_TAG_END.lastIndex=end;let close=REGEX_CLOSING_STYLE_TAG_END.exec(source);if(close)end+=close[0].length}return{start,end,attributes,content:{start:contentStart,end:contentEnd}}}function readStaticAttributes(source,from,into){let i=from;for(;;){let start=i,end=nameEnd(source,i,!0);if(end===start)return i;i=end;let value=!0;if(source.charCodeAt(i)===EQUALS2){let at=skipWhitespace(source,i+1),quote=source.charCodeAt(at),valueEnd=-1;if(isQuote(quote)){let close=source.indexOf(source[at],at+1);if(close!==-1)valueEnd=close+1}if(valueEnd===-1){valueEnd=at;while(valueEnd<source.length&&source.charCodeAt(valueEnd)!==GT2&&!isWhitespace(source.charCodeAt(valueEnd)))valueEnd++}let quotes=isQuote(quote)?1:0;value=source.slice(at+quotes,valueEnd-quotes),i=valueEnd}into.push({name:source.slice(start,end),value,start,end:i}),i=skipWhitespace(source,i)}}function readAttributes(source,from,into){let i=from;for(;;){for(;;){if(source.startsWith("/*",i)){let end=source.indexOf("*/",i+2);i=end===-1?source.length:end+2}else if(source.startsWith("//",i)){let end=source.indexOf(`
|
|
3
|
+
`,i+2);i=end===-1?source.length:end}else break;i=skipWhitespace(source,i)}let start=i;if(source.charCodeAt(i)===BRACE){i=skipWhitespace(source,expressionEnd(source,i+1));continue}let nameEndAt=nameEnd(source,i,!0);if(nameEndAt===start)return i;let end=nameEndAt,value=!0;if(i=skipWhitespace(source,nameEndAt),source.charCodeAt(i)===EQUALS2){let at=skipWhitespace(source,i+1);end=source.startsWith("/>",at)?at+1:attributeValueEnd(source,at),value=isQuote(source.charCodeAt(at))?source.slice(at+1,Math.max(at+1,end-1)):source.slice(at,end),i=skipWhitespace(source,end)}into?.push({name:source.slice(start,nameEndAt),value,start,end})}}function attributeValueEnd(source,from){let quote=source.charCodeAt(from);if(isQuote(quote)){let i=from+1;while(i<source.length){let code=source.charCodeAt(i);if(code===quote)return i+1;i=code===BRACE?expressionEnd(source,i+1):i+1}return source.length}let i=from;while(i<source.length&&!endsUnquotedValue(source,i))i=source.charCodeAt(i)===BRACE?expressionEnd(source,i+1):i+1;return i}function textareaEnd(source,from){let i=from;while(i<source.length){let code=source.charCodeAt(i);if(code===LT){if(REGEX_CLOSING_TEXTAREA.lastIndex=i,REGEX_CLOSING_TEXTAREA.test(source))return REGEX_CLOSING_TEXTAREA.lastIndex}i=code===BRACE?expressionEnd(source,i+1):i+1}return source.length}
|
|
4
|
+
export{withoutByteOrderMark,isDigit,isWhitespace,skipWhitespace,isTypeScript,closingScriptTag,closingScriptTagEnd,isVoid,styleContentEnd,isQuote,nameEnd,endsUnquotedValue,isWordCode,scan,closingBracket,lineEnd,wordCodesEnd,skipTrivia,isWordAt,closingTagOmitted,lexComponent2,topLevelTags};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
class Output{code="";copies=[];spans=[];source;constructor(source){this.source=source}raw(text){return this.code+=text,this}copy(start,end){if(end>start)this.copies.push([this.code.length,start,end-start]),this.code+=this.source.slice(start,end);return this}from(offset,fn){let start=this.code.length;return fn(),this.spans.push([start,this.code.length,offset]),this}toSource(offset){let lo=0,hi=this.copies.length-1;while(lo<=hi){let mid=lo+hi>>1,[gen,src,len]=this.copies[mid];if(offset<gen)hi=mid-1;else if(offset>=gen+len)lo=mid+1;else return src+offset-gen}let best;for(let span of this.spans){if(offset<span[0]||offset>=span[1])continue;if(!best||span[1]-span[0]<best[1]-best[0])best=span}return best?best[2]:null}}function createLocator(text){let starts=[0];for(let i=text.indexOf(`
|
|
2
|
+
`);i!==-1;i=text.indexOf(`
|
|
3
|
+
`,i+1))starts.push(i+1);return{position(offset){let lo=0,hi=starts.length-1;while(lo<hi){let mid=lo+hi+1>>1;if(starts[mid]<=offset)lo=mid;else hi=mid-1}return{line:lo+1,column:offset-starts[lo]+1}},offset(line,column){return(starts[line-1]??text.length)+column-1}}}
|
|
4
|
+
export{Output,createLocator};
|