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