vue-component-meta 0.39.0 → 0.39.4
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/out/index.d.ts +5 -24
- package/out/index.js +400 -65
- package/out/types.d.ts +62 -0
- package/out/types.js +4 -0
- package/package.json +4 -3
package/out/index.d.ts
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type: string;
|
|
7
|
-
documentationComment: string;
|
|
8
|
-
}[];
|
|
9
|
-
events: {
|
|
10
|
-
name: any;
|
|
11
|
-
parametersType: string;
|
|
12
|
-
parameters: {
|
|
13
|
-
name: string;
|
|
14
|
-
type: string;
|
|
15
|
-
isOptional: string;
|
|
16
|
-
}[];
|
|
17
|
-
documentationComment: string;
|
|
18
|
-
}[];
|
|
19
|
-
slots: {
|
|
20
|
-
name: string;
|
|
21
|
-
propsType: string;
|
|
22
|
-
documentationComment: string;
|
|
23
|
-
}[];
|
|
24
|
-
};
|
|
1
|
+
import type { MetaCheckerOptions, ComponentMeta, EventMeta, ExposeMeta, MetaCheckerSchemaOptions, PropertyMeta, PropertyMetaSchema, SlotMeta } from './types';
|
|
2
|
+
export type { MetaCheckerOptions, ComponentMeta, EventMeta, ExposeMeta, MetaCheckerSchemaOptions, PropertyMeta, PropertyMetaSchema, SlotMeta };
|
|
3
|
+
export declare function createComponentMetaChecker(tsconfigPath: string, checkerOptions?: MetaCheckerOptions): {
|
|
4
|
+
getExportNames: (componentPath: string) => string[];
|
|
5
|
+
getComponentMeta: (componentPath: string, exportName?: string) => ComponentMeta;
|
|
25
6
|
};
|
package/out/index.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createComponentMetaChecker = void 0;
|
|
4
4
|
const vue = require("@volar/vue-language-core");
|
|
5
5
|
const ts = require("typescript/lib/tsserverlibrary");
|
|
6
|
-
function createComponentMetaChecker(tsconfigPath) {
|
|
6
|
+
function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
|
|
7
7
|
const parsedCommandLine = vue.tsShared.createParsedCommandLine(ts, {
|
|
8
8
|
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
|
|
9
9
|
readDirectory: (path, extensions, exclude, include, depth) => {
|
|
@@ -13,98 +13,127 @@ function createComponentMetaChecker(tsconfigPath) {
|
|
|
13
13
|
readFile: ts.sys.readFile,
|
|
14
14
|
}, tsconfigPath);
|
|
15
15
|
const scriptSnapshot = {};
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
const globalComponentName = tsconfigPath.replace(/\\/g, '/') + '.global.ts';
|
|
17
|
+
const host = Object.assign(Object.assign({}, ts.sys), { getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options), useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, getCompilationSettings: () => parsedCommandLine.options, getScriptFileNames: () => {
|
|
18
|
+
return [
|
|
19
|
+
...parsedCommandLine.fileNames,
|
|
20
|
+
...parsedCommandLine.fileNames.map(getMetaFileName),
|
|
21
|
+
globalComponentName,
|
|
22
|
+
getMetaFileName(globalComponentName),
|
|
23
|
+
];
|
|
24
24
|
}, getProjectReferences: () => parsedCommandLine.projectReferences, getScriptVersion: (fileName) => '0', getScriptSnapshot: (fileName) => {
|
|
25
25
|
if (!scriptSnapshot[fileName]) {
|
|
26
|
-
|
|
26
|
+
let fileText;
|
|
27
|
+
if (fileName.endsWith('.meta.ts')) {
|
|
28
|
+
fileText = getMetaScriptContent(fileName);
|
|
29
|
+
}
|
|
30
|
+
else if (fileName === globalComponentName) {
|
|
31
|
+
fileText = `
|
|
32
|
+
import { defineComponent } from 'vue';
|
|
33
|
+
export default defineComponent({});
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
fileText = ts.sys.readFile(fileName);
|
|
38
|
+
}
|
|
27
39
|
if (fileText !== undefined) {
|
|
28
40
|
scriptSnapshot[fileName] = ts.ScriptSnapshot.fromString(fileText);
|
|
29
41
|
}
|
|
30
42
|
}
|
|
31
43
|
return scriptSnapshot[fileName];
|
|
32
|
-
}, getTypeScriptModule: () => ts, getVueCompilationSettings: () => parsedCommandLine.vueOptions })
|
|
33
|
-
const
|
|
44
|
+
}, getTypeScriptModule: () => ts, getVueCompilationSettings: () => parsedCommandLine.vueOptions });
|
|
45
|
+
const core = vue.createLanguageContext(host);
|
|
46
|
+
const proxyApis = checkerOptions.forceUseTs ? {
|
|
47
|
+
getScriptKind: (fileName) => {
|
|
48
|
+
if (fileName.endsWith('.vue.js')) {
|
|
49
|
+
return ts.ScriptKind.TS;
|
|
50
|
+
}
|
|
51
|
+
if (fileName.endsWith('.vue.jsx')) {
|
|
52
|
+
return ts.ScriptKind.TSX;
|
|
53
|
+
}
|
|
54
|
+
return core.typescriptLanguageServiceHost.getScriptKind(fileName);
|
|
55
|
+
},
|
|
56
|
+
} : {};
|
|
57
|
+
const proxyHost = new Proxy(core.typescriptLanguageServiceHost, {
|
|
58
|
+
get(target, propKey) {
|
|
59
|
+
if (propKey in proxyApis) {
|
|
60
|
+
return proxyApis[propKey];
|
|
61
|
+
}
|
|
62
|
+
return target[propKey];
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
const tsLs = ts.createLanguageService(proxyHost);
|
|
34
66
|
const program = tsLs.getProgram();
|
|
35
67
|
const typeChecker = program.getTypeChecker();
|
|
68
|
+
let globalPropNames = [];
|
|
69
|
+
globalPropNames = getComponentMeta(globalComponentName).props.map(prop => prop.name);
|
|
36
70
|
return {
|
|
71
|
+
getExportNames,
|
|
37
72
|
getComponentMeta,
|
|
38
73
|
};
|
|
74
|
+
function getMetaFileName(fileName) {
|
|
75
|
+
return (fileName.endsWith('.vue') ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + '.meta.ts';
|
|
76
|
+
}
|
|
39
77
|
function getMetaScriptContent(fileName) {
|
|
40
78
|
return `
|
|
41
|
-
import
|
|
42
|
-
export default
|
|
79
|
+
import * as Components from '${fileName.substring(0, fileName.length - '.meta.ts'.length)}';
|
|
80
|
+
export default {} as { [K in keyof typeof Components]: InstanceType<typeof Components[K]>; };;
|
|
43
81
|
`;
|
|
44
82
|
}
|
|
45
|
-
function
|
|
83
|
+
function getExportNames(componentPath) {
|
|
84
|
+
return _getExports(componentPath).exports.map(e => e.getName());
|
|
85
|
+
}
|
|
86
|
+
function getComponentMeta(componentPath, exportName = 'default') {
|
|
46
87
|
var _a;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
52
|
-
if (!moduleSymbol) {
|
|
53
|
-
throw 'Could not find module symbol';
|
|
54
|
-
}
|
|
55
|
-
const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
|
|
56
|
-
let symbolNode;
|
|
57
|
-
for (const symbol of exportedSymbols) {
|
|
58
|
-
const [declaration] = (_a = symbol.getDeclarations()) !== null && _a !== void 0 ? _a : [];
|
|
59
|
-
if (ts.isExportAssignment(declaration)) {
|
|
60
|
-
symbolNode = declaration.expression;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (!symbolNode) {
|
|
64
|
-
throw 'Could not find symbol node';
|
|
88
|
+
const { symbolNode, exports } = _getExports(componentPath);
|
|
89
|
+
const _export = exports.find((property) => property.getName() === exportName);
|
|
90
|
+
if (!_export) {
|
|
91
|
+
throw `Could not find export ${exportName}`;
|
|
65
92
|
}
|
|
66
|
-
const
|
|
67
|
-
const symbolProperties =
|
|
93
|
+
const componentType = typeChecker.getTypeOfSymbolAtLocation(_export, symbolNode);
|
|
94
|
+
const symbolProperties = (_a = componentType.getProperties()) !== null && _a !== void 0 ? _a : [];
|
|
95
|
+
const { resolveNestedProperties, resolveEventSignature, resolveExposedProperties, resolveSlotProperties, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions.schema);
|
|
68
96
|
return {
|
|
69
97
|
props: getProps(),
|
|
70
98
|
events: getEvents(),
|
|
71
99
|
slots: getSlots(),
|
|
100
|
+
exposed: getExposed(),
|
|
72
101
|
};
|
|
73
102
|
function getProps() {
|
|
74
103
|
const $props = symbolProperties.find(prop => prop.escapedName === '$props');
|
|
104
|
+
const propEventRegex = /^(on[A-Z])/;
|
|
105
|
+
let result = [];
|
|
75
106
|
if ($props) {
|
|
76
107
|
const type = typeChecker.getTypeOfSymbolAtLocation($props, symbolNode);
|
|
77
|
-
const properties = type.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
name: prop.escapedName,
|
|
82
|
-
// @ts-ignore
|
|
83
|
-
isOptional: !!((_b = (_a = prop.declarations) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.questionToken),
|
|
84
|
-
type: typeChecker.typeToString(typeChecker.getTypeOfSymbolAtLocation(prop, symbolNode)),
|
|
85
|
-
documentationComment: ts.displayPartsToString(prop.getDocumentationComment(typeChecker)),
|
|
86
|
-
});
|
|
87
|
-
});
|
|
108
|
+
const properties = type.getApparentProperties();
|
|
109
|
+
result = properties
|
|
110
|
+
.map(resolveNestedProperties)
|
|
111
|
+
.filter((prop) => !prop.name.match(propEventRegex));
|
|
88
112
|
}
|
|
89
|
-
|
|
113
|
+
// fill global
|
|
114
|
+
for (const prop of result) {
|
|
115
|
+
prop.global = globalPropNames.includes(prop.name);
|
|
116
|
+
}
|
|
117
|
+
// fill defaults
|
|
118
|
+
const printer = ts.createPrinter(checkerOptions.printer);
|
|
119
|
+
const snapshot = host.getScriptSnapshot(componentPath);
|
|
120
|
+
const vueDefaults = componentPath.endsWith('.vue') && exportName === 'default' ? readVueComponentDefaultProps(snapshot.getText(0, snapshot.getLength()), printer) : {};
|
|
121
|
+
const tsDefaults = !componentPath.endsWith('.vue') ? readTsComponentDefaultProps(componentPath.substring(componentPath.lastIndexOf('.') + 1), // ts | js | tsx | jsx
|
|
122
|
+
snapshot.getText(0, snapshot.getLength()), exportName, printer) : {};
|
|
123
|
+
for (const [propName, defaultExp] of Object.entries(Object.assign(Object.assign({}, vueDefaults), tsDefaults))) {
|
|
124
|
+
const prop = result.find(p => p.name === propName);
|
|
125
|
+
if (prop) {
|
|
126
|
+
prop.default = defaultExp;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
90
130
|
}
|
|
91
131
|
function getEvents() {
|
|
92
132
|
const $emit = symbolProperties.find(prop => prop.escapedName === '$emit');
|
|
93
133
|
if ($emit) {
|
|
94
134
|
const type = typeChecker.getTypeOfSymbolAtLocation($emit, symbolNode);
|
|
95
135
|
const calls = type.getCallSignatures();
|
|
96
|
-
return calls.map(
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
name: typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode).value,
|
|
99
|
-
parametersType: typeChecker.typeToString(typeChecker.getTypeOfSymbolAtLocation(call.parameters[1], symbolNode)),
|
|
100
|
-
// @ts-ignore
|
|
101
|
-
parameters: typeChecker.getTypeArguments(typeChecker.getTypeOfSymbolAtLocation(call.parameters[1], symbolNode)).map(arg => ({
|
|
102
|
-
name: 'TODO',
|
|
103
|
-
type: typeChecker.typeToString(arg),
|
|
104
|
-
isOptional: 'TODO',
|
|
105
|
-
})),
|
|
106
|
-
documentationComment: ts.displayPartsToString(call.getDocumentationComment(typeChecker)),
|
|
107
|
-
}));
|
|
136
|
+
return calls.map(resolveEventSignature).filter(event => event.name);
|
|
108
137
|
}
|
|
109
138
|
return [];
|
|
110
139
|
}
|
|
@@ -115,16 +144,322 @@ function createComponentMetaChecker(tsconfigPath) {
|
|
|
115
144
|
if ($slots) {
|
|
116
145
|
const type = typeChecker.getTypeOfSymbolAtLocation($slots, symbolNode);
|
|
117
146
|
const properties = type.getProperties();
|
|
118
|
-
return properties.map(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
147
|
+
return properties.map(resolveSlotProperties);
|
|
148
|
+
}
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
function getExposed() {
|
|
152
|
+
const exposed = symbolProperties.filter(prop =>
|
|
153
|
+
// only exposed props will have a syntheticOrigin
|
|
154
|
+
Boolean(prop.syntheticOrigin));
|
|
155
|
+
if (exposed.length) {
|
|
156
|
+
return exposed.map(resolveExposedProperties);
|
|
124
157
|
}
|
|
125
158
|
return [];
|
|
126
159
|
}
|
|
127
160
|
}
|
|
161
|
+
function _getExports(componentPath) {
|
|
162
|
+
var _a;
|
|
163
|
+
const sourceFile = program === null || program === void 0 ? void 0 : program.getSourceFile(getMetaFileName(componentPath));
|
|
164
|
+
if (!sourceFile) {
|
|
165
|
+
throw 'Could not find main source file';
|
|
166
|
+
}
|
|
167
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
168
|
+
if (!moduleSymbol) {
|
|
169
|
+
throw 'Could not find module symbol';
|
|
170
|
+
}
|
|
171
|
+
const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
|
|
172
|
+
let symbolNode;
|
|
173
|
+
for (const symbol of exportedSymbols) {
|
|
174
|
+
const [declaration] = (_a = symbol.getDeclarations()) !== null && _a !== void 0 ? _a : [];
|
|
175
|
+
if (ts.isExportAssignment(declaration)) {
|
|
176
|
+
symbolNode = declaration.expression;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (!symbolNode) {
|
|
180
|
+
throw 'Could not find symbol node';
|
|
181
|
+
}
|
|
182
|
+
const exportDefaultType = typeChecker.getTypeAtLocation(symbolNode);
|
|
183
|
+
const exports = exportDefaultType.getProperties();
|
|
184
|
+
return {
|
|
185
|
+
symbolNode,
|
|
186
|
+
exports,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
128
189
|
}
|
|
129
190
|
exports.createComponentMetaChecker = createComponentMetaChecker;
|
|
191
|
+
function createSchemaResolvers(typeChecker, symbolNode, options = false) {
|
|
192
|
+
var _a;
|
|
193
|
+
const enabled = !!options;
|
|
194
|
+
const ignore = typeof options === 'object' ? (_a = options.ignore) !== null && _a !== void 0 ? _a : [] : [];
|
|
195
|
+
function shouldIgnore(subtype) {
|
|
196
|
+
const type = typeChecker.typeToString(subtype);
|
|
197
|
+
if (type === 'any') {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
if (ignore.length === 0) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return ignore.includes(type);
|
|
204
|
+
}
|
|
205
|
+
function reducer(acc, cur) {
|
|
206
|
+
acc[cur.name] = cur;
|
|
207
|
+
return acc;
|
|
208
|
+
}
|
|
209
|
+
function resolveNestedProperties(prop) {
|
|
210
|
+
var _a, _b, _c;
|
|
211
|
+
const subtype = typeChecker.getTypeOfSymbolAtLocation(prop, symbolNode);
|
|
212
|
+
const schema = enabled ? resolveSchema(subtype) : undefined;
|
|
213
|
+
return {
|
|
214
|
+
name: prop.getEscapedName().toString(),
|
|
215
|
+
global: false,
|
|
216
|
+
description: ts.displayPartsToString(prop.getDocumentationComment(typeChecker)),
|
|
217
|
+
tags: prop.getJsDocTags(typeChecker).map(tag => {
|
|
218
|
+
var _a;
|
|
219
|
+
return ({
|
|
220
|
+
name: tag.name,
|
|
221
|
+
text: (_a = tag.text) === null || _a === void 0 ? void 0 : _a.map(part => part.text).join(''),
|
|
222
|
+
});
|
|
223
|
+
}),
|
|
224
|
+
required: !Boolean((_c = (_b = (_a = prop.declarations) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.questionToken) !== null && _c !== void 0 ? _c : false),
|
|
225
|
+
type: typeChecker.typeToString(subtype),
|
|
226
|
+
schema,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function resolveSlotProperties(prop) {
|
|
230
|
+
const subtype = typeChecker.getTypeOfSymbolAtLocation(typeChecker.getTypeOfSymbolAtLocation(prop, symbolNode).getCallSignatures()[0].parameters[0], symbolNode);
|
|
231
|
+
const schema = enabled ? resolveSchema(subtype) : undefined;
|
|
232
|
+
return {
|
|
233
|
+
name: prop.getName(),
|
|
234
|
+
type: typeChecker.typeToString(subtype),
|
|
235
|
+
description: ts.displayPartsToString(prop.getDocumentationComment(typeChecker)),
|
|
236
|
+
schema,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function resolveExposedProperties(expose) {
|
|
240
|
+
const subtype = typeChecker.getTypeOfSymbolAtLocation(expose, symbolNode);
|
|
241
|
+
const schema = enabled ? resolveSchema(subtype) : undefined;
|
|
242
|
+
return {
|
|
243
|
+
name: expose.getName(),
|
|
244
|
+
type: typeChecker.typeToString(subtype),
|
|
245
|
+
description: ts.displayPartsToString(expose.getDocumentationComment(typeChecker)),
|
|
246
|
+
schema,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function resolveEventSignature(call) {
|
|
250
|
+
const subtype = typeChecker.getTypeOfSymbolAtLocation(call.parameters[1], symbolNode);
|
|
251
|
+
const schema = enabled
|
|
252
|
+
? typeChecker.getTypeArguments(subtype).map(resolveSchema)
|
|
253
|
+
: undefined;
|
|
254
|
+
return {
|
|
255
|
+
name: typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode).value,
|
|
256
|
+
type: typeChecker.typeToString(subtype),
|
|
257
|
+
signature: typeChecker.signatureToString(call),
|
|
258
|
+
schema,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function resolveCallbackSchema(signature) {
|
|
262
|
+
const schema = enabled && signature.parameters.length > 0
|
|
263
|
+
? typeChecker
|
|
264
|
+
.getTypeArguments(typeChecker.getTypeOfSymbolAtLocation(signature.parameters[0], symbolNode))
|
|
265
|
+
.map(resolveSchema)
|
|
266
|
+
: undefined;
|
|
267
|
+
return {
|
|
268
|
+
kind: 'event',
|
|
269
|
+
type: typeChecker.signatureToString(signature),
|
|
270
|
+
schema,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function resolveEventSchema(subtype) {
|
|
274
|
+
return (subtype.getCallSignatures().length === 1)
|
|
275
|
+
? resolveCallbackSchema(subtype.getCallSignatures()[0])
|
|
276
|
+
: typeChecker.typeToString(subtype);
|
|
277
|
+
}
|
|
278
|
+
function resolveNestedSchema(subtype) {
|
|
279
|
+
if (subtype.getCallSignatures().length === 0 &&
|
|
280
|
+
(subtype.isClassOrInterface() || subtype.isIntersection() || subtype.objectFlags & ts.ObjectFlags.Anonymous)) {
|
|
281
|
+
if (shouldIgnore(subtype)) {
|
|
282
|
+
return typeChecker.typeToString(subtype);
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
kind: 'object',
|
|
286
|
+
type: typeChecker.typeToString(subtype),
|
|
287
|
+
schema: subtype.getProperties().map(resolveNestedProperties).reduce(reducer, {})
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
return resolveEventSchema(subtype);
|
|
291
|
+
}
|
|
292
|
+
function resolveArraySchema(subtype) {
|
|
293
|
+
// @ts-ignore - typescript internal, isArrayLikeType exists
|
|
294
|
+
if (typeChecker.isArrayLikeType(subtype)) {
|
|
295
|
+
if (shouldIgnore(subtype)) {
|
|
296
|
+
return typeChecker.typeToString(subtype);
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
kind: 'array',
|
|
300
|
+
type: typeChecker.typeToString(subtype),
|
|
301
|
+
schema: typeChecker.getTypeArguments(subtype).map(resolveSchema)
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return resolveNestedSchema(subtype);
|
|
305
|
+
}
|
|
306
|
+
function resolveSchema(subtype) {
|
|
307
|
+
return subtype.isUnion()
|
|
308
|
+
? {
|
|
309
|
+
kind: 'enum',
|
|
310
|
+
type: typeChecker.typeToString(subtype),
|
|
311
|
+
schema: subtype.types.map(resolveArraySchema)
|
|
312
|
+
}
|
|
313
|
+
: resolveArraySchema(subtype);
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
resolveNestedProperties,
|
|
317
|
+
resolveSlotProperties,
|
|
318
|
+
resolveEventSignature,
|
|
319
|
+
resolveExposedProperties,
|
|
320
|
+
resolveCallbackSchema,
|
|
321
|
+
resolveEventSchema,
|
|
322
|
+
resolveNestedSchema,
|
|
323
|
+
resolveArraySchema,
|
|
324
|
+
resolveSchema,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function readVueComponentDefaultProps(vueFileText, printer) {
|
|
328
|
+
const result = {};
|
|
329
|
+
scriptSetupWorker();
|
|
330
|
+
sciptWorker();
|
|
331
|
+
return result;
|
|
332
|
+
function scriptSetupWorker() {
|
|
333
|
+
const vueSourceFile = vue.createSourceFile('/tmp.vue', vueFileText, {}, {}, ts);
|
|
334
|
+
const descriptor = vueSourceFile.getDescriptor();
|
|
335
|
+
const scriptSetupRanges = vueSourceFile.getScriptSetupRanges();
|
|
336
|
+
if (descriptor.scriptSetup && (scriptSetupRanges === null || scriptSetupRanges === void 0 ? void 0 : scriptSetupRanges.withDefaultsArg)) {
|
|
337
|
+
const defaultsText = descriptor.scriptSetup.content.substring(scriptSetupRanges.withDefaultsArg.start, scriptSetupRanges.withDefaultsArg.end);
|
|
338
|
+
const ast = ts.createSourceFile('/tmp.' + descriptor.scriptSetup.lang, '(' + defaultsText + ')', ts.ScriptTarget.Latest);
|
|
339
|
+
const obj = findObjectLiteralExpression(ast);
|
|
340
|
+
if (obj) {
|
|
341
|
+
for (const prop of obj.properties) {
|
|
342
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
343
|
+
const name = prop.name.getText(ast);
|
|
344
|
+
const exp = printer.printNode(ts.EmitHint.Expression, resolveDefaultOptionExpression(prop.initializer), ast);
|
|
345
|
+
;
|
|
346
|
+
result[name] = exp;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function findObjectLiteralExpression(node) {
|
|
351
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
352
|
+
return node;
|
|
353
|
+
}
|
|
354
|
+
let result;
|
|
355
|
+
node.forEachChild(child => {
|
|
356
|
+
if (!result) {
|
|
357
|
+
result = findObjectLiteralExpression(child);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
return result;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
function sciptWorker() {
|
|
365
|
+
const vueSourceFile = vue.createSourceFile('/tmp.vue', vueFileText, {}, {}, ts);
|
|
366
|
+
const descriptor = vueSourceFile.getDescriptor();
|
|
367
|
+
if (descriptor.script) {
|
|
368
|
+
const scriptResult = readTsComponentDefaultProps(descriptor.script.lang, descriptor.script.content, 'default', printer);
|
|
369
|
+
for (const [key, value] of Object.entries(scriptResult)) {
|
|
370
|
+
result[key] = value;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function readTsComponentDefaultProps(lang, tsFileText, exportName, printer) {
|
|
376
|
+
var _a, _b;
|
|
377
|
+
const result = {};
|
|
378
|
+
const ast = ts.createSourceFile('/tmp.' + lang, tsFileText, ts.ScriptTarget.Latest);
|
|
379
|
+
const props = getPropsNode();
|
|
380
|
+
if (props) {
|
|
381
|
+
for (const prop of props.properties) {
|
|
382
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
383
|
+
const name = (_a = prop.name) === null || _a === void 0 ? void 0 : _a.getText(ast);
|
|
384
|
+
if (ts.isObjectLiteralExpression(prop.initializer)) {
|
|
385
|
+
for (const propOption of prop.initializer.properties) {
|
|
386
|
+
if (ts.isPropertyAssignment(propOption)) {
|
|
387
|
+
if (((_b = propOption.name) === null || _b === void 0 ? void 0 : _b.getText(ast)) === 'default') {
|
|
388
|
+
const _default = propOption.initializer;
|
|
389
|
+
result[name] = printer.printNode(ts.EmitHint.Expression, resolveDefaultOptionExpression(_default), ast);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return result;
|
|
398
|
+
function getComponentNode() {
|
|
399
|
+
let result;
|
|
400
|
+
if (exportName === 'default') {
|
|
401
|
+
ast.forEachChild(child => {
|
|
402
|
+
if (ts.isExportAssignment(child)) {
|
|
403
|
+
result = child.expression;
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
ast.forEachChild(child => {
|
|
409
|
+
var _a;
|
|
410
|
+
if (ts.isVariableStatement(child)
|
|
411
|
+
&& ((_a = child.modifiers) === null || _a === void 0 ? void 0 : _a.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword))) {
|
|
412
|
+
for (const dec of child.declarationList.declarations) {
|
|
413
|
+
if (dec.name.getText(ast) === exportName) {
|
|
414
|
+
result = dec.initializer;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
422
|
+
function getComponentOptionsNode() {
|
|
423
|
+
const component = getComponentNode();
|
|
424
|
+
if (component) {
|
|
425
|
+
// export default { ... }
|
|
426
|
+
if (ts.isObjectLiteralExpression(component)) {
|
|
427
|
+
return component;
|
|
428
|
+
}
|
|
429
|
+
// export default defineComponent({ ... })
|
|
430
|
+
// export default Vue.extend({ ... })
|
|
431
|
+
else if (ts.isCallExpression(component)) {
|
|
432
|
+
if (component.arguments.length) {
|
|
433
|
+
const arg = component.arguments[0];
|
|
434
|
+
if (ts.isObjectLiteralExpression(arg)) {
|
|
435
|
+
return arg;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function getPropsNode() {
|
|
442
|
+
const options = getComponentOptionsNode();
|
|
443
|
+
const props = options === null || options === void 0 ? void 0 : options.properties.find(prop => { var _a; return ((_a = prop.name) === null || _a === void 0 ? void 0 : _a.getText(ast)) === 'props'; });
|
|
444
|
+
if (props && ts.isPropertyAssignment(props)) {
|
|
445
|
+
if (ts.isObjectLiteralExpression(props.initializer)) {
|
|
446
|
+
return props.initializer;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function resolveDefaultOptionExpression(_default) {
|
|
452
|
+
if (ts.isArrowFunction(_default)) {
|
|
453
|
+
if (ts.isBlock(_default.body)) {
|
|
454
|
+
return _default; // TODO
|
|
455
|
+
}
|
|
456
|
+
else if (ts.isParenthesizedExpression(_default.body)) {
|
|
457
|
+
return _default.body.expression;
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
return _default.body;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return _default;
|
|
464
|
+
}
|
|
130
465
|
//# sourceMappingURL=index.js.map
|
package/out/types.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface ComponentMeta {
|
|
2
|
+
props: PropertyMeta[];
|
|
3
|
+
events: EventMeta[];
|
|
4
|
+
slots: SlotMeta[];
|
|
5
|
+
exposed: ExposeMeta[];
|
|
6
|
+
}
|
|
7
|
+
export interface PropertyMeta {
|
|
8
|
+
name: string;
|
|
9
|
+
default?: string;
|
|
10
|
+
description: string;
|
|
11
|
+
global: boolean;
|
|
12
|
+
required: boolean;
|
|
13
|
+
type: string;
|
|
14
|
+
tags: {
|
|
15
|
+
name: string;
|
|
16
|
+
text?: string;
|
|
17
|
+
}[];
|
|
18
|
+
schema?: PropertyMetaSchema;
|
|
19
|
+
}
|
|
20
|
+
export interface EventMeta {
|
|
21
|
+
name: string;
|
|
22
|
+
type: string;
|
|
23
|
+
signature: string;
|
|
24
|
+
schema?: PropertyMetaSchema[];
|
|
25
|
+
}
|
|
26
|
+
export interface SlotMeta {
|
|
27
|
+
name: string;
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
schema?: PropertyMetaSchema;
|
|
31
|
+
}
|
|
32
|
+
export interface ExposeMeta {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
type: string;
|
|
36
|
+
schema?: PropertyMetaSchema;
|
|
37
|
+
}
|
|
38
|
+
export declare type PropertyMetaSchema = string | {
|
|
39
|
+
kind: 'enum';
|
|
40
|
+
type: string;
|
|
41
|
+
schema?: PropertyMetaSchema[];
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'array';
|
|
44
|
+
type: string;
|
|
45
|
+
schema?: PropertyMetaSchema[];
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'event';
|
|
48
|
+
type: string;
|
|
49
|
+
schema?: PropertyMetaSchema[];
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'object';
|
|
52
|
+
type: string;
|
|
53
|
+
schema?: Record<string, PropertyMeta>;
|
|
54
|
+
};
|
|
55
|
+
export declare type MetaCheckerSchemaOptions = boolean | {
|
|
56
|
+
ignore?: string[];
|
|
57
|
+
};
|
|
58
|
+
export interface MetaCheckerOptions {
|
|
59
|
+
schema?: MetaCheckerSchemaOptions;
|
|
60
|
+
forceUseTs?: boolean;
|
|
61
|
+
printer?: import('typescript').PrinterOptions;
|
|
62
|
+
}
|
package/out/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-component-meta",
|
|
3
|
-
"version": "0.39.
|
|
3
|
+
"version": "0.39.4",
|
|
4
4
|
"main": "out/index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"directory": "packages/vue-component-meta"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@volar/vue-language-core": "0.39.
|
|
16
|
+
"@volar/vue-language-core": "0.39.4"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"typescript": "*"
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
|
+
"gitHead": "e3f6327b11a0a41c1b448c2ecc25ba85b9986dee"
|
|
21
22
|
}
|