@uicontract/parser-vue 0.1.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 +21 -0
- package/README.md +46 -0
- package/dist/context-extractor.d.ts +98 -0
- package/dist/context-extractor.d.ts.map +1 -0
- package/dist/context-extractor.js +192 -0
- package/dist/context-extractor.js.map +1 -0
- package/dist/file-discovery.d.ts +9 -0
- package/dist/file-discovery.d.ts.map +1 -0
- package/dist/file-discovery.js +77 -0
- package/dist/file-discovery.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/sfc-visitor.d.ts +10 -0
- package/dist/sfc-visitor.d.ts.map +1 -0
- package/dist/sfc-visitor.js +115 -0
- package/dist/sfc-visitor.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 UIC Contributors
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @uicontract/parser-vue
|
|
2
|
+
|
|
3
|
+
Vue and Nuxt parser for discovering interactive UI elements.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @uicontract/parser-vue
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { VueParser } from '@uicontract/parser-vue';
|
|
15
|
+
|
|
16
|
+
const parser = new VueParser();
|
|
17
|
+
|
|
18
|
+
// Detect whether a project uses Vue
|
|
19
|
+
const isVue = await parser.detect('/path/to/my-app');
|
|
20
|
+
|
|
21
|
+
// Discover all interactive elements
|
|
22
|
+
const { elements, warnings, metadata } = await parser.discover('/path/to/my-app', {
|
|
23
|
+
include: ['src/**/*.vue'],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
console.log(`Found ${elements.length} elements in ${metadata.filesScanned} files`);
|
|
27
|
+
// elements: RawElement[] ready for @uicontract/namer
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
- **`VueParser`**: Implements the `Parser` interface from `@uicontract/core`.
|
|
33
|
+
- **`detect(dir)`**: Returns `true` if the directory contains a Vue 3 or Nuxt project.
|
|
34
|
+
- **`discover(dir, options)`**: Parses `.vue` Single File Component templates using `@vue/compiler-dom`. Returns `{ elements, warnings, metadata }`.
|
|
35
|
+
|
|
36
|
+
Discovered element types: `button`, `a` (link), `input`, `select`, `textarea`, `form`.
|
|
37
|
+
|
|
38
|
+
Targets Vue 3 and Nuxt projects. Unexpected syntax produces a `warning` entry rather than throwing, so partial results are always returned.
|
|
39
|
+
|
|
40
|
+
## Part of UIC
|
|
41
|
+
|
|
42
|
+
This package is part of [UIC (UI Contracts)](https://github.com/sherifkozman/uicontract) — making web app UIs machine-readable.
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
[MIT](../../LICENSE)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context extraction helpers for Vue SFC template AST.
|
|
3
|
+
* Extracts component names, routes, labels, handlers, data attributes,
|
|
4
|
+
* and conditional/dynamic flags from Vue template elements.
|
|
5
|
+
*/
|
|
6
|
+
/** Vue compiler-dom node prop with type 6 = attribute, type 7 = directive */
|
|
7
|
+
interface VueAttributeNode {
|
|
8
|
+
type: 6;
|
|
9
|
+
name: string;
|
|
10
|
+
value?: {
|
|
11
|
+
content: string;
|
|
12
|
+
} | undefined;
|
|
13
|
+
}
|
|
14
|
+
interface VueDirectiveNode {
|
|
15
|
+
type: 7;
|
|
16
|
+
name: string;
|
|
17
|
+
arg?: {
|
|
18
|
+
content: string;
|
|
19
|
+
} | null;
|
|
20
|
+
exp?: {
|
|
21
|
+
content: string;
|
|
22
|
+
} | null;
|
|
23
|
+
}
|
|
24
|
+
type VuePropNode = VueAttributeNode | VueDirectiveNode;
|
|
25
|
+
/** Vue compiler-dom element node (type 1) */
|
|
26
|
+
interface VueElementNode {
|
|
27
|
+
type: 1;
|
|
28
|
+
tag: string;
|
|
29
|
+
props: VuePropNode[];
|
|
30
|
+
children: VueChildNode[];
|
|
31
|
+
loc: {
|
|
32
|
+
start: {
|
|
33
|
+
line: number;
|
|
34
|
+
column: number;
|
|
35
|
+
};
|
|
36
|
+
end: {
|
|
37
|
+
line: number;
|
|
38
|
+
column: number;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Vue compiler-dom text node (type 2) */
|
|
43
|
+
interface VueTextNode {
|
|
44
|
+
type: 2;
|
|
45
|
+
content: string;
|
|
46
|
+
}
|
|
47
|
+
/** Vue compiler-dom interpolation node (type 5) */
|
|
48
|
+
interface VueInterpolationNode {
|
|
49
|
+
type: 5;
|
|
50
|
+
content: {
|
|
51
|
+
content: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
type VueChildNode = VueElementNode | VueTextNode | VueInterpolationNode | {
|
|
55
|
+
type: number;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Extract a component name from the file path.
|
|
59
|
+
* Vue components are named by their filename: `MyComponent.vue` -> `MyComponent`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function extractComponentName(filePath: string): string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Infer a Nuxt route from a file path.
|
|
64
|
+
* Files under a `pages/` directory map to routes:
|
|
65
|
+
* - `pages/index.vue` -> `/`
|
|
66
|
+
* - `pages/about.vue` -> `/about`
|
|
67
|
+
* - `pages/users/[id].vue` -> `/users/[id]`
|
|
68
|
+
*/
|
|
69
|
+
export declare function extractRoute(filePath: string, projectRoot: string): string | null;
|
|
70
|
+
/**
|
|
71
|
+
* Extract the best human-readable label for a Vue template element.
|
|
72
|
+
* Priority: aria-label > text content children > placeholder
|
|
73
|
+
*/
|
|
74
|
+
export declare function extractLabel(node: VueElementNode): string | null;
|
|
75
|
+
/**
|
|
76
|
+
* Extract the event handler name from Vue directives.
|
|
77
|
+
* @click="handleClick" → "handleClick"
|
|
78
|
+
* v-on:submit="handleSubmit" → "handleSubmit"
|
|
79
|
+
*/
|
|
80
|
+
export declare function extractHandler(node: VueElementNode): string | null;
|
|
81
|
+
/**
|
|
82
|
+
* Collect all data-* attributes from a Vue element.
|
|
83
|
+
*/
|
|
84
|
+
export declare function extractDataAttributes(node: VueElementNode): Record<string, string>;
|
|
85
|
+
/**
|
|
86
|
+
* Check if a node or any of its ancestors has v-if, v-else-if, v-else, or v-show.
|
|
87
|
+
*/
|
|
88
|
+
export declare function isConditional(node: VueElementNode, ancestors: VueElementNode[]): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Check if any ancestor has a v-for directive.
|
|
91
|
+
*/
|
|
92
|
+
export declare function isDynamic(ancestors: VueElementNode[]): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Check if a Vue element node has any event handler directives (@click, v-on:*, etc.)
|
|
95
|
+
*/
|
|
96
|
+
export declare function hasEventDirective(node: VueElementNode): boolean;
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=context-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-extractor.d.ts","sourceRoot":"","sources":["../src/context-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,6EAA6E;AAC7E,UAAU,gBAAgB;IACxB,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACzC;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjC,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClC;AAED,KAAK,WAAW,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAEvD,6CAA6C;AAC7C,UAAU,cAAc;IACtB,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,GAAG,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,GAAG,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACzF;AAED,0CAA0C;AAC1C,UAAU,WAAW;IACnB,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mDAAmD;AACnD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B;AAED,KAAK,YAAY,GAAG,cAAc,GAAG,WAAW,GAAG,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAM3F;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpE;AAMD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjF;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CA+BhE;AAMD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAiClE;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUlF;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAcxF;AAMD;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAO9D;AAeD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAW/D"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context extraction helpers for Vue SFC template AST.
|
|
3
|
+
* Extracts component names, routes, labels, handlers, data attributes,
|
|
4
|
+
* and conditional/dynamic flags from Vue template elements.
|
|
5
|
+
*/
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Component name
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Extract a component name from the file path.
|
|
12
|
+
* Vue components are named by their filename: `MyComponent.vue` -> `MyComponent`.
|
|
13
|
+
*/
|
|
14
|
+
export function extractComponentName(filePath) {
|
|
15
|
+
const base = path.basename(filePath, '.vue');
|
|
16
|
+
return base || null;
|
|
17
|
+
}
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Route extraction (Nuxt pages/ convention)
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Infer a Nuxt route from a file path.
|
|
23
|
+
* Files under a `pages/` directory map to routes:
|
|
24
|
+
* - `pages/index.vue` -> `/`
|
|
25
|
+
* - `pages/about.vue` -> `/about`
|
|
26
|
+
* - `pages/users/[id].vue` -> `/users/[id]`
|
|
27
|
+
*/
|
|
28
|
+
export function extractRoute(filePath, projectRoot) {
|
|
29
|
+
const rel = path.relative(projectRoot, filePath).replace(/\\/g, '/');
|
|
30
|
+
const pagesIndex = rel.indexOf('pages/');
|
|
31
|
+
if (pagesIndex === -1)
|
|
32
|
+
return null;
|
|
33
|
+
const afterPages = rel.slice(pagesIndex + 'pages/'.length);
|
|
34
|
+
const withoutExt = afterPages.replace(/\.vue$/, '');
|
|
35
|
+
// index -> /
|
|
36
|
+
if (withoutExt === 'index') {
|
|
37
|
+
return '/';
|
|
38
|
+
}
|
|
39
|
+
// Remove trailing /index
|
|
40
|
+
const route = withoutExt.replace(/\/index$/, '');
|
|
41
|
+
return '/' + route;
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Label extraction
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Extract the best human-readable label for a Vue template element.
|
|
48
|
+
* Priority: aria-label > text content children > placeholder
|
|
49
|
+
*/
|
|
50
|
+
export function extractLabel(node) {
|
|
51
|
+
// 1. aria-label attribute
|
|
52
|
+
for (const prop of node.props) {
|
|
53
|
+
if (prop.type === 6 && prop.name === 'aria-label' && prop.value) {
|
|
54
|
+
return prop.value.content;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 2. Children text content
|
|
58
|
+
const textParts = [];
|
|
59
|
+
for (const child of node.children) {
|
|
60
|
+
if (child.type === 2) {
|
|
61
|
+
// TextNode
|
|
62
|
+
const trimmed = child.content.trim();
|
|
63
|
+
if (trimmed)
|
|
64
|
+
textParts.push(trimmed);
|
|
65
|
+
}
|
|
66
|
+
else if (child.type === 5) {
|
|
67
|
+
// InterpolationNode {{ expr }} — skip dynamic content
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (textParts.length > 0) {
|
|
71
|
+
return textParts.join(' ');
|
|
72
|
+
}
|
|
73
|
+
// 3. placeholder attribute
|
|
74
|
+
for (const prop of node.props) {
|
|
75
|
+
if (prop.type === 6 && prop.name === 'placeholder' && prop.value) {
|
|
76
|
+
return prop.value.content;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Handler extraction
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
/**
|
|
85
|
+
* Extract the event handler name from Vue directives.
|
|
86
|
+
* @click="handleClick" → "handleClick"
|
|
87
|
+
* v-on:submit="handleSubmit" → "handleSubmit"
|
|
88
|
+
*/
|
|
89
|
+
export function extractHandler(node) {
|
|
90
|
+
const eventNames = ['click', 'submit', 'change', 'input', 'focus', 'blur', 'keydown', 'keyup', 'keypress'];
|
|
91
|
+
for (const prop of node.props) {
|
|
92
|
+
if (prop.type !== 7 || prop.name !== 'on')
|
|
93
|
+
continue;
|
|
94
|
+
const arg = prop.arg;
|
|
95
|
+
if (!arg || !eventNames.includes(arg.content))
|
|
96
|
+
continue;
|
|
97
|
+
const exp = prop.exp;
|
|
98
|
+
if (!exp)
|
|
99
|
+
continue;
|
|
100
|
+
const content = exp.content.trim();
|
|
101
|
+
// Simple identifier: handleClick
|
|
102
|
+
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(content)) {
|
|
103
|
+
return content;
|
|
104
|
+
}
|
|
105
|
+
// Member expression: obj.method — extract last part
|
|
106
|
+
const dotMatch = /\.([a-zA-Z_$][a-zA-Z0-9_$]*)$/.exec(content);
|
|
107
|
+
if (dotMatch?.[1]) {
|
|
108
|
+
return dotMatch[1];
|
|
109
|
+
}
|
|
110
|
+
// Call expression: handleClick() — extract function name
|
|
111
|
+
const callMatch = /^([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/.exec(content);
|
|
112
|
+
if (callMatch?.[1]) {
|
|
113
|
+
return callMatch[1];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Data attribute extraction
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
/**
|
|
122
|
+
* Collect all data-* attributes from a Vue element.
|
|
123
|
+
*/
|
|
124
|
+
export function extractDataAttributes(node) {
|
|
125
|
+
const result = {};
|
|
126
|
+
for (const prop of node.props) {
|
|
127
|
+
if (prop.type === 6 && prop.name.startsWith('data-')) {
|
|
128
|
+
result[prop.name] = prop.value?.content ?? '';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Conditional detection
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* Check if a node or any of its ancestors has v-if, v-else-if, v-else, or v-show.
|
|
138
|
+
*/
|
|
139
|
+
export function isConditional(node, ancestors) {
|
|
140
|
+
// Check current node
|
|
141
|
+
if (hasDirective(node, ['if', 'else-if', 'else', 'show'])) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
// Check ancestors
|
|
145
|
+
for (const ancestor of ancestors) {
|
|
146
|
+
if (hasDirective(ancestor, ['if', 'else-if', 'else', 'show'])) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Dynamic detection
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
/**
|
|
156
|
+
* Check if any ancestor has a v-for directive.
|
|
157
|
+
*/
|
|
158
|
+
export function isDynamic(ancestors) {
|
|
159
|
+
for (const ancestor of ancestors) {
|
|
160
|
+
if (hasDirective(ancestor, ['for'])) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
// Helpers
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
function hasDirective(node, names) {
|
|
170
|
+
for (const prop of node.props) {
|
|
171
|
+
if (prop.type === 7 && names.includes(prop.name)) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if a Vue element node has any event handler directives (@click, v-on:*, etc.)
|
|
179
|
+
*/
|
|
180
|
+
export function hasEventDirective(node) {
|
|
181
|
+
const eventNames = ['click', 'submit', 'change', 'input', 'focus', 'blur', 'keydown', 'keyup', 'keypress'];
|
|
182
|
+
for (const prop of node.props) {
|
|
183
|
+
if (prop.type === 7 && prop.name === 'on') {
|
|
184
|
+
const arg = prop.arg;
|
|
185
|
+
if (arg && eventNames.includes(arg.content)) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=context-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-extractor.js","sourceRoot":"","sources":["../src/context-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File discovery for Vue SFC files.
|
|
3
|
+
*/
|
|
4
|
+
import type { ParserOptions } from '@uicontract/core';
|
|
5
|
+
/**
|
|
6
|
+
* Recursively discover .vue files in a directory.
|
|
7
|
+
*/
|
|
8
|
+
export declare function discoverFiles(dir: string, options: ParserOptions): Promise<string[]>;
|
|
9
|
+
//# sourceMappingURL=file-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-discovery.d.ts","sourceRoot":"","sources":["../src/file-discovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAetD;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File discovery for Vue SFC files.
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
const DEFAULT_INCLUDE = ['**/*.vue'];
|
|
7
|
+
const DEFAULT_EXCLUDE = [
|
|
8
|
+
'**/node_modules/**',
|
|
9
|
+
'**/dist/**',
|
|
10
|
+
'**/build/**',
|
|
11
|
+
'**/.nuxt/**',
|
|
12
|
+
'**/.output/**',
|
|
13
|
+
'**/coverage/**',
|
|
14
|
+
'**/__tests__/**',
|
|
15
|
+
'**/*.test.vue',
|
|
16
|
+
'**/*.spec.vue',
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Recursively discover .vue files in a directory.
|
|
20
|
+
*/
|
|
21
|
+
export async function discoverFiles(dir, options) {
|
|
22
|
+
const includePatterns = options.include ?? DEFAULT_INCLUDE;
|
|
23
|
+
const excludePatterns = options.exclude ?? DEFAULT_EXCLUDE;
|
|
24
|
+
const maxDepth = options.maxDepth ?? 10;
|
|
25
|
+
const files = [];
|
|
26
|
+
await walkDir(dir, dir, files, includePatterns, excludePatterns, 0, maxDepth);
|
|
27
|
+
return files.sort();
|
|
28
|
+
}
|
|
29
|
+
async function walkDir(baseDir, currentDir, results, _include, _exclude, depth, maxDepth) {
|
|
30
|
+
if (depth > maxDepth)
|
|
31
|
+
return;
|
|
32
|
+
let entries;
|
|
33
|
+
try {
|
|
34
|
+
entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
41
|
+
const relPath = path.relative(baseDir, fullPath).replace(/\\/g, '/');
|
|
42
|
+
// Check excludes
|
|
43
|
+
if (isExcluded(relPath, entry.name, _exclude))
|
|
44
|
+
continue;
|
|
45
|
+
if (entry.isDirectory()) {
|
|
46
|
+
await walkDir(baseDir, fullPath, results, _include, _exclude, depth + 1, maxDepth);
|
|
47
|
+
}
|
|
48
|
+
else if (entry.isFile() && entry.name.endsWith('.vue')) {
|
|
49
|
+
results.push(fullPath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isExcluded(relPath, name, excludePatterns) {
|
|
54
|
+
for (const pattern of excludePatterns) {
|
|
55
|
+
// Simple pattern matching for common cases
|
|
56
|
+
if (pattern === '**/node_modules/**' && relPath.includes('node_modules'))
|
|
57
|
+
return true;
|
|
58
|
+
if (pattern === '**/dist/**' && relPath.includes('dist/'))
|
|
59
|
+
return true;
|
|
60
|
+
if (pattern === '**/build/**' && relPath.includes('build/'))
|
|
61
|
+
return true;
|
|
62
|
+
if (pattern === '**/.nuxt/**' && relPath.includes('.nuxt'))
|
|
63
|
+
return true;
|
|
64
|
+
if (pattern === '**/.output/**' && relPath.includes('.output'))
|
|
65
|
+
return true;
|
|
66
|
+
if (pattern === '**/coverage/**' && relPath.includes('coverage/'))
|
|
67
|
+
return true;
|
|
68
|
+
if (pattern === '**/__tests__/**' && relPath.includes('__tests__/'))
|
|
69
|
+
return true;
|
|
70
|
+
if (pattern === '**/*.test.vue' && name.endsWith('.test.vue'))
|
|
71
|
+
return true;
|
|
72
|
+
if (pattern === '**/*.spec.vue' && name.endsWith('.spec.vue'))
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=file-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-discovery.js","sourceRoot":"","sources":["../src/file-discovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,MAAM,eAAe,GAAG,CAAC,UAAU,CAAC,CAAC;AACrC,MAAM,eAAe,GAAG;IACtB,oBAAoB;IACpB,YAAY;IACZ,aAAa;IACb,aAAa;IACb,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,eAAe;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,OAAsB;IAEtB,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IAC3D,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IAExC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9E,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,OAAe,EACf,UAAkB,EAClB,OAAiB,EACjB,QAAkB,EAClB,QAAkB,EAClB,KAAa,EACb,QAAgB;IAEhB,IAAI,KAAK,GAAG,QAAQ;QAAE,OAAO;IAE7B,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAA+B,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAErE,iBAAiB;QACjB,IAAI,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;YAAE,SAAS;QAExD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QACrF,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,IAAY,EAAE,eAAyB;IAC1E,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,2CAA2C;QAC3C,IAAI,OAAO,KAAK,oBAAoB,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;YAAE,OAAO,IAAI,CAAC;QACtF,IAAI,OAAO,KAAK,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QACvE,IAAI,OAAO,KAAK,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QACzE,IAAI,OAAO,KAAK,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QACxE,IAAI,OAAO,KAAK,eAAe,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5E,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/E,IAAI,OAAO,KAAK,iBAAiB,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;QACjF,IAAI,OAAO,KAAK,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3E,IAAI,OAAO,KAAK,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;IAC7E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @uicontract/parser-vue — Vue/Nuxt parser for UIC.
|
|
3
|
+
* Implements the Parser interface from @uicontract/core.
|
|
4
|
+
*/
|
|
5
|
+
import type { Parser, DiscoveryResult, ParserOptions } from '@uicontract/core';
|
|
6
|
+
export declare const VERSION = "0.0.0";
|
|
7
|
+
/** The Vue/Nuxt parser implementation. */
|
|
8
|
+
export declare class VueParser implements Parser {
|
|
9
|
+
readonly framework = "vue";
|
|
10
|
+
detect(dir: string): Promise<boolean>;
|
|
11
|
+
discover(dir: string, options: ParserOptions): Promise<DiscoveryResult>;
|
|
12
|
+
}
|
|
13
|
+
export declare const vueParser: VueParser;
|
|
14
|
+
export { discoverFiles } from './file-discovery.js';
|
|
15
|
+
export { parseVueFile } from './sfc-visitor.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAA6B,MAAM,kBAAkB,CAAC;AAI1G,eAAO,MAAM,OAAO,UAAU,CAAC;AAkC/B,0CAA0C;AAC1C,qBAAa,SAAU,YAAW,MAAM;IACtC,QAAQ,CAAC,SAAS,SAAS;IAErB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;CAiC9E;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @uicontract/parser-vue — Vue/Nuxt parser for UIC.
|
|
3
|
+
* Implements the Parser interface from @uicontract/core.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'node:fs/promises';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
import { discoverFiles } from './file-discovery.js';
|
|
8
|
+
import { parseVueFile } from './sfc-visitor.js';
|
|
9
|
+
export const VERSION = '0.0.0';
|
|
10
|
+
/** Detect whether a directory likely contains a Vue project. */
|
|
11
|
+
async function detectVue(dir) {
|
|
12
|
+
// Check for package.json with vue or nuxt dependency
|
|
13
|
+
try {
|
|
14
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
15
|
+
const raw = await fs.readFile(pkgPath, 'utf-8');
|
|
16
|
+
const pkg = JSON.parse(raw);
|
|
17
|
+
const deps = {
|
|
18
|
+
...(typeof pkg['dependencies'] === 'object' && pkg['dependencies'] !== null
|
|
19
|
+
? pkg['dependencies']
|
|
20
|
+
: {}),
|
|
21
|
+
...(typeof pkg['devDependencies'] === 'object' && pkg['devDependencies'] !== null
|
|
22
|
+
? pkg['devDependencies']
|
|
23
|
+
: {}),
|
|
24
|
+
...(typeof pkg['peerDependencies'] === 'object' && pkg['peerDependencies'] !== null
|
|
25
|
+
? pkg['peerDependencies']
|
|
26
|
+
: {}),
|
|
27
|
+
};
|
|
28
|
+
if ('vue' in deps || 'nuxt' in deps)
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// No package.json or unreadable — fall through to file check
|
|
33
|
+
}
|
|
34
|
+
// Fallback: any .vue file present
|
|
35
|
+
try {
|
|
36
|
+
const files = await discoverFiles(dir, { maxDepth: 3 });
|
|
37
|
+
return files.length > 0;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** The Vue/Nuxt parser implementation. */
|
|
44
|
+
export class VueParser {
|
|
45
|
+
framework = 'vue';
|
|
46
|
+
async detect(dir) {
|
|
47
|
+
return detectVue(dir);
|
|
48
|
+
}
|
|
49
|
+
async discover(dir, options) {
|
|
50
|
+
const startTime = Date.now();
|
|
51
|
+
const warnings = [];
|
|
52
|
+
const elements = [];
|
|
53
|
+
let filesSkipped = 0;
|
|
54
|
+
const files = await discoverFiles(dir, options);
|
|
55
|
+
for (const file of files) {
|
|
56
|
+
try {
|
|
57
|
+
const source = await fs.readFile(file, 'utf-8');
|
|
58
|
+
const fileElements = parseVueFile(source, file, dir);
|
|
59
|
+
elements.push(...fileElements);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
filesSkipped++;
|
|
63
|
+
warnings.push({
|
|
64
|
+
code: 'PARSE_ERROR',
|
|
65
|
+
message: `Failed to parse: ${error instanceof Error ? error.message : String(error)}`,
|
|
66
|
+
filePath: path.relative(dir, file),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
elements,
|
|
72
|
+
warnings,
|
|
73
|
+
metadata: {
|
|
74
|
+
filesScanned: files.length,
|
|
75
|
+
filesSkipped,
|
|
76
|
+
scanDurationMs: Date.now() - startTime,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export const vueParser = new VueParser();
|
|
82
|
+
// Re-export internal modules for consumers that need direct access
|
|
83
|
+
export { discoverFiles } from './file-discovery.js';
|
|
84
|
+
export { parseVueFile } from './sfc-visitor.js';
|
|
85
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SFC template visitor that discovers interactive elements in Vue templates.
|
|
3
|
+
* Uses @vue/compiler-dom to parse the <template> block of .vue files.
|
|
4
|
+
*/
|
|
5
|
+
import type { RawElement } from '@uicontract/core';
|
|
6
|
+
/**
|
|
7
|
+
* Parse a Vue SFC file and return discovered interactive elements.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseVueFile(source: string, absoluteFilePath: string, projectRoot: string): RawElement[];
|
|
10
|
+
//# sourceMappingURL=sfc-visitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfc-visitor.d.ts","sourceRoot":"","sources":["../src/sfc-visitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC;AAoG3E;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,MAAM,GAClB,UAAU,EAAE,CA8Bd"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SFC template visitor that discovers interactive elements in Vue templates.
|
|
3
|
+
* Uses @vue/compiler-dom to parse the <template> block of .vue files.
|
|
4
|
+
*/
|
|
5
|
+
import { parse as compilerParse } from '@vue/compiler-dom';
|
|
6
|
+
import { extractComponentName, extractRoute, extractLabel, extractHandler, extractDataAttributes, isConditional, isDynamic, hasEventDirective, } from './context-extractor.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Constants
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** Interactive HTML element tag names that are always captured. */
|
|
11
|
+
const ALWAYS_INTERACTIVE = new Set([
|
|
12
|
+
'button',
|
|
13
|
+
'input',
|
|
14
|
+
'select',
|
|
15
|
+
'textarea',
|
|
16
|
+
'a',
|
|
17
|
+
'form',
|
|
18
|
+
]);
|
|
19
|
+
/** Elements that are interactive only when they have event handlers. */
|
|
20
|
+
const GENERIC_INTERACTIVE = new Set(['div', 'span', 'img', 'label']);
|
|
21
|
+
/** All valid InteractiveElementType values. */
|
|
22
|
+
const VALID_ELEMENT_TYPES = new Set([
|
|
23
|
+
'button', 'input', 'select', 'textarea', 'a', 'form',
|
|
24
|
+
'div', 'span', 'img', 'label',
|
|
25
|
+
]);
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Template extraction
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Extract the template content and its line offset from a .vue SFC file.
|
|
31
|
+
* Returns null if no <template> block is found.
|
|
32
|
+
*/
|
|
33
|
+
function extractTemplate(source) {
|
|
34
|
+
const openTagPattern = /<template[^>]*>/;
|
|
35
|
+
const closeTag = '</template>';
|
|
36
|
+
const openMatch = openTagPattern.exec(source);
|
|
37
|
+
if (!openMatch)
|
|
38
|
+
return null;
|
|
39
|
+
const contentStart = openMatch.index + openMatch[0].length;
|
|
40
|
+
const closeIndex = source.lastIndexOf(closeTag);
|
|
41
|
+
if (closeIndex === -1 || closeIndex <= contentStart)
|
|
42
|
+
return null;
|
|
43
|
+
const content = source.slice(contentStart, closeIndex);
|
|
44
|
+
// Count newlines before the template content to calculate line offset
|
|
45
|
+
const lineOffset = source.slice(0, contentStart).split('\n').length - 1;
|
|
46
|
+
return { content, lineOffset };
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Public API
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
/**
|
|
52
|
+
* Parse a Vue SFC file and return discovered interactive elements.
|
|
53
|
+
*/
|
|
54
|
+
export function parseVueFile(source, absoluteFilePath, projectRoot) {
|
|
55
|
+
const template = extractTemplate(source);
|
|
56
|
+
if (!template)
|
|
57
|
+
return [];
|
|
58
|
+
let ast;
|
|
59
|
+
try {
|
|
60
|
+
ast = compilerParse(template.content);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const elements = [];
|
|
66
|
+
const componentName = extractComponentName(absoluteFilePath);
|
|
67
|
+
const route = extractRoute(absoluteFilePath, projectRoot);
|
|
68
|
+
const relFilePath = absoluteFilePath
|
|
69
|
+
.replace(/\\/g, '/')
|
|
70
|
+
.replace(projectRoot.replace(/\\/g, '/').replace(/\/?$/, '/'), '');
|
|
71
|
+
walkNode(ast, elements, relFilePath, componentName, route, template.lineOffset, []);
|
|
72
|
+
return elements;
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// AST walking
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
function walkNode(node, elements, filePath, componentName, route, lineOffset, ancestors) {
|
|
78
|
+
const children = node.children;
|
|
79
|
+
if (!children)
|
|
80
|
+
return;
|
|
81
|
+
for (const child of children) {
|
|
82
|
+
if (child.type === 1) {
|
|
83
|
+
// NodeTypes.ELEMENT
|
|
84
|
+
const elementNode = child;
|
|
85
|
+
processElement(elementNode, elements, filePath, componentName, route, lineOffset, ancestors);
|
|
86
|
+
walkNode(child, elements, filePath, componentName, route, lineOffset, [...ancestors, elementNode]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function processElement(node, elements, filePath, componentName, route, lineOffset, ancestors) {
|
|
91
|
+
const tag = node.tag;
|
|
92
|
+
const isAlwaysInteractive = ALWAYS_INTERACTIVE.has(tag);
|
|
93
|
+
const isGenericWithHandler = GENERIC_INTERACTIVE.has(tag) && hasEventDirective(node);
|
|
94
|
+
if (!isAlwaysInteractive && !isGenericWithHandler)
|
|
95
|
+
return;
|
|
96
|
+
if (!VALID_ELEMENT_TYPES.has(tag))
|
|
97
|
+
return;
|
|
98
|
+
const elementType = tag;
|
|
99
|
+
const line = node.loc.start.line + lineOffset;
|
|
100
|
+
const column = node.loc.start.column;
|
|
101
|
+
elements.push({
|
|
102
|
+
type: elementType,
|
|
103
|
+
filePath,
|
|
104
|
+
line,
|
|
105
|
+
column,
|
|
106
|
+
componentName,
|
|
107
|
+
route,
|
|
108
|
+
label: extractLabel(node),
|
|
109
|
+
handler: extractHandler(node),
|
|
110
|
+
attributes: extractDataAttributes(node),
|
|
111
|
+
conditional: isConditional(node, ancestors),
|
|
112
|
+
dynamic: isDynamic(ancestors),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=sfc-visitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfc-visitor.js","sourceRoot":"","sources":["../src/sfc-visitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,mEAAmE;AACnE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAS;IACzC,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,UAAU;IACV,GAAG;IACH,MAAM;CACP,CAAC,CAAC;AAEH,wEAAwE;AACxE,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7E,+CAA+C;AAC/C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS;IAC1C,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM;IACpD,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAC9B,CAAC,CAAC;AAoCH,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,cAAc,GAAG,iBAAiB,CAAC;IACzC,MAAM,QAAQ,GAAG,aAAa,CAAC;IAE/B,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5B,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,UAAU,IAAI,YAAY;QAAE,OAAO,IAAI,CAAC;IAEjE,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAEvD,sEAAsE;IACtE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAExE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACjC,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,gBAAwB,EACxB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEzB,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,MAAM,aAAa,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAE1D,MAAM,WAAW,GAAG,gBAAgB;SACjC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAErE,QAAQ,CACN,GAA8B,EAC9B,QAAQ,EACR,WAAW,EACX,aAAa,EACb,KAAK,EACL,QAAQ,CAAC,UAAU,EACnB,EAAE,CACH,CAAC;IAEF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,SAAS,QAAQ,CACf,IAAkB,EAClB,QAAsB,EACtB,QAAgB,EAChB,aAA4B,EAC5B,KAAoB,EACpB,UAAkB,EAClB,SAA2B;IAE3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,IAAI,CAAC,QAAQ;QAAE,OAAO;IAEtB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACrB,oBAAoB;YACpB,MAAM,WAAW,GAAG,KAAkC,CAAC;YACvD,cAAc,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YAC7F,QAAQ,CACN,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,KAAK,EACL,UAAU,EACV,CAAC,GAAG,SAAS,EAAE,WAAW,CAAC,CAC5B,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CACrB,IAAoB,EACpB,QAAsB,EACtB,QAAgB,EAChB,aAA4B,EAC5B,KAAoB,EACpB,UAAkB,EAClB,SAA2B;IAE3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IAErB,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAErF,IAAI,CAAC,mBAAmB,IAAI,CAAC,oBAAoB;QAAE,OAAO;IAE1D,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAE1C,MAAM,WAAW,GAAG,GAA6B,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;IAErC,QAAQ,CAAC,IAAI,CAAC;QACZ,IAAI,EAAE,WAAW;QACjB,QAAQ;QACR,IAAI;QACJ,MAAM;QACN,aAAa;QACb,KAAK;QACL,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC;QACzB,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;QAC7B,UAAU,EAAE,qBAAqB,CAAC,IAAI,CAAC;QACvC,WAAW,EAAE,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC;QAC3C,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uicontract/parser-vue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue and Nuxt parser for discovering interactive UI elements",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "UIC Contributors",
|
|
8
|
+
"homepage": "https://github.com/sherifkozman/uicontract/tree/main/packages/parser-vue",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/sherifkozman/uicontract.git",
|
|
12
|
+
"directory": "packages/parser-vue"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/sherifkozman/uicontract/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"uic",
|
|
19
|
+
"ui-contracts",
|
|
20
|
+
"parser",
|
|
21
|
+
"vue",
|
|
22
|
+
"nuxt",
|
|
23
|
+
"ast"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@vue/compiler-dom": "^3.5.0",
|
|
46
|
+
"@uicontract/core": "0.1.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc -b",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"lint": "eslint src"
|
|
53
|
+
}
|
|
54
|
+
}
|