@markuplint/vue-parser 4.6.23 → 5.0.0-alpha.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.
@@ -79,9 +79,10 @@ Parser<ASTNode, State> (@markuplint/parser-utils)
79
79
  | `nodeize()` | vue-eslint-parser AST ノード(VText、VElement、VExpressionContainer)を markuplint AST に変換 |
80
80
  | `flattenNodes()` | 基底のフラット化を拡張し、兄弟ノード間にテンプレートコメントを注入 |
81
81
  | `afterFlattenNodes()` | `exposeWhiteSpace: false`、`exposeInvalidNode: false`、`concatText: false` で基底を呼び出す |
82
- | `visitAttr()` | Vue ディレクティブの省略形を `potentialName`/`isDirective` メタデータに解決 |
83
82
  | `detectElementType()` | PascalCase コンポーネントと Vue 組み込みコンポーネントを検出 |
84
83
 
84
+ > **注記:** `visitAttr()` オーバーライドは削除されました。Vue ディレクティブ処理(`v-bind`、`v-on`、`v-model`、`v-slot` など)は `@markuplint/vue-spec` の `directivePatterns` で管理されています。
85
+
85
86
  ### `duplicatableAttrs`
86
87
 
87
88
  `'class'` と `'style'` を含む `Set<string>` -- `v-bind:class` と `class` が同一要素に共存できるように、重複可能な属性を定義します。
@@ -134,9 +135,11 @@ Parser<ASTNode, State> (@markuplint/parser-utils)
134
135
 
135
136
  この2パスアプローチが必要な理由は、vue-eslint-parser がコメントをメインノードツリーとは別に提供するため、正しい位置にインターリーブする必要があるからです。
136
137
 
137
- ## 属性処理(visitAttr)
138
+ ## ディレクティブ処理(@markuplint/vue-spec の directivePatterns)
139
+
140
+ Vue ディレクティブの解決はパーサー自体ではなく、`@markuplint/vue-spec` で定義された `directivePatterns` によって管理されています。spec がディレクティブを `potentialName`、`isDirective`、`isDynamicValue` メタデータにマッピングするパターンを宣言します。
138
141
 
139
- `visitAttr()` メソッドはまず `super.visitAttr(token)` を呼び出し、その後 Vue 固有のディレクティブ解決を適用します。
142
+ > **二段階解決:** パーサーレベルのテスト(`index.spec.ts`)はパーサー自体が設定する raw AST 値を示します(例: 波括弧式のみ `isDynamicValue: true`)。コアレベルのテスト(`ml-core` や `rules`)は `ml-core` の `MLAttr` コンストラクタが `directivePatterns` を適用した後の最終解決値を示します。例えば、値なしの `on:click` はパーサーレベルでは `isDynamicValue: false` ですが、コアレベルでは `directivePatterns` マッチにより `isDynamicValue: true` に解決されます。
140
143
 
141
144
  ### クォートセット
142
145
 
@@ -228,6 +231,22 @@ Parser<ASTNode, State> (@markuplint/parser-utils)
228
231
 
229
232
  vue-eslint-parser 依存は Vue 2 と Vue 3 の両方のテンプレート構文をサポートしています。パーサーは AST レベルで Vue バージョンを区別しません -- どちらも同じ `VElement`、`VText`、`VExpressionContainer` ノードタイプを生成します。Vue 3 固有の機能(`<Teleport>` や `<Suspense>` など)はパーサーレベルの変更ではなく、要素タイプ検出を通じて処理されます。
230
233
 
234
+ ## 制約事項
235
+
236
+ ### `v-if` / `v-for` の `blockBehavior` 未対応
237
+
238
+ 他のフレームワークパーサー(Svelte、Pug、Alpine、JSX、Astro)は条件分岐/ループ構文に `blockBehavior` を設定し、コアエンジンが `conditionalChildNodes()` を通じて全てのありうる子ノードパターンを列挙できるようにしています。Vue パーサーはこれを**サポートしていません**。そのため、`permitted-contents` などのルールは Vue テンプレートの `v-if`/`v-else` 分岐や `v-for` イテレーション全体のコンテンツモデル検証ができません。
239
+
240
+ **実装が困難な理由:**
241
+
242
+ Alpine.js では条件分岐とループに決まったパターン — `<template x-for="...">` / `<template x-if="...">` — を使用しており、`<template>` 要素をそのまま PSBlock に変換できます。Vue のディレクティブは根本的に異なる仕組みで動作します:
243
+
244
+ 1. **ディレクティブは任意の要素に付与可能**: `v-if`、`v-for`、`v-else`、`v-else-if` は任意の要素に配置できます(例: `<div v-if="...">`、`<li v-for="...">`)。要素は属性検証のために有効な HTML 要素として残しつつ、コンテンツモデル解析のためにブロックとしても機能させる必要があります — この二重の役割は現在のパーサーアーキテクチャではサポートされていません。
245
+
246
+ 2. **兄弟要素ベースの分岐**: `v-else` と `v-else-if` はラッパーブロックの子構造ではなく、**兄弟**要素の属性です。条件グループの構築には、現在のノード単位の `nodeize()` モデルを超えた兄弟間解析が必要です。
247
+
248
+ 現在の Vue パーサーはこれらのディレクティブを属性レベルでのみ処理しており(`isDirective: true`)、属性検証エラーは抑制されますが、構造的なブロック情報はコアエンジンに提供されません。
249
+
231
250
  ## 主要ソースファイル
232
251
 
233
252
  | ファイル | 用途 |
package/ARCHITECTURE.md CHANGED
@@ -79,9 +79,10 @@ The parser maintains internal state through the `State` type:
79
79
  | `nodeize()` | Converts vue-eslint-parser AST nodes (VText, VElement, VExpressionContainer) to markuplint AST |
80
80
  | `flattenNodes()` | Extends base flattening to inject template comments between sibling nodes |
81
81
  | `afterFlattenNodes()` | Calls base with `exposeWhiteSpace: false`, `exposeInvalidNode: false`, `concatText: false` |
82
- | `visitAttr()` | Resolves Vue directive shorthands to `potentialName`/`isDirective` metadata |
83
82
  | `detectElementType()` | Detects PascalCase components and Vue built-in components |
84
83
 
84
+ > **Note:** The `visitAttr()` override has been removed. Vue directive handling (`v-bind`, `v-on`, `v-model`, `v-slot`, etc.) is now managed via `directivePatterns` in `@markuplint/vue-spec`.
85
+
85
86
  ### `duplicatableAttrs`
86
87
 
87
88
  A `Set<string>` containing `'class'` and `'style'` -- attributes that may appear multiple times on a single element (via `v-bind:class` alongside `class`).
@@ -134,9 +135,11 @@ The `flattenNodes()` method extends the base `Parser.flattenNodes()` to inject t
134
135
 
135
136
  This two-pass approach is necessary because vue-eslint-parser provides comments separately from the main node tree, and they must be interleaved at the correct positions.
136
137
 
137
- ## Attribute Processing (visitAttr)
138
+ ## Directive Handling (directivePatterns in @markuplint/vue-spec)
139
+
140
+ Vue directive resolution is managed by `directivePatterns` defined in `@markuplint/vue-spec`, not by the parser itself. The spec declares patterns that the core engine uses to map directives to `potentialName`, `isDirective`, and `isDynamicValue` metadata.
138
141
 
139
- The `visitAttr()` method calls `super.visitAttr(token)` first, then applies Vue-specific directive resolution.
142
+ > **Two-stage resolution:** Parser-level tests (`index.spec.ts`) show raw AST values where `isDynamicValue` and `isDirective` reflect only what the parser itself sets (e.g., curly-brace expressions). Core-level tests (`ml-core` and `rules`) show the final resolved values after `directivePatterns` are applied by `ml-core`'s `MLAttr` constructor. For example, `on:click` without a value shows `isDynamicValue: false` at the parser level, but resolves to `isDynamicValue: true` at the core level via the `directivePatterns` match.
140
143
 
141
144
  ### Quote Set
142
145
 
@@ -228,6 +231,22 @@ These settings reflect that Vue's template parser handles whitespace and node va
228
231
 
229
232
  The vue-eslint-parser dependency supports both Vue 2 and Vue 3 template syntax. The parser does not distinguish between Vue versions at the AST level -- both produce the same `VElement`, `VText`, and `VExpressionContainer` node types. Vue 3-specific features like `<Teleport>` and `<Suspense>` are handled through element type detection rather than parser-level changes.
230
233
 
234
+ ## Limitations
235
+
236
+ ### No `blockBehavior` support for `v-if` / `v-for`
237
+
238
+ Other framework parsers (Svelte, Pug, Alpine, JSX, Astro) set `blockBehavior` on their conditional/loop constructs so that the core engine can enumerate all possible child node patterns via `conditionalChildNodes()`. The Vue parser does **not** support this. As a result, rules like `permitted-contents` cannot validate content models across `v-if`/`v-else` branches or `v-for` iterations in Vue templates.
239
+
240
+ **Why this is difficult to implement:**
241
+
242
+ In Alpine.js, conditionals and loops use a fixed pattern — `<template x-for="...">` / `<template x-if="...">` — where the `<template>` element can be cleanly converted into a PSBlock. Vue's directives work fundamentally differently:
243
+
244
+ 1. **Directives attach to arbitrary elements**: `v-if`, `v-for`, `v-else`, and `v-else-if` can appear on any element (e.g., `<div v-if="...">`, `<li v-for="...">`). The element must remain a valid HTML element for attribute validation while simultaneously acting as a block for content model analysis — a dual role the current parser architecture does not support.
245
+
246
+ 2. **Sibling-based branching**: `v-else` and `v-else-if` are attributes on **sibling** elements, not child constructs of a wrapper block. Building conditional groups requires cross-sibling analysis that goes beyond the current per-node `nodeize()` model.
247
+
248
+ The current Vue parser handles these directives at the attribute level only (`isDirective: true`), which suppresses attribute validation errors but does not provide structural block information to the core engine.
249
+
231
250
  ## Key Source Files
232
251
 
233
252
  | File | Purpose |
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [5.0.0-alpha.0](https://github.com/markuplint/markuplint/compare/v4.14.1...v5.0.0-alpha.0) (2026-02-20)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **ml-core:** improve detection of namespace ([5b507ad](https://github.com/markuplint/markuplint/commit/5b507ad7c19c5015b8ce587845d901e31dfa6518))
11
+ - **vue-parser:** update vue-eslint-parser to 10.3.0 and fix TS4053 errors ([b4633ea](https://github.com/markuplint/markuplint/commit/b4633eaeeb55c3b969127071094fde8e51bfb451))
12
+
13
+ - refactor(vue-parser)!: update for simplified AST token properties ([b7e52df](https://github.com/markuplint/markuplint/commit/b7e52df21b6af0a4f2b61b327e60ed609f4359cc))
14
+
15
+ ### BREAKING CHANGES
16
+
17
+ - Replace startOffset/endOffset with offset and
18
+ offset + raw.length in flattenNodes comment handling.
19
+
20
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
21
+
6
22
  ## [4.6.23](https://github.com/markuplint/markuplint/compare/@markuplint/vue-parser@4.6.22...@markuplint/vue-parser@4.6.23) (2026-02-10)
7
23
 
8
24
  **Note:** Version bump only for package @markuplint/vue-parser
package/SKILL.md CHANGED
@@ -14,12 +14,12 @@ detection, update vue-eslint-parser version support, and fix comment injection.
14
14
 
15
15
  `$ARGUMENTS` specifies the task. Supported tasks:
16
16
 
17
- | Task | Description |
18
- | ------------------------------- | ------------------------------------------------ |
19
- | `add-directive` | Add or modify a Vue directive in visitAttr() |
20
- | `modify-element-type-detection` | Update detectElementType() matchers |
21
- | `update-vue-version-support` | Handle vue-eslint-parser API changes |
22
- | `fix-comment-injection` | Fix template comment injection in flattenNodes() |
17
+ | Task | Description |
18
+ | ------------------------------- | ------------------------------------------------------------- |
19
+ | `add-directive` | Add or modify a Vue directive in directivePatterns (vue-spec) |
20
+ | `modify-element-type-detection` | Update detectElementType() matchers |
21
+ | `update-vue-version-support` | Handle vue-eslint-parser API changes |
22
+ | `fix-comment-injection` | Fix template comment injection in flattenNodes() |
23
23
 
24
24
  If omitted, defaults to `add-directive`.
25
25
 
@@ -35,11 +35,11 @@ Also read:
35
35
 
36
36
  ## Task: add-directive
37
37
 
38
- Add or modify a Vue directive in `visitAttr()`. Follow recipe #1 in `docs/maintenance.md`.
38
+ Add or modify a Vue directive in `directivePatterns` (`@markuplint/vue-spec`). Follow recipe #1 in `docs/maintenance.md`.
39
39
 
40
40
  ### Step 1: Understand the directive
41
41
 
42
- 1. Read `src/parser.ts` and find the `visitAttr()` method
42
+ 1. Open `@markuplint/vue-spec` (`packages/@markuplint/vue-spec/src/index.ts`) and find the `directivePatterns` array
43
43
  2. Identify where in the priority chain the new directive should be processed
44
44
  3. Determine whether the directive needs `potentialName`, `isDirective`, or `isDynamicValue`
45
45
 
@@ -134,4 +134,4 @@ Fix template comment injection in `flattenNodes()`. Follow recipe #4 in `docs/ma
134
134
  3. **Use `isDirective: true`** for directives with no HTML equivalent (e.g., `v-if`, `v-for`).
135
135
  4. **Test with `nodeListToDebugMaps`** — this is the standard assertion pattern for parser tests.
136
136
  5. **Add JSDoc comments** to all new public methods and properties.
137
- 6. **Preserve directive priority order** in `visitAttr()` — `v-on` before `v-bind` before `v-model` before `v-slot` before generic `v-`.
137
+ 6. **Preserve directive priority order** in `directivePatterns` — `.prop` shorthand before `v-bind` with modifiers before `v-bind`/`:` before `v-on`/`@` before `v-model` before `v-slot`/`#` before generic `v-`.
@@ -49,7 +49,7 @@ expect(doc.nodeList[0].elementType).toBe('authored');
49
49
 
50
50
  ### 1. Vue ディレクティブの追加・変更
51
51
 
52
- 1. `src/parser.ts` を読み、`visitAttr()` メソッドを見つける
52
+ 1. `@markuplint/vue-spec`(`packages/@markuplint/vue-spec/src/index.ts`)を開き、`directivePatterns` 配列を確認する
53
53
  2. 優先チェーン内の正しい位置を特定:
54
54
  - `v-on` / `@`(イベントバインディング) — 最初
55
55
  - `v-bind` / `:`(プロパティバインディング) — 2番目
@@ -158,12 +158,12 @@ yarn test --scope @markuplint/vue-parser
158
158
 
159
159
  **症状:** `v-custom` のような Vue ディレクティブが `isDirective: true` としてマークされず、通常の HTML 属性として扱われる。
160
160
 
161
- **原因:** `visitAttr()` でディレクティブパターンがマッチしないか、新しいディレクティブブロックが汎用 `v-*` キャッチオールの後に配置されている。
161
+ **原因:** `directivePatterns`(`@markuplint/vue-spec` で定義)でディレクティブパターンがマッチしないか、新しいパターンが汎用 `v-*` キャッチオールの後に配置されている。
162
162
 
163
163
  **解決策:**
164
164
 
165
165
  1. ディレクティブブロックの正規表現パターンを確認 — 完全な属性名にマッチすることを確認
166
- 2. ブロックが `visitAttr()` 末尾の汎用 `v-*` キャッチオールの前に配置されていることを確認
166
+ 2. パターンが `directivePatterns` 配列内の汎用 `v-*` キャッチオールの前に配置されていることを確認
167
167
  3. 返却オブジェクトに `isDirective: true as const` が含まれていることを検証
168
168
 
169
169
  ### テンプレートコメントが AST に含まれていない
@@ -49,7 +49,7 @@ expect(doc.nodeList[0].elementType).toBe('authored');
49
49
 
50
50
  ### 1. Adding or Modifying a Vue Directive
51
51
 
52
- 1. Read `src/parser.ts` and find the `visitAttr()` method
52
+ 1. Open `@markuplint/vue-spec` (`packages/@markuplint/vue-spec/src/index.ts`) and find the `directivePatterns` array
53
53
  2. Identify the correct position in the priority chain:
54
54
  - `v-on` / `@` (event binding) — first
55
55
  - `v-bind` / `:` (property binding) — second
@@ -158,12 +158,12 @@ yarn test --scope @markuplint/vue-parser
158
158
 
159
159
  **Symptom:** A Vue directive like `v-custom` is treated as a regular HTML attribute instead of being marked as `isDirective: true`.
160
160
 
161
- **Cause:** The directive pattern does not match in `visitAttr()`, or the new directive block is placed after the generic `v-*` catch-all.
161
+ **Cause:** The directive pattern does not match in `directivePatterns` (defined in `@markuplint/vue-spec`), or the new pattern is placed after the generic `v-*` catch-all.
162
162
 
163
163
  **Solution:**
164
164
 
165
165
  1. Check the regex pattern in your directive block — ensure it matches the full attribute name
166
- 2. Ensure the block is placed before the generic `v-*` catch-all at the end of `visitAttr()`
166
+ 2. Ensure the pattern is placed before the generic `v-*` catch-all in the `directivePatterns` array
167
167
  3. Verify the return object includes `isDirective: true as const`
168
168
 
169
169
  ### Template comments are missing from the AST
package/lib/parser.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import type { ASTNode, ASTComment } from './vue-parser/index.js';
2
2
  import type { MLASTParentNode, MLASTNodeTreeItem } from '@markuplint/ml-ast';
3
- import type { Token } from '@markuplint/parser-utils';
4
3
  import { ParserError, Parser } from '@markuplint/parser-utils';
5
4
  type State = {
6
5
  comments: readonly ASTComment[];
@@ -12,11 +11,10 @@ type State = {
12
11
  * Recognizes Vue built-in components and PascalCase user components.
13
12
  */
14
13
  declare class VueParser extends Parser<ASTNode, State> {
15
- readonly duplicatableAttrs: Set<string>;
16
14
  constructor();
17
15
  tokenize(): {
18
- ast: (import("vue-eslint-parser/ast/nodes").VElement | import("vue-eslint-parser/ast/nodes").VText | import("vue-eslint-parser/ast/nodes").VExpressionContainer)[];
19
- isFragment: boolean;
16
+ readonly ast: ASTNode[];
17
+ readonly isFragment: boolean;
20
18
  };
21
19
  parseError(error: any): ParserError;
22
20
  /**
@@ -40,19 +38,6 @@ declare class VueParser extends Parser<ASTNode, State> {
40
38
  */
41
39
  flattenNodes(nodeTree: readonly MLASTNodeTreeItem[]): MLASTNodeTreeItem[];
42
40
  afterFlattenNodes(nodeList: readonly MLASTNodeTreeItem[]): readonly MLASTNodeTreeItem[];
43
- /**
44
- * Visits an attribute token and resolves Vue-specific directive shorthands.
45
- * Handles `v-on` / `@` (event binding), `v-bind` / `:` (property binding),
46
- * `v-model`, `v-slot` / `#`, and other `v-` prefixed directives.
47
- *
48
- * @param token - The token representing the attribute
49
- * @returns The parsed attribute node with Vue-specific metadata
50
- */
51
- visitAttr(token: Token): (import("@markuplint/ml-ast").MLASTHTMLAttr & {
52
- __rightText?: string;
53
- }) | (import("@markuplint/ml-ast").MLASTSpreadAttr & {
54
- __rightText?: string;
55
- });
56
41
  /**
57
42
  * > In SFCs, it's recommended to use `PascalCase` tag names
58
43
  * > for child components to differentiate from native HTML elements.
package/lib/parser.js CHANGED
@@ -13,7 +13,6 @@ class VueParser extends Parser {
13
13
  }, {
14
14
  comments: [],
15
15
  });
16
- this.duplicatableAttrs = new Set(['class', 'style']);
17
16
  }
18
17
  tokenize() {
19
18
  const ast = vueParse(this.rawCode);
@@ -73,7 +72,6 @@ class VueParser extends Parser {
73
72
  depth,
74
73
  parentNode,
75
74
  nodeName: originNode.name,
76
- namespace: originNode.namespace,
77
75
  }, originNode.children, {
78
76
  createEndTagToken: () => {
79
77
  if (!originNode.endTag) {
@@ -103,9 +101,13 @@ class VueParser extends Parser {
103
101
  const newNodeList = [];
104
102
  let prevNode = null;
105
103
  for (const node of nodeList) {
106
- const lastOffset = prevNode?.endOffset ?? node.parentNode?.endOffset ?? 0;
104
+ const lastOffset = prevNode
105
+ ? prevNode.offset + prevNode.raw.length
106
+ : node.parentNode
107
+ ? node.parentNode.offset + node.parentNode.raw.length
108
+ : 0;
107
109
  const betweenComment = this.state.comments.find(comment => {
108
- return lastOffset <= comment.range[0] && comment.range[1] <= node.startOffset;
110
+ return lastOffset <= comment.range[0] && comment.range[1] <= node.offset;
109
111
  });
110
112
  if (betweenComment) {
111
113
  const token = this.sliceFragment(betweenComment.range[0], betweenComment.range[1]);
@@ -135,108 +137,6 @@ class VueParser extends Parser {
135
137
  concatText: false,
136
138
  });
137
139
  }
138
- /**
139
- * Visits an attribute token and resolves Vue-specific directive shorthands.
140
- * Handles `v-on` / `@` (event binding), `v-bind` / `:` (property binding),
141
- * `v-model`, `v-slot` / `#`, and other `v-` prefixed directives.
142
- *
143
- * @param token - The token representing the attribute
144
- * @returns The parsed attribute node with Vue-specific metadata
145
- */
146
- visitAttr(token) {
147
- const attr = super.visitAttr(token);
148
- if (attr.type === 'spread') {
149
- return attr;
150
- }
151
- {
152
- /**
153
- * `v-on`
154
- */
155
- const [, directive, potentialName] = attr.name.raw.match(/^(v-on:|@)([^.]+)(?:\.([^.]+))?$/i) ?? [];
156
- if (directive && potentialName) {
157
- return {
158
- ...attr,
159
- potentialName: `on${potentialName.toLowerCase()}`,
160
- isDynamicValue: true,
161
- };
162
- }
163
- }
164
- {
165
- /**
166
- * `v-bind`
167
- */
168
- const [, directive, potentialName, modifier] = attr.name.raw.match(/^(v-bind:|:)([^.]+)(?:\.([^.]+))?$/i) ?? [];
169
- if (directive && potentialName) {
170
- if (this.duplicatableAttrs.has(potentialName.toLowerCase())) {
171
- this.updateAttr(attr, { isDuplicatable: true });
172
- }
173
- if (!modifier) {
174
- return {
175
- ...attr,
176
- potentialName,
177
- isDynamicValue: true,
178
- };
179
- }
180
- switch (modifier) {
181
- case '.attr': {
182
- return {
183
- ...attr,
184
- potentialName,
185
- isDynamicValue: true,
186
- };
187
- }
188
- /* eslint-disable unicorn/no-useless-switch-case */
189
- case '.prop':
190
- case '.camel':
191
- default: {
192
- const name = `v-bind:${potentialName}${modifier ?? ''}`;
193
- return {
194
- ...attr,
195
- potentialName: attr.name.raw === name ? undefined : name,
196
- isDirective: true,
197
- };
198
- }
199
- /* eslint-enable unicorn/no-useless-switch-case */
200
- }
201
- }
202
- }
203
- {
204
- /**
205
- * `v-model`
206
- */
207
- const [, directive] = attr.name.raw.match(/^(v-model)(?:\.([^.]+))?$/i) ?? [];
208
- if (directive) {
209
- return {
210
- ...attr,
211
- isDirective: true,
212
- };
213
- }
214
- }
215
- {
216
- /**
217
- * `v-slot`
218
- */
219
- const slotName = (attr.name.raw.match(/^(v-slot:|#)(.+)$/i) ?? [])[2];
220
- const name = `v-slot:${slotName}`;
221
- if (slotName) {
222
- return {
223
- ...attr,
224
- potentialName: attr.name.raw === name ? undefined : name,
225
- isDirective: true,
226
- };
227
- }
228
- }
229
- /**
230
- * If directives
231
- */
232
- if (attr.name.raw.startsWith('v-')) {
233
- return {
234
- ...attr,
235
- isDirective: true,
236
- };
237
- }
238
- return attr;
239
- }
240
140
  /**
241
141
  * > In SFCs, it's recommended to use `PascalCase` tag names
242
142
  * > for child components to differentiate from native HTML elements.
@@ -8,7 +8,10 @@ export type VueTokens = VueESLintParser.AST.ESLintProgram;
8
8
  * @returns The parsed AST program node containing the template body
9
9
  */
10
10
  export declare function vueParse(vueTemplate: string): VueTokens;
11
+ export type VElement = VueESLintParser.AST.VElement;
12
+ export type VText = VueESLintParser.AST.VText;
13
+ export type VExpressionContainer = VueESLintParser.AST.VExpressionContainer;
11
14
  /** Union of AST node types that can appear as children in a Vue template. */
12
- export type ASTNode = VueESLintParser.AST.VElement | VueESLintParser.AST.VText | VueESLintParser.AST.VExpressionContainer;
15
+ export type ASTNode = VElement | VText | VExpressionContainer;
13
16
  /** Represents a comment token in the Vue template AST with location information. */
14
17
  export type ASTComment = VueESLintParser.AST.Token & VueESLintParser.AST.HasLocation;
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@markuplint/vue-parser",
3
- "version": "4.6.23",
3
+ "version": "5.0.0-alpha.0",
4
4
  "description": "Vue parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
7
7
  "license": "MIT",
8
+ "engines": {
9
+ "node": ">=22"
10
+ },
8
11
  "type": "module",
9
12
  "exports": {
10
13
  ".": {
@@ -21,10 +24,10 @@
21
24
  "clean": "tsc --build --clean tsconfig.build.json"
22
25
  },
23
26
  "dependencies": {
24
- "@markuplint/html-parser": "4.6.23",
25
- "@markuplint/ml-ast": "4.4.11",
26
- "@markuplint/parser-utils": "4.8.11",
27
- "vue-eslint-parser": "10.2.0"
27
+ "@markuplint/html-parser": "5.0.0-alpha.0",
28
+ "@markuplint/ml-ast": "5.0.0-alpha.0",
29
+ "@markuplint/parser-utils": "5.0.0-alpha.0",
30
+ "vue-eslint-parser": "10.4.0"
28
31
  },
29
- "gitHead": "193ee7c1262bbed95424e38efdf1a8e56ff049f4"
32
+ "gitHead": "13dcfc84ec83d87360c720e253383b60767e1b56"
30
33
  }