vue-component-meta 0.39.2 → 0.39.3

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 CHANGED
@@ -1,53 +1,6 @@
1
- export declare type PropertyMeta = {
2
- name: string;
3
- default?: string;
4
- description: string;
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 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): {
32
4
  getExportNames: (componentPath: string) => string[];
33
- getComponentMeta: (componentPath: string, exportName?: string) => {
34
- props: PropertyMeta[];
35
- events: {
36
- name: string;
37
- type: string;
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
- }[];
51
- };
5
+ getComponentMeta: (componentPath: string, exportName?: string) => ComponentMeta;
52
6
  };
53
- export declare function findCmponentDefaultProps(componentPath: string): Record<string, string>;
package/out/index.js CHANGED
@@ -1,83 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findCmponentDefaultProps = exports.createComponentMetaChecker = void 0;
3
+ exports.createComponentMetaChecker = void 0;
4
4
  const vue = require("@volar/vue-language-core");
5
5
  const ts = require("typescript/lib/tsserverlibrary");
6
- function createSchemaResolvers(typeChecker, symbolNode) {
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) {
6
+ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
81
7
  const parsedCommandLine = vue.tsShared.createParsedCommandLine(ts, {
82
8
  useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
83
9
  readDirectory: (path, extensions, exclude, include, depth) => {
@@ -88,7 +14,7 @@ function createComponentMetaChecker(tsconfigPath) {
88
14
  }, tsconfigPath);
89
15
  const scriptSnapshot = {};
90
16
  const globalComponentName = tsconfigPath.replace(/\\/g, '/') + '.global.ts';
91
- const core = vue.createLanguageContext(Object.assign(Object.assign({}, ts.sys), { getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options), useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, getCompilationSettings: () => parsedCommandLine.options, getScriptFileNames: () => {
17
+ const host = Object.assign(Object.assign({}, ts.sys), { getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options), useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, getCompilationSettings: () => parsedCommandLine.options, getScriptFileNames: () => {
92
18
  return [
93
19
  ...parsedCommandLine.fileNames,
94
20
  ...parsedCommandLine.fileNames.map(getMetaFileName),
@@ -115,32 +41,36 @@ function createComponentMetaChecker(tsconfigPath) {
115
41
  }
116
42
  }
117
43
  return scriptSnapshot[fileName];
118
- }, getTypeScriptModule: () => ts, getVueCompilationSettings: () => parsedCommandLine.vueOptions }));
119
- const tsLs = ts.createLanguageService(core.typescriptLanguageServiceHost);
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);
120
66
  const program = tsLs.getProgram();
121
67
  const typeChecker = program.getTypeChecker();
68
+ let globalPropNames = [];
69
+ globalPropNames = getComponentMeta(globalComponentName).props.map(prop => prop.name);
122
70
  return {
123
- getGlobalPropNames,
124
71
  getExportNames,
125
72
  getComponentMeta,
126
73
  };
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
74
  function getMetaFileName(fileName) {
145
75
  return (fileName.endsWith('.vue') ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + '.meta.ts';
146
76
  }
@@ -162,6 +92,7 @@ function createComponentMetaChecker(tsconfigPath) {
162
92
  }
163
93
  const componentType = typeChecker.getTypeOfSymbolAtLocation(_export, symbolNode);
164
94
  const symbolProperties = (_a = componentType.getProperties()) !== null && _a !== void 0 ? _a : [];
95
+ const { resolveNestedProperties, resolveEventSignature, resolveExposedProperties, resolveSlotProperties, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions.schema);
165
96
  return {
166
97
  props: getProps(),
167
98
  events: getEvents(),
@@ -170,21 +101,29 @@ function createComponentMetaChecker(tsconfigPath) {
170
101
  };
171
102
  function getProps() {
172
103
  const $props = symbolProperties.find(prop => prop.escapedName === '$props');
104
+ const propEventRegex = /^(on[A-Z])/;
173
105
  let result = [];
174
106
  if ($props) {
175
107
  const type = typeChecker.getTypeOfSymbolAtLocation($props, symbolNode);
176
108
  const properties = type.getApparentProperties();
177
- const { resolveSymbolSchema } = createSchemaResolvers(typeChecker, symbolNode);
178
- result = properties.map(resolveSymbolSchema);
109
+ result = properties
110
+ .map(resolveNestedProperties)
111
+ .filter((prop) => !prop.name.match(propEventRegex));
112
+ }
113
+ // fill global
114
+ for (const prop of result) {
115
+ prop.global = globalPropNames.includes(prop.name);
179
116
  }
180
117
  // fill defaults
181
- if (componentPath.endsWith('.vue') && exportName === 'default') {
182
- const defaults = findCmponentDefaultProps(componentPath);
183
- for (const propName in defaults) {
184
- const prop = result.find(p => p.name === propName);
185
- if (prop) {
186
- prop.default = defaults[propName];
187
- }
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;
188
127
  }
189
128
  }
190
129
  return result;
@@ -194,13 +133,7 @@ function createComponentMetaChecker(tsconfigPath) {
194
133
  if ($emit) {
195
134
  const type = typeChecker.getTypeOfSymbolAtLocation($emit, symbolNode);
196
135
  const calls = type.getCallSignatures();
197
- const { resolveSchema } = createSchemaResolvers(typeChecker, symbolNode);
198
- return calls.map(call => ({
199
- name: typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode).value,
200
- type: typeChecker.typeToString(typeChecker.getTypeOfSymbolAtLocation(call.parameters[1], symbolNode)),
201
- signature: typeChecker.signatureToString(call),
202
- schema: typeChecker.getTypeArguments(typeChecker.getTypeOfSymbolAtLocation(call.parameters[1], symbolNode)).map(resolveSchema),
203
- }));
136
+ return calls.map(resolveEventSignature).filter(event => event.name);
204
137
  }
205
138
  return [];
206
139
  }
@@ -211,11 +144,7 @@ function createComponentMetaChecker(tsconfigPath) {
211
144
  if ($slots) {
212
145
  const type = typeChecker.getTypeOfSymbolAtLocation($slots, symbolNode);
213
146
  const properties = type.getProperties();
214
- return properties.map(prop => ({
215
- name: prop.getName(),
216
- type: typeChecker.typeToString(typeChecker.getTypeOfSymbolAtLocation(typeChecker.getTypeOfSymbolAtLocation(prop, symbolNode).getCallSignatures()[0].parameters[0], symbolNode)),
217
- description: ts.displayPartsToString(prop.getDocumentationComment(typeChecker)),
218
- }));
147
+ return properties.map(resolveSlotProperties);
219
148
  }
220
149
  return [];
221
150
  }
@@ -224,11 +153,7 @@ function createComponentMetaChecker(tsconfigPath) {
224
153
  // only exposed props will have a syntheticOrigin
225
154
  Boolean(prop.syntheticOrigin));
226
155
  if (exposed.length) {
227
- return exposed.map(expose => ({
228
- name: expose.getName(),
229
- type: typeChecker.typeToString(typeChecker.getTypeOfSymbolAtLocation(expose, symbolNode)),
230
- description: ts.displayPartsToString(expose.getDocumentationComment(typeChecker)),
231
- }));
156
+ return exposed.map(resolveExposedProperties);
232
157
  }
233
158
  return [];
234
159
  }
@@ -263,42 +188,278 @@ function createComponentMetaChecker(tsconfigPath) {
263
188
  }
264
189
  }
265
190
  exports.createComponentMetaChecker = createComponentMetaChecker;
266
- function findCmponentDefaultProps(componentPath) {
267
- const fileText = ts.sys.readFile(componentPath);
268
- if (fileText === undefined) {
269
- throw new Error(`${componentPath} not found`);
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;
270
208
  }
271
- const vueSourceFile = vue.createSourceFile(componentPath, fileText, {}, {}, ts);
272
- const descriptor = vueSourceFile.getDescriptor();
273
- const scriptSetupRanges = vueSourceFile.getScriptSetupRanges();
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) {
274
328
  const result = {};
275
- if (descriptor.scriptSetup && (scriptSetupRanges === null || scriptSetupRanges === void 0 ? void 0 : scriptSetupRanges.withDefaultsArg)) {
276
- const defaultsText = descriptor.scriptSetup.content.substring(scriptSetupRanges.withDefaultsArg.start, scriptSetupRanges.withDefaultsArg.end);
277
- const ast = ts.createSourceFile('/tmp.' + descriptor.scriptSetup.lang, '(' + defaultsText + ')', ts.ScriptTarget.Latest);
278
- const obj = findObjectLiteralExpression(ast);
279
- if (obj) {
280
- for (const prop of obj.properties) {
281
- if (ts.isPropertyAssignment(prop)) {
282
- const name = prop.name.getText(ast);
283
- const exp = prop.initializer.getText(ast);
284
- result[name] = exp;
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
+ }
285
348
  }
286
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
+ }
287
362
  }
288
- function findObjectLiteralExpression(node) {
289
- if (ts.isObjectLiteralExpression(node)) {
290
- return node;
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;
291
371
  }
292
- let result;
293
- node.forEachChild(child => {
294
- if (!result) {
295
- result = findObjectLiteralExpression(child);
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
+ }
296
393
  }
297
- });
298
- return result;
394
+ }
299
395
  }
300
396
  }
301
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;
302
464
  }
303
- exports.findCmponentDefaultProps = findCmponentDefaultProps;
304
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
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ ;
4
+ //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-component-meta",
3
- "version": "0.39.2",
3
+ "version": "0.39.3",
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.2"
16
+ "@volar/vue-language-core": "0.39.3"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "typescript": "*"
20
20
  },
21
- "gitHead": "eac2dca4206dfa3f92ad50dd53650f924a9e6f94"
21
+ "gitHead": "57a7b0f627e58277ec34241ccbe4bf5253f7daf8"
22
22
  }