vue-component-meta 0.39.4 → 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 CHANGED
@@ -1,6 +1,12 @@
1
+ import * as ts from 'typescript/lib/tsserverlibrary';
1
2
  import type { MetaCheckerOptions, ComponentMeta, EventMeta, ExposeMeta, MetaCheckerSchemaOptions, PropertyMeta, PropertyMetaSchema, SlotMeta } from './types';
2
3
  export type { MetaCheckerOptions, ComponentMeta, EventMeta, ExposeMeta, MetaCheckerSchemaOptions, PropertyMeta, PropertyMetaSchema, SlotMeta };
3
4
  export declare function createComponentMetaChecker(tsconfigPath: string, checkerOptions?: MetaCheckerOptions): {
4
5
  getExportNames: (componentPath: string) => string[];
5
6
  getComponentMeta: (componentPath: string, exportName?: string) => ComponentMeta;
7
+ __internal__: {
8
+ program: ts.Program;
9
+ tsLs: ts.LanguageService;
10
+ typeChecker: ts.TypeChecker;
11
+ };
6
12
  };
package/out/index.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, "__esModule", { value: true });
3
2
  exports.createComponentMetaChecker = void 0;
4
3
  const vue = require("@volar/vue-language-core");
@@ -70,6 +69,11 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
70
69
  return {
71
70
  getExportNames,
72
71
  getComponentMeta,
72
+ __internal__: {
73
+ program,
74
+ tsLs,
75
+ typeChecker,
76
+ },
73
77
  };
74
78
  function getMetaFileName(fileName) {
75
79
  return (fileName.endsWith('.vue') ? fileName : fileName.substring(0, fileName.lastIndexOf('.'))) + '.meta.ts';
@@ -77,7 +81,7 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
77
81
  function getMetaScriptContent(fileName) {
78
82
  return `
79
83
  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]>; };;
84
+ export default {} as { [K in keyof typeof Components]: InstanceType<typeof Components[K]>; };
81
85
  `;
82
86
  }
83
87
  function getExportNames(componentPath) {
@@ -92,7 +96,6 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
92
96
  }
93
97
  const componentType = typeChecker.getTypeOfSymbolAtLocation(_export, symbolNode);
94
98
  const symbolProperties = (_a = componentType.getProperties()) !== null && _a !== void 0 ? _a : [];
95
- const { resolveNestedProperties, resolveEventSignature, resolveExposedProperties, resolveSlotProperties, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions.schema);
96
99
  return {
97
100
  props: getProps(),
98
101
  events: getEvents(),
@@ -105,9 +108,12 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
105
108
  let result = [];
106
109
  if ($props) {
107
110
  const type = typeChecker.getTypeOfSymbolAtLocation($props, symbolNode);
108
- const properties = type.getApparentProperties();
111
+ const properties = type.getProperties();
109
112
  result = properties
110
- .map(resolveNestedProperties)
113
+ .map((prop) => {
114
+ const { resolveNestedProperties, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions);
115
+ return resolveNestedProperties(prop);
116
+ })
111
117
  .filter((prop) => !prop.name.match(propEventRegex));
112
118
  }
113
119
  // fill global
@@ -115,15 +121,23 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
115
121
  prop.global = globalPropNames.includes(prop.name);
116
122
  }
117
123
  // fill defaults
118
- const printer = ts.createPrinter(checkerOptions.printer);
124
+ const printer = checkerOptions.printer ? ts.createPrinter(checkerOptions.printer) : undefined;
119
125
  const snapshot = host.getScriptSnapshot(componentPath);
120
- const vueDefaults = componentPath.endsWith('.vue') && exportName === 'default' ? readVueComponentDefaultProps(snapshot.getText(0, snapshot.getLength()), printer) : {};
126
+ const vueDefaults = componentPath.endsWith('.vue') && exportName === 'default'
127
+ ? readVueComponentDefaultProps(snapshot.getText(0, snapshot.getLength()), printer)
128
+ : {};
121
129
  const tsDefaults = !componentPath.endsWith('.vue') ? readTsComponentDefaultProps(componentPath.substring(componentPath.lastIndexOf('.') + 1), // ts | js | tsx | jsx
122
130
  snapshot.getText(0, snapshot.getLength()), exportName, printer) : {};
123
131
  for (const [propName, defaultExp] of Object.entries(Object.assign(Object.assign({}, vueDefaults), tsDefaults))) {
124
132
  const prop = result.find(p => p.name === propName);
125
133
  if (prop) {
126
- prop.default = defaultExp;
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
140
+ }
127
141
  }
128
142
  }
129
143
  return result;
@@ -133,7 +147,10 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
133
147
  if ($emit) {
134
148
  const type = typeChecker.getTypeOfSymbolAtLocation($emit, symbolNode);
135
149
  const calls = type.getCallSignatures();
136
- return calls.map(resolveEventSignature).filter(event => event.name);
150
+ return calls.map((call) => {
151
+ const { resolveEventSignature, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions);
152
+ return resolveEventSignature(call);
153
+ }).filter(event => event.name);
137
154
  }
138
155
  return [];
139
156
  }
@@ -144,7 +161,10 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
144
161
  if ($slots) {
145
162
  const type = typeChecker.getTypeOfSymbolAtLocation($slots, symbolNode);
146
163
  const properties = type.getProperties();
147
- return properties.map(resolveSlotProperties);
164
+ return properties.map((prop) => {
165
+ const { resolveSlotProperties, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions);
166
+ return resolveSlotProperties(prop);
167
+ });
148
168
  }
149
169
  return [];
150
170
  }
@@ -153,7 +173,10 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
153
173
  // only exposed props will have a syntheticOrigin
154
174
  Boolean(prop.syntheticOrigin));
155
175
  if (exposed.length) {
156
- return exposed.map(resolveExposedProperties);
176
+ return exposed.map((prop) => {
177
+ const { resolveExposedProperties, } = createSchemaResolvers(typeChecker, symbolNode, checkerOptions);
178
+ return resolveExposedProperties(prop);
179
+ });
157
180
  }
158
181
  return [];
159
182
  }
@@ -188,10 +211,10 @@ function createComponentMetaChecker(tsconfigPath, checkerOptions = {}) {
188
211
  }
189
212
  }
190
213
  exports.createComponentMetaChecker = createComponentMetaChecker;
191
- function createSchemaResolvers(typeChecker, symbolNode, options = false) {
214
+ function createSchemaResolvers(typeChecker, symbolNode, { rawType, schema: options }) {
192
215
  var _a;
193
216
  const enabled = !!options;
194
- const ignore = typeof options === 'object' ? (_a = options.ignore) !== null && _a !== void 0 ? _a : [] : [];
217
+ const ignore = typeof options === 'object' ? [...(_a = options === null || options === void 0 ? void 0 : options.ignore) !== null && _a !== void 0 ? _a : []] : [];
195
218
  function shouldIgnore(subtype) {
196
219
  const type = typeChecker.typeToString(subtype);
197
220
  if (type === 'any') {
@@ -202,6 +225,10 @@ function createSchemaResolvers(typeChecker, symbolNode, options = false) {
202
225
  }
203
226
  return ignore.includes(type);
204
227
  }
228
+ function setVisited(subtype) {
229
+ const type = typeChecker.typeToString(subtype);
230
+ ignore.push(type);
231
+ }
205
232
  function reducer(acc, cur) {
206
233
  acc[cur.name] = cur;
207
234
  return acc;
@@ -223,6 +250,7 @@ function createSchemaResolvers(typeChecker, symbolNode, options = false) {
223
250
  }),
224
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),
225
252
  type: typeChecker.typeToString(subtype),
253
+ rawType: rawType ? subtype : undefined,
226
254
  schema,
227
255
  };
228
256
  }
@@ -232,6 +260,7 @@ function createSchemaResolvers(typeChecker, symbolNode, options = false) {
232
260
  return {
233
261
  name: prop.getName(),
234
262
  type: typeChecker.typeToString(subtype),
263
+ rawType: rawType ? subtype : undefined,
235
264
  description: ts.displayPartsToString(prop.getDocumentationComment(typeChecker)),
236
265
  schema,
237
266
  };
@@ -242,6 +271,7 @@ function createSchemaResolvers(typeChecker, symbolNode, options = false) {
242
271
  return {
243
272
  name: expose.getName(),
244
273
  type: typeChecker.typeToString(subtype),
274
+ rawType: rawType ? subtype : undefined,
245
275
  description: ts.displayPartsToString(expose.getDocumentationComment(typeChecker)),
246
276
  schema,
247
277
  };
@@ -254,6 +284,7 @@ function createSchemaResolvers(typeChecker, symbolNode, options = false) {
254
284
  return {
255
285
  name: typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode).value,
256
286
  type: typeChecker.typeToString(subtype),
287
+ rawType: rawType ? subtype : undefined,
257
288
  signature: typeChecker.signatureToString(call),
258
289
  schema,
259
290
  };
@@ -270,66 +301,57 @@ function createSchemaResolvers(typeChecker, symbolNode, options = false) {
270
301
  schema,
271
302
  };
272
303
  }
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, {})
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)
288
316
  };
289
317
  }
290
- return resolveEventSchema(subtype);
291
- }
292
- function resolveArraySchema(subtype) {
293
318
  // @ts-ignore - typescript internal, isArrayLikeType exists
294
- if (typeChecker.isArrayLikeType(subtype)) {
295
- if (shouldIgnore(subtype)) {
296
- return typeChecker.typeToString(subtype);
297
- }
298
- return {
319
+ else if (typeChecker.isArrayLikeType(subtype)) {
320
+ schema = {
299
321
  kind: 'array',
300
- type: typeChecker.typeToString(subtype),
322
+ type,
301
323
  schema: typeChecker.getTypeArguments(subtype).map(resolveSchema)
302
324
  };
303
325
  }
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);
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;
314
339
  }
315
340
  return {
316
341
  resolveNestedProperties,
317
342
  resolveSlotProperties,
318
343
  resolveEventSignature,
319
344
  resolveExposedProperties,
320
- resolveCallbackSchema,
321
- resolveEventSchema,
322
- resolveNestedSchema,
323
- resolveArraySchema,
324
345
  resolveSchema,
325
346
  };
326
347
  }
327
348
  function readVueComponentDefaultProps(vueFileText, printer) {
328
- const result = {};
349
+ let result = {};
329
350
  scriptSetupWorker();
330
- sciptWorker();
351
+ scriptWorker();
331
352
  return result;
332
353
  function scriptSetupWorker() {
354
+ var _a;
333
355
  const vueSourceFile = vue.createSourceFile('/tmp.vue', vueFileText, {}, {}, ts);
334
356
  const descriptor = vueSourceFile.getDescriptor();
335
357
  const scriptSetupRanges = vueSourceFile.getScriptSetupRanges();
@@ -341,27 +363,37 @@ function readVueComponentDefaultProps(vueFileText, printer) {
341
363
  for (const prop of obj.properties) {
342
364
  if (ts.isPropertyAssignment(prop)) {
343
365
  const name = prop.name.getText(ast);
344
- const exp = printer.printNode(ts.EmitHint.Expression, resolveDefaultOptionExpression(prop.initializer), ast);
345
- ;
346
- result[name] = exp;
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
+ };
347
371
  }
348
372
  }
349
373
  }
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;
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));
361
381
  }
362
382
  }
383
+ function findObjectLiteralExpression(node) {
384
+ if (ts.isObjectLiteralExpression(node)) {
385
+ return node;
386
+ }
387
+ let result;
388
+ node.forEachChild(child => {
389
+ if (!result) {
390
+ result = findObjectLiteralExpression(child);
391
+ }
392
+ });
393
+ return result;
394
+ }
363
395
  }
364
- function sciptWorker() {
396
+ function scriptWorker() {
365
397
  const vueSourceFile = vue.createSourceFile('/tmp.vue', vueFileText, {}, {}, ts);
366
398
  const descriptor = vueSourceFile.getDescriptor();
367
399
  if (descriptor.script) {
@@ -373,28 +405,12 @@ function readVueComponentDefaultProps(vueFileText, printer) {
373
405
  }
374
406
  }
375
407
  function readTsComponentDefaultProps(lang, tsFileText, exportName, printer) {
376
- var _a, _b;
377
- const result = {};
378
408
  const ast = ts.createSourceFile('/tmp.' + lang, tsFileText, ts.ScriptTarget.Latest);
379
409
  const props = getPropsNode();
380
410
  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
- }
411
+ return resolvePropsOption(ast, props, printer);
396
412
  }
397
- return result;
413
+ return {};
398
414
  function getComponentNode() {
399
415
  let result;
400
416
  if (exportName === 'default') {
@@ -448,6 +464,30 @@ function readTsComponentDefaultProps(lang, tsFileText, exportName, printer) {
448
464
  }
449
465
  }
450
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
+ }
489
+ return result;
490
+ }
451
491
  function resolveDefaultOptionExpression(_default) {
452
492
  if (ts.isArrowFunction(_default)) {
453
493
  if (ts.isBlock(_default.body)) {
package/out/types.d.ts CHANGED
@@ -11,6 +11,7 @@ export interface PropertyMeta {
11
11
  global: boolean;
12
12
  required: boolean;
13
13
  type: string;
14
+ rawType?: ts.Type;
14
15
  tags: {
15
16
  name: string;
16
17
  text?: string;
@@ -20,12 +21,14 @@ export interface PropertyMeta {
20
21
  export interface EventMeta {
21
22
  name: string;
22
23
  type: string;
24
+ rawType?: ts.Type;
23
25
  signature: string;
24
26
  schema?: PropertyMetaSchema[];
25
27
  }
26
28
  export interface SlotMeta {
27
29
  name: string;
28
30
  type: string;
31
+ rawType?: ts.Type;
29
32
  description: string;
30
33
  schema?: PropertyMetaSchema;
31
34
  }
@@ -33,6 +36,7 @@ export interface ExposeMeta {
33
36
  name: string;
34
37
  description: string;
35
38
  type: string;
39
+ rawType?: ts.Type;
36
40
  schema?: PropertyMetaSchema;
37
41
  }
38
42
  export declare type PropertyMetaSchema = string | {
@@ -59,4 +63,5 @@ export interface MetaCheckerOptions {
59
63
  schema?: MetaCheckerSchemaOptions;
60
64
  forceUseTs?: boolean;
61
65
  printer?: import('typescript').PrinterOptions;
66
+ rawType?: boolean;
62
67
  }
package/out/types.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, "__esModule", { value: true });
3
2
  ;
4
3
  //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-component-meta",
3
- "version": "0.39.4",
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.4"
16
+ "@volar/vue-language-core": "0.39.5"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "typescript": "*"
20
20
  },
21
- "gitHead": "e3f6327b11a0a41c1b448c2ecc25ba85b9986dee"
21
+ "gitHead": "b2efb244b43f24b3e351c72e731f31090e51a736"
22
22
  }