Skip to content

Commit 7d91101

Browse files
committed
feat: support extendComponentMeta in component parser utility
1 parent 0d6a0a7 commit 7d91101

File tree

3 files changed

+101
-2
lines changed

3 files changed

+101
-2
lines changed

src/parser/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { isAbsolute, join } from "pathe"
55
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'
66
import { withBase } from "ufo"
77
import { hash } from "crypto"
8+
import { defu } from 'defu'
89

910
export interface Options {
1011
rootDir: string
@@ -66,7 +67,18 @@ function _getComponentMeta(fullPath: string, opts: Options) {
6667
exclude: []
6768
},
6869
)
69-
return refineMeta(
70+
71+
const baseMeta = refineMeta(
7072
checker.getComponentMeta(fullPath)
7173
)
72-
}
74+
75+
// Apply extendComponentMeta(...) overrides from the component source
76+
try {
77+
const code = readFileSync(fullPath, 'utf-8')
78+
const extendComponentMetaMatch = code.match(/extendComponentMeta\((\{[\s\S]*?\})\)/)
79+
const extendedComponentMeta = extendComponentMetaMatch?.length ? eval(`(${extendComponentMetaMatch[1]})`) : null
80+
return defu(baseMeta, extendedComponentMeta) as ComponentMeta
81+
} catch {
82+
return baseMeta
83+
}
84+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<template>
2+
<div>
3+
<h3>Extended Meta Component</h3>
4+
<p>This component has extended metadata</p>
5+
<slot />
6+
</div>
7+
</template>
8+
9+
<script setup>
10+
11+
extendComponentMeta({
12+
description: 'A component that demonstrates extendComponentMeta functionality',
13+
version: '1.0.0',
14+
tags: ['test', 'meta'],
15+
customData: {
16+
for: 'Test Suite',
17+
category: 'utility'
18+
}
19+
})
20+
21+
defineProps({
22+
title: {
23+
type: String,
24+
default: 'Default Title'
25+
},
26+
enabled: {
27+
type: Boolean,
28+
default: true
29+
}
30+
})
31+
32+
defineEmits(['updated'])
33+
34+
</script>

test/get-component-meta.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,57 @@ describe("get-component-meta", () => {
3838
expect(meta.props.length).toEqual(4);
3939
expect((meta as unknown as Record<string, unknown>).cachedAt).toBeDefined();
4040
});
41+
42+
test("parse ExtendMetaComponent with extendComponentMeta", { timeout: 10000 }, () => {
43+
const meta = getComponentMeta("components/ExtendMetaComponent.vue", {
44+
rootDir,
45+
})
46+
47+
// Check basic component metadata from defineProps/defineEmits
48+
expect(meta.props.length).toEqual(2); // title, enabled
49+
expect(meta.props.find(p => p.name === 'title')).toBeDefined();
50+
expect(meta.props.find(p => p.name === 'enabled')).toBeDefined();
51+
expect(meta.events.length).toEqual(1);
52+
expect(meta.events[0].name).toEqual('updated');
53+
54+
// Check that extendComponentMeta adds custom metadata fields
55+
const extendedMeta = meta as unknown as Record<string, unknown>;
56+
expect(extendedMeta.description).toEqual('A component that demonstrates extendComponentMeta functionality');
57+
expect(extendedMeta.version).toEqual('1.0.0');
58+
expect(extendedMeta.tags).toEqual(['test', 'meta']);
59+
expect(extendedMeta.customData).toEqual({
60+
for: 'Test Suite',
61+
category: 'utility'
62+
});
63+
});
64+
65+
test("parse ExtendMetaComponent with extendComponentMeta (cached)", { timeout: 10000 }, () => {
66+
const meta = getComponentMeta("components/ExtendMetaComponent.vue", {
67+
rootDir,
68+
cache: true
69+
})
70+
71+
// Check that extendComponentMeta custom fields persist through caching
72+
const extendedMeta = meta as unknown as Record<string, unknown>;
73+
expect(extendedMeta.description).toEqual('A component that demonstrates extendComponentMeta functionality');
74+
expect(extendedMeta.version).toEqual('1.0.0');
75+
expect(extendedMeta.tags).toEqual(['test', 'meta']);
76+
expect(extendedMeta.customData).toEqual({
77+
for: 'Test Suite',
78+
category: 'utility'
79+
});
80+
expect(extendedMeta.cachedAt).toBeUndefined();
81+
});
82+
83+
test("parse ExtendMetaComponent cached retrieval", { timeout: 10000 }, () => {
84+
const meta = getComponentMeta("components/ExtendMetaComponent.vue", {
85+
rootDir,
86+
cache: true
87+
})
88+
89+
// Check that extendComponentMeta custom fields are preserved in cached version
90+
const extendedMeta = meta as unknown as Record<string, unknown>;
91+
expect(extendedMeta.description).toEqual('A component that demonstrates extendComponentMeta functionality');
92+
expect(extendedMeta.cachedAt).toBeDefined();
93+
});
4194
});

0 commit comments

Comments
 (0)