@vue/language-core 2.0.26-alpha.2 → 2.0.28

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.
Files changed (45) hide show
  1. package/index.d.ts +1 -1
  2. package/index.js +1 -1
  3. package/lib/codegen/script/component.d.ts +2 -0
  4. package/lib/codegen/script/component.js +57 -41
  5. package/lib/codegen/script/globalTypes.js +4 -9
  6. package/lib/codegen/script/index.js +11 -1
  7. package/lib/codegen/script/scriptSetup.js +52 -32
  8. package/lib/codegen/template/element.js +25 -26
  9. package/lib/codegen/template/elementChildren.js +1 -1
  10. package/lib/codegen/template/elementEvents.js +10 -1
  11. package/lib/codegen/template/elementProps.js +1 -1
  12. package/lib/codegen/template/objectKey.d.ts +1 -0
  13. package/lib/codegen/template/objectKey.js +34 -0
  14. package/lib/languageModule.js +8 -7
  15. package/lib/languagePlugin.d.ts +8 -0
  16. package/lib/languagePlugin.js +175 -0
  17. package/lib/parsers/scriptSetupRanges.d.ts +3 -1
  18. package/lib/parsers/scriptSetupRanges.js +8 -0
  19. package/lib/plugins/file-dot-setup.d.ts +3 -0
  20. package/lib/plugins/file-dot-setup.js +34 -0
  21. package/lib/plugins/file-html.js +14 -3
  22. package/lib/plugins/file-md.js +14 -3
  23. package/lib/plugins/file-vue.js +14 -3
  24. package/lib/plugins/vue-script-js.js +1 -1
  25. package/lib/plugins/vue-sfc-customblocks.js +1 -1
  26. package/lib/plugins/vue-sfc-scripts.js +1 -1
  27. package/lib/plugins/vue-sfc-styles.js +1 -1
  28. package/lib/plugins/vue-sfc-template.js +1 -1
  29. package/lib/plugins/vue-template-html.js +1 -1
  30. package/lib/plugins/vue-template-inline-css.js +1 -1
  31. package/lib/plugins/vue-template-inline-ts.js +1 -1
  32. package/lib/plugins/vue-tsx.d.ts +3 -1
  33. package/lib/plugins/vue-tsx.js +1 -1
  34. package/lib/plugins.d.ts +2 -26
  35. package/lib/plugins.js +24 -10
  36. package/lib/types.d.ts +15 -11
  37. package/lib/types.js +2 -2
  38. package/lib/utils/ts.js +7 -20
  39. package/lib/virtualFile/computedFiles.d.ts +2 -2
  40. package/lib/virtualFile/computedSfc.d.ts +2 -2
  41. package/lib/virtualFile/computedVueSfc.d.ts +2 -2
  42. package/lib/virtualFile/computedVueSfc.js +3 -2
  43. package/lib/virtualFile/vueFile.d.ts +3 -3
  44. package/lib/virtualFile/vueFile.js +1 -1
  45. package/package.json +4 -4
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ /// <reference types="@volar/typescript" />
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createRootFileChecker = createRootFileChecker;
5
+ exports.createVueLanguagePlugin = createVueLanguagePlugin;
6
+ exports.createVueLanguagePlugin2 = createVueLanguagePlugin2;
7
+ exports.getAllExtensions = getAllExtensions;
8
+ const language_core_1 = require("@volar/language-core");
9
+ const CompilerDOM = require("@vue/compiler-dom");
10
+ const plugins_1 = require("./plugins");
11
+ const CompilerVue2 = require("./utils/vue2TemplateCompiler");
12
+ const vueFile_1 = require("./virtualFile/vueFile");
13
+ const normalFileRegistries = [];
14
+ const holderFileRegistries = [];
15
+ function getVueFileRegistry(isGlobalTypesHolder, key, plugins) {
16
+ const fileRegistries = isGlobalTypesHolder ? holderFileRegistries : normalFileRegistries;
17
+ let fileRegistry = fileRegistries.find(r => r.key === key
18
+ && r.plugins.length === plugins.length
19
+ && r.plugins.every(plugin => plugins.includes(plugin)))?.files;
20
+ if (!fileRegistry) {
21
+ fileRegistry = new Map();
22
+ fileRegistries.push({
23
+ key: key,
24
+ plugins: plugins,
25
+ files: fileRegistry,
26
+ });
27
+ }
28
+ return fileRegistry;
29
+ }
30
+ function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins) {
31
+ const values = [
32
+ ...Object.keys(vueCompilerOptions)
33
+ .sort()
34
+ .filter(key => key !== 'plugins')
35
+ .map(key => [key, vueCompilerOptions[key]]),
36
+ [...new Set(plugins.map(plugin => plugin.requiredCompilerOptions ?? []).flat())]
37
+ .sort()
38
+ .map(key => [key, compilerOptions[key]]),
39
+ ];
40
+ return JSON.stringify(values);
41
+ }
42
+ function createRootFileChecker(getProjectVersion, getRootFileNames, caseSensitive) {
43
+ const fileNames = new language_core_1.FileMap(caseSensitive);
44
+ let projectVersion;
45
+ return (fileName) => {
46
+ if (!getProjectVersion || projectVersion !== getProjectVersion()) {
47
+ projectVersion = getProjectVersion?.();
48
+ fileNames.clear();
49
+ for (const rootFileName of getRootFileNames()) {
50
+ fileNames.set(rootFileName, undefined);
51
+ }
52
+ }
53
+ return fileNames.has(fileName);
54
+ };
55
+ }
56
+ // TODO: replace `createVueLanguagePlugin` with `createVueLanguagePlugin2` in 2.1
57
+ function createVueLanguagePlugin(ts, asFileName, _getProjectVersion, isRootFile, compilerOptions, vueCompilerOptions) {
58
+ return createVueLanguagePlugin2(ts, asFileName, isRootFile, compilerOptions, vueCompilerOptions);
59
+ }
60
+ function createVueLanguagePlugin2(ts, asFileName, isRootFile, compilerOptions, vueCompilerOptions) {
61
+ const pluginContext = {
62
+ modules: {
63
+ '@vue/compiler-dom': vueCompilerOptions.target < 3
64
+ ? {
65
+ ...CompilerDOM,
66
+ compile: CompilerVue2.compile,
67
+ }
68
+ : CompilerDOM,
69
+ typescript: ts,
70
+ },
71
+ compilerOptions,
72
+ vueCompilerOptions,
73
+ globalTypesHolder: undefined,
74
+ };
75
+ const plugins = (0, plugins_1.createPlugins)(pluginContext);
76
+ return {
77
+ getLanguageId(scriptId) {
78
+ const fileName = asFileName(scriptId);
79
+ for (const plugin of plugins) {
80
+ const languageId = plugin.getLanguageId?.(fileName);
81
+ if (languageId) {
82
+ return languageId;
83
+ }
84
+ }
85
+ },
86
+ createVirtualCode(scriptId, languageId, snapshot) {
87
+ const fileName = asFileName(scriptId);
88
+ if (plugins.some(plugin => plugin.isValidFile?.(fileName, languageId))) {
89
+ if (!pluginContext.globalTypesHolder && isRootFile(fileName)) {
90
+ pluginContext.globalTypesHolder = fileName;
91
+ }
92
+ const fileRegistry = getFileRegistry(pluginContext.globalTypesHolder === fileName);
93
+ const code = fileRegistry.get(fileName);
94
+ if (code) {
95
+ code.update(snapshot);
96
+ return code;
97
+ }
98
+ else {
99
+ const code = new vueFile_1.VueVirtualCode(fileName, languageId, snapshot, vueCompilerOptions, plugins, ts);
100
+ fileRegistry.set(fileName, code);
101
+ return code;
102
+ }
103
+ }
104
+ },
105
+ updateVirtualCode(_fileId, code, snapshot) {
106
+ code.update(snapshot);
107
+ return code;
108
+ },
109
+ // TODO: when global types holder deleted, move global types to another file
110
+ // disposeVirtualCode(fileId, code) {
111
+ // const isGlobalTypesHolder = code.fileName === pluginContext.globalTypesHolder;
112
+ // const fileRegistry = getFileRegistry(isGlobalTypesHolder);
113
+ // fileRegistry.delete(fileId);
114
+ // if (isGlobalTypesHolder) {
115
+ // pluginContext.globalTypesHolder = undefined;
116
+ // const fileRegistry2 = getFileRegistry(false);
117
+ // for (const [fileId, code] of fileRegistry2) {
118
+ // if (isValidGlobalTypesHolder(code.fileName)) {
119
+ // pluginContext.globalTypesHolder = code.fileName;
120
+ // fileRegistry2.delete(fileId);
121
+ // // force dirty
122
+ // files?.delete(fileId);
123
+ // files?.set(
124
+ // fileId,
125
+ // code.languageId,
126
+ // code.snapshot,
127
+ // );
128
+ // break;
129
+ // }
130
+ // }
131
+ // }
132
+ // },
133
+ typescript: {
134
+ extraFileExtensions: getAllExtensions(vueCompilerOptions)
135
+ .map(ext => ({
136
+ extension: ext.slice(1),
137
+ isMixedContent: true,
138
+ scriptKind: 7,
139
+ })),
140
+ getServiceScript(root) {
141
+ for (const code of (0, language_core_1.forEachEmbeddedCode)(root)) {
142
+ if (/script_(js|jsx|ts|tsx)/.test(code.id)) {
143
+ const lang = code.id.substring('script_'.length);
144
+ return {
145
+ code,
146
+ extension: '.' + lang,
147
+ scriptKind: lang === 'js' ? ts.ScriptKind.JS
148
+ : lang === 'jsx' ? ts.ScriptKind.JSX
149
+ : lang === 'tsx' ? ts.ScriptKind.TSX
150
+ : ts.ScriptKind.TS,
151
+ };
152
+ }
153
+ }
154
+ },
155
+ },
156
+ };
157
+ function getFileRegistry(isGlobalTypesHolder) {
158
+ return getVueFileRegistry(isGlobalTypesHolder, getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins), vueCompilerOptions.plugins);
159
+ }
160
+ }
161
+ function getAllExtensions(options) {
162
+ const result = new Set();
163
+ for (const key in options) {
164
+ if (key === 'extensions' || key.endsWith('Extensions')) {
165
+ const value = options[key];
166
+ if (Array.isArray(value) && value.every(v => typeof v === 'string')) {
167
+ for (const ext of value) {
168
+ result.add(ext);
169
+ }
170
+ }
171
+ }
172
+ }
173
+ return [...result];
174
+ }
175
+ //# sourceMappingURL=languagePlugin.js.map
@@ -32,7 +32,9 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript'),
32
32
  define?: ReturnType<(node: ts.CallExpression) => TextRange & {
33
33
  arg?: TextRange;
34
34
  typeArg?: TextRange;
35
- }>;
35
+ }> & {
36
+ hasUnionTypeArg?: boolean;
37
+ };
36
38
  };
37
39
  expose: {
38
40
  name?: string;
@@ -168,6 +168,14 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
168
168
  if (ts.isVariableDeclaration(parent)) {
169
169
  emits.name = getNodeText(ts, parent.name, ast);
170
170
  }
171
+ if (node.typeArguments?.length && ts.isTypeLiteralNode(node.typeArguments[0]) && node.typeArguments[0].members.at(0)) {
172
+ for (const member of node.typeArguments[0].members) {
173
+ if (ts.isCallSignatureDeclaration(member) && member.parameters[0].type && ts.isUnionTypeNode(member.parameters[0].type)) {
174
+ emits.define.hasUnionTypeArg = true;
175
+ return;
176
+ }
177
+ }
178
+ }
171
179
  }
172
180
  else if (vueCompilerOptions.macros.defineExpose.includes(callText)) {
173
181
  expose.define = parseDefineFunction(node);
@@ -0,0 +1,3 @@
1
+ import type { VueLanguagePlugin } from '../types';
2
+ declare const plugin: VueLanguagePlugin;
3
+ export default plugin;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const parseSfc_1 = require("../utils/parseSfc");
4
+ const jsxWrapper = ['<script setup lang="jsx">\n', '\n</script>'];
5
+ const tsxWrapper = ['<script setup lang="tsx">\n', '\n</script>'];
6
+ const plugin = _ctx => {
7
+ return {
8
+ version: 2.1,
9
+ isValidFile(fileName) {
10
+ return fileName.endsWith('.setup.jsx') || fileName.endsWith('.setup.tsx');
11
+ },
12
+ parseSFC2(fileName, _languageId, content) {
13
+ if (fileName.endsWith('.setup.jsx')) {
14
+ console.log('[Vue] parseSFC2', fileName);
15
+ return patchSFC((0, parseSfc_1.parse)(`${jsxWrapper[0]}${content}${jsxWrapper[1]}`));
16
+ }
17
+ if (fileName.endsWith('.setup.tsx')) {
18
+ console.log('[Vue] parseSFC2', fileName);
19
+ return patchSFC((0, parseSfc_1.parse)(`${tsxWrapper[0]}${content}${tsxWrapper[1]}`));
20
+ }
21
+ },
22
+ };
23
+ };
24
+ exports.default = plugin;
25
+ function patchSFC(sfc) {
26
+ sfc.descriptor.scriptSetup.loc.start.column -= jsxWrapper[0].length;
27
+ sfc.descriptor.scriptSetup.loc.start.offset -= jsxWrapper[0].length;
28
+ sfc.descriptor.scriptSetup.loc.end.offset -= jsxWrapper[0].length;
29
+ if (sfc.descriptor.scriptSetup.loc.end.line === sfc.descriptor.scriptSetup.loc.start.line) {
30
+ sfc.descriptor.scriptSetup.loc.end.column -= jsxWrapper[0].length;
31
+ }
32
+ return sfc;
33
+ }
34
+ //# sourceMappingURL=file-dot-setup.js.map
@@ -2,10 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const sfcBlockReg = /\<(script|style)\b([\s\S]*?)\>([\s\S]*?)\<\/\1\>/g;
4
4
  const langReg = /\blang\s*=\s*(['\"]?)(\S*)\b\1/;
5
- const plugin = () => {
5
+ const plugin = ({ vueCompilerOptions }) => {
6
6
  return {
7
- version: 2,
8
- parseSFC(fileName, content) {
7
+ version: 2.1,
8
+ getLanguageId(fileName) {
9
+ if (vueCompilerOptions.petiteVueExtensions.some(ext => fileName.endsWith(ext))) {
10
+ return 'html';
11
+ }
12
+ },
13
+ isValidFile(_fileName, languageId) {
14
+ return languageId === 'html';
15
+ },
16
+ parseSFC2(fileName, languageId, content) {
17
+ if (languageId !== 'html') {
18
+ return;
19
+ }
9
20
  let sfc = {
10
21
  descriptor: {
11
22
  filename: fileName,
@@ -11,10 +11,21 @@ const sfcBlockReg = /\<(script|style)\b[\s\S]*?\>([\s\S]*?)\<\/\1\>/g;
11
11
  const angleBracketReg = /\<\S*\:\S*\>/g;
12
12
  const linkReg = /\[[\s\S]*?\]\([\s\S]*?\)/g;
13
13
  const codeSnippetImportReg = /^\s*<<<\s*.+/gm;
14
- const plugin = () => {
14
+ const plugin = ({ vueCompilerOptions }) => {
15
15
  return {
16
- version: 2,
17
- parseSFC(_fileName, content) {
16
+ version: 2.1,
17
+ getLanguageId(fileName) {
18
+ if (vueCompilerOptions.vitePressExtensions.some(ext => fileName.endsWith(ext))) {
19
+ return 'markdown';
20
+ }
21
+ },
22
+ isValidFile(_fileName, languageId) {
23
+ return languageId === 'markdown';
24
+ },
25
+ parseSFC2(_fileName, languageId, content) {
26
+ if (languageId !== 'markdown') {
27
+ return;
28
+ }
18
29
  content = content
19
30
  // code block
20
31
  .replace(codeblockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
@@ -1,10 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const parseSfc_1 = require("../utils/parseSfc");
4
- const plugin = _ctx => {
4
+ const plugin = ({ vueCompilerOptions }) => {
5
5
  return {
6
- version: 2,
7
- parseSFC(_fileName, content) {
6
+ version: 2.1,
7
+ getLanguageId(fileName) {
8
+ if (vueCompilerOptions.extensions.some(ext => fileName.endsWith(ext))) {
9
+ return 'vue';
10
+ }
11
+ },
12
+ isValidFile(_fileName, languageId) {
13
+ return languageId === 'vue';
14
+ },
15
+ parseSFC2(_fileName, languageId, content) {
16
+ if (languageId !== 'vue') {
17
+ return;
18
+ }
8
19
  return (0, parseSfc_1.parse)(content);
9
20
  },
10
21
  updateSFC(sfc, change) {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const plugin = ({ modules }) => {
4
4
  return {
5
- version: 2,
5
+ version: 2.1,
6
6
  compileSFCScript(lang, script) {
7
7
  if (lang === 'js' || lang === 'ts' || lang === 'jsx' || lang === 'tsx') {
8
8
  const ts = modules.typescript;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const shared_1 = require("./shared");
4
4
  const plugin = () => {
5
5
  return {
6
- version: 2,
6
+ version: 2.1,
7
7
  getEmbeddedCodes(_fileName, sfc) {
8
8
  return sfc.customBlocks.map((customBlock, i) => ({
9
9
  id: 'custom_block_' + i,
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const plugin = () => {
4
4
  return {
5
- version: 2,
5
+ version: 2.1,
6
6
  getEmbeddedCodes(_fileName, sfc) {
7
7
  const names = [];
8
8
  if (sfc.script) {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const shared_1 = require("./shared");
4
4
  const plugin = () => {
5
5
  return {
6
- version: 2,
6
+ version: 2.1,
7
7
  getEmbeddedCodes(_fileName, sfc) {
8
8
  const result = [];
9
9
  for (let i = 0; i < sfc.styles.length; i++) {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const shared_1 = require("./shared");
4
4
  const plugin = () => {
5
5
  return {
6
- version: 2,
6
+ version: 2.1,
7
7
  getEmbeddedCodes(_fileName, sfc) {
8
8
  if (sfc.template) {
9
9
  return [{
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const plugin = ({ modules }) => {
4
4
  return {
5
- version: 2,
5
+ version: 2.1,
6
6
  compileSFCTemplate(lang, template, options) {
7
7
  if (lang === 'html' || lang === 'md') {
8
8
  const compiler = modules['@vue/compiler-dom'];
@@ -10,7 +10,7 @@ const codeFeatures = {
10
10
  };
11
11
  const plugin = () => {
12
12
  return {
13
- version: 2,
13
+ version: 2.1,
14
14
  getEmbeddedCodes(_fileName, sfc) {
15
15
  if (!sfc.template?.ast) {
16
16
  return [];
@@ -22,7 +22,7 @@ const formatBrackets = {
22
22
  const plugin = ctx => {
23
23
  const parseds = new WeakMap();
24
24
  return {
25
- version: 2,
25
+ version: 2.1,
26
26
  getEmbeddedCodes(_fileName, sfc) {
27
27
  if (!sfc.template?.ast) {
28
28
  return [];
@@ -43,7 +43,9 @@ export declare const tsCodegen: WeakMap<Sfc, {
43
43
  define?: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
44
44
  arg?: import("../types").TextRange;
45
45
  typeArg?: import("../types").TextRange;
46
- }>;
46
+ }> & {
47
+ hasUnionTypeArg?: boolean;
48
+ };
47
49
  };
48
50
  expose: {
49
51
  name?: string;
@@ -10,7 +10,7 @@ const scriptSetupRanges_1 = require("../parsers/scriptSetupRanges");
10
10
  exports.tsCodegen = new WeakMap();
11
11
  const plugin = ctx => {
12
12
  return {
13
- version: 2,
13
+ version: 2.1,
14
14
  requiredCompilerOptions: [
15
15
  'noPropertyAccessFromIndexSignature',
16
16
  'exactOptionalPropertyTypes',
package/lib/plugins.d.ts CHANGED
@@ -1,27 +1,3 @@
1
- import { pluginVersion, type VueLanguagePlugin } from './types';
1
+ import { VueLanguagePlugin } from './types';
2
2
  export * from './plugins/shared';
3
- export declare function getBasePlugins(pluginContext: Parameters<VueLanguagePlugin>[0]): {
4
- version: typeof pluginVersion;
5
- name?: string;
6
- order?: number;
7
- requiredCompilerOptions?: string[];
8
- parseSFC?(fileName: string, content: string): import("@vue/compiler-sfc").SFCParseResult | undefined;
9
- updateSFC?(oldResult: import("@vue/compiler-sfc").SFCParseResult, textChange: {
10
- start: number;
11
- end: number;
12
- newText: string;
13
- }): import("@vue/compiler-sfc").SFCParseResult | undefined;
14
- resolveTemplateCompilerOptions?(options: import("@vue/compiler-dom").CompilerOptions): import("@vue/compiler-dom").CompilerOptions;
15
- compileSFCScript?(lang: string, script: string): import("typescript").SourceFile | undefined;
16
- compileSFCTemplate?(lang: string, template: string, options: import("@vue/compiler-dom").CompilerOptions): import("@vue/compiler-dom").CodegenResult | undefined;
17
- updateSFCTemplate?(oldResult: import("@vue/compiler-dom").CodegenResult, textChange: {
18
- start: number;
19
- end: number;
20
- newText: string;
21
- }): import("@vue/compiler-dom").CodegenResult | undefined;
22
- getEmbeddedCodes?(fileName: string, sfc: import("./types").Sfc): {
23
- id: string;
24
- lang: string;
25
- }[];
26
- resolveEmbeddedCode?(fileName: string, sfc: import("./types").Sfc, embeddedFile: import("./types").VueEmbeddedCode): void;
27
- }[];
3
+ export declare function createPlugins(pluginContext: Parameters<VueLanguagePlugin>[0]): import("./types").VueLanguagePluginReturn[];
package/lib/plugins.js CHANGED
@@ -14,20 +14,26 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getBasePlugins = getBasePlugins;
17
+ exports.createPlugins = createPlugins;
18
+ const file_html_1 = require("./plugins/file-html");
19
+ const file_md_1 = require("./plugins/file-md");
20
+ const file_vue_1 = require("./plugins/file-vue");
21
+ const vue_script_js_1 = require("./plugins/vue-script-js");
18
22
  const vue_sfc_customblocks_1 = require("./plugins/vue-sfc-customblocks");
19
23
  const vue_sfc_scripts_1 = require("./plugins/vue-sfc-scripts");
20
24
  const vue_sfc_styles_1 = require("./plugins/vue-sfc-styles");
21
25
  const vue_sfc_template_1 = require("./plugins/vue-sfc-template");
22
- const vue_script_js_1 = require("./plugins/vue-script-js");
23
26
  const vue_template_html_1 = require("./plugins/vue-template-html");
24
27
  const vue_template_inline_css_1 = require("./plugins/vue-template-inline-css");
25
28
  const vue_template_inline_ts_1 = require("./plugins/vue-template-inline-ts");
26
29
  const vue_tsx_1 = require("./plugins/vue-tsx");
27
30
  const types_1 = require("./types");
28
31
  __exportStar(require("./plugins/shared"), exports);
29
- function getBasePlugins(pluginContext) {
32
+ function createPlugins(pluginContext) {
30
33
  const plugins = [
34
+ file_vue_1.default,
35
+ file_md_1.default,
36
+ file_html_1.default,
31
37
  vue_script_js_1.default,
32
38
  vue_template_html_1.default,
33
39
  vue_template_inline_css_1.default,
@@ -40,28 +46,36 @@ function getBasePlugins(pluginContext) {
40
46
  ...pluginContext.vueCompilerOptions.plugins,
41
47
  ];
42
48
  const pluginInstances = plugins
43
- .map(plugin => {
49
+ .flatMap(plugin => {
44
50
  try {
45
51
  const instance = plugin(pluginContext);
46
- instance.name ??= plugin.__moduleName;
52
+ const moduleName = plugin.__moduleName;
53
+ if (Array.isArray(instance)) {
54
+ for (let i = 0; i < instance.length; i++) {
55
+ instance[i].name ??= `${moduleName} (${i})`;
56
+ }
57
+ }
58
+ else {
59
+ instance.name ??= moduleName;
60
+ }
47
61
  return instance;
48
62
  }
49
63
  catch (err) {
50
64
  console.warn('[Vue] Failed to create plugin', err);
51
65
  }
52
66
  })
53
- .filter((plugin) => !!plugin)
67
+ .filter(plugin => !!plugin)
54
68
  .sort((a, b) => {
55
69
  const aOrder = a.order ?? 0;
56
70
  const bOrder = b.order ?? 0;
57
71
  return aOrder - bOrder;
58
72
  });
59
73
  return pluginInstances.filter(plugin => {
60
- const valid = plugin.version === types_1.pluginVersion;
61
- if (!valid) {
62
- console.warn(`[Vue] Plugin ${JSON.stringify(plugin.name)} API version incompatible, expected "${types_1.pluginVersion}" but got "${plugin.version}".`);
74
+ if (!types_1.validVersions.includes(plugin.version)) {
75
+ console.warn(`[Vue] Plugin ${plugin.name} is not compatible with the current Vue language tools version. (version: ${plugin.version}, supported versions: ${JSON.stringify(types_1.validVersions)})`);
76
+ return false;
63
77
  }
64
- return valid;
78
+ return true;
65
79
  });
66
80
  }
67
81
  //# sourceMappingURL=plugins.js.map
package/lib/types.d.ts CHANGED
@@ -48,21 +48,16 @@ export interface VueCompilerOptions {
48
48
  experimentalResolveStyleCssClasses: 'scoped' | 'always' | 'never';
49
49
  experimentalModelPropName: Record<string, Record<string, boolean | Record<string, string> | Record<string, string>[]>>;
50
50
  }
51
- export declare const pluginVersion = 2;
52
- export type VueLanguagePlugin = (ctx: {
53
- modules: {
54
- typescript: typeof import('typescript');
55
- '@vue/compiler-dom': typeof import('@vue/compiler-dom');
56
- };
57
- compilerOptions: ts.CompilerOptions;
58
- vueCompilerOptions: VueCompilerOptions;
59
- globalTypesHolder: string | undefined;
60
- }) => {
61
- version: typeof pluginVersion;
51
+ export declare const validVersions: readonly [2, 2.1];
52
+ export type VueLanguagePluginReturn = {
53
+ version: typeof validVersions[number];
62
54
  name?: string;
63
55
  order?: number;
64
56
  requiredCompilerOptions?: string[];
57
+ getLanguageId?(fileName: string): string | undefined;
58
+ isValidFile?(fileName: string, languageId: string): boolean;
65
59
  parseSFC?(fileName: string, content: string): SFCParseResult | undefined;
60
+ parseSFC2?(fileName: string, languageId: string, content: string): SFCParseResult | undefined;
66
61
  updateSFC?(oldResult: SFCParseResult, textChange: {
67
62
  start: number;
68
63
  end: number;
@@ -82,6 +77,15 @@ export type VueLanguagePlugin = (ctx: {
82
77
  }[];
83
78
  resolveEmbeddedCode?(fileName: string, sfc: Sfc, embeddedFile: VueEmbeddedCode): void;
84
79
  };
80
+ export type VueLanguagePlugin = (ctx: {
81
+ modules: {
82
+ typescript: typeof import('typescript');
83
+ '@vue/compiler-dom': typeof import('@vue/compiler-dom');
84
+ };
85
+ compilerOptions: ts.CompilerOptions;
86
+ vueCompilerOptions: VueCompilerOptions;
87
+ globalTypesHolder: string | undefined;
88
+ }) => VueLanguagePluginReturn | VueLanguagePluginReturn[];
85
89
  export interface SfcBlock {
86
90
  name: string;
87
91
  start: number;
package/lib/types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.pluginVersion = void 0;
4
- exports.pluginVersion = 2;
3
+ exports.validVersions = void 0;
4
+ exports.validVersions = [2, 2.1];
5
5
  //# sourceMappingURL=types.js.map
package/lib/utils/ts.js CHANGED
@@ -4,6 +4,7 @@ exports.createParsedCommandLineByJson = createParsedCommandLineByJson;
4
4
  exports.createParsedCommandLine = createParsedCommandLine;
5
5
  exports.resolveVueCompilerOptions = resolveVueCompilerOptions;
6
6
  const path = require("path-browserify");
7
+ const languagePlugin_1 = require("../languagePlugin");
7
8
  function createParsedCommandLineByJson(ts, parseConfigHost, rootDir, json, configFileName = rootDir + '/jsconfig.json') {
8
9
  const proxyHost = proxyParseConfigHostForExtendConfigPaths(parseConfigHost);
9
10
  ts.parseJsonConfigFileContent(json, proxyHost.host, rootDir, {}, configFileName);
@@ -18,11 +19,8 @@ function createParsedCommandLineByJson(ts, parseConfigHost, rootDir, json, confi
18
19
  catch (err) { }
19
20
  }
20
21
  const resolvedVueOptions = resolveVueCompilerOptions(vueOptions);
21
- const parsed = ts.parseJsonConfigFileContent(json, proxyHost.host, rootDir, {}, configFileName, undefined, [
22
- ...resolvedVueOptions.extensions,
23
- ...resolvedVueOptions.vitePressExtensions,
24
- ...resolvedVueOptions.petiteVueExtensions,
25
- ].map(extension => ({
22
+ const parsed = ts.parseJsonConfigFileContent(json, proxyHost.host, rootDir, {}, configFileName, undefined, (0, languagePlugin_1.getAllExtensions)(resolvedVueOptions)
23
+ .map(extension => ({
26
24
  extension: extension.slice(1),
27
25
  isMixedContent: true,
28
26
  scriptKind: ts.ScriptKind.Deferred,
@@ -52,11 +50,8 @@ function createParsedCommandLine(ts, parseConfigHost, tsConfigPath) {
52
50
  catch (err) { }
53
51
  }
54
52
  const resolvedVueOptions = resolveVueCompilerOptions(vueOptions);
55
- const parsed = ts.parseJsonSourceFileConfigFileContent(config, proxyHost.host, path.dirname(tsConfigPath), {}, tsConfigPath, undefined, [
56
- ...resolvedVueOptions.extensions,
57
- ...resolvedVueOptions.vitePressExtensions,
58
- ...resolvedVueOptions.petiteVueExtensions,
59
- ].map(extension => ({
53
+ const parsed = ts.parseJsonSourceFileConfigFileContent(config, proxyHost.host, path.dirname(tsConfigPath), {}, tsConfigPath, undefined, (0, languagePlugin_1.getAllExtensions)(resolvedVueOptions)
54
+ .map(extension => ({
60
55
  extension: extension.slice(1),
61
56
  isMixedContent: true,
62
57
  scriptKind: ts.ScriptKind.Deferred,
@@ -129,14 +124,7 @@ function getPartialVueCompilerOptions(ts, tsConfigSourceFile) {
129
124
  const resolvedPath = resolvePath(pluginPath);
130
125
  if (resolvedPath) {
131
126
  const plugin = require(resolvedPath);
132
- if (Array.isArray(plugin)) {
133
- for (let i = 0; i < plugin.length; i++) {
134
- plugin[i].__moduleName = `${pluginPath} (${i})`;
135
- }
136
- }
137
- else {
138
- plugin.__moduleName = pluginPath;
139
- }
127
+ plugin.__moduleName = pluginPath;
140
128
  return plugin;
141
129
  }
142
130
  else {
@@ -147,8 +135,7 @@ function getPartialVueCompilerOptions(ts, tsConfigSourceFile) {
147
135
  console.warn('[Vue] Resolve plugin path failed:', pluginPath, error);
148
136
  }
149
137
  return [];
150
- })
151
- .flat(Infinity);
138
+ });
152
139
  result.plugins = plugins;
153
140
  }
154
141
  return result;
@@ -1,4 +1,4 @@
1
1
  import type { VirtualCode } from '@volar/language-core';
2
- import type { Sfc, VueLanguagePlugin } from '../types';
3
- export declare function computedFiles(plugins: ReturnType<VueLanguagePlugin>[], fileName: string, sfc: Sfc): () => VirtualCode[];
2
+ import type { Sfc, VueLanguagePluginReturn } from '../types';
3
+ export declare function computedFiles(plugins: VueLanguagePluginReturn[], fileName: string, sfc: Sfc): () => VirtualCode[];
4
4
  export declare function resolveCommonLanguageId(lang: string): string;