@vue/typescript-plugin 2.2.0 → 2.2.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/lib/client.d.ts CHANGED
@@ -1,17 +1,13 @@
1
- export declare function collectExtractProps(...args: Parameters<typeof import('./requests/collectExtractProps.js')['collectExtractProps']>): Promise<{
1
+ export declare const collectExtractProps: (fileName: string, templateCodeRange: [number, number]) => Promise<{
2
2
  name: string;
3
3
  type: string;
4
4
  model: boolean;
5
5
  }[] | null | undefined>;
6
- export declare function getImportPathForFile(...args: Parameters<typeof import('./requests/getImportPathForFile.js')['getImportPathForFile']>): Promise<string | null | undefined>;
7
- export declare function getPropertiesAtLocation(...args: Parameters<typeof import('./requests/getPropertiesAtLocation.js')['getPropertiesAtLocation']>): Promise<string[] | null | undefined>;
8
- export declare function getQuickInfoAtPosition(...args: Parameters<typeof import('./requests/getQuickInfoAtPosition.js')['getQuickInfoAtPosition']>): Promise<string | null | undefined>;
9
- export declare function getComponentProps(fileName: string, componentName: string): Promise<{
10
- name: string;
11
- required?: true;
12
- commentMarkdown?: string;
13
- }[] | null | undefined>;
14
- export declare function getComponentEvents(...args: Parameters<typeof import('./requests/componentInfos.js')['getComponentEvents']>): Promise<string[] | null | undefined>;
15
- export declare function getTemplateContextProps(...args: Parameters<typeof import('./requests/componentInfos.js')['getTemplateContextProps']>): Promise<string[] | null | undefined>;
6
+ export declare const getImportPathForFile: (fileName: string, incomingFileName: string, preferences: import("typescript").UserPreferences) => Promise<string | null | undefined>;
7
+ export declare const getPropertiesAtLocation: (fileName: string, position: number) => Promise<string[] | null | undefined>;
8
+ export declare const getQuickInfoAtPosition: (fileName: string, position: number) => Promise<string | null | undefined>;
9
+ export declare function getComponentProps(fileName: string, componentName: string): Promise<import("./requests/getComponentProps").ComponentPropInfo[] | null | undefined>;
10
+ export declare const getComponentEvents: (fileName: string, tag: string) => Promise<string[] | null | undefined>;
11
+ export declare const getComponentDirectives: (fileName: string) => Promise<string[] | null | undefined>;
16
12
  export declare function getComponentNames(fileName: string): Promise<string[] | undefined>;
17
- export declare function getElementAttrs(...args: Parameters<typeof import('./requests/componentInfos.js')['getElementAttrs']>): Promise<string[] | null | undefined>;
13
+ export declare const getElementAttrs: (fileName: string, tagName: string) => Promise<string[] | null | undefined>;
package/lib/client.js CHANGED
@@ -1,27 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.collectExtractProps = collectExtractProps;
4
- exports.getImportPathForFile = getImportPathForFile;
5
- exports.getPropertiesAtLocation = getPropertiesAtLocation;
6
- exports.getQuickInfoAtPosition = getQuickInfoAtPosition;
3
+ exports.getElementAttrs = exports.getComponentDirectives = exports.getComponentEvents = exports.getQuickInfoAtPosition = exports.getPropertiesAtLocation = exports.getImportPathForFile = exports.collectExtractProps = void 0;
7
4
  exports.getComponentProps = getComponentProps;
8
- exports.getComponentEvents = getComponentEvents;
9
- exports.getTemplateContextProps = getTemplateContextProps;
10
5
  exports.getComponentNames = getComponentNames;
11
- exports.getElementAttrs = getElementAttrs;
12
6
  const utils_1 = require("./utils");
13
- function collectExtractProps(...args) {
14
- return sendRequest('collectExtractProps', ...args);
15
- }
16
- async function getImportPathForFile(...args) {
17
- return await sendRequest('getImportPathForFile', ...args);
18
- }
19
- async function getPropertiesAtLocation(...args) {
20
- return await sendRequest('getPropertiesAtLocation', ...args);
21
- }
22
- function getQuickInfoAtPosition(...args) {
23
- return sendRequest('getQuickInfoAtPosition', ...args);
24
- }
7
+ exports.collectExtractProps = createRequest('collectExtractProps');
8
+ exports.getImportPathForFile = createRequest('getImportPathForFile');
9
+ exports.getPropertiesAtLocation = createRequest('getPropertiesAtLocation');
10
+ exports.getQuickInfoAtPosition = createRequest('getQuickInfoAtPosition');
25
11
  // Component Infos
26
12
  async function getComponentProps(fileName, componentName) {
27
13
  const server = await (0, utils_1.getBestServer)(fileName);
@@ -30,12 +16,8 @@ async function getComponentProps(fileName, componentName) {
30
16
  }
31
17
  return await server.getComponentProps(fileName, componentName);
32
18
  }
33
- function getComponentEvents(...args) {
34
- return sendRequest('getComponentEvents', ...args);
35
- }
36
- function getTemplateContextProps(...args) {
37
- return sendRequest('getTemplateContextProps', ...args);
38
- }
19
+ exports.getComponentEvents = createRequest('getComponentEvents');
20
+ exports.getComponentDirectives = createRequest('getComponentDirectives');
39
21
  async function getComponentNames(fileName) {
40
22
  const server = await (0, utils_1.getBestServer)(fileName);
41
23
  if (!server) {
@@ -47,14 +29,14 @@ async function getComponentNames(fileName) {
47
29
  }
48
30
  return Object.keys(componentAndProps);
49
31
  }
50
- function getElementAttrs(...args) {
51
- return sendRequest('getElementAttrs', ...args);
52
- }
53
- async function sendRequest(requestType, fileName, ...rest) {
54
- const server = await (0, utils_1.getBestServer)(fileName);
55
- if (!server) {
56
- return;
57
- }
58
- return server.sendRequest(requestType, fileName, ...rest);
32
+ exports.getElementAttrs = createRequest('getElementAttrs');
33
+ function createRequest(requestType) {
34
+ return async function (...[fileName, ...rest]) {
35
+ const server = await (0, utils_1.getBestServer)(fileName);
36
+ if (!server) {
37
+ return;
38
+ }
39
+ return server.sendRequest(requestType, fileName, ...rest);
40
+ };
59
41
  }
60
42
  //# sourceMappingURL=client.js.map
package/lib/common.js CHANGED
@@ -4,7 +4,7 @@ exports.proxyLanguageServiceForVue = proxyLanguageServiceForVue;
4
4
  exports.getComponentSpans = getComponentSpans;
5
5
  const language_core_1 = require("@vue/language-core");
6
6
  const shared_1 = require("@vue/shared");
7
- const componentInfos_1 = require("./requests/componentInfos");
7
+ const getComponentNames_1 = require("./requests/getComponentNames");
8
8
  const windowsPathReg = /\\/g;
9
9
  function proxyLanguageServiceForVue(ts, language, languageService, vueOptions, asScriptId) {
10
10
  const proxyCache = new Map();
@@ -102,7 +102,7 @@ function getCompletionEntryDetails(language, asScriptId, getCompletionEntryDetai
102
102
  const { fileName } = args[6]?.__isAutoImport;
103
103
  const sourceScript = language.scripts.get(asScriptId(fileName));
104
104
  if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
105
- const sfc = sourceScript.generated.root._vueSfc.get();
105
+ const sfc = sourceScript.generated.root.vueSfc;
106
106
  if (!sfc?.descriptor.script && !sfc?.descriptor.scriptSetup) {
107
107
  for (const codeAction of details?.codeActions ?? []) {
108
108
  for (const change of codeAction.changes) {
@@ -173,7 +173,7 @@ function getEncodedSemanticClassifications(ts, language, languageService, asScri
173
173
  const sourceScript = language.scripts.get(asScriptId(fileName));
174
174
  const root = sourceScript?.generated?.root;
175
175
  if (root instanceof language_core_1.VueVirtualCode) {
176
- const { template } = root._sfc;
176
+ const { template } = root.sfc;
177
177
  if (template) {
178
178
  for (const componentSpan of getComponentSpans.call({ typescript: ts, languageService }, root, template, {
179
179
  start: span.start - template.startTagEnd,
@@ -190,7 +190,7 @@ function getEncodedSemanticClassifications(ts, language, languageService, asScri
190
190
  function getComponentSpans(vueCode, template, spanTemplateRange) {
191
191
  const { typescript: ts, languageService } = this;
192
192
  const result = [];
193
- const validComponentNames = (0, componentInfos_1._getComponentNames)(ts, languageService, vueCode);
193
+ const validComponentNames = (0, getComponentNames_1._getComponentNames)(ts, languageService, vueCode);
194
194
  const components = new Set([
195
195
  ...validComponentNames,
196
196
  ...validComponentNames.map(language_core_1.hyphenateTag),
@@ -18,7 +18,7 @@ function collectExtractProps(fileName, templateCodeRange) {
18
18
  const checker = program.getTypeChecker();
19
19
  const script = sourceScript.generated?.languagePlugin.typescript?.getServiceScript(root);
20
20
  const maps = script ? [...language.maps.forEach(script.code)].map(([_sourceScript, map]) => map) : [];
21
- const sfc = root._sfc;
21
+ const { sfc } = root;
22
22
  sourceFile.forEachChild(function visit(node) {
23
23
  if (ts.isPropertyAccessExpression(node)
24
24
  && ts.isIdentifier(node.expression)
@@ -0,0 +1,2 @@
1
+ import type { RequestContext } from './types';
2
+ export declare function getComponentDirectives(this: RequestContext, fileName: string): string[] | undefined;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getComponentDirectives = getComponentDirectives;
4
+ const language_core_1 = require("@vue/language-core");
5
+ const utils_1 = require("./utils");
6
+ function getComponentDirectives(fileName) {
7
+ const { typescript: ts, language, languageService, getFileId } = this;
8
+ const volarFile = language.scripts.get(getFileId(fileName));
9
+ if (!(volarFile?.generated?.root instanceof language_core_1.VueVirtualCode)) {
10
+ return;
11
+ }
12
+ const vueCode = volarFile.generated.root;
13
+ const directives = (0, utils_1.getVariableType)(ts, languageService, vueCode, '__VLS_directives');
14
+ if (!directives) {
15
+ return [];
16
+ }
17
+ return directives.type.getProperties()
18
+ .map(({ name }) => name)
19
+ .filter(name => name.startsWith('v') && name.length >= 2 && name[1] === name[1].toUpperCase())
20
+ .filter(name => !['vBind', 'vIf', 'vOn', 'VOnce', 'vShow', 'VSlot'].includes(name));
21
+ }
22
+ //# sourceMappingURL=getComponentDirectives.js.map
@@ -0,0 +1,2 @@
1
+ import type { RequestContext } from './types';
2
+ export declare function getComponentEvents(this: RequestContext, fileName: string, tag: string): string[] | undefined;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getComponentEvents = getComponentEvents;
4
+ const language_core_1 = require("@vue/language-core");
5
+ const utils_1 = require("./utils");
6
+ function getComponentEvents(fileName, tag) {
7
+ const { typescript: ts, language, languageService, getFileId } = this;
8
+ const volarFile = language.scripts.get(getFileId(fileName));
9
+ if (!(volarFile?.generated?.root instanceof language_core_1.VueVirtualCode)) {
10
+ return;
11
+ }
12
+ const vueCode = volarFile.generated.root;
13
+ const program = languageService.getProgram();
14
+ const checker = program.getTypeChecker();
15
+ const components = (0, utils_1.getVariableType)(ts, languageService, vueCode, '__VLS_components');
16
+ if (!components) {
17
+ return [];
18
+ }
19
+ const componentType = (0, utils_1.getComponentType)(ts, languageService, vueCode, components, fileName, tag);
20
+ if (!componentType) {
21
+ return [];
22
+ }
23
+ const result = new Set();
24
+ // for (const sig of componentType.getCallSignatures()) {
25
+ // const emitParam = sig.parameters[1];
26
+ // if (emitParam) {
27
+ // // TODO
28
+ // }
29
+ // }
30
+ for (const sig of componentType.getConstructSignatures()) {
31
+ const instanceType = sig.getReturnType();
32
+ const emitSymbol = instanceType.getProperty('$emit');
33
+ if (emitSymbol) {
34
+ const emitType = checker.getTypeOfSymbolAtLocation(emitSymbol, components.node);
35
+ for (const call of emitType.getCallSignatures()) {
36
+ const eventNameParamSymbol = call.parameters[0];
37
+ if (eventNameParamSymbol) {
38
+ const eventNameParamType = checker.getTypeOfSymbolAtLocation(eventNameParamSymbol, components.node);
39
+ if (eventNameParamType.isStringLiteral()) {
40
+ result.add(eventNameParamType.value);
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ return [...result];
47
+ }
48
+ //# sourceMappingURL=getComponentEvents.js.map
@@ -0,0 +1,5 @@
1
+ import { VueVirtualCode } from '@vue/language-core';
2
+ import type * as ts from 'typescript';
3
+ import type { RequestContext } from './types';
4
+ export declare function getComponentNames(this: RequestContext, fileName: string): string[] | undefined;
5
+ export declare function _getComponentNames(ts: typeof import('typescript'), tsLs: ts.LanguageService, vueCode: VueVirtualCode): string[];
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getComponentNames = getComponentNames;
4
+ exports._getComponentNames = _getComponentNames;
5
+ const language_core_1 = require("@vue/language-core");
6
+ const utils_1 = require("./utils");
7
+ function getComponentNames(fileName) {
8
+ const { typescript: ts, language, languageService, getFileId } = this;
9
+ const volarFile = language.scripts.get(getFileId(fileName));
10
+ if (!(volarFile?.generated?.root instanceof language_core_1.VueVirtualCode)) {
11
+ return;
12
+ }
13
+ const vueCode = volarFile.generated.root;
14
+ return _getComponentNames(ts, languageService, vueCode);
15
+ }
16
+ function _getComponentNames(ts, tsLs, vueCode) {
17
+ const names = (0, utils_1.getVariableType)(ts, tsLs, vueCode, '__VLS_components')
18
+ ?.type
19
+ ?.getProperties()
20
+ .map(c => c.name)
21
+ .filter(entry => !entry.includes('$') && !entry.startsWith('_'))
22
+ ?? [];
23
+ names.push((0, utils_1.getSelfComponentName)(vueCode.fileName));
24
+ return names;
25
+ }
26
+ //# sourceMappingURL=getComponentNames.js.map
@@ -0,0 +1,9 @@
1
+ import type { RequestContext } from './types';
2
+ export interface ComponentPropInfo {
3
+ name: string;
4
+ required?: boolean;
5
+ deprecated?: boolean;
6
+ commentMarkdown?: string;
7
+ values?: string[];
8
+ }
9
+ export declare function getComponentProps(this: RequestContext, fileName: string, tag: string): ComponentPropInfo[] | undefined;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getComponentProps = getComponentProps;
4
+ const language_core_1 = require("@vue/language-core");
5
+ const utils_1 = require("./utils");
6
+ function getComponentProps(fileName, tag) {
7
+ const { typescript: ts, language, languageService, getFileId } = this;
8
+ const volarFile = language.scripts.get(getFileId(fileName));
9
+ if (!(volarFile?.generated?.root instanceof language_core_1.VueVirtualCode)) {
10
+ return;
11
+ }
12
+ const vueCode = volarFile.generated.root;
13
+ const program = languageService.getProgram();
14
+ const checker = program.getTypeChecker();
15
+ const components = (0, utils_1.getVariableType)(ts, languageService, vueCode, '__VLS_components');
16
+ if (!components) {
17
+ return [];
18
+ }
19
+ const componentType = (0, utils_1.getComponentType)(ts, languageService, vueCode, components, fileName, tag);
20
+ if (!componentType) {
21
+ return [];
22
+ }
23
+ const result = new Map();
24
+ for (const sig of componentType.getCallSignatures()) {
25
+ const propParam = sig.parameters[0];
26
+ if (propParam) {
27
+ const propsType = checker.getTypeOfSymbolAtLocation(propParam, components.node);
28
+ const props = propsType.getProperties();
29
+ for (const prop of props) {
30
+ const name = prop.name;
31
+ const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
32
+ const { content: commentMarkdown, deprecated } = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags());
33
+ result.set(name, {
34
+ name,
35
+ required,
36
+ deprecated,
37
+ commentMarkdown
38
+ });
39
+ }
40
+ }
41
+ }
42
+ for (const sig of componentType.getConstructSignatures()) {
43
+ const instanceType = sig.getReturnType();
44
+ const propsSymbol = instanceType.getProperty('$props');
45
+ if (propsSymbol) {
46
+ const propsType = checker.getTypeOfSymbolAtLocation(propsSymbol, components.node);
47
+ const props = propsType.getProperties();
48
+ for (const prop of props) {
49
+ if (prop.flags & ts.SymbolFlags.Method) { // #2443
50
+ continue;
51
+ }
52
+ const name = prop.name;
53
+ const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
54
+ const { content: commentMarkdown, deprecated } = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags());
55
+ result.set(name, {
56
+ name,
57
+ required,
58
+ deprecated,
59
+ commentMarkdown
60
+ });
61
+ }
62
+ }
63
+ }
64
+ return [...result.values()];
65
+ }
66
+ function generateCommentMarkdown(parts, jsDocTags) {
67
+ const parsedComment = _symbolDisplayPartsToMarkdown(parts);
68
+ const parsedJsDoc = _jsDocTagInfoToMarkdown(jsDocTags);
69
+ const content = [parsedComment, parsedJsDoc].filter(str => !!str).join('\n\n');
70
+ const deprecated = jsDocTags.some(tag => tag.name === 'deprecated');
71
+ return {
72
+ content,
73
+ deprecated
74
+ };
75
+ }
76
+ function _symbolDisplayPartsToMarkdown(parts) {
77
+ return parts.map(part => {
78
+ switch (part.kind) {
79
+ case 'keyword':
80
+ return `\`${part.text}\``;
81
+ case 'functionName':
82
+ return `**${part.text}**`;
83
+ default:
84
+ return part.text;
85
+ }
86
+ }).join('');
87
+ }
88
+ function _jsDocTagInfoToMarkdown(jsDocTags) {
89
+ return jsDocTags.map(tag => {
90
+ const tagName = `*@${tag.name}*`;
91
+ const tagText = tag.text?.map(t => {
92
+ if (t.kind === 'parameterName') {
93
+ return `\`${t.text}\``;
94
+ }
95
+ else {
96
+ return t.text;
97
+ }
98
+ }).join('') || '';
99
+ return `${tagName} ${tagText}`;
100
+ }).join('\n\n');
101
+ }
102
+ //# sourceMappingURL=getComponentProps.js.map
@@ -0,0 +1,2 @@
1
+ import type { RequestContext } from './types';
2
+ export declare function getElementAttrs(this: RequestContext, fileName: string, tagName: string): string[] | undefined;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getElementAttrs = getElementAttrs;
4
+ const vue = require("@vue/language-core");
5
+ function getElementAttrs(fileName, tagName) {
6
+ const { typescript: ts, language, languageService, getFileId } = this;
7
+ const volarFile = language.scripts.get(getFileId(fileName));
8
+ if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
9
+ return;
10
+ }
11
+ const program = languageService.getProgram();
12
+ let tsSourceFile;
13
+ if (tsSourceFile = program.getSourceFile(fileName)) {
14
+ const checker = program.getTypeChecker();
15
+ const typeNode = tsSourceFile.statements
16
+ .filter(ts.isTypeAliasDeclaration)
17
+ .find(node => node.name.getText() === '__VLS_IntrinsicElementsCompletion');
18
+ if (checker && typeNode) {
19
+ const type = checker.getTypeFromTypeNode(typeNode.type);
20
+ const el = type.getProperty(tagName);
21
+ if (el) {
22
+ const attrs = checker.getTypeOfSymbolAtLocation(el, typeNode).getProperties();
23
+ return attrs.map(c => c.name);
24
+ }
25
+ }
26
+ }
27
+ return [];
28
+ }
29
+ //# sourceMappingURL=getElementAttrs.js.map
@@ -0,0 +1,8 @@
1
+ import type { VueVirtualCode } from '@vue/language-core';
2
+ import type * as ts from 'typescript';
3
+ export declare function getComponentType(ts: typeof import('typescript'), languageService: ts.LanguageService, vueCode: VueVirtualCode, components: NonNullable<ReturnType<typeof getVariableType>>, fileName: string, tag: string): ts.Type | undefined;
4
+ export declare function getSelfComponentName(fileName: string): Capitalize<string>;
5
+ export declare function getVariableType(ts: typeof import('typescript'), languageService: ts.LanguageService, vueCode: VueVirtualCode, name: string): {
6
+ node: ts.Node;
7
+ type: ts.Type;
8
+ } | undefined;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getComponentType = getComponentType;
4
+ exports.getSelfComponentName = getSelfComponentName;
5
+ exports.getVariableType = getVariableType;
6
+ const shared_1 = require("@vue/shared");
7
+ const path = require("node:path");
8
+ function getComponentType(ts, languageService, vueCode, components, fileName, tag) {
9
+ const program = languageService.getProgram();
10
+ const checker = program.getTypeChecker();
11
+ const name = tag.split('.');
12
+ let componentSymbol = components.type.getProperty(name[0])
13
+ ?? components.type.getProperty((0, shared_1.camelize)(name[0]))
14
+ ?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
15
+ let componentType;
16
+ if (!componentSymbol) {
17
+ const name = getSelfComponentName(fileName);
18
+ if (name === (0, shared_1.capitalize)((0, shared_1.camelize)(tag))) {
19
+ componentType = getVariableType(ts, languageService, vueCode, '__VLS_self')?.type;
20
+ }
21
+ }
22
+ else {
23
+ componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
24
+ for (let i = 1; i < name.length; i++) {
25
+ componentSymbol = componentType.getProperty(name[i]);
26
+ if (componentSymbol) {
27
+ componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
28
+ }
29
+ }
30
+ }
31
+ return componentType;
32
+ }
33
+ function getSelfComponentName(fileName) {
34
+ const baseName = path.basename(fileName);
35
+ return (0, shared_1.capitalize)((0, shared_1.camelize)(baseName.slice(0, baseName.lastIndexOf('.'))));
36
+ }
37
+ function getVariableType(ts, languageService, vueCode, name) {
38
+ const program = languageService.getProgram();
39
+ let tsSourceFile;
40
+ if (tsSourceFile = program.getSourceFile(vueCode.fileName)) {
41
+ const node = searchVariableDeclarationNode(ts, tsSourceFile, name);
42
+ const checker = program.getTypeChecker();
43
+ if (checker && node) {
44
+ return {
45
+ node: node,
46
+ type: checker.getTypeAtLocation(node),
47
+ };
48
+ }
49
+ }
50
+ }
51
+ function searchVariableDeclarationNode(ts, sourceFile, name) {
52
+ let componentsNode;
53
+ walk(sourceFile);
54
+ return componentsNode;
55
+ function walk(node) {
56
+ if (componentsNode) {
57
+ return;
58
+ }
59
+ else if (ts.isVariableDeclaration(node) && node.name.getText() === name) {
60
+ componentsNode = node;
61
+ }
62
+ else {
63
+ node.forEachChild(walk);
64
+ }
65
+ }
66
+ }
67
+ //# sourceMappingURL=utils.js.map
package/lib/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Language } from '@vue/language-core';
2
2
  import type * as ts from 'typescript';
3
- export type RequestType = 'containsFile' | 'projectInfo' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'subscribeComponentProps' | 'getComponentEvents' | 'getTemplateContextProps' | 'getElementAttrs';
3
+ export type RequestType = 'containsFile' | 'projectInfo' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'subscribeComponentProps' | 'getComponentEvents' | 'getComponentDirectives' | 'getElementAttrs';
4
4
  export type NotificationType = 'componentNamesUpdated' | 'componentPropsUpdated';
5
5
  export type RequestData = [
6
6
  seq: number,
package/lib/server.js CHANGED
@@ -5,7 +5,11 @@ const language_core_1 = require("@vue/language-core");
5
5
  const fs = require("node:fs");
6
6
  const net = require("node:net");
7
7
  const collectExtractProps_1 = require("./requests/collectExtractProps");
8
- const componentInfos_1 = require("./requests/componentInfos");
8
+ const getComponentDirectives_1 = require("./requests/getComponentDirectives");
9
+ const getComponentEvents_1 = require("./requests/getComponentEvents");
10
+ const getComponentNames_1 = require("./requests/getComponentNames");
11
+ const getComponentProps_1 = require("./requests/getComponentProps");
12
+ const getElementAttrs_1 = require("./requests/getElementAttrs");
9
13
  const getImportPathForFile_1 = require("./requests/getImportPathForFile");
10
14
  const getPropertiesAtLocation_1 = require("./requests/getPropertiesAtLocation");
11
15
  const getQuickInfoAtPosition_1 = require("./requests/getQuickInfoAtPosition");
@@ -51,7 +55,7 @@ async function startNamedPipeServer(ts, info, language, projectKind) {
51
55
  });
52
56
  connection.on('error', err => console.error('[Vue Named Pipe Server]', err.message));
53
57
  for (const [fileName, [componentNames, componentProps]] of currentData) {
54
- notify(connection, 'componentNamesUpdated', fileName, Object.keys(componentNames));
58
+ notify(connection, 'componentNamesUpdated', fileName, componentNames);
55
59
  for (const [name, props] of Object.entries(componentProps)) {
56
60
  notify(connection, 'componentPropsUpdated', fileName, [name, props]);
57
61
  }
@@ -100,7 +104,7 @@ async function startNamedPipeServer(ts, info, language, projectKind) {
100
104
  currentData.set(scriptInfo.fileName, data);
101
105
  }
102
106
  const [oldComponentNames, componentProps] = data;
103
- const newComponentNames = componentInfos_1.getComponentNames.apply(requestContext, [scriptInfo.fileName]) ?? [];
107
+ const newComponentNames = getComponentNames_1.getComponentNames.apply(requestContext, [scriptInfo.fileName]) ?? [];
104
108
  if (JSON.stringify(oldComponentNames) !== JSON.stringify(newComponentNames)) {
105
109
  data[0] = newComponentNames;
106
110
  for (const connection of connections) {
@@ -112,7 +116,7 @@ async function startNamedPipeServer(ts, info, language, projectKind) {
112
116
  if (token?.isCancellationRequested()) {
113
117
  break;
114
118
  }
115
- const newProps = componentInfos_1.getComponentProps.apply(requestContext, [scriptInfo.fileName, name]) ?? [];
119
+ const newProps = getComponentProps_1.getComponentProps.apply(requestContext, [scriptInfo.fileName, name]) ?? [];
116
120
  if (JSON.stringify(props) !== JSON.stringify(newProps)) {
117
121
  componentProps[name] = newProps;
118
122
  for (const connection of connections) {
@@ -171,7 +175,7 @@ async function startNamedPipeServer(ts, info, language, projectKind) {
171
175
  }
172
176
  else if (requestType === 'subscribeComponentProps') {
173
177
  const tag = args[1];
174
- const props = componentInfos_1.getComponentProps.apply(requestContext, [fileName, tag]) ?? [];
178
+ const props = getComponentProps_1.getComponentProps.apply(requestContext, [fileName, tag]) ?? [];
175
179
  let data = currentData.get(fileName);
176
180
  if (!data) {
177
181
  data = [[], {}];
@@ -181,13 +185,13 @@ async function startNamedPipeServer(ts, info, language, projectKind) {
181
185
  return props;
182
186
  }
183
187
  else if (requestType === 'getComponentEvents') {
184
- return componentInfos_1.getComponentEvents.apply(requestContext, args);
188
+ return getComponentEvents_1.getComponentEvents.apply(requestContext, args);
185
189
  }
186
- else if (requestType === 'getTemplateContextProps') {
187
- return componentInfos_1.getTemplateContextProps.apply(requestContext, args);
190
+ else if (requestType === 'getComponentDirectives') {
191
+ return getComponentDirectives_1.getComponentDirectives.apply(requestContext, args);
188
192
  }
189
193
  else if (requestType === 'getElementAttrs') {
190
- return componentInfos_1.getElementAttrs.apply(requestContext, args);
194
+ return getElementAttrs_1.getElementAttrs.apply(requestContext, args);
191
195
  }
192
196
  console.warn('[Vue Named Pipe Server] Unknown request:', requestType);
193
197
  debugger;
package/lib/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { FileMap } from '@vue/language-core';
2
2
  import * as net from 'node:net';
3
3
  import type * as ts from 'typescript';
4
+ import type { ComponentPropInfo } from './requests/getComponentProps';
4
5
  import type { NotificationData, ProjectInfo, RequestData } from './server';
5
6
  export { TypeScriptProjectHost } from '@volar/typescript';
6
7
  export declare function getServerPath(kind: ts.server.ProjectKind, id: number): string;
@@ -9,18 +10,10 @@ declare class NamedPipeServer {
9
10
  connecting: boolean;
10
11
  projectInfo?: ProjectInfo;
11
12
  containsFileCache: Map<string, Promise<boolean | null | undefined>>;
12
- componentNamesAndProps: FileMap<Record<string, {
13
- name: string;
14
- required?: true;
15
- commentMarkdown?: string;
16
- }[] | null>>;
13
+ componentNamesAndProps: FileMap<Record<string, ComponentPropInfo[] | null>>;
17
14
  constructor(kind: ts.server.ProjectKind, id: number);
18
15
  containsFile(fileName: string): Promise<boolean | null | undefined> | undefined;
19
- getComponentProps(fileName: string, tag: string): Promise<{
20
- name: string;
21
- required?: true;
22
- commentMarkdown?: string;
23
- }[] | null | undefined>;
16
+ getComponentProps(fileName: string, tag: string): Promise<ComponentPropInfo[] | null | undefined>;
24
17
  update(): void;
25
18
  connect(): void;
26
19
  close(): void;
package/lib/utils.js CHANGED
@@ -153,7 +153,9 @@ class NamedPipeServer {
153
153
  else if (type === 'componentPropsUpdated') {
154
154
  const components = this.componentNamesAndProps.get(fileName) ?? {};
155
155
  const [name, props] = data;
156
- components[name] = props;
156
+ if (name in components) {
157
+ components[name] = props;
158
+ }
157
159
  }
158
160
  else {
159
161
  console.error('Unknown notification type:', type);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/typescript-plugin",
3
- "version": "2.2.0",
3
+ "version": "2.2.4",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -14,11 +14,11 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@volar/typescript": "~2.4.11",
17
- "@vue/language-core": "2.2.0",
17
+ "@vue/language-core": "2.2.4",
18
18
  "@vue/shared": "^3.5.0"
19
19
  },
20
20
  "devDependencies": {
21
- "@types/node": "latest"
21
+ "@types/node": "^22.10.4"
22
22
  },
23
- "gitHead": "5babca774658d4b9afbe877ac7c8cafdaecf2c3e"
23
+ "gitHead": "c28986596935cb43979c9d437c25f292bdb36cef"
24
24
  }
@@ -1,13 +0,0 @@
1
- import * as vue from '@vue/language-core';
2
- import type * as ts from 'typescript';
3
- import type { RequestContext } from './types';
4
- export declare function getComponentProps(this: RequestContext, fileName: string, tag: string): {
5
- name: string;
6
- required?: true;
7
- commentMarkdown?: string;
8
- }[] | undefined;
9
- export declare function getComponentEvents(this: RequestContext, fileName: string, tag: string): string[] | undefined;
10
- export declare function getTemplateContextProps(this: RequestContext, fileName: string): string[] | undefined;
11
- export declare function getComponentNames(this: RequestContext, fileName: string): string[] | undefined;
12
- export declare function _getComponentNames(ts: typeof import('typescript'), tsLs: ts.LanguageService, vueCode: vue.VueVirtualCode): string[];
13
- export declare function getElementAttrs(this: RequestContext, fileName: string, tagName: string): string[] | undefined;
@@ -1,249 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getComponentProps = getComponentProps;
4
- exports.getComponentEvents = getComponentEvents;
5
- exports.getTemplateContextProps = getTemplateContextProps;
6
- exports.getComponentNames = getComponentNames;
7
- exports._getComponentNames = _getComponentNames;
8
- exports.getElementAttrs = getElementAttrs;
9
- const vue = require("@vue/language-core");
10
- const shared_1 = require("@vue/shared");
11
- function getComponentProps(fileName, tag) {
12
- const { typescript: ts, language, languageService, getFileId } = this;
13
- const volarFile = language.scripts.get(getFileId(fileName));
14
- if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
15
- return;
16
- }
17
- const vueCode = volarFile.generated.root;
18
- const program = languageService.getProgram();
19
- const checker = program.getTypeChecker();
20
- const components = getVariableType(ts, languageService, vueCode, '__VLS_components');
21
- if (!components) {
22
- return [];
23
- }
24
- const name = tag.split('.');
25
- let componentSymbol = components.type.getProperty(name[0])
26
- ?? components.type.getProperty((0, shared_1.camelize)(name[0]))
27
- ?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
28
- if (!componentSymbol) {
29
- return [];
30
- }
31
- let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
32
- for (let i = 1; i < name.length; i++) {
33
- componentSymbol = componentType.getProperty(name[i]);
34
- if (componentSymbol) {
35
- componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
36
- }
37
- else {
38
- return [];
39
- }
40
- }
41
- const result = new Map();
42
- for (const sig of componentType.getCallSignatures()) {
43
- const propParam = sig.parameters[0];
44
- if (propParam) {
45
- const propsType = checker.getTypeOfSymbolAtLocation(propParam, components.node);
46
- const props = propsType.getProperties();
47
- for (const prop of props) {
48
- const name = prop.name;
49
- const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
50
- const commentMarkdown = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags()) || undefined;
51
- result.set(name, { name, required, commentMarkdown });
52
- }
53
- }
54
- }
55
- for (const sig of componentType.getConstructSignatures()) {
56
- const instanceType = sig.getReturnType();
57
- const propsSymbol = instanceType.getProperty('$props');
58
- if (propsSymbol) {
59
- const propsType = checker.getTypeOfSymbolAtLocation(propsSymbol, components.node);
60
- const props = propsType.getProperties();
61
- for (const prop of props) {
62
- if (prop.flags & ts.SymbolFlags.Method) { // #2443
63
- continue;
64
- }
65
- const name = prop.name;
66
- const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
67
- const commentMarkdown = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags()) || undefined;
68
- result.set(name, { name, required, commentMarkdown });
69
- }
70
- }
71
- }
72
- return [...result.values()];
73
- }
74
- function getComponentEvents(fileName, tag) {
75
- const { typescript: ts, language, languageService, getFileId } = this;
76
- const volarFile = language.scripts.get(getFileId(fileName));
77
- if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
78
- return;
79
- }
80
- const vueCode = volarFile.generated.root;
81
- const program = languageService.getProgram();
82
- const checker = program.getTypeChecker();
83
- const components = getVariableType(ts, languageService, vueCode, '__VLS_components');
84
- if (!components) {
85
- return [];
86
- }
87
- const name = tag.split('.');
88
- let componentSymbol = components.type.getProperty(name[0]);
89
- if (!componentSymbol) {
90
- componentSymbol = components.type.getProperty((0, shared_1.camelize)(name[0]))
91
- ?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
92
- }
93
- if (!componentSymbol) {
94
- return [];
95
- }
96
- let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
97
- for (let i = 1; i < name.length; i++) {
98
- componentSymbol = componentType.getProperty(name[i]);
99
- if (componentSymbol) {
100
- componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
101
- }
102
- else {
103
- return [];
104
- }
105
- }
106
- const result = new Set();
107
- // for (const sig of componentType.getCallSignatures()) {
108
- // const emitParam = sig.parameters[1];
109
- // if (emitParam) {
110
- // // TODO
111
- // }
112
- // }
113
- for (const sig of componentType.getConstructSignatures()) {
114
- const instanceType = sig.getReturnType();
115
- const emitSymbol = instanceType.getProperty('$emit');
116
- if (emitSymbol) {
117
- const emitType = checker.getTypeOfSymbolAtLocation(emitSymbol, components.node);
118
- for (const call of emitType.getCallSignatures()) {
119
- const eventNameParamSymbol = call.parameters[0];
120
- if (eventNameParamSymbol) {
121
- const eventNameParamType = checker.getTypeOfSymbolAtLocation(eventNameParamSymbol, components.node);
122
- if (eventNameParamType.isStringLiteral()) {
123
- result.add(eventNameParamType.value);
124
- }
125
- }
126
- }
127
- }
128
- }
129
- return [...result];
130
- }
131
- function getTemplateContextProps(fileName) {
132
- const { typescript: ts, language, languageService, getFileId } = this;
133
- const volarFile = language.scripts.get(getFileId(fileName));
134
- if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
135
- return;
136
- }
137
- const vueCode = volarFile.generated.root;
138
- return getVariableType(ts, languageService, vueCode, '__VLS_ctx')
139
- ?.type
140
- ?.getProperties()
141
- .map(c => c.name);
142
- }
143
- function getComponentNames(fileName) {
144
- const { typescript: ts, language, languageService, getFileId } = this;
145
- const volarFile = language.scripts.get(getFileId(fileName));
146
- if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
147
- return;
148
- }
149
- const vueCode = volarFile.generated.root;
150
- return getVariableType(ts, languageService, vueCode, '__VLS_components')
151
- ?.type
152
- ?.getProperties()
153
- .map(c => c.name)
154
- .filter(entry => !entry.includes('$') && !entry.startsWith('_'))
155
- ?? [];
156
- }
157
- function _getComponentNames(ts, tsLs, vueCode) {
158
- return getVariableType(ts, tsLs, vueCode, '__VLS_components')
159
- ?.type
160
- ?.getProperties()
161
- .map(c => c.name)
162
- .filter(entry => !entry.includes('$') && !entry.startsWith('_'))
163
- ?? [];
164
- }
165
- function getElementAttrs(fileName, tagName) {
166
- const { typescript: ts, language, languageService, getFileId } = this;
167
- const volarFile = language.scripts.get(getFileId(fileName));
168
- if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
169
- return;
170
- }
171
- const program = languageService.getProgram();
172
- let tsSourceFile;
173
- if (tsSourceFile = program.getSourceFile(fileName)) {
174
- const typeNode = tsSourceFile.statements.find((node) => ts.isTypeAliasDeclaration(node) && node.name.getText() === '__VLS_IntrinsicElementsCompletion');
175
- const checker = program.getTypeChecker();
176
- if (checker && typeNode) {
177
- const type = checker.getTypeFromTypeNode(typeNode.type);
178
- const el = type.getProperty(tagName);
179
- if (el) {
180
- const attrs = checker.getTypeOfSymbolAtLocation(el, typeNode).getProperties();
181
- return attrs.map(c => c.name);
182
- }
183
- }
184
- }
185
- return [];
186
- }
187
- function getVariableType(ts, languageService, vueCode, name) {
188
- const program = languageService.getProgram();
189
- let tsSourceFile;
190
- if (tsSourceFile = program.getSourceFile(vueCode.fileName)) {
191
- const node = searchVariableDeclarationNode(ts, tsSourceFile, name);
192
- const checker = program.getTypeChecker();
193
- if (checker && node) {
194
- return {
195
- node: node,
196
- type: checker.getTypeAtLocation(node),
197
- };
198
- }
199
- }
200
- }
201
- function searchVariableDeclarationNode(ts, sourceFile, name) {
202
- let componentsNode;
203
- walk(sourceFile);
204
- return componentsNode;
205
- function walk(node) {
206
- if (componentsNode) {
207
- return;
208
- }
209
- else if (ts.isVariableDeclaration(node) && node.name.getText() === name) {
210
- componentsNode = node;
211
- }
212
- else {
213
- node.forEachChild(walk);
214
- }
215
- }
216
- }
217
- function generateCommentMarkdown(parts, jsDocTags) {
218
- const parsedComment = _symbolDisplayPartsToMarkdown(parts);
219
- const parsedJsDoc = _jsDocTagInfoToMarkdown(jsDocTags);
220
- let result = [parsedComment, parsedJsDoc].filter(str => !!str).join('\n\n');
221
- return result;
222
- }
223
- function _symbolDisplayPartsToMarkdown(parts) {
224
- return parts.map(part => {
225
- switch (part.kind) {
226
- case 'keyword':
227
- return `\`${part.text}\``;
228
- case 'functionName':
229
- return `**${part.text}**`;
230
- default:
231
- return part.text;
232
- }
233
- }).join('');
234
- }
235
- function _jsDocTagInfoToMarkdown(jsDocTags) {
236
- return jsDocTags.map(tag => {
237
- const tagName = `*@${tag.name}*`;
238
- const tagText = tag.text?.map(t => {
239
- if (t.kind === 'parameterName') {
240
- return `\`${t.text}\``;
241
- }
242
- else {
243
- return t.text;
244
- }
245
- }).join('') || '';
246
- return `${tagName} ${tagText}`;
247
- }).join('\n\n');
248
- }
249
- //# sourceMappingURL=componentInfos.js.map