@component-compass/parser-vue 0.0.0-pr-3-8916f3c-20260507145532

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @component-compass/parser-vue
2
+
3
+ Consumer-scan parser for Vue Single-File Components. Detects component usages in `.vue` files (template blocks + script imports).
4
+
5
+ Used by `@component-compass/cli` at scan time.
@@ -0,0 +1,2 @@
1
+ import type { ParserPlugin } from "@component-compass/plugin-core";
2
+ export declare const vuePlugin: ParserPlugin;
package/dist/index.js ADDED
@@ -0,0 +1,110 @@
1
+ import { basename, extname } from "node:path";
2
+ import { serialiseComponentId, externalPackageOf } from "@component-compass/plugin-core";
3
+ import { asWrapperId } from "@component-compass/plugin-core";
4
+ import { posixPath } from "@component-compass/ast-utils";
5
+ import { splitSfc } from "./parse-sfc.js";
6
+ import { walkVueTemplate } from "./walk-template.js";
7
+ import { extractScriptImports } from "./script-imports.js";
8
+ function wrapperIdFromName(name) {
9
+ const kebab = name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
10
+ return asWrapperId(`wrap-${kebab.replaceAll(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")}`);
11
+ }
12
+ function vueTagForms(importName) {
13
+ const lowercased = importName.toLowerCase();
14
+ // Vue convention: PascalCase like `VBtn` becomes kebab `v-btn`. Insert a hyphen
15
+ // before any uppercase letter that is preceded by a letter/digit (handles both
16
+ // `aB`→`a-b` and the leading-uppercase case `VB`→`v-b`).
17
+ const kebab = importName
18
+ .replace(/([A-Za-z0-9])([A-Z])/g, "$1-$2")
19
+ .toLowerCase();
20
+ return Array.from(new Set([lowercased, kebab]));
21
+ }
22
+ export const vuePlugin = {
23
+ name: "vue",
24
+ extensions: [".vue"],
25
+ parse(file, source, ctx) {
26
+ const parts = splitSfc(source);
27
+ const warnings = parts.errors.map((e) => ({
28
+ code: "PARSE_FAILURE",
29
+ message: `SFC parse error: ${e.message}`,
30
+ file,
31
+ // line: 0 means "unknown" when the SFC parser didn't surface a location.
32
+ line: typeof e.line === "number" ? e.line : 0,
33
+ }));
34
+ let imports = [];
35
+ let importSpecs = [];
36
+ if (parts.scriptSource) {
37
+ const scriptResult = extractScriptImports({
38
+ file,
39
+ source: parts.scriptSource,
40
+ lang: parts.scriptLang ?? "js",
41
+ });
42
+ imports = scriptResult.imports;
43
+ importSpecs = scriptResult.importSpecs;
44
+ warnings.push(...scriptResult.warnings);
45
+ }
46
+ if (!parts.templateSource) {
47
+ return { occurrences: [], wrappers: [], imports, warnings };
48
+ }
49
+ // Build map of template tag (lowercased + kebab forms) → vue-direct binding,
50
+ // for direct Vue DS imports that resolve to a vue-component manifest entry.
51
+ const templateBindings = new Map();
52
+ // Track imports that did NOT match a manifest entry for opportunistic classification.
53
+ const unmappedBindings = new Map();
54
+ for (const spec of importSpecs) {
55
+ const indexed = ctx.index.byImport.get(`${spec.source}::${spec.imported}`);
56
+ if (indexed?.kind === "vue-component") {
57
+ const binding = {
58
+ kind: "vue-direct",
59
+ package: externalPackageOf(indexed.source),
60
+ export: indexed.export,
61
+ specifier: spec.source,
62
+ importName: spec.imported,
63
+ };
64
+ for (const form of vueTagForms(spec.local)) {
65
+ templateBindings.set(form, binding);
66
+ }
67
+ }
68
+ else if (!indexed) {
69
+ // No manifest match — track for opportunistic classification.
70
+ const unmapped = {
71
+ kind: "vue-unmapped",
72
+ importedName: spec.imported,
73
+ specifier: spec.source,
74
+ };
75
+ for (const form of vueTagForms(spec.local)) {
76
+ unmappedBindings.set(form, unmapped);
77
+ }
78
+ }
79
+ }
80
+ const lineOffset = source.slice(0, parts.templateOffset ?? 0).split("\n").length - 1;
81
+ const occurrences = walkVueTemplate(file, parts.templateSource, ctx.index, templateBindings, ctx.config.captureValues, lineOffset, unmappedBindings, ctx.repoRoot);
82
+ if (occurrences.length === 0) {
83
+ return { occurrences: [], wrappers: [], imports, warnings };
84
+ }
85
+ const componentName = basename(file, extname(file));
86
+ const seen = new Set();
87
+ const componentDeps = [];
88
+ for (const o of occurrences) {
89
+ const key = serialiseComponentId(o.componentId);
90
+ if (seen.has(key))
91
+ continue;
92
+ seen.add(key);
93
+ componentDeps.push(o.componentId);
94
+ }
95
+ const wrapper = {
96
+ id: wrapperIdFromName(componentName),
97
+ name: componentName,
98
+ file: posixPath(file),
99
+ exportName: "default",
100
+ componentDeps,
101
+ };
102
+ return {
103
+ occurrences,
104
+ wrappers: [wrapper],
105
+ imports,
106
+ warnings,
107
+ };
108
+ },
109
+ };
110
+ //# 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,11 @@
1
+ export type SfcParts = {
2
+ templateSource?: string;
3
+ templateOffset?: number;
4
+ scriptSource?: string;
5
+ scriptLang?: "ts" | "js";
6
+ errors: Array<{
7
+ message: string;
8
+ line?: number;
9
+ }>;
10
+ };
11
+ export declare function splitSfc(source: string): SfcParts;
@@ -0,0 +1,32 @@
1
+ import { parse } from "@vue/compiler-sfc";
2
+ import { errorMessage } from "@component-compass/ast-utils";
3
+ export function splitSfc(source) {
4
+ const { descriptor, errors } = parse(source);
5
+ const result = {
6
+ errors: errors.map((e) => {
7
+ const line = lineFromVueError(e);
8
+ return {
9
+ ...(line !== undefined ? { line } : {}),
10
+ message: `SFC parse error: ${errorMessage(e)}`,
11
+ };
12
+ }),
13
+ };
14
+ if (descriptor.template) {
15
+ result.templateSource = descriptor.template.content;
16
+ result.templateOffset = descriptor.template.loc.start.offset;
17
+ }
18
+ const script = descriptor.scriptSetup ?? descriptor.script;
19
+ if (script) {
20
+ result.scriptSource = script.content;
21
+ result.scriptLang = script.lang === "ts" ? "ts" : "js";
22
+ }
23
+ return result;
24
+ }
25
+ function lineFromVueError(e) {
26
+ if (typeof e !== "object" || e === null || !("loc" in e))
27
+ return undefined;
28
+ const loc = e.loc;
29
+ const line = loc?.start?.line;
30
+ return typeof line === "number" ? line : undefined;
31
+ }
32
+ //# sourceMappingURL=parse-sfc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-sfc.js","sourceRoot":"","sources":["../src/parse-sfc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAU5D,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAa;QACvB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACvB,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACjC,OAAO;gBACL,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,OAAO,EAAE,oBAAoB,YAAY,CAAC,CAAC,CAAC,EAAE;aAC/C,CAAC;QACJ,CAAC,CAAC;KACH,CAAC;IACF,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;QACxB,MAAM,CAAC,cAAc,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;QACpD,MAAM,CAAC,cAAc,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;IAC/D,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,IAAI,UAAU,CAAC,MAAM,CAAC;IAC3D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC;QACrC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAU;IAClC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3E,MAAM,GAAG,GAAI,CAA6C,CAAC,GAAG,CAAC;IAC/D,MAAM,IAAI,GAAG,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC;IAC9B,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { FileImport, Warning } from "@component-compass/plugin-core";
2
+ export type ExtractOptions = {
3
+ file: string;
4
+ source: string;
5
+ lang: "ts" | "js";
6
+ };
7
+ export type ImportSpec = {
8
+ /** Local binding name as written in the script (after `as` rename, if any). */
9
+ local: string;
10
+ /** Imported export name from the source module. "default" for default imports; "*" for namespace imports. */
11
+ imported: string;
12
+ source: string;
13
+ };
14
+ export type ExtractResult = {
15
+ imports: FileImport[];
16
+ /** Structured imports carrying both local + imported names; used for resolver lookups. */
17
+ importSpecs: ImportSpec[];
18
+ warnings: Warning[];
19
+ };
20
+ export declare function extractScriptImports(opts: ExtractOptions): ExtractResult;
@@ -0,0 +1,72 @@
1
+ import { parse } from "@babel/parser";
2
+ import { posixPath, errorMessage, traverse } from "@component-compass/ast-utils";
3
+ export function extractScriptImports(opts) {
4
+ const imports = [];
5
+ const importSpecs = [];
6
+ const warnings = [];
7
+ let ast;
8
+ try {
9
+ ast = parse(opts.source, {
10
+ sourceType: "module",
11
+ plugins: opts.lang === "ts" ? ["typescript"] : [],
12
+ errorRecovery: true,
13
+ });
14
+ }
15
+ catch (e) {
16
+ warnings.push({
17
+ code: "PARSE_FAILURE",
18
+ message: `SFC script parse error: ${errorMessage(e)}`,
19
+ file: opts.file,
20
+ // line: 0 means "unknown" — Babel didn't surface a location for this error.
21
+ line: 0,
22
+ });
23
+ return { imports, importSpecs, warnings };
24
+ }
25
+ const recovered = ast.errors ?? [];
26
+ for (const err of recovered) {
27
+ warnings.push({
28
+ code: "PARSE_FAILURE",
29
+ message: `Recovered SFC script parse error: ${err.message}`,
30
+ file: opts.file,
31
+ // line: 0 means "unknown" when Babel didn't supply a location.
32
+ line: typeof err.loc?.line === "number" ? err.loc.line : 0,
33
+ });
34
+ }
35
+ const filePosix = posixPath(opts.file);
36
+ traverse(ast, {
37
+ ImportDeclaration(path) {
38
+ const source = path.node.source.value;
39
+ for (const spec of path.node.specifiers) {
40
+ if (spec.type !== "ImportSpecifier" &&
41
+ spec.type !== "ImportDefaultSpecifier" &&
42
+ spec.type !== "ImportNamespaceSpecifier") {
43
+ continue;
44
+ }
45
+ const local = spec.local.name;
46
+ const line = spec.loc?.start.line ?? 1;
47
+ const column = (spec.loc?.start.column ?? 0) + 1;
48
+ imports.push({
49
+ file: filePosix,
50
+ imported: local,
51
+ source,
52
+ loc: { file: filePosix, line, column },
53
+ });
54
+ let importedName;
55
+ if (spec.type === "ImportDefaultSpecifier") {
56
+ importedName = "default";
57
+ }
58
+ else if (spec.type === "ImportNamespaceSpecifier") {
59
+ importedName = "*";
60
+ }
61
+ else {
62
+ // ImportSpecifier
63
+ const imp = spec.imported;
64
+ importedName = imp.type === "Identifier" ? imp.name : imp.value;
65
+ }
66
+ importSpecs.push({ local, imported: importedName, source });
67
+ }
68
+ },
69
+ });
70
+ return { imports, importSpecs, warnings };
71
+ }
72
+ //# sourceMappingURL=script-imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-imports.js","sourceRoot":"","sources":["../src/script-imports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ComponentIndex, Occurrence } from "@component-compass/plugin-core";
2
+ export type VueDirectBinding = {
3
+ kind: "vue-direct";
4
+ package: string;
5
+ export: string;
6
+ specifier: string;
7
+ importName: string;
8
+ };
9
+ export type VueUnmappedBinding = {
10
+ kind: "vue-unmapped";
11
+ /** The original imported export name (e.g. "Button" or "default"). */
12
+ importedName: string;
13
+ /** The import specifier (module path). */
14
+ specifier: string;
15
+ };
16
+ export declare function walkVueTemplate(file: string, template: string, index: ComponentIndex, templateBindings: Map<string, VueDirectBinding>, captureValues: boolean, lineOffset: number, unmappedBindings?: Map<string, VueUnmappedBinding>, repoRoot?: string): Occurrence[];
@@ -0,0 +1,222 @@
1
+ import { parseFragment } from "parse5";
2
+ import { asTagName, externalPackageOf } from "@component-compass/plugin-core";
3
+ import { posixPath, isElement, hasChildren, classifyImportOrigin } from "@component-compass/ast-utils";
4
+ export function walkVueTemplate(file, template, index, templateBindings, captureValues, lineOffset, unmappedBindings, repoRoot) {
5
+ const occurrences = [];
6
+ const doc = parseFragment(template, { sourceCodeLocationInfo: true });
7
+ function visit(node) {
8
+ if (isElement(node)) {
9
+ const rawTag = node.tagName;
10
+ const indexedWc = index.byTag.get(rawTag);
11
+ if (indexedWc) {
12
+ emitWcOccurrence(node, indexedWc);
13
+ }
14
+ else {
15
+ const direct = templateBindings.get(rawTag);
16
+ if (direct) {
17
+ emitVueDirectOccurrence(node, direct);
18
+ }
19
+ else if (unmappedBindings && repoRoot) {
20
+ const unmapped = unmappedBindings.get(rawTag);
21
+ if (unmapped) {
22
+ const origin = classifyImportOrigin(unmapped.specifier, {
23
+ repoRoot,
24
+ fromFile: file,
25
+ });
26
+ if (origin.type === "external") {
27
+ emitOpportunisticVueOccurrence(node, unmapped, origin.package);
28
+ }
29
+ else if (origin.type === "local") {
30
+ const localDefs = index.local.byPath.get(origin.filePath);
31
+ const matched = localDefs?.find((d) => unmapped.importedName === "default"
32
+ ? d.isDefault
33
+ : d.exportName === unmapped.importedName && !d.isDefault);
34
+ if (matched && matched.componentId.kind === "vue-component") {
35
+ emitLocalVueOccurrence(node, unmapped, matched.componentId);
36
+ }
37
+ // Miss → skip silently.
38
+ }
39
+ // unresolved → skip silently
40
+ }
41
+ else if (rawTag.includes("-")) {
42
+ // Hyphenated tag not in index: emit unknown-source custom-element
43
+ emitUnknownWcOccurrence(node);
44
+ }
45
+ }
46
+ else if (rawTag.includes("-") && !index.byTag.has(rawTag)) {
47
+ // No unmapped bindings provided but tag is hyphenated and not in index
48
+ emitUnknownWcOccurrence(node);
49
+ }
50
+ }
51
+ for (const child of node.childNodes)
52
+ visit(child);
53
+ }
54
+ else if (hasChildren(node)) {
55
+ for (const child of node.childNodes)
56
+ visit(child);
57
+ }
58
+ }
59
+ function emitWcOccurrence(node, indexed) {
60
+ const tag = asTagName(node.tagName);
61
+ const { props, events } = readAttrs(node, captureValues);
62
+ const loc = node.sourceCodeLocation;
63
+ occurrences.push({
64
+ componentId: { kind: "custom-element", tagName: tag, source: { type: "external", package: externalPackageOf(indexed.source) } },
65
+ loc: {
66
+ file: posixPath(file),
67
+ line: (loc?.startLine ?? 1) + lineOffset,
68
+ column: loc?.startCol ?? 1,
69
+ },
70
+ via: { kind: "html-tag" },
71
+ props,
72
+ events,
73
+ });
74
+ }
75
+ function emitOpportunisticVueOccurrence(node, binding, pkg) {
76
+ const { props, events } = readAttrs(node, captureValues);
77
+ const loc = node.sourceCodeLocation;
78
+ const via = {
79
+ kind: "vue-template",
80
+ specifier: binding.specifier,
81
+ import: binding.importedName,
82
+ };
83
+ occurrences.push({
84
+ componentId: { kind: "vue-component", export: binding.importedName, source: { type: "external", package: pkg } },
85
+ loc: {
86
+ file: posixPath(file),
87
+ line: (loc?.startLine ?? 1) + lineOffset,
88
+ column: loc?.startCol ?? 1,
89
+ },
90
+ via,
91
+ props,
92
+ events,
93
+ });
94
+ }
95
+ function emitLocalVueOccurrence(node, binding, componentId) {
96
+ const { props, events } = readAttrs(node, captureValues);
97
+ const loc = node.sourceCodeLocation;
98
+ const via = {
99
+ kind: "vue-template",
100
+ specifier: binding.specifier,
101
+ import: binding.importedName,
102
+ };
103
+ occurrences.push({
104
+ componentId,
105
+ loc: {
106
+ file: posixPath(file),
107
+ line: (loc?.startLine ?? 1) + lineOffset,
108
+ column: loc?.startCol ?? 1,
109
+ },
110
+ via,
111
+ props,
112
+ events,
113
+ });
114
+ }
115
+ function emitUnknownWcOccurrence(node) {
116
+ const tag = asTagName(node.tagName);
117
+ const { props, events } = readAttrs(node, captureValues);
118
+ const loc = node.sourceCodeLocation;
119
+ occurrences.push({
120
+ componentId: { kind: "custom-element", tagName: tag, source: { type: "unknown" } },
121
+ loc: {
122
+ file: posixPath(file),
123
+ line: (loc?.startLine ?? 1) + lineOffset,
124
+ column: loc?.startCol ?? 1,
125
+ },
126
+ via: { kind: "html-tag" },
127
+ props,
128
+ events,
129
+ });
130
+ }
131
+ function emitVueDirectOccurrence(node, binding) {
132
+ const { props, events } = readAttrs(node, captureValues);
133
+ const loc = node.sourceCodeLocation;
134
+ const via = {
135
+ kind: "vue-template",
136
+ specifier: binding.specifier,
137
+ import: binding.importName,
138
+ };
139
+ occurrences.push({
140
+ componentId: { kind: "vue-component", export: binding.export, source: { type: "external", package: binding.package } },
141
+ loc: {
142
+ file: posixPath(file),
143
+ line: (loc?.startLine ?? 1) + lineOffset,
144
+ column: loc?.startCol ?? 1,
145
+ },
146
+ via,
147
+ props,
148
+ events,
149
+ });
150
+ }
151
+ visit(doc);
152
+ return occurrences;
153
+ }
154
+ const IDENT_RE = /^[A-Za-z_$][\w$]*$/;
155
+ const QUOTED_STRING_RE = /^(['"])(.*)\1$/s;
156
+ const NUMERIC_RE = /^-?\d+(\.\d+)?$/;
157
+ const BOOLEAN_RE = /^(true|false)$/;
158
+ function readAttrs(el, captureValues) {
159
+ const props = [];
160
+ const events = [];
161
+ for (const attr of el.attrs) {
162
+ if (/^@|^v-on:/.test(attr.name)) {
163
+ events.push(attr.name.replace(/^@|^v-on:/, ""));
164
+ continue;
165
+ }
166
+ // Bare `v-bind="obj"` (no arg) → spread sentinel, deduped.
167
+ if (attr.name === "v-bind") {
168
+ if (props.some((p) => p.name === "...rest"))
169
+ continue;
170
+ props.push({ name: "...rest", isDynamic: true, dynamicKind: "spread" });
171
+ continue;
172
+ }
173
+ // Other Vue directives that aren't prop bindings → ignore.
174
+ if (/^v-/.test(attr.name) && !/^v-bind:/.test(attr.name))
175
+ continue;
176
+ if (/^[:.]|^v-bind:/.test(attr.name)) {
177
+ const name = attr.name.replace(/^[:.]|^v-bind:/, "");
178
+ const expr = attr.value.trim();
179
+ const usage = classifyBindExpr(name, expr, captureValues);
180
+ props.push(usage);
181
+ continue;
182
+ }
183
+ // Static attribute. parse5 reports value `""` for boolean shorthand.
184
+ const usage = { name: attr.name, isDynamic: false };
185
+ if (captureValues) {
186
+ // Boolean shorthand: <X foo /> → literalValue: true.
187
+ // The HTML parser exposes both `<X foo>` and `<X foo="">` as value `""`.
188
+ // Treat empty value as boolean shorthand for consistency with the
189
+ // three-state model; explicit empty strings on Vue attributes are
190
+ // exceedingly rare in practice.
191
+ usage.literalValue = attr.value === "" ? true : attr.value;
192
+ }
193
+ props.push(usage);
194
+ }
195
+ return { props, events };
196
+ }
197
+ function classifyBindExpr(name, expr, captureValues) {
198
+ const quoted = expr.match(QUOTED_STRING_RE);
199
+ if (quoted) {
200
+ const usage = { name, isDynamic: false };
201
+ if (captureValues)
202
+ usage.literalValue = quoted[2] ?? "";
203
+ return usage;
204
+ }
205
+ if (NUMERIC_RE.test(expr)) {
206
+ const usage = { name, isDynamic: false };
207
+ if (captureValues)
208
+ usage.literalValue = Number(expr);
209
+ return usage;
210
+ }
211
+ if (BOOLEAN_RE.test(expr)) {
212
+ const usage = { name, isDynamic: false };
213
+ if (captureValues)
214
+ usage.literalValue = expr === "true";
215
+ return usage;
216
+ }
217
+ if (IDENT_RE.test(expr)) {
218
+ return { name, isDynamic: true, dynamicKind: "identifier" };
219
+ }
220
+ return { name, isDynamic: true, dynamicKind: "expr" };
221
+ }
222
+ //# sourceMappingURL=walk-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk-template.js","sourceRoot":"","sources":["../src/walk-template.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@component-compass/parser-vue",
3
+ "version": "0.0.0-pr-3-8916f3c-20260507145532",
4
+ "description": "Consumer-scan parser for Vue Single-File Components. Detects component usages in .vue files.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "componentCompass": {
10
+ "kind": "parser"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "test": "vitest run --passWithNoTests",
25
+ "typecheck": "tsc --noEmit",
26
+ "lint": "biome lint src tests",
27
+ "clean": "rm -rf dist .turbo"
28
+ },
29
+ "dependencies": {
30
+ "@babel/parser": "^7.29.0",
31
+ "@component-compass/ast-utils": "0.0.0-pr-3-8916f3c-20260507145532",
32
+ "@component-compass/plugin-core": "0.0.0-pr-3-8916f3c-20260507145532",
33
+ "@vue/compiler-sfc": "^3.5.33",
34
+ "parse5": "^8.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^24.0.0",
38
+ "typescript": "^5.9.0",
39
+ "vitest": "^4.0.0"
40
+ },
41
+ "engines": {
42
+ "node": ">=24"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ }
47
+ }