sveast 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -15,6 +15,174 @@ export declare function isValidType(text: string, options?: {
15
15
  inline?: boolean;
16
16
  }): boolean;
17
17
 
18
+ /** A module specifier: the string after `from`, or after `import` in `import "a"`. */
19
+ export interface LexedSource {
20
+ /** The string's value, with escapes decoded. */
21
+ value: string;
22
+ /** The offset of the opening quote. */
23
+ start: number;
24
+ /** The offset after the closing quote. */
25
+ end: number;
26
+ }
27
+
28
+ /** A name an `import` binds. */
29
+ export interface LexedImportSpecifier {
30
+ /** `"default"` for `a` in `import a from`, `"namespace"` for `* as a`, `"named"` for a name in braces. */
31
+ kind: "default" | "namespace" | "named";
32
+ /** The name in the imported module: `"default"`, `"*"` for a namespace, or the name before `as`, with a string's value for `"a-b" as c`. */
33
+ imported: string;
34
+ /** The name it's bound to in this module. */
35
+ local: string;
36
+ /** Whether it's only a type: in `import type`, or with `type` before it. */
37
+ typeOnly: boolean;
38
+ /** The offset of the name, of `*`, or of `type` before the name. */
39
+ start: number;
40
+ /** The offset after the local name. */
41
+ end: number;
42
+ }
43
+
44
+ /** A name an `export … from` re-exports. */
45
+ export interface LexedExportSpecifier {
46
+ /** `"all"` for `export *`, `"namespace"` for `export * as a`, `"named"` for a name in braces. */
47
+ kind: "all" | "namespace" | "named";
48
+ /** The name in the other module: `"*"` for `all` and `namespace`, or the name before `as`, with a string's value for `"a-b" as c`. */
49
+ local: string;
50
+ /** The name it's exported as, or `null` for `export *`. */
51
+ exported: string | null;
52
+ /** Whether it's only a type: in `export type`, or with `type` before it. */
53
+ typeOnly: boolean;
54
+ /** The offset of the name, of `*`, or of `type` before the name. */
55
+ start: number;
56
+ /** The offset after the exported name, or after `*` for `export *`. */
57
+ end: number;
58
+ }
59
+
60
+ interface LexedStatementBase {
61
+ /** The offset of `import` or `export`. */
62
+ start: number;
63
+ /** The offset after the statement's `;`, or its last token without one. */
64
+ end: number;
65
+ /** The module it imports from, or `null` for a statement the lexer doesn't recognize. */
66
+ source: LexedSource | null;
67
+ /** Whether it's `import type` or `export type`. */
68
+ typeOnly: boolean;
69
+ }
70
+
71
+ /** An `import` statement. */
72
+ export interface LexedImport extends LexedStatementBase {
73
+ kind: "import";
74
+ specifiers: LexedImportSpecifier[];
75
+ }
76
+
77
+ /** An `export … from` statement. */
78
+ export interface LexedExport extends LexedStatementBase {
79
+ kind: "export";
80
+ specifiers: LexedExportSpecifier[];
81
+ }
82
+
83
+ export type LexedStatement = LexedImport | LexedExport;
84
+
85
+ /**
86
+ * A module's top-level `import` statements and `export … from`
87
+ * re-exports, read without a parser: each statement's offsets, its
88
+ * source and the names it imports or re-exports. It finds statements as
89
+ * {@link parseImportsExports} does with `localExports: false`, and on
90
+ * every statement that accepts, gives the same offsets, sources and names,
91
+ * but it doesn't check syntax and never throws. A statement it can't read,
92
+ * including TypeScript's `import a = require("a")`, is returned with
93
+ * `source: null` and no specifiers, ending where it stopped reading.
94
+ * TypeScript's `type` forms are always read.
95
+ */
96
+ export declare function lexImportsExports(source: string): LexedStatement[];
97
+
98
+ /** An attribute of a top-level `<script>`, `<style>` or `<svelte:options>`. */
99
+ export interface LexedAttribute {
100
+ name: string;
101
+ /**
102
+ * The value as written, without its quotes: character references
103
+ * aren't decoded, and an expression keeps its braces, as in `"{true}"`
104
+ * for `runes={true}`. `true` for an attribute without a value.
105
+ */
106
+ value: string | true;
107
+ /** The offset of the name. */
108
+ start: number;
109
+ /** The offset after the value, or after the name without one. */
110
+ end: number;
111
+ }
112
+
113
+ /** The text between a top-level element's tags. */
114
+ export interface LexedContent {
115
+ start: number;
116
+ end: number;
117
+ }
118
+
119
+ /** A top-level `<script>`. */
120
+ export interface LexedScript {
121
+ /** The offset of `<script`. */
122
+ start: number;
123
+ /** The offset after `</script>`. */
124
+ end: number;
125
+ /** `"module"` for `<script module>` or `<script context="module">`. */
126
+ context: "default" | "module";
127
+ attributes: LexedAttribute[];
128
+ content: LexedContent;
129
+ }
130
+
131
+ /** The top-level `<style>`. */
132
+ export interface LexedStyle {
133
+ /** The offset of `<style`. */
134
+ start: number;
135
+ /** The offset after `</style>`. */
136
+ end: number;
137
+ attributes: LexedAttribute[];
138
+ content: LexedContent;
139
+ }
140
+
141
+ /** `<svelte:options>`. */
142
+ export interface LexedOptions {
143
+ /** The offset of `<svelte:options`. */
144
+ start: number;
145
+ /** The offset after `/>` or `</svelte:options>`. */
146
+ end: number;
147
+ attributes: LexedAttribute[];
148
+ }
149
+
150
+ /** A component's top-level sections, as {@link lexComponent} finds them. */
151
+ export interface LexedComponent {
152
+ /**
153
+ * Whether `parse` reads the component as TypeScript, which needs the
154
+ * TypeScript plugin: svelte decides it from the first `<script>` with a
155
+ * `lang`, so this is `true` when that one has `lang="ts"`.
156
+ */
157
+ typescript: boolean;
158
+ /** The `<script>` without `module`, as `parse`'s `instance`. */
159
+ instance: LexedScript | null;
160
+ /** The `<script module>`, as `parse`'s `module`. */
161
+ module: LexedScript | null;
162
+ /** The `<style>`, as `parse`'s `css`. */
163
+ css: LexedStyle | null;
164
+ /** `<svelte:options>`, as `parse`'s `options`. */
165
+ options: LexedOptions | null;
166
+ }
167
+
168
+ /**
169
+ * A component's top-level `<script>`, `<script module>`, `<style>` and
170
+ * `<svelte:options>`, with their attributes and the offsets of their tags
171
+ * and content, read without a parser: e.g. to find a component's
172
+ * language or imports, or to rewrite its scripts, without parsing the
173
+ * markup. The offsets are `parse`'s, so they're into the source without
174
+ * a leading byte order mark.
175
+ *
176
+ * The markup is skipped by tracking only tags, attribute values, blocks
177
+ * and the brackets, strings, comments and templates of each `{…}`
178
+ * expression, so a `<script>` inside an element, a block, a string or a
179
+ * comment isn't one. It stops after the last `<script`, `<style` or
180
+ * `<svelte:options`. Where `parse` accepts the component, the sections
181
+ * are the same as its `instance`, `module`, `css` and `options`; it
182
+ * doesn't check syntax and never throws.
183
+ */
184
+ export declare function lexComponent(input: string): LexedComponent;
185
+
18
186
  /**
19
187
  * Options for {@link parse}. The defaults give svelte's own output, minus
20
188
  * `loc` and `name_loc`.
@@ -1776,6 +1944,56 @@ interface Location {
1776
1944
  character: number;
1777
1945
  }
1778
1946
 
1947
+ /**
1948
+ * A function from an offset in `text` to its line, from 1, and column,
1949
+ * from 0, in UTF-16 code units: what `loc: true` gives the node that
1950
+ * starts there, without parsing with `loc`. Lines end at `\n`, as in
1951
+ * svelte's markup `loc` and in `ParseError`; acorn's `loc` in
1952
+ * scripts and modules also ends them at a `\r` not followed by `\n`, at
1953
+ * U+2028 and at U+2029. `parse` drops a leading byte order mark, so pass
1954
+ * the text without it. Lines are found on the first call; lookups in
1955
+ * source order are fastest.
1956
+ *
1957
+ * ```ts
1958
+ * import { createLocator, parse, walk } from "sveast";
1959
+ *
1960
+ * const locate = createLocator(source);
1961
+ * walk(parse(source), {
1962
+ * enter(node) {
1963
+ * if (node.type === "Component") console.log(node.name, locate(node.start).line);
1964
+ * },
1965
+ * });
1966
+ * ```
1967
+ */
1968
+ export declare function createLocator(text: string): (offset: number) => Position;
1969
+
1970
+ /**
1971
+ * Parses a component's top-level `<script>`s, `<style>` and
1972
+ * `<svelte:options>` as {@link parse} does, and skips the markup between
1973
+ * them as `lexComponent` skips it: `fragment` has no nodes, `comments`
1974
+ * only the scripts' comments, and errors in the markup aren't reported.
1975
+ * The rest is `parse`'s, offsets included. For a pass that only reads the
1976
+ * scripts, such as a component's props or its module script's exports.
1977
+ *
1978
+ * Throws a {@link ParseError} on a syntax error in a section.
1979
+ */
1980
+ export declare function parseSections(source: string, options?: ParseOptions): AST.Root;
1981
+
1982
+ /**
1983
+ * Whether svelte compiles the component in runes mode, as
1984
+ * `compile(source).metadata.runes` says: `<svelte:options runes>` if it
1985
+ * has one, otherwise whether it uses a rune, such as `$state` or
1986
+ * `$props`, or `await` outside a function in its instance script or
1987
+ * markup. A `$state` that subscribes to a store named `state` isn't a
1988
+ * rune, as in svelte.
1989
+ *
1990
+ * It reads `<svelte:options>` without parsing, and a component that has
1991
+ * no rune's name and no `await` isn't parsed either. Otherwise it parses
1992
+ * the scripts, and the markup only if one of them is in it, and throws a
1993
+ * `ParseError` on a syntax error there.
1994
+ */
1995
+ export declare function isRunesMode(source: string): boolean;
1996
+
1779
1997
  /**
1780
1998
  * The fields of each node type that hold child nodes, in source order.
1781
1999
  * Typed against the AST, so a node type without an entry, or a key that
@@ -1982,6 +2200,58 @@ export declare const visitorKeys: {
1982
2200
  readonly TSInstantiationExpression: readonly ["expression", "typeArguments"];
1983
2201
  };
1984
2202
 
2203
+ /** A table of the fields of each node type that {@link walk} visits, such as {@link visitorKeys} or {@link markupVisitorKeys}. */
2204
+ export type VisitorKeys = Readonly<Partial<Record<string, readonly string[]>>>;
2205
+
2206
+ /**
2207
+ * The fields of the markup's nodes that hold other markup nodes, for a
2208
+ * {@link walk} that never enters the scripts, the styles or the
2209
+ * expressions: `Root` holds only its `fragment`, an `ExpressionTag` or a
2210
+ * directive has no children, and a block holds only its fragments.
2211
+ */
2212
+ export declare const markupVisitorKeys: {
2213
+ readonly Root: readonly ["fragment"];
2214
+ readonly Fragment: readonly ["nodes"];
2215
+ readonly Text: readonly [];
2216
+ readonly Comment: readonly [];
2217
+ readonly ExpressionTag: readonly [];
2218
+ readonly HtmlTag: readonly [];
2219
+ readonly ConstTag: readonly [];
2220
+ readonly DeclarationTag: readonly [];
2221
+ readonly DebugTag: readonly [];
2222
+ readonly RenderTag: readonly [];
2223
+ readonly AttachTag: readonly [];
2224
+ readonly Attribute: readonly ["value"];
2225
+ readonly SpreadAttribute: readonly [];
2226
+ readonly AnimateDirective: readonly [];
2227
+ readonly BindDirective: readonly [];
2228
+ readonly ClassDirective: readonly [];
2229
+ readonly LetDirective: readonly [];
2230
+ readonly OnDirective: readonly [];
2231
+ readonly StyleDirective: readonly ["value"];
2232
+ readonly TransitionDirective: readonly [];
2233
+ readonly UseDirective: readonly [];
2234
+ readonly Component: readonly ["attributes", "fragment"];
2235
+ readonly TitleElement: readonly ["attributes", "fragment"];
2236
+ readonly SlotElement: readonly ["attributes", "fragment"];
2237
+ readonly RegularElement: readonly ["attributes", "fragment"];
2238
+ readonly SvelteBody: readonly ["attributes", "fragment"];
2239
+ readonly SvelteBoundary: readonly ["attributes", "fragment"];
2240
+ readonly SvelteComponent: readonly ["attributes", "fragment"];
2241
+ readonly SvelteDocument: readonly ["attributes", "fragment"];
2242
+ readonly SvelteElement: readonly ["attributes", "fragment"];
2243
+ readonly SvelteFragment: readonly ["attributes", "fragment"];
2244
+ readonly SvelteHead: readonly ["attributes", "fragment"];
2245
+ readonly SvelteOptions: readonly ["attributes", "fragment"];
2246
+ readonly SvelteSelf: readonly ["attributes", "fragment"];
2247
+ readonly SvelteWindow: readonly ["attributes", "fragment"];
2248
+ readonly IfBlock: readonly ["consequent", "alternate"];
2249
+ readonly EachBlock: readonly ["body", "fallback"];
2250
+ readonly AwaitBlock: readonly ["pending", "then", "catch"];
2251
+ readonly KeyBlock: readonly ["fragment"];
2252
+ readonly SnippetBlock: readonly ["body"];
2253
+ };
2254
+
1985
2255
  /**
1986
2256
  * Return it from `enter` or `leave` to end the walk: no further `enter` or
1987
2257
  * `leave` calls, including `leave` on the node's ancestors.
@@ -2014,9 +2284,12 @@ export interface Visitor {
2014
2284
  * Visits `node` and its descendants depth-first, in source order, calling
2015
2285
  * `visitor.enter` before a node's children and `visitor.leave` after them.
2016
2286
  * `parent[key]` is the node, or `parent[key][index]` when the field is an
2017
- * array; all three are `null` for `node` itself.
2287
+ * array; all three are `null` for `node` itself. `keys` says which fields
2288
+ * of each node type to visit, {@link visitorKeys} by default; with
2289
+ * {@link markupVisitorKeys}, only the markup is visited. A node whose
2290
+ * type it has no entry for throws.
2018
2291
  */
2019
- export declare function walk(node: AST.SvelteNode, visitor: Visitor): void;
2292
+ export declare function walk(node: AST.SvelteNode, visitor: Visitor, keys?: VisitorKeys): void;
2020
2293
 
2021
2294
  /**
2022
2295
  * The `Identifier` nodes a pattern binds, in source order: `a`, `c`, `d`,
package/index.js CHANGED
@@ -1 +1 @@
1
- import{isValidType as t}from"./is-valid-type.js";import{parse as p}from"./parse.js";import{parseImportsExports as i}from"./parse-imports-exports.js";import{ParseError as a,parseModule as f}from"./parse-module.js";import{extractIdentifiers as y,isReference as l,SKIP as n,STOP as P,visitorKeys as d,walk as I}from"./walk.js";export{a as ParseError,n as SKIP,P as STOP,y as extractIdentifiers,l as isReference,t as isValidType,p as parse,i as parseImportsExports,f as parseModule,d as visitorKeys,I as walk};
1
+ import{isValidType as t}from"./is-valid-type.js";import{lexComponent as p,lexImportsExports as s}from"./lexer.js";import{parse as i}from"./parse.js";import{parseImportsExports as f}from"./parse-imports-exports.js";import{ParseError as d,parseModule as n}from"./parse-module.js";import{parseSections as L}from"./parse-sections.js";import{isRunesMode as l}from"./runes.js";import{createLocator as I,extractIdentifiers as u,isReference as E,markupVisitorKeys as P,SKIP as O,STOP as K,visitorKeys as V,walk as k}from"./walk.js";export{d as ParseError,O as SKIP,K as STOP,I as createLocator,u as extractIdentifiers,E as isReference,l as isRunesMode,t as isValidType,p as lexComponent,s as lexImportsExports,P as markupVisitorKeys,i as parse,f as parseImportsExports,n as parseModule,L as parseSections,V as visitorKeys,k as walk};
package/is-valid-type.js CHANGED
@@ -1 +1 @@
1
- import{t}from"./shared-f8ty80r9.js";import{g}from"./shared-c4vs4cam.js";var a=new Set("abstract accessor arguments as asserts async await break case catch class const continue debugger declare default delete do else enum eval export extends false finally for function get global if implements import in infer instanceof interface intrinsic is keyof let module namespace new null of out override package private protected public readonly return satisfies set static super switch this throw true try type typeof unique var void while with yield".split(" ")),c=new Set("any bigint boolean false never null number object string symbol true undefined unknown void".split(" ")),d=new Set("get set new readonly static public private protected".split(" "));function u(e){return e>=97&&e<=122||e>=65&&e<=90||e===95||e===36}function o(e){return e>=48&&e<=57}function h(e){return u(e)||o(e)}class l{text;pos=0;constructor(e){this.text=e}readAll(){if(!this.type())return!1;return this.peek(),this.pos===this.text.length}peek(){let e=this.text,s=this.pos,r=e.charCodeAt(s);while(r===32||r===9)r=e.charCodeAt(++s);return this.pos=s,r}eat(e){if(this.peek()!==e.charCodeAt(0))return!1;return this.pos++,!0}word(){if(!u(this.peek()))return;let e=this.pos,s=e+1;while(h(this.text.charCodeAt(s)))s++;return this.pos=s,this.text.slice(e,s)}name(){let e=this.word();return e!==void 0&&!a.has(e)}string(){let e=this.peek();if(e!==34&&e!==39)return!1;let s=this.text;for(let r=this.pos+1;r<s.length;r++){let i=s.charCodeAt(r);if(i===e)return this.pos=r+1,!0;if(i===92||i===10||i===13||i===8232||i===8233)return!1}return!1}number(){let e=this.text,s=this.pos;if(e.charCodeAt(s)===45)s++;let r=s;while(o(e.charCodeAt(s)))s++;if(s===r||s-r>1&&e.charCodeAt(r)===48)return!1;if(e.charCodeAt(s)===46){let n=++s;while(o(e.charCodeAt(s)))s++;if(s===n)return!1}let i=e.charCodeAt(s);if(h(i)||i===46)return!1;return this.pos=s,!0}type(){if(this.peek()===40){let e=this.pos;if(this.functionType())return!0;this.pos=e}do do if(!this.operatorType())return!1;while(this.eat("&"));while(this.eat("|"));return!0}operatorType(){let e=this.pos;if(this.word()==="keyof")return this.operatorType();if(this.pos=e,!this.primaryType())return!1;while(this.eat("[")){if(this.eat("]"))continue;if(!this.type()||!this.eat("]"))return!1}return!0}primaryType(){let e=this.peek();if(e===40)return this.pos++,this.type()&&this.eat(")");if(e===123)return this.objectType();if(e===91)return this.tupleType();if(e===34||e===39)return this.string();if(e===45||o(e))return this.number();let s=this.word();if(s===void 0)return!1;if(s==="typeof")return this.typeQuery();if(s==="import")return this.importType(!0);if(c.has(s)){let r=this.peek();return r!==46&&r!==60}if(a.has(s))return!1;while(this.eat("."))if(this.word()===void 0)return!1;return!this.eat("<")||this.typeArguments()}typeArguments(){do if(!this.type())return!1;while(this.eat(","));return this.eat(">")}typeQuery(){let e=this.pos;if(this.word()==="import")return this.importType(!1);this.pos=e;do if(!this.name())return!1;while(this.eat("."));return!0}importType(e){if(!this.eat("(")||!this.string()||!this.eat(")"))return!1;while(this.eat("."))if(!this.name())return!1;return!e||!this.eat("<")||this.typeArguments()}objectType(){this.pos++;while(!this.eat("}")){if(!this.typeMember())return!1;if(!this.eat(";")&&!this.eat(",")&&this.peek()!==125)return!1}return!0}typeMember(){let e=this.peek();if(this.eat("[")){let s=this.peek();if(s===34||s===39){if(!this.string()||!this.eat("]"))return!1}else return this.name()&&this.eat(":")&&this.type()&&this.eat("]")&&this.eat(":")&&this.type()}else if(e===34||e===39){if(!this.string())return!1}else{let s=this.word();if(s===void 0||d.has(s))return!1}return this.eat("?"),this.eat(":")&&this.type()}tupleType(){if(this.pos++,this.eat("]"))return!0;do if(!this.type())return!1;while(this.eat(","));return this.eat("]")}functionType(){if(this.pos++,!this.eat(")")){let e=new Set;for(;;){this.peek();let s=this.text.startsWith("...",this.pos);if(s)this.pos+=3;let r=this.word();if(r===void 0||a.has(r)||e.has(r))return!1;if(e.add(r),!s)this.eat("?");if(!this.eat(":")||!this.type())return!1;if(s||!this.eat(","))break}if(!this.eat(")"))return!1}if(this.peek(),!this.text.startsWith("=>",this.pos))return!1;return this.pos+=2,this.type()}}function f(e){return new l(e).readAll()}var y=t.extend(g);function S(e,s={}){return f(e)||m(e,s.inline??!1)}function m(e,s){let r=!1,i=new y(s?{ecmaVersion:16,sourceType:"module",onComment:(n,b,T,p)=>{if(!n&&p===e.length)r=!0}}:{ecmaVersion:16,sourceType:"module"},e);try{return i.parseWholeType(),!r}catch(n){if(n instanceof SyntaxError)return!1;throw n}}export{S as isValidType,m as parsesAsType};
1
+ import{t}from"./shared-e8rqjefv.js";import{R}from"./shared-qc7kjfqj.js";var a=new Set("abstract accessor arguments as asserts async await break case catch class const continue debugger declare default delete do else enum eval export extends false finally for function get global if implements import in infer instanceof interface intrinsic is keyof let module namespace new null of out override package private protected public readonly return satisfies set static super switch this throw true try type typeof unique var void while with yield".split(" ")),c=new Set("any bigint boolean false never null number object string symbol true undefined unknown void".split(" ")),d=new Set("get set new readonly static public private protected".split(" "));function u(e){return e>=97&&e<=122||e>=65&&e<=90||e===95||e===36}function o(e){return e>=48&&e<=57}function h(e){return u(e)||o(e)}class l{text;pos=0;constructor(e){this.text=e}readAll(){if(!this.type())return!1;return this.peek(),this.pos===this.text.length}peek(){let e=this.text,s=this.pos,r=e.charCodeAt(s);while(r===32||r===9)r=e.charCodeAt(++s);return this.pos=s,r}eat(e){if(this.peek()!==e.charCodeAt(0))return!1;return this.pos++,!0}word(){if(!u(this.peek()))return;let e=this.pos,s=e+1;while(h(this.text.charCodeAt(s)))s++;return this.pos=s,this.text.slice(e,s)}name(){let e=this.word();return e!==void 0&&!a.has(e)}string(){let e=this.peek();if(e!==34&&e!==39)return!1;let s=this.text;for(let r=this.pos+1;r<s.length;r++){let i=s.charCodeAt(r);if(i===e)return this.pos=r+1,!0;if(i===92||i===10||i===13||i===8232||i===8233)return!1}return!1}number(){let e=this.text,s=this.pos;if(e.charCodeAt(s)===45)s++;let r=s;while(o(e.charCodeAt(s)))s++;if(s===r||s-r>1&&e.charCodeAt(r)===48)return!1;if(e.charCodeAt(s)===46){let n=++s;while(o(e.charCodeAt(s)))s++;if(s===n)return!1}let i=e.charCodeAt(s);if(h(i)||i===46)return!1;return this.pos=s,!0}type(){if(this.peek()===40){let e=this.pos;if(this.functionType())return!0;this.pos=e}do do if(!this.operatorType())return!1;while(this.eat("&"));while(this.eat("|"));return!0}operatorType(){let e=this.pos;if(this.word()==="keyof")return this.operatorType();if(this.pos=e,!this.primaryType())return!1;while(this.eat("[")){if(this.eat("]"))continue;if(!this.type()||!this.eat("]"))return!1}return!0}primaryType(){let e=this.peek();if(e===40)return this.pos++,this.type()&&this.eat(")");if(e===123)return this.objectType();if(e===91)return this.tupleType();if(e===34||e===39)return this.string();if(e===45||o(e))return this.number();let s=this.word();if(s===void 0)return!1;if(s==="typeof")return this.typeQuery();if(s==="import")return this.importType(!0);if(c.has(s)){let r=this.peek();return r!==46&&r!==60}if(a.has(s))return!1;while(this.eat("."))if(this.word()===void 0)return!1;return!this.eat("<")||this.typeArguments()}typeArguments(){do if(!this.type())return!1;while(this.eat(","));return this.eat(">")}typeQuery(){let e=this.pos;if(this.word()==="import")return this.importType(!1);this.pos=e;do if(!this.name())return!1;while(this.eat("."));return!0}importType(e){if(!this.eat("(")||!this.string()||!this.eat(")"))return!1;while(this.eat("."))if(!this.name())return!1;return!e||!this.eat("<")||this.typeArguments()}objectType(){this.pos++;while(!this.eat("}")){if(!this.typeMember())return!1;if(!this.eat(";")&&!this.eat(",")&&this.peek()!==125)return!1}return!0}typeMember(){let e=this.peek();if(this.eat("[")){let s=this.peek();if(s===34||s===39){if(!this.string()||!this.eat("]"))return!1}else return this.name()&&this.eat(":")&&this.type()&&this.eat("]")&&this.eat(":")&&this.type()}else if(e===34||e===39){if(!this.string())return!1}else{let s=this.word();if(s===void 0||d.has(s))return!1}return this.eat("?"),this.eat(":")&&this.type()}tupleType(){if(this.pos++,this.eat("]"))return!0;do if(!this.type())return!1;while(this.eat(","));return this.eat("]")}functionType(){if(this.pos++,!this.eat(")")){let e=new Set;for(;;){this.peek();let s=this.text.startsWith("...",this.pos);if(s)this.pos+=3;let r=this.word();if(r===void 0||a.has(r)||e.has(r))return!1;if(e.add(r),!s)this.eat("?");if(!this.eat(":")||!this.type())return!1;if(s||!this.eat(","))break}if(!this.eat(")"))return!1}if(this.peek(),!this.text.startsWith("=>",this.pos))return!1;return this.pos+=2,this.type()}}function f(e){return new l(e).readAll()}var y=t.extend(R);function C(e,s={}){return f(e)||m(e,s.inline??!1)}function m(e,s){let r=!1,i=new y(s?{ecmaVersion:16,sourceType:"module",onComment:(n,b,T,p)=>{if(!n&&p===e.length)r=!0}}:{ecmaVersion:16,sourceType:"module"},e);try{return i.parseWholeType(),!r}catch(n){if(n instanceof SyntaxError)return!1;throw n}}export{C as isValidType,m as parsesAsType};
package/lexer.d.ts ADDED
@@ -0,0 +1,167 @@
1
+ /** A module specifier: the string after `from`, or after `import` in `import "a"`. */
2
+ export interface LexedSource {
3
+ /** The string's value, with escapes decoded. */
4
+ value: string;
5
+ /** The offset of the opening quote. */
6
+ start: number;
7
+ /** The offset after the closing quote. */
8
+ end: number;
9
+ }
10
+
11
+ /** A name an `import` binds. */
12
+ export interface LexedImportSpecifier {
13
+ /** `"default"` for `a` in `import a from`, `"namespace"` for `* as a`, `"named"` for a name in braces. */
14
+ kind: "default" | "namespace" | "named";
15
+ /** The name in the imported module: `"default"`, `"*"` for a namespace, or the name before `as`, with a string's value for `"a-b" as c`. */
16
+ imported: string;
17
+ /** The name it's bound to in this module. */
18
+ local: string;
19
+ /** Whether it's only a type: in `import type`, or with `type` before it. */
20
+ typeOnly: boolean;
21
+ /** The offset of the name, of `*`, or of `type` before the name. */
22
+ start: number;
23
+ /** The offset after the local name. */
24
+ end: number;
25
+ }
26
+
27
+ /** A name an `export … from` re-exports. */
28
+ export interface LexedExportSpecifier {
29
+ /** `"all"` for `export *`, `"namespace"` for `export * as a`, `"named"` for a name in braces. */
30
+ kind: "all" | "namespace" | "named";
31
+ /** The name in the other module: `"*"` for `all` and `namespace`, or the name before `as`, with a string's value for `"a-b" as c`. */
32
+ local: string;
33
+ /** The name it's exported as, or `null` for `export *`. */
34
+ exported: string | null;
35
+ /** Whether it's only a type: in `export type`, or with `type` before it. */
36
+ typeOnly: boolean;
37
+ /** The offset of the name, of `*`, or of `type` before the name. */
38
+ start: number;
39
+ /** The offset after the exported name, or after `*` for `export *`. */
40
+ end: number;
41
+ }
42
+
43
+ interface LexedStatementBase {
44
+ /** The offset of `import` or `export`. */
45
+ start: number;
46
+ /** The offset after the statement's `;`, or its last token without one. */
47
+ end: number;
48
+ /** The module it imports from, or `null` for a statement the lexer doesn't recognize. */
49
+ source: LexedSource | null;
50
+ /** Whether it's `import type` or `export type`. */
51
+ typeOnly: boolean;
52
+ }
53
+
54
+ /** An `import` statement. */
55
+ export interface LexedImport extends LexedStatementBase {
56
+ kind: "import";
57
+ specifiers: LexedImportSpecifier[];
58
+ }
59
+
60
+ /** An `export … from` statement. */
61
+ export interface LexedExport extends LexedStatementBase {
62
+ kind: "export";
63
+ specifiers: LexedExportSpecifier[];
64
+ }
65
+
66
+ export type LexedStatement = LexedImport | LexedExport;
67
+
68
+ /**
69
+ * A module's top-level `import` statements and `export … from`
70
+ * re-exports, read without a parser: each statement's offsets, its
71
+ * source and the names it imports or re-exports. It finds statements as
72
+ * {@link parseImportsExports} does with `localExports: false`, and on
73
+ * every statement that accepts, gives the same offsets, sources and names,
74
+ * but it doesn't check syntax and never throws. A statement it can't read,
75
+ * including TypeScript's `import a = require("a")`, is returned with
76
+ * `source: null` and no specifiers, ending where it stopped reading.
77
+ * TypeScript's `type` forms are always read.
78
+ */
79
+ export declare function lexImportsExports(source: string): LexedStatement[];
80
+
81
+ /** An attribute of a top-level `<script>`, `<style>` or `<svelte:options>`. */
82
+ export interface LexedAttribute {
83
+ name: string;
84
+ /**
85
+ * The value as written, without its quotes: character references
86
+ * aren't decoded, and an expression keeps its braces, as in `"{true}"`
87
+ * for `runes={true}`. `true` for an attribute without a value.
88
+ */
89
+ value: string | true;
90
+ /** The offset of the name. */
91
+ start: number;
92
+ /** The offset after the value, or after the name without one. */
93
+ end: number;
94
+ }
95
+
96
+ /** The text between a top-level element's tags. */
97
+ export interface LexedContent {
98
+ start: number;
99
+ end: number;
100
+ }
101
+
102
+ /** A top-level `<script>`. */
103
+ export interface LexedScript {
104
+ /** The offset of `<script`. */
105
+ start: number;
106
+ /** The offset after `</script>`. */
107
+ end: number;
108
+ /** `"module"` for `<script module>` or `<script context="module">`. */
109
+ context: "default" | "module";
110
+ attributes: LexedAttribute[];
111
+ content: LexedContent;
112
+ }
113
+
114
+ /** The top-level `<style>`. */
115
+ export interface LexedStyle {
116
+ /** The offset of `<style`. */
117
+ start: number;
118
+ /** The offset after `</style>`. */
119
+ end: number;
120
+ attributes: LexedAttribute[];
121
+ content: LexedContent;
122
+ }
123
+
124
+ /** `<svelte:options>`. */
125
+ export interface LexedOptions {
126
+ /** The offset of `<svelte:options`. */
127
+ start: number;
128
+ /** The offset after `/>` or `</svelte:options>`. */
129
+ end: number;
130
+ attributes: LexedAttribute[];
131
+ }
132
+
133
+ /** A component's top-level sections, as {@link lexComponent} finds them. */
134
+ export interface LexedComponent {
135
+ /**
136
+ * Whether `parse` reads the component as TypeScript, which needs the
137
+ * TypeScript plugin: svelte decides it from the first `<script>` with a
138
+ * `lang`, so this is `true` when that one has `lang="ts"`.
139
+ */
140
+ typescript: boolean;
141
+ /** The `<script>` without `module`, as `parse`'s `instance`. */
142
+ instance: LexedScript | null;
143
+ /** The `<script module>`, as `parse`'s `module`. */
144
+ module: LexedScript | null;
145
+ /** The `<style>`, as `parse`'s `css`. */
146
+ css: LexedStyle | null;
147
+ /** `<svelte:options>`, as `parse`'s `options`. */
148
+ options: LexedOptions | null;
149
+ }
150
+
151
+ /**
152
+ * A component's top-level `<script>`, `<script module>`, `<style>` and
153
+ * `<svelte:options>`, with their attributes and the offsets of their tags
154
+ * and content, read without a parser: e.g. to find a component's
155
+ * language or imports, or to rewrite its scripts, without parsing the
156
+ * markup. The offsets are `parse`'s, so they're into the source without
157
+ * a leading byte order mark.
158
+ *
159
+ * The markup is skipped by tracking only tags, attribute values, blocks
160
+ * and the brackets, strings, comments and templates of each `{…}`
161
+ * expression, so a `<script>` inside an element, a block, a string or a
162
+ * comment isn't one. It stops after the last `<script`, `<style` or
163
+ * `<svelte:options`. Where `parse` accepts the component, the sections
164
+ * are the same as its `instance`, `module`, `css` and `options`; it
165
+ * doesn't check syntax and never throws.
166
+ */
167
+ export declare function lexComponent(input: string): LexedComponent;
package/lexer.js ADDED
@@ -0,0 +1,2 @@
1
+ import{r,M,h,d,N}from"./shared-j60qxzy3.js";import"./shared-2ahdjk78.js";import{G}from"./shared-a5mpxvcm.js";function g(e){let t=new m(e),n=[];return M(e,!1,(i,s)=>{let o=t.statement(s);return n.push(o),o.end}),n}class m{source;pos=0;end=0;escapeEnd=0;constructor(e){this.source=e}statement(e){this.pos=this.end=e+6;let t=this.source.charCodeAt(e)===105?{kind:"import",start:e,end:0,source:null,typeOnly:!1,specifiers:[]}:{kind:"export",start:e,end:0,source:null,typeOnly:!1,specifiers:[]};if(!(t.kind==="import"?this.import(t):this.export(t)))t.source=null,t.specifiers=[];return t.end=this.end,t}import(e){let t=this.string();if(t!==null)return e.source=t,this.finish();if(this.isWord("type")){let o=this.peek(4);if(o===123||o===42||c(o)&&!this.isWordAfter(4,"from"))e.typeOnly=!0,this.advance(4)}let{specifiers:n,typeOnly:i}=e,s=this.at();if(s!==123&&s!==42){let o=this.pos,a=this.name();if(a===null)return!1;if(this.at()===61)return this.importEquals();if(n.push({kind:"default",imported:"default",local:a,typeOnly:i,start:o,end:this.end}),!this.eat(44))return this.from(e);s=this.at()}if(s===42){let o=this.pos;if(this.advance(1),!this.eatWord("as"))return!1;let a=this.name();if(a===null)return!1;return n.push({kind:"namespace",imported:"*",local:a,typeOnly:i,start:o,end:this.end}),this.from(e)}if(!this.eat(123))return!1;while(!this.eat(125)){let o=this.skip(),a=this.typeModifier()||i,u=this.name(),f=u??this.string()?.value;if(f===void 0)return!1;let l=u;if(this.eatWord("as"))l=this.name();if(l===null)return!1;if(n.push({kind:"named",imported:f,local:l,typeOnly:a,start:o,end:this.end}),!this.eat(44)&&this.at()!==125)return!1}return this.from(e)}export(e){if(this.eatWord("import")){if(this.isWord("type")&&c(this.peek(4))&&!this.isWordAfter(4,"from"))e.typeOnly=!0,this.advance(4);return this.name()!==null&&this.at()===61&&this.importEquals()}if(this.isWord("type")){let i=this.peek(4);if(i===123||i===42)e.typeOnly=!0,this.advance(4)}let{specifiers:t,typeOnly:n}=e;if(this.at()===42){let i=this.pos;this.advance(1);let s=null;if(this.eatWord("as")){if(s=this.moduleExportName(),s===null)return!1}return t.push({kind:s===null?"all":"namespace",local:"*",exported:s,typeOnly:n,start:i,end:this.end}),this.from(e)}if(!this.eat(123))return!1;while(!this.eat(125)){let i=this.skip(),s=this.typeModifier()||n,o=this.moduleExportName();if(o===null)return!1;let a=o;if(this.eatWord("as"))a=this.moduleExportName();if(a===null)return!1;if(t.push({kind:"named",local:o,exported:a,typeOnly:s,start:i,end:this.end}),!this.eat(44)&&this.at()!==125)return!1}return this.from(e)}typeModifier(){if(!this.isWord("type"))return!1;let e=this.peek(4);if(e===34||e===39||c(e)&&!this.isWordAfter(4,"as"))return this.advance(4),!0;return!1}importEquals(){if(this.advance(1),this.isWord("require")&&this.peek(7)===40){if(this.advance(7),this.eat(40),this.string()===null||!this.eat(41))return!1}else do if(this.name()===null)return!1;while(this.eat(46));return this.eat(59),!0}from(e){if(!this.eatWord("from"))return!1;return e.source=this.string(),e.source!==null&&this.finish()}finish(){let e=this.isWord("with")?4:0;if(this.isWord("assert")&&!x(this.source,this.end,this.pos))e=6;if(e!==0&&this.peek(e)===123){this.advance(e),this.eat(123);while(!this.eat(125))if(this.string()===null&&this.name()===null&&!this.eat(58)&&!this.eat(44))return!1}return this.eat(59),!0}skip(){return this.pos=d(this.source,this.pos),this.pos}at(){return this.source.charCodeAt(this.skip())}advance(e){this.pos+=e,this.end=this.pos}peek(e){return this.source.charCodeAt(d(this.source,this.pos+e))}isWordAfter(e,t){return N(this.source,d(this.source,this.pos+e),t)}eat(e){if(this.at()!==e)return!1;return this.advance(1),!0}isWord(e){return N(this.source,this.skip(),e)}eatWord(e){if(!this.isWord(e))return!1;return this.advance(e.length),!0}moduleExportName(){return this.name()??this.string()?.value??null}name(){let e=this.source,t=this.skip();if(!r(e.charCodeAt(t))||h(e.charCodeAt(t)))return null;let n="",i=t,s=t;while(s<e.length){let o=e.charCodeAt(s);if(o===92){if(e.charCodeAt(s+1)!==117)return null;let a=this.unicodeEscape(s+2);if(a===null)return null;n+=e.slice(i,s)+a,s=i=this.escapeEnd}else if(r(o))s++;else break}return this.advance(s-t),n+e.slice(i,s)}string(){let e=this.source,t=this.skip(),n=e.charCodeAt(t);if(n!==34&&n!==39)return null;let i="",s=t+1;for(let o=s;o<e.length;){let a=e.charCodeAt(o);if(a===n)return this.advance(o+1-t),{value:i+e.slice(s,o),start:t,end:o+1};if(a===10||a===13)return null;if(a===92){let u=this.escape(o+1);if(u===null)return null;i+=e.slice(s,o)+u,o=s=this.escapeEnd}else o++}return null}escape(e){let t=this.source.charCodeAt(e);switch(this.escapeEnd=e+1,t){case 110:return`
2
+ `;case 114:return"\r";case 116:return"\t";case 98:return"\b";case 118:return"\v";case 102:return"\f";case 48:return h(this.source.charCodeAt(e+1))?null:"\x00";case 120:return this.hexEscape(e+1,2);case 117:return this.unicodeEscape(e+1);case 13:if(this.source.charCodeAt(e+1)===10)this.escapeEnd++;return"";case 10:case 8232:case 8233:return"";default:return h(t)||e>=this.source.length?null:String.fromCharCode(t)}}unicodeEscape(e){if(this.source.charCodeAt(e)!==123)return this.hexEscape(e,4);let t=0,n=e+1;for(;this.source.charCodeAt(n)!==125;n++){let i=p(this.source.charCodeAt(n));if(i===-1)return null;if(t=t*16+i,t>1114111)return null}if(n===e+1)return null;return this.escapeEnd=n+1,String.fromCodePoint(t)}hexEscape(e,t){let n=0;for(let i=e;i<e+t;i++){let s=p(this.source.charCodeAt(i));if(s===-1)return null;n=n*16+s}return this.escapeEnd=e+t,String.fromCharCode(n)}}function c(e){return e!==92&&r(e)&&!h(e)}function p(e){if(h(e))return e-48;let t=e|32;return t>=97&&t<=102?t-87:-1}function x(e,t,n){for(let i=t;i<n;i++){let s=e.charCodeAt(i);if(s===10||s===13||s===8232||s===8233)return!0}return!1}export{G as lexComponent,g as lexImportsExports};