@markuplint/svelte-parser 4.7.0-alpha.1 → 4.7.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017-2024 Yusuke Hirao
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,8 +1,7 @@
1
- /// <reference types="svelte" />
2
1
  import type { SvelteParser } from './parser.js';
3
2
  import type { ChildToken, Token } from '@markuplint/parser-utils';
4
- import type { Block } from 'svelte/compiler';
5
- export declare function parseBlock(parser: SvelteParser, token: ChildToken, originBlockNode: Block): {
3
+ import type { SvelteBlock } from './svelte-parser/index.js';
4
+ export declare function parseBlock(parser: SvelteParser, token: ChildToken, originBlockNode: SvelteBlock): {
6
5
  openToken: Token;
7
6
  closeToken: Token;
8
7
  };
package/lib/parser.d.ts CHANGED
@@ -15,10 +15,11 @@ export declare class SvelteParser extends Parser<SvelteNode> {
15
15
  nodeize(originNode: SvelteNode, parentNode: MLASTParentNode | null, depth: number): readonly import("@markuplint/ml-ast").MLASTNodeTreeItem[];
16
16
  visitPsBlock(token: ChildToken & {
17
17
  readonly nodeName: string;
18
+ readonly isFragment: boolean;
18
19
  }, childNodes?: readonly SvelteNode[], conditionalType?: MLASTPreprocessorSpecificBlockConditionalType): readonly [MLASTPreprocessorSpecificBlock];
19
20
  visitChildren(children: readonly SvelteNode[], parentNode: MLASTParentNode | null): never[];
20
21
  visitAttr(token: Token): (import("@markuplint/ml-ast").MLASTSpreadAttr & {
21
- __rightText?: string | undefined;
22
+ __rightText?: string;
22
23
  }) | {
23
24
  isDynamicValue: true | undefined;
24
25
  isDirective: true | undefined;
@@ -34,9 +35,9 @@ export declare class SvelteParser extends Parser<SvelteNode> {
34
35
  startQuote: import("@markuplint/ml-ast").MLASTToken;
35
36
  value: import("@markuplint/ml-ast").MLASTToken;
36
37
  endQuote: import("@markuplint/ml-ast").MLASTToken;
37
- potentialValue?: string | undefined;
38
- valueType?: "string" | "number" | "boolean" | "code" | undefined;
39
- candidate?: string | undefined;
38
+ potentialValue?: string;
39
+ valueType?: "string" | "number" | "boolean" | "code";
40
+ candidate?: string;
40
41
  uuid: string;
41
42
  raw: string;
42
43
  startOffset: number;
@@ -45,7 +46,7 @@ export declare class SvelteParser extends Parser<SvelteNode> {
45
46
  endLine: number;
46
47
  startCol: number;
47
48
  endCol: number;
48
- __rightText?: string | undefined;
49
+ __rightText?: string;
49
50
  };
50
51
  /**
51
52
  * > A lowercase tag, like `<div>`, denotes a regular HTML element.
package/lib/parser.js CHANGED
@@ -7,7 +7,7 @@ var _SvelteParser_instances, _SvelteParser_parseAwaitBlock, _SvelteParser_parseE
7
7
  import { getNamespace } from '@markuplint/html-parser';
8
8
  import { ParserError, Parser, AttrState } from '@markuplint/parser-utils';
9
9
  import { parseBlock } from './parse-block.js';
10
- import { blockOrTags, svelteParse } from './svelte-parser/index.js';
10
+ import { svelteParse } from './svelte-parser/index.js';
11
11
  export class SvelteParser extends Parser {
12
12
  constructor() {
13
13
  super({
@@ -53,21 +53,8 @@ export class SvelteParser extends Parser {
53
53
  nodeize(
54
54
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
55
55
  originNode, parentNode, depth) {
56
- let token = this.sliceFragment(originNode.start, originNode.end);
56
+ const token = this.sliceFragment(originNode.start, originNode.end);
57
57
  const parentNamespace = parentNode && 'namespace' in parentNode ? parentNode.namespace : 'http://www.w3.org/1999/xhtml';
58
- /**
59
- * Temporarily correct location shift issue with the new parser.
60
- */
61
- if (blockOrTags.includes(originNode.type) && !token.raw.startsWith('{')) {
62
- let start = token.startOffset;
63
- while (this.rawCode[start] !== '{') {
64
- start--;
65
- }
66
- token = {
67
- ...token,
68
- ...this.sliceFragment(start, originNode.end),
69
- };
70
- }
71
58
  switch (originNode.type) {
72
59
  case 'Text': {
73
60
  return this.visitText({
@@ -89,6 +76,7 @@ export class SvelteParser extends Parser {
89
76
  depth,
90
77
  parentNode,
91
78
  nodeName: 'ExpressionTag',
79
+ isFragment: false,
92
80
  });
93
81
  }
94
82
  case 'Component':
@@ -96,7 +84,7 @@ export class SvelteParser extends Parser {
96
84
  const children = originNode.fragment.nodes ?? [];
97
85
  const reEndTag = new RegExp(`</${originNode.name}\\s*>$`, 'i');
98
86
  const startTagEndOffset = children.length > 0
99
- ? children[0]?.start ?? 0
87
+ ? (children[0]?.start ?? 0)
100
88
  : token.raw.replace(reEndTag, '').length + token.startOffset;
101
89
  const startTagLocation = this.sliceFragment(token.startOffset, startTagEndOffset);
102
90
  return this.visitElement({
@@ -135,6 +123,7 @@ export class SvelteParser extends Parser {
135
123
  depth,
136
124
  parentNode,
137
125
  nodeName: ifElseBlock.type,
126
+ isFragment: false,
138
127
  }, ifElseBlock.children, {
139
128
  if: 'if',
140
129
  elseif: 'if:elseif',
@@ -171,12 +160,14 @@ export class SvelteParser extends Parser {
171
160
  depth,
172
161
  parentNode,
173
162
  nodeName: 'key',
163
+ isFragment: true,
174
164
  }, originNode.fragment.nodes)[0],
175
165
  this.visitPsBlock({
176
166
  ...closeToken,
177
167
  depth,
178
168
  parentNode,
179
169
  nodeName: '/key',
170
+ isFragment: true,
180
171
  })[0],
181
172
  ];
182
173
  }
@@ -192,12 +183,14 @@ export class SvelteParser extends Parser {
192
183
  depth,
193
184
  parentNode,
194
185
  nodeName: 'snippet',
186
+ isFragment: false,
195
187
  }, originNode.body.nodes)[0],
196
188
  this.visitPsBlock({
197
189
  ...closeToken,
198
190
  depth,
199
191
  parentNode,
200
192
  nodeName: '/snippet',
193
+ isFragment: false,
201
194
  })[0],
202
195
  ];
203
196
  }
@@ -208,6 +201,7 @@ export class SvelteParser extends Parser {
208
201
  depth,
209
202
  parentNode,
210
203
  nodeName: originNode.type,
204
+ isFragment: true,
211
205
  }, childNodes);
212
206
  }
213
207
  }
@@ -356,8 +350,8 @@ originBlockNode) {
356
350
  * find___^
357
351
  */
358
352
  const catchExpStart = thenToken
359
- ? thenEnd ?? thenToken.startOffset + thenToken.raw.length
360
- : pendingEnd ?? awaitExpEnd;
353
+ ? (thenEnd ?? thenToken.startOffset + thenToken.raw.length)
354
+ : (pendingEnd ?? awaitExpEnd);
361
355
  /**
362
356
  * `{:catch name}...{/await}`
363
357
  */
@@ -385,6 +379,7 @@ originBlockNode) {
385
379
  depth: token.depth,
386
380
  parentNode: token.parentNode,
387
381
  nodeName: 'await',
382
+ isFragment: false,
388
383
  }, originBlockNode.pending?.nodes, 'await')[0]);
389
384
  if (thenToken) {
390
385
  expressions.push(this.visitPsBlock({
@@ -392,6 +387,7 @@ originBlockNode) {
392
387
  depth: token.depth,
393
388
  parentNode: token.parentNode,
394
389
  nodeName: 'await:then',
390
+ isFragment: false,
395
391
  }, originBlockNode.then?.nodes, 'await:then')[0]);
396
392
  }
397
393
  if (catchToken) {
@@ -400,6 +396,7 @@ originBlockNode) {
400
396
  depth: token.depth,
401
397
  parentNode: token.parentNode,
402
398
  nodeName: 'await:catch',
399
+ isFragment: false,
403
400
  }, originBlockNode.catch?.nodes, 'await:catch')[0]);
404
401
  }
405
402
  expressions.push(this.visitPsBlock({
@@ -407,6 +404,7 @@ originBlockNode) {
407
404
  depth: token.depth,
408
405
  parentNode: token.parentNode,
409
406
  nodeName: '/await',
407
+ isFragment: false,
410
408
  }, undefined, 'end')[0]);
411
409
  return expressions;
412
410
  }, _SvelteParser_parseEachBlock = function _SvelteParser_parseEachBlock(token,
@@ -447,6 +445,7 @@ originBlockNode) {
447
445
  depth: token.depth,
448
446
  parentNode: token.parentNode,
449
447
  nodeName: 'each',
448
+ isFragment: false,
450
449
  }, originBlockNode.body.nodes, 'each')[0]);
451
450
  if (elseToken) {
452
451
  expressions.push(this.visitPsBlock({
@@ -454,6 +453,7 @@ originBlockNode) {
454
453
  depth: token.depth,
455
454
  parentNode: token.parentNode,
456
455
  nodeName: 'each:empty',
456
+ isFragment: false,
457
457
  }, originBlockNode.fallback?.nodes, 'each:empty')[0]);
458
458
  }
459
459
  expressions.push(this.visitPsBlock({
@@ -461,6 +461,7 @@ originBlockNode) {
461
461
  depth: token.depth,
462
462
  parentNode: token.parentNode,
463
463
  nodeName: '/each',
464
+ isFragment: false,
464
465
  }, undefined, 'end')[0]);
465
466
  return expressions;
466
467
  }, _SvelteParser_traverseIfBlock = function _SvelteParser_traverseIfBlock(
@@ -1,9 +1,12 @@
1
- /// <reference types="svelte" />
2
- import type { Attribute, AwaitBlock, Block, Comment, Directive, EachBlock, ElementLike, IfBlock, SpreadAttribute, Tag, Text } from 'svelte/compiler';
3
- export type SvelteNode = Text | Tag | ElementLike | Comment | Block;
4
- export type SvelteIfBlock = IfBlock;
5
- export type SvelteEachBlock = EachBlock;
6
- export type SvelteAwaitBlock = AwaitBlock;
1
+ import type { AST } from 'svelte/compiler';
2
+ export type SvelteNode = AST.Text | Tag | ElementLike | AST.Comment | SvelteBlock;
3
+ export type SvelteIfBlock = AST.IfBlock;
4
+ export type SvelteEachBlock = AST.EachBlock;
5
+ export type SvelteAwaitBlock = AST.AwaitBlock;
7
6
  export declare function svelteParse(template: string): SvelteNode[];
8
- export type SvelteDirective = Directive | Attribute | SpreadAttribute;
9
- export declare const blockOrTags: string[];
7
+ export type SvelteDirective = Directive | AST.Attribute | AST.SpreadAttribute;
8
+ export type SvelteBlock = AST.EachBlock | AST.IfBlock | AST.AwaitBlock | AST.KeyBlock | AST.SnippetBlock;
9
+ type Tag = AST.ExpressionTag | AST.HtmlTag | AST.ConstTag | AST.DebugTag | AST.RenderTag;
10
+ type Directive = AST.AnimateDirective | AST.BindDirective | AST.ClassDirective | AST.LetDirective | AST.OnDirective | AST.StyleDirective | AST.TransitionDirective | AST.UseDirective;
11
+ type ElementLike = AST.Component | AST.TitleElement | AST.SlotElement | AST.RegularElement | AST.SvelteBody | AST.SvelteComponent | AST.SvelteDocument | AST.SvelteElement | AST.SvelteFragment | AST.SvelteHead | AST.SvelteOptionsRaw | AST.SvelteSelf | AST.SvelteWindow;
12
+ export {};
@@ -3,14 +3,3 @@ export function svelteParse(template) {
3
3
  const ast = parse(template, { modern: true });
4
4
  return ast.fragment.nodes ?? [];
5
5
  }
6
- export const blockOrTags = [
7
- 'IfBlock',
8
- 'EachBlock',
9
- 'AwaitBlock',
10
- 'KeyBlock',
11
- 'SnippetBlock',
12
- 'HtmlTag',
13
- 'DebugTag',
14
- 'ConstTag',
15
- 'RenderTag',
16
- ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/svelte-parser",
3
- "version": "4.7.0-alpha.1",
3
+ "version": "4.7.0",
4
4
  "description": "Svelte parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -9,10 +9,12 @@
9
9
  "type": "module",
10
10
  "exports": {
11
11
  ".": {
12
- "import": "./lib/index.js"
12
+ "import": "./lib/index.js",
13
+ "types": "./lib/index.d.ts"
13
14
  },
14
15
  "./kit": {
15
- "import": "./lib/sveltekit-parser.js"
16
+ "import": "./lib/sveltekit-parser.js",
17
+ "types": "./lib/sveltekit-parser.d.ts"
16
18
  }
17
19
  },
18
20
  "types": "lib/index.d.ts",
@@ -27,9 +29,10 @@
27
29
  "clean": "tsc --build --clean"
28
30
  },
29
31
  "dependencies": {
30
- "@markuplint/html-parser": "4.6.2",
31
- "@markuplint/ml-ast": "4.3.1",
32
- "@markuplint/parser-utils": "4.6.2",
33
- "svelte": "5.0.0-next.141"
34
- }
32
+ "@markuplint/html-parser": "4.6.10",
33
+ "@markuplint/ml-ast": "4.4.7",
34
+ "@markuplint/parser-utils": "4.7.1",
35
+ "svelte": "5.1.3"
36
+ },
37
+ "gitHead": "fab5b494f0bdc491aa83cb2c8722738d557fbefd"
35
38
  }
@@ -1,8 +0,0 @@
1
- /// <reference types="svelte" />
2
- import type { SvelteParser } from './parser.js';
3
- import type { ChildToken, Token } from '@markuplint/parser-utils';
4
- import type { Block } from 'svelte/compiler';
5
- export declare function parseBlock(parser: SvelteParser, token: ChildToken, originBlockNode: Block): {
6
- openToken: Token;
7
- closeToken: Token;
8
- };
@@ -1,47 +0,0 @@
1
- export function parseBlock(
2
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
3
- parser, token,
4
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
5
- originBlockNode) {
6
- const range = token.raw;
7
- /**
8
- * `{#xxx}...{:xxx}...{/xxx}`
9
- * find___^
10
- */
11
- // eslint-disable-next-line regexp/strict
12
- const eachCloseStartIndex = range.match(/{\s*\/[a-z]+\s*}$/)?.index;
13
- if (eachCloseStartIndex == null) {
14
- throw new SyntaxError('Block close tag not found');
15
- }
16
- /**
17
- * `{/xxx}`
18
- */
19
- const closeToken = parser.sliceFragment(token.startOffset + eachCloseStartIndex, originBlockNode.end);
20
- const fragment = originBlockNode.type === 'IfBlock'
21
- ? originBlockNode.consequent.nodes
22
- : originBlockNode.type === 'AwaitBlock'
23
- ? originBlockNode.pending?.nodes
24
- : originBlockNode.type === 'KeyBlock'
25
- ? originBlockNode.fragment.nodes
26
- : originBlockNode.body.nodes;
27
- const fragStart = fragment?.at(0)?.start;
28
- const fragEnd = fragment?.at(-1)?.end;
29
- /**
30
- * This token does not guarantee an open tag.
31
- * For example, it might include `:then` or `:else`.
32
- * Therefore, this variable is not used in
33
- * `EachBlock` or `AwaitBlock`.
34
- * It is only used in `KeyBlock` and `SnippetBlock`.
35
- */
36
- let openToken;
37
- if (fragStart != null && fragEnd != null) {
38
- openToken = parser.sliceFragment(token.startOffset, fragStart);
39
- }
40
- else {
41
- openToken = parser.sliceFragment(token.startOffset, eachCloseStartIndex);
42
- }
43
- return {
44
- openToken,
45
- closeToken,
46
- };
47
- }