@astrojs/language-server 2.13.2 → 2.14.0

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 (37) hide show
  1. package/bin/nodeServer.js +1 -1
  2. package/dist/buildMappings.js +1 -2
  3. package/dist/core/astro2tsx.js +3 -4
  4. package/dist/core/compilerUtils.js +1 -2
  5. package/dist/core/frontmatterHolders.d.ts +32 -0
  6. package/dist/core/frontmatterHolders.js +119 -0
  7. package/dist/core/index.d.ts +1 -1
  8. package/dist/core/index.js +9 -6
  9. package/dist/core/parseAstro.js +1 -2
  10. package/dist/core/parseCSS.js +1 -2
  11. package/dist/core/parseHTML.js +2 -3
  12. package/dist/core/parseJS.js +1 -2
  13. package/dist/core/svelte.js +1 -2
  14. package/dist/core/utils.js +5 -6
  15. package/dist/core/vue.js +1 -2
  16. package/dist/importPackage.js +8 -9
  17. package/dist/languageServerPlugin.d.ts +4 -3
  18. package/dist/languageServerPlugin.js +14 -6
  19. package/dist/nodeServer.js +48 -18
  20. package/dist/plugins/astro.d.ts +2 -2
  21. package/dist/plugins/astro.js +2 -2
  22. package/dist/plugins/html.d.ts +1 -1
  23. package/dist/plugins/typescript/codeActions.js +2 -3
  24. package/dist/plugins/typescript/completions.d.ts +1 -1
  25. package/dist/plugins/typescript/completions.js +2 -3
  26. package/dist/plugins/typescript/diagnostics.d.ts +7 -7
  27. package/dist/plugins/typescript/diagnostics.js +2 -2
  28. package/dist/plugins/typescript/index.d.ts +1 -1
  29. package/dist/plugins/typescript/utils.js +1 -2
  30. package/dist/plugins/typescript-addons/snippets.js +1 -2
  31. package/dist/plugins/utils.d.ts +3 -2
  32. package/dist/plugins/utils.js +13 -12
  33. package/dist/plugins/yaml.d.ts +3 -0
  34. package/dist/plugins/yaml.js +110 -0
  35. package/dist/utils.js +3 -4
  36. package/package.json +8 -5
  37. package/types/astro-jsx.d.ts +2 -2
package/bin/nodeServer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  if (process.argv.includes('--version')) {
3
3
  const pkgJSON = require('../package.json');
4
- console.log(`${pkgJSON['version']}`);
4
+ console.info(`${pkgJSON['version']}`);
5
5
  } else {
6
6
  require('../dist/nodeServer.js');
7
7
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildMappings = void 0;
3
+ exports.buildMappings = buildMappings;
4
4
  function buildMappings(chunks) {
5
5
  let length = 0;
6
6
  const mappings = [];
@@ -20,5 +20,4 @@ function buildMappings(chunks) {
20
20
  }
21
21
  return mappings;
22
22
  }
23
- exports.buildMappings = buildMappings;
24
23
  //# sourceMappingURL=buildMappings.js.map
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.astro2tsx = exports.getTSXRangesAsLSPRanges = exports.safeConvertToTSX = void 0;
3
+ exports.safeConvertToTSX = safeConvertToTSX;
4
+ exports.getTSXRangesAsLSPRanges = getTSXRangesAsLSPRanges;
5
+ exports.astro2tsx = astro2tsx;
4
6
  const sync_1 = require("@astrojs/compiler/sync");
5
7
  const sourcemap_codec_1 = require("@jridgewell/sourcemap-codec");
6
8
  const language_server_1 = require("@volar/language-server");
@@ -50,7 +52,6 @@ function safeConvertToTSX(content, options) {
50
52
  };
51
53
  }
52
54
  }
53
- exports.safeConvertToTSX = safeConvertToTSX;
54
55
  function getTSXRangesAsLSPRanges(tsx) {
55
56
  const textDocument = vscode_html_languageservice_1.TextDocument.create('', 'typescriptreact', 0, tsx.code);
56
57
  return {
@@ -60,7 +61,6 @@ function getTSXRangesAsLSPRanges(tsx) {
60
61
  styles: tsx.metaRanges.styles ?? [],
61
62
  };
62
63
  }
63
- exports.getTSXRangesAsLSPRanges = getTSXRangesAsLSPRanges;
64
64
  function astro2tsx(input, fileName) {
65
65
  const tsx = safeConvertToTSX(input, { filename: fileName });
66
66
  return {
@@ -69,7 +69,6 @@ function astro2tsx(input, fileName) {
69
69
  ranges: getTSXRangesAsLSPRanges(tsx),
70
70
  };
71
71
  }
72
- exports.astro2tsx = astro2tsx;
73
72
  function getVirtualCodeTSX(input, tsx, fileName) {
74
73
  tsx.code = (0, utils_js_1.patchTSX)(tsx.code, fileName);
75
74
  const v3Mappings = (0, sourcemap_codec_1.decode)(tsx.map.mappings);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PointToPosition = void 0;
3
+ exports.PointToPosition = PointToPosition;
4
4
  const language_server_1 = require("@volar/language-server");
5
5
  /**
6
6
  * Transform a Point from the Astro compiler to an LSP Position
@@ -9,5 +9,4 @@ function PointToPosition(point) {
9
9
  // Columns and lines are 0-based in LSP, but the compiler's Point are 1 based.
10
10
  return language_server_1.Position.create(point.line - 1, point.column - 1);
11
11
  }
12
- exports.PointToPosition = PointToPosition;
13
12
  //# sourceMappingURL=compilerUtils.js.map
@@ -0,0 +1,32 @@
1
+ import { type CodeMapping, type LanguagePlugin, type VirtualCode } from '@volar/language-core';
2
+ import type ts from 'typescript';
3
+ import type { URI } from 'vscode-uri';
4
+ export declare const SUPPORTED_FRONTMATTER_EXTENSIONS: {
5
+ md: string;
6
+ mdx: string;
7
+ mdoc: string;
8
+ };
9
+ export declare const SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS: string[];
10
+ export declare const frontmatterRE: RegExp;
11
+ export type CollectionConfig = {
12
+ folder: URI;
13
+ config: {
14
+ collections: {
15
+ hasSchema: boolean;
16
+ name: string;
17
+ }[];
18
+ entries: Record<string, string>;
19
+ };
20
+ };
21
+ export declare function getFrontmatterLanguagePlugin(collectionConfigs: CollectionConfig[]): LanguagePlugin<URI, FrontmatterHolder>;
22
+ export declare class FrontmatterHolder implements VirtualCode {
23
+ fileName: string;
24
+ languageId: string;
25
+ snapshot: ts.IScriptSnapshot;
26
+ collection: string | undefined;
27
+ id: string;
28
+ mappings: CodeMapping[];
29
+ embeddedCodes: VirtualCode[];
30
+ hasFrontmatter: boolean;
31
+ constructor(fileName: string, languageId: string, snapshot: ts.IScriptSnapshot, collection: string | undefined);
32
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FrontmatterHolder = exports.frontmatterRE = exports.SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS = exports.SUPPORTED_FRONTMATTER_EXTENSIONS = void 0;
4
+ exports.getFrontmatterLanguagePlugin = getFrontmatterLanguagePlugin;
5
+ const yaml2ts_1 = require("@astrojs/yaml2ts");
6
+ const language_core_1 = require("@volar/language-core");
7
+ exports.SUPPORTED_FRONTMATTER_EXTENSIONS = { md: 'markdown', mdx: 'mdx', mdoc: 'mdoc' };
8
+ exports.SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS = Object.keys(exports.SUPPORTED_FRONTMATTER_EXTENSIONS);
9
+ const SUPPORTED_FRONTMATTER_EXTENSIONS_VALUES = Object.values(exports.SUPPORTED_FRONTMATTER_EXTENSIONS);
10
+ exports.frontmatterRE = /^---(.*?)^---/ms;
11
+ function getCollectionName(collectionConfigs, fileURI) {
12
+ for (const collection of collectionConfigs) {
13
+ if (collection.config.entries[fileURI]) {
14
+ return collection.config.entries[fileURI];
15
+ }
16
+ }
17
+ }
18
+ function getFrontmatterLanguagePlugin(collectionConfigs) {
19
+ return {
20
+ getLanguageId(scriptId) {
21
+ const fileType = exports.SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS.find((ext) => scriptId.path.endsWith(`.${ext}`));
22
+ if (fileType) {
23
+ return exports.SUPPORTED_FRONTMATTER_EXTENSIONS[fileType];
24
+ }
25
+ },
26
+ createVirtualCode(scriptId, languageId, snapshot) {
27
+ if (SUPPORTED_FRONTMATTER_EXTENSIONS_VALUES.includes(languageId)) {
28
+ return new FrontmatterHolder(scriptId.fsPath.replace(/\\/g, '/'), languageId, snapshot, getCollectionName(collectionConfigs,
29
+ // The scriptId here is encoded and somewhat normalized, as such we can't use it directly to compare with
30
+ // the file URLs in the collection config entries that Astro generates.
31
+ decodeURIComponent(scriptId.toString()).toLowerCase()));
32
+ }
33
+ },
34
+ typescript: {
35
+ extraFileExtensions: exports.SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS.map((ext) => ({
36
+ extension: ext,
37
+ isMixedContent: true,
38
+ scriptKind: 7,
39
+ })),
40
+ getServiceScript(astroCode) {
41
+ for (const code of (0, language_core_1.forEachEmbeddedCode)(astroCode)) {
42
+ if (code.id === yaml2ts_1.VIRTUAL_CODE_ID) {
43
+ return {
44
+ code,
45
+ extension: '.ts',
46
+ scriptKind: 3,
47
+ };
48
+ }
49
+ }
50
+ return undefined;
51
+ },
52
+ },
53
+ };
54
+ }
55
+ class FrontmatterHolder {
56
+ constructor(fileName, languageId, snapshot, collection) {
57
+ this.fileName = fileName;
58
+ this.languageId = languageId;
59
+ this.snapshot = snapshot;
60
+ this.collection = collection;
61
+ this.id = 'frontmatter-holder';
62
+ this.hasFrontmatter = false;
63
+ this.mappings = [
64
+ {
65
+ sourceOffsets: [0],
66
+ generatedOffsets: [0],
67
+ lengths: [this.snapshot.getLength()],
68
+ data: {
69
+ verification: true,
70
+ completion: true,
71
+ semantic: true,
72
+ navigation: true,
73
+ structure: true,
74
+ format: true,
75
+ },
76
+ },
77
+ ];
78
+ this.embeddedCodes = [];
79
+ this.snapshot = snapshot;
80
+ // If the file is not part of a collection, we don't need to do anything
81
+ if (!this.collection) {
82
+ return;
83
+ }
84
+ const frontmatterContent = exports.frontmatterRE
85
+ .exec(this.snapshot.getText(0, this.snapshot.getLength()))?.[0]
86
+ .replaceAll('---', ' ') ?? '';
87
+ this.hasFrontmatter = frontmatterContent.length > 0;
88
+ this.embeddedCodes.push({
89
+ id: `yaml_frontmatter_${this.collection}`,
90
+ languageId: 'yaml',
91
+ snapshot: {
92
+ getText: (start, end) => frontmatterContent.substring(start, end),
93
+ getLength: () => frontmatterContent.length,
94
+ getChangeRange: () => undefined,
95
+ },
96
+ mappings: [
97
+ {
98
+ sourceOffsets: [0],
99
+ generatedOffsets: [0],
100
+ lengths: [frontmatterContent.length],
101
+ data: {
102
+ verification: true,
103
+ completion: true,
104
+ semantic: true,
105
+ navigation: true,
106
+ structure: true,
107
+ format: false,
108
+ },
109
+ },
110
+ ],
111
+ });
112
+ if (this.hasFrontmatter) {
113
+ const yaml2tsResult = (0, yaml2ts_1.yaml2ts)(frontmatterContent, this.collection);
114
+ this.embeddedCodes.push(yaml2tsResult.virtualCode);
115
+ }
116
+ }
117
+ }
118
+ exports.FrontmatterHolder = FrontmatterHolder;
119
+ //# sourceMappingURL=frontmatterHolders.js.map
@@ -4,7 +4,7 @@ import type ts from 'typescript';
4
4
  import type { HTMLDocument } from 'vscode-html-languageservice';
5
5
  import type { URI } from 'vscode-uri';
6
6
  import { type AstroInstall } from '../utils.js';
7
- import { AstroMetadata } from './parseAstro';
7
+ import type { AstroMetadata } from './parseAstro';
8
8
  export declare function getAstroLanguagePlugin(astroInstall: AstroInstall | undefined, ts: typeof import('typescript')): LanguagePlugin<URI, AstroVirtualCode>;
9
9
  export declare class AstroVirtualCode implements VirtualCode {
10
10
  fileName: string;
@@ -23,7 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.AstroVirtualCode = exports.getAstroLanguagePlugin = void 0;
26
+ exports.AstroVirtualCode = void 0;
27
+ exports.getAstroLanguagePlugin = getAstroLanguagePlugin;
27
28
  const path = __importStar(require("node:path"));
28
29
  const language_core_1 = require("@volar/language-core");
29
30
  const utils_js_1 = require("../utils.js");
@@ -69,8 +70,8 @@ function getAstroLanguagePlugin(astroInstall, ts) {
69
70
  code,
70
71
  extension: fileExtension,
71
72
  scriptKind: fileExtension === '.mjs'
72
- ? (1)
73
- : (3),
73
+ ? 1
74
+ : 3,
74
75
  });
75
76
  }
76
77
  }
@@ -109,7 +110,7 @@ function getAstroLanguagePlugin(astroInstall, ts) {
109
110
  target: ts.ScriptTarget.ESNext ?? 99,
110
111
  jsx: ts.JsxEmit.Preserve ?? 1,
111
112
  resolveJsonModule: true,
112
- allowJs: true,
113
+ allowJs: true, // Needed for inline scripts, which are virtual .js files
113
114
  isolatedModules: true,
114
115
  moduleResolution: baseCompilationSettings.moduleResolution === ts.ModuleResolutionKind.Classic ||
115
116
  !baseCompilationSettings.moduleResolution
@@ -122,7 +123,6 @@ function getAstroLanguagePlugin(astroInstall, ts) {
122
123
  },
123
124
  };
124
125
  }
125
- exports.getAstroLanguagePlugin = getAstroLanguagePlugin;
126
126
  class AstroVirtualCode {
127
127
  constructor(fileName, snapshot) {
128
128
  this.fileName = fileName;
@@ -160,7 +160,10 @@ class AstroVirtualCode {
160
160
  this.embeddedCodes = [htmlVirtualCode, tsx.virtualCode];
161
161
  }
162
162
  get hasCompilationErrors() {
163
- return this.compilerDiagnostics.filter((diag) => diag.severity === 1).length > 0;
163
+ return (
164
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
165
+ this.compilerDiagnostics.filter((diag) => diag.severity === 1)
166
+ .length > 0);
164
167
  }
165
168
  }
166
169
  exports.AstroVirtualCode = AstroVirtualCode;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAstroMetadata = void 0;
3
+ exports.getAstroMetadata = getAstroMetadata;
4
4
  const sync_1 = require("@astrojs/compiler/sync");
5
5
  function getAstroMetadata(fileName, input, options = { position: true }) {
6
6
  const parseResult = safeParseAst(fileName, input, options);
@@ -9,7 +9,6 @@ function getAstroMetadata(fileName, input, options = { position: true }) {
9
9
  frontmatter: getFrontmatterStatus(parseResult.ast, input),
10
10
  };
11
11
  }
12
- exports.getAstroMetadata = getAstroMetadata;
13
12
  function safeParseAst(fileName, input, parseOptions) {
14
13
  try {
15
14
  const parseResult = (0, sync_1.parse)(input, parseOptions);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractStylesheets = void 0;
3
+ exports.extractStylesheets = extractStylesheets;
4
4
  const muggle_string_1 = require("muggle-string");
5
5
  const buildMappings_js_1 = require("../buildMappings.js");
6
6
  const SUPPORTED_LANGUAGES = ['css', 'scss', 'less'];
@@ -10,7 +10,6 @@ function isSupportedLanguage(lang) {
10
10
  function extractStylesheets(styles) {
11
11
  return mergeCSSContextsByLanguage(styles);
12
12
  }
13
- exports.extractStylesheets = extractStylesheets;
14
13
  function mergeCSSContextsByLanguage(inlineStyles) {
15
14
  const codes = {
16
15
  css: [],
@@ -23,7 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.preprocessHTML = exports.parseHTML = void 0;
26
+ exports.parseHTML = parseHTML;
27
+ exports.preprocessHTML = preprocessHTML;
27
28
  const html = __importStar(require("vscode-html-languageservice"));
28
29
  const utils_1 = require("../plugins/utils");
29
30
  const htmlLs = html.getLanguageService();
@@ -34,7 +35,6 @@ function parseHTML(snapshot, frontmatterEnd) {
34
35
  htmlDocument: getHTMLDocument(htmlContent),
35
36
  };
36
37
  }
37
- exports.parseHTML = parseHTML;
38
38
  const createScanner = htmlLs.createScanner;
39
39
  /**
40
40
  * scan the text and remove any `>` or `<` that cause the tag to end short
@@ -81,7 +81,6 @@ function preprocessHTML(text, frontmatterEnd) {
81
81
  scanner = createScanner(content, offset, state ?? html.ScannerState.WithinTag);
82
82
  }
83
83
  }
84
- exports.preprocessHTML = preprocessHTML;
85
84
  function getHTMLVirtualCode(preprocessedHTML) {
86
85
  return {
87
86
  id: `html`,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractScriptTags = void 0;
3
+ exports.extractScriptTags = extractScriptTags;
4
4
  const muggle_string_1 = require("muggle-string");
5
5
  const buildMappings_1 = require("../buildMappings");
6
6
  function extractScriptTags(scripts) {
@@ -26,7 +26,6 @@ function extractScriptTags(scripts) {
26
26
  embeddedJSCodes.push(...JSONScripts);
27
27
  return embeddedJSCodes;
28
28
  }
29
- exports.extractScriptTags = extractScriptTags;
30
29
  function moduleScriptToVirtualCode(script, index) {
31
30
  let extension = 'mts';
32
31
  let languageId = 'typescript';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSvelteLanguagePlugin = void 0;
3
+ exports.getSvelteLanguagePlugin = getSvelteLanguagePlugin;
4
4
  const language_core_1 = require("@volar/language-core");
5
5
  const utils_js_1 = require("./utils.js");
6
6
  function getSvelteLanguagePlugin() {
@@ -32,7 +32,6 @@ function getSvelteLanguagePlugin() {
32
32
  },
33
33
  };
34
34
  }
35
- exports.getSvelteLanguagePlugin = getSvelteLanguagePlugin;
36
35
  class SvelteVirtualCode {
37
36
  constructor(fileName, snapshot) {
38
37
  this.fileName = fileName;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchTSX = exports.classNameFromFilename = exports.framework2tsx = void 0;
3
+ exports.framework2tsx = framework2tsx;
4
+ exports.classNameFromFilename = classNameFromFilename;
5
+ exports.patchTSX = patchTSX;
4
6
  const vscode_uri_1 = require("vscode-uri");
5
7
  const importPackage_1 = require("../importPackage");
6
8
  function framework2tsx(filePath, sourceCode, framework) {
@@ -26,7 +28,6 @@ function framework2tsx(filePath, sourceCode, framework) {
26
28
  };
27
29
  }
28
30
  }
29
- exports.framework2tsx = framework2tsx;
30
31
  /**
31
32
  * Transform a string into PascalCase
32
33
  */
@@ -43,7 +44,7 @@ function classNameFromFilename(filename) {
43
44
  const withoutInvalidCharacters = withoutExtensions
44
45
  .split('')
45
46
  // Although "-" is invalid, we leave it in, pascal-case-handling will throw it out later
46
- .filter((char) => /[A-Za-z$_\d-]/.test(char))
47
+ .filter((char) => /[\w$-]/.test(char))
47
48
  .join('');
48
49
  const firstValidCharIdx = withoutInvalidCharacters
49
50
  .split('')
@@ -55,12 +56,11 @@ function classNameFromFilename(filename) {
55
56
  const finalName = firstValidCharIdx === -1 ? `A${inPascalCase}` : inPascalCase;
56
57
  return finalName;
57
58
  }
58
- exports.classNameFromFilename = classNameFromFilename;
59
59
  // TODO: Patch the upstream packages with these changes
60
60
  function patchTSX(code, filePath) {
61
61
  const basename = filePath.split('/').pop();
62
62
  const isDynamic = basename.startsWith('[') && basename.endsWith(']');
63
- return code.replace(/\b(\S*)__AstroComponent_/gm, (fullMatch, m1) => {
63
+ return code.replace(/\b(\S*)__AstroComponent_/g, (fullMatch, m1) => {
64
64
  // If we don't have a match here, it usually means the file has a weird name that couldn't be expressed with valid identifier characters
65
65
  if (!m1) {
66
66
  if (basename === '404')
@@ -70,5 +70,4 @@ function patchTSX(code, filePath) {
70
70
  return isDynamic ? `_${m1}_` : m1[0].toUpperCase() + m1.slice(1);
71
71
  });
72
72
  }
73
- exports.patchTSX = patchTSX;
74
73
  //# sourceMappingURL=utils.js.map
package/dist/core/vue.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getVueLanguagePlugin = void 0;
3
+ exports.getVueLanguagePlugin = getVueLanguagePlugin;
4
4
  const language_core_1 = require("@volar/language-core");
5
5
  const utils_js_1 = require("./utils.js");
6
6
  function getVueLanguagePlugin() {
@@ -32,7 +32,6 @@ function getVueLanguagePlugin() {
32
32
  },
33
33
  };
34
34
  }
35
- exports.getVueLanguagePlugin = getVueLanguagePlugin;
36
35
  class VueVirtualCode {
37
36
  constructor(fileName, snapshot) {
38
37
  this.fileName = fileName;
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getWorkspacePnpPath = exports.getPrettierPluginPath = exports.importPrettier = exports.importVueIntegration = exports.importSvelteIntegration = exports.getPackagePath = exports.setIsTrusted = void 0;
3
+ exports.setIsTrusted = setIsTrusted;
4
+ exports.getPackagePath = getPackagePath;
5
+ exports.importSvelteIntegration = importSvelteIntegration;
6
+ exports.importVueIntegration = importVueIntegration;
7
+ exports.importPrettier = importPrettier;
8
+ exports.getPrettierPluginPath = getPrettierPluginPath;
9
+ exports.getWorkspacePnpPath = getWorkspacePnpPath;
4
10
  const node_path_1 = require("node:path");
5
11
  let isTrusted = true;
6
12
  function setIsTrusted(_isTrusted) {
7
13
  isTrusted = _isTrusted;
8
14
  }
9
- exports.setIsTrusted = setIsTrusted;
10
15
  /**
11
16
  * Get the path of a package's directory from the paths in `fromPath`, if `root` is set to false, it will return the path of the package's entry point
12
17
  */
@@ -20,11 +25,10 @@ function getPackagePath(packageName, fromPath, root = true) {
20
25
  ? (0, node_path_1.dirname)(require.resolve(packageName + '/package.json', { paths }))
21
26
  : require.resolve(packageName, { paths });
22
27
  }
23
- catch (e) {
28
+ catch {
24
29
  return undefined;
25
30
  }
26
31
  }
27
- exports.getPackagePath = getPackagePath;
28
32
  function importEditorIntegration(packageName, fromPath) {
29
33
  const pkgPath = getPackagePath(packageName, [fromPath]);
30
34
  if (pkgPath) {
@@ -45,11 +49,9 @@ function importEditorIntegration(packageName, fromPath) {
45
49
  function importSvelteIntegration(fromPath) {
46
50
  return importEditorIntegration('@astrojs/svelte', fromPath);
47
51
  }
48
- exports.importSvelteIntegration = importSvelteIntegration;
49
52
  function importVueIntegration(fromPath) {
50
53
  return importEditorIntegration('@astrojs/vue', fromPath);
51
54
  }
52
- exports.importVueIntegration = importVueIntegration;
53
55
  function importPrettier(fromPath) {
54
56
  const prettierPkg = getPackagePath('prettier', [fromPath, __dirname]);
55
57
  if (!prettierPkg) {
@@ -57,7 +59,6 @@ function importPrettier(fromPath) {
57
59
  }
58
60
  return require(prettierPkg);
59
61
  }
60
- exports.importPrettier = importPrettier;
61
62
  function getPrettierPluginPath(fromPath) {
62
63
  const prettierPluginPath = getPackagePath('prettier-plugin-astro', [fromPath, __dirname], false);
63
64
  if (!prettierPluginPath) {
@@ -65,7 +66,6 @@ function getPrettierPluginPath(fromPath) {
65
66
  }
66
67
  return prettierPluginPath;
67
68
  }
68
- exports.getPrettierPluginPath = getPrettierPluginPath;
69
69
  function getWorkspacePnpPath(workspacePath) {
70
70
  try {
71
71
  const possiblePath = (0, node_path_1.resolve)(workspacePath, '.pnp.cjs');
@@ -76,5 +76,4 @@ function getWorkspacePnpPath(workspacePath) {
76
76
  return null;
77
77
  }
78
78
  }
79
- exports.getWorkspacePnpPath = getWorkspacePnpPath;
80
79
  //# sourceMappingURL=importPackage.js.map
@@ -1,4 +1,5 @@
1
- import { Connection, LanguagePlugin, LanguageServiceEnvironment } from '@volar/language-server/node';
1
+ import { type Connection, type LanguagePlugin, type LanguageServiceEnvironment } from '@volar/language-server/node';
2
2
  import { URI } from 'vscode-uri';
3
- export declare function getLanguagePlugins(connection: Connection, ts: typeof import('typescript'), serviceEnv: LanguageServiceEnvironment, tsconfig: string | undefined): LanguagePlugin<URI, import("@volar/language-server/node").VirtualCode>[];
4
- export declare function getLanguageServicePlugins(connection: Connection, ts: typeof import('typescript')): import("@volar/language-server/node").LanguageServicePlugin<any>[];
3
+ import { type CollectionConfig } from './core/frontmatterHolders.js';
4
+ export declare function getLanguagePlugins(connection: Connection, ts: typeof import('typescript'), serviceEnv: LanguageServiceEnvironment, tsconfig: string | undefined, collectionConfigs: CollectionConfig[]): LanguagePlugin<URI, import("@volar/language-server/node").VirtualCode>[];
5
+ export declare function getLanguageServicePlugins(connection: Connection, ts: typeof import('typescript'), collectionConfigs: CollectionConfig[]): import("@volar/language-server/node").LanguageServicePlugin<any>[];
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLanguageServicePlugins = exports.getLanguagePlugins = void 0;
3
+ exports.getLanguagePlugins = getLanguagePlugins;
4
+ exports.getLanguageServicePlugins = getLanguageServicePlugins;
4
5
  const node_1 = require("@volar/language-server/node");
5
6
  const vscode_uri_1 = require("vscode-uri");
6
7
  const core_1 = require("./core");
@@ -13,11 +14,13 @@ const volar_service_css_1 = require("volar-service-css");
13
14
  const volar_service_emmet_1 = require("volar-service-emmet");
14
15
  const volar_service_prettier_1 = require("volar-service-prettier");
15
16
  const volar_service_typescript_twoslash_queries_1 = require("volar-service-typescript-twoslash-queries");
17
+ const frontmatterHolders_js_1 = require("./core/frontmatterHolders.js");
16
18
  const astro_js_1 = require("./plugins/astro.js");
17
19
  const html_js_1 = require("./plugins/html.js");
18
20
  const index_js_1 = require("./plugins/typescript-addons/index.js");
19
21
  const index_js_2 = require("./plugins/typescript/index.js");
20
- function getLanguagePlugins(connection, ts, serviceEnv, tsconfig) {
22
+ const yaml_js_1 = require("./plugins/yaml.js");
23
+ function getLanguagePlugins(connection, ts, serviceEnv, tsconfig, collectionConfigs) {
21
24
  const languagePlugins = [
22
25
  (0, vue_js_1.getVueLanguagePlugin)(),
23
26
  (0, svelte_js_1.getSvelteLanguagePlugin)(),
@@ -36,12 +39,14 @@ function getLanguagePlugins(connection, ts, serviceEnv, tsconfig) {
36
39
  type: node_1.MessageType.Warning,
37
40
  });
38
41
  }
42
+ if (collectionConfigs.length) {
43
+ languagePlugins.push((0, frontmatterHolders_js_1.getFrontmatterLanguagePlugin)(collectionConfigs));
44
+ }
39
45
  languagePlugins.unshift((0, core_1.getAstroLanguagePlugin)(typeof astroInstall === 'string' ? undefined : astroInstall, ts));
40
46
  return languagePlugins;
41
47
  }
42
- exports.getLanguagePlugins = getLanguagePlugins;
43
- function getLanguageServicePlugins(connection, ts) {
44
- return [
48
+ function getLanguageServicePlugins(connection, ts, collectionConfigs) {
49
+ const LanguageServicePlugins = [
45
50
  (0, html_js_1.create)(),
46
51
  (0, volar_service_css_1.create)(),
47
52
  (0, volar_service_emmet_1.create)(),
@@ -51,6 +56,10 @@ function getLanguageServicePlugins(connection, ts) {
51
56
  (0, astro_js_1.create)(ts),
52
57
  getPrettierService(),
53
58
  ];
59
+ if (collectionConfigs.length) {
60
+ LanguageServicePlugins.push((0, yaml_js_1.create)(collectionConfigs));
61
+ }
62
+ return LanguageServicePlugins;
54
63
  function getPrettierService() {
55
64
  let prettier;
56
65
  let prettierPluginPath;
@@ -123,5 +132,4 @@ function getLanguageServicePlugins(connection, ts) {
123
132
  });
124
133
  }
125
134
  }
126
- exports.getLanguageServicePlugins = getLanguageServicePlugins;
127
135
  //# sourceMappingURL=languageServerPlugin.js.map
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const node_1 = require("@volar/language-server/node");
4
+ const vscode_uri_1 = require("vscode-uri");
5
+ const frontmatterHolders_js_1 = require("./core/frontmatterHolders.js");
4
6
  const languageServerPlugin_js_1 = require("./languageServerPlugin.js");
5
7
  const connection = (0, node_1.createConnection)();
6
8
  const server = (0, node_1.createServer)(connection);
9
+ let contentIntellisenseEnabled = false;
7
10
  connection.listen();
8
11
  connection.onInitialize((params) => {
9
12
  const tsdk = params.initializationOptions?.typescript?.tsdk;
@@ -11,30 +14,57 @@ connection.onInitialize((params) => {
11
14
  throw new Error('The `typescript.tsdk` init option is required. It should point to a directory containing a `typescript.js` or `tsserverlibrary.js` file, such as `node_modules/typescript/lib`.');
12
15
  }
13
16
  const { typescript, diagnosticMessages } = (0, node_1.loadTsdkByPath)(tsdk, params.locale);
17
+ contentIntellisenseEnabled = params.initializationOptions?.contentIntellisense ?? false;
18
+ let collectionConfigs = [];
19
+ if (contentIntellisenseEnabled) {
20
+ // The vast majority of clients support workspaceFolders, but notably our tests currently don't
21
+ // Ref: https://github.com/volarjs/volar.js/issues/229
22
+ const folders = params.workspaceFolders ?? (params.rootUri ? [{ uri: params.rootUri }] : []) ?? [];
23
+ collectionConfigs = folders.flatMap((folder) => {
24
+ try {
25
+ const folderUri = vscode_uri_1.URI.parse(folder.uri);
26
+ let config = server.fs.readFile(vscode_uri_1.Utils.joinPath(folderUri, '.astro/collections/collections.json'));
27
+ if (!config) {
28
+ return [];
29
+ }
30
+ // `server.fs.readFile` can theoretically be async, but in practice it's always sync
31
+ const collections = JSON.parse(config);
32
+ return { folder: folderUri, config: collections };
33
+ }
34
+ catch (err) {
35
+ // If the file doesn't exist, we don't really care, but if it's something else, we want to know
36
+ if (err && err.code !== 'ENOENT')
37
+ console.error(err);
38
+ return [];
39
+ }
40
+ });
41
+ }
14
42
  return server.initialize(params, (0, node_1.createTypeScriptProject)(typescript, diagnosticMessages, ({ env, configFileName }) => {
15
43
  return {
16
- languagePlugins: (0, languageServerPlugin_js_1.getLanguagePlugins)(connection, typescript, env, configFileName),
44
+ languagePlugins: (0, languageServerPlugin_js_1.getLanguagePlugins)(connection, typescript, env, configFileName, collectionConfigs),
17
45
  setup() { },
18
46
  };
19
- }), (0, languageServerPlugin_js_1.getLanguageServicePlugins)(connection, typescript), { pullModelDiagnostics: params.initializationOptions?.pullModelDiagnostics });
47
+ }), (0, languageServerPlugin_js_1.getLanguageServicePlugins)(connection, typescript, collectionConfigs), { pullModelDiagnostics: params.initializationOptions?.pullModelDiagnostics });
20
48
  });
21
49
  connection.onInitialized(() => {
22
50
  server.initialized();
23
- server.watchFiles([
24
- `**/*.{${[
25
- 'js',
26
- 'cjs',
27
- 'mjs',
28
- 'ts',
29
- 'cts',
30
- 'mts',
31
- 'jsx',
32
- 'tsx',
33
- 'json',
34
- 'astro',
35
- 'vue',
36
- 'svelte',
37
- ].join(',')}}`,
38
- ]);
51
+ const extensions = [
52
+ 'js',
53
+ 'cjs',
54
+ 'mjs',
55
+ 'ts',
56
+ 'cts',
57
+ 'mts',
58
+ 'jsx',
59
+ 'tsx',
60
+ 'json',
61
+ 'astro',
62
+ 'vue',
63
+ 'svelte',
64
+ ];
65
+ if (contentIntellisenseEnabled) {
66
+ extensions.push(...frontmatterHolders_js_1.SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS);
67
+ }
68
+ server.watchFiles([`**/*.{${extensions.join(',')}}`]);
39
69
  });
40
70
  //# sourceMappingURL=nodeServer.js.map
@@ -1,2 +1,2 @@
1
- import { LanguageServicePlugin } from '@volar/language-server';
2
- export declare const create: (ts: typeof import('typescript')) => LanguageServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-server';
2
+ export declare const create: (ts: typeof import("typescript")) => LanguageServicePlugin;
@@ -126,7 +126,7 @@ function getFrontmatterCompletion(file, document, position) {
126
126
  return {
127
127
  ...base,
128
128
  insertText: '---\n$0\n---',
129
- textEdit: prefix.match(/^\s*\-+/)
129
+ textEdit: /^\s*-+/.test(prefix)
130
130
  ? language_server_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, '---\n$0\n---')
131
131
  : undefined,
132
132
  };
@@ -142,7 +142,7 @@ function getFrontmatterCompletion(file, document, position) {
142
142
  ...base,
143
143
  insertText,
144
144
  detail: insertText === '---' ? 'Close component script block' : 'Create component script block',
145
- textEdit: prefix.match(/^\s*\-+/)
145
+ textEdit: /^\s*-+/.test(prefix)
146
146
  ? language_server_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, insertText)
147
147
  : undefined,
148
148
  };
@@ -1,2 +1,2 @@
1
- import { LanguageServicePlugin } from '@volar/language-server';
1
+ import type { LanguageServicePlugin } from '@volar/language-server';
2
2
  export declare const create: () => LanguageServicePlugin;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enhancedResolveCodeAction = exports.enhancedProvideCodeActions = void 0;
3
+ exports.enhancedProvideCodeActions = enhancedProvideCodeActions;
4
+ exports.enhancedResolveCodeAction = enhancedResolveCodeAction;
4
5
  const language_server_1 = require("@volar/language-server");
5
6
  const vscode_uri_1 = require("vscode-uri");
6
7
  const index_js_1 = require("../../core/index.js");
@@ -8,7 +9,6 @@ const utils_js_1 = require("./utils.js");
8
9
  function enhancedProvideCodeActions(codeActions, context) {
9
10
  return codeActions.map((codeAction) => mapCodeAction(codeAction, context));
10
11
  }
11
- exports.enhancedProvideCodeActions = enhancedProvideCodeActions;
12
12
  function enhancedResolveCodeAction(codeAction, context) {
13
13
  /**
14
14
  * TypeScript code actions don't come through here, as they're considered to be already fully resolved
@@ -17,7 +17,6 @@ function enhancedResolveCodeAction(codeAction, context) {
17
17
  */
18
18
  return mapCodeAction(codeAction, context);
19
19
  }
20
- exports.enhancedResolveCodeAction = enhancedResolveCodeAction;
21
20
  function mapCodeAction(codeAction, context) {
22
21
  if (!codeAction.edit || !codeAction.edit.documentChanges)
23
22
  return codeAction;
@@ -1,3 +1,3 @@
1
- import { CompletionItem, CompletionList, LanguageServiceContext } from '@volar/language-server';
1
+ import type { CompletionItem, CompletionList, LanguageServiceContext } from '@volar/language-server';
2
2
  export declare function enhancedProvideCompletionItems(completions: CompletionList): CompletionList;
3
3
  export declare function enhancedResolveCompletionItem(resolvedCompletion: CompletionItem, context: LanguageServiceContext): CompletionItem;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enhancedResolveCompletionItem = exports.enhancedProvideCompletionItems = void 0;
3
+ exports.enhancedProvideCompletionItems = enhancedProvideCompletionItems;
4
+ exports.enhancedResolveCompletionItem = enhancedResolveCompletionItem;
4
5
  const language_server_1 = require("@volar/language-server");
5
6
  const vscode_uri_1 = require("vscode-uri");
6
7
  const index_js_1 = require("../../core/index.js");
@@ -25,7 +26,6 @@ function enhancedProvideCompletionItems(completions) {
25
26
  });
26
27
  return completions;
27
28
  }
28
- exports.enhancedProvideCompletionItems = enhancedProvideCompletionItems;
29
29
  function enhancedResolveCompletionItem(resolvedCompletion, context) {
30
30
  // Make sure we keep our icons even when the completion is resolved
31
31
  if (resolvedCompletion.data.isComponent) {
@@ -42,7 +42,6 @@ function enhancedResolveCompletionItem(resolvedCompletion, context) {
42
42
  }
43
43
  return resolvedCompletion;
44
44
  }
45
- exports.enhancedResolveCompletionItem = enhancedResolveCompletionItem;
46
45
  function getDetailForFileCompletion(detail, source) {
47
46
  return `${detail}\n\n${source}`;
48
47
  }
@@ -1,12 +1,12 @@
1
1
  import type { Diagnostic } from '@volar/language-server';
2
2
  export declare enum DiagnosticCodes {
3
- IS_NOT_A_MODULE = 2306,
4
- CANNOT_FIND_MODULE = 2307,
5
- DUPLICATED_JSX_ATTRIBUTES = 17001,
6
- CANT_RETURN_OUTSIDE_FUNC = 1108,
7
- ISOLATED_MODULE_COMPILE_ERR = 1208,
8
- TYPE_NOT_ASSIGNABLE = 2322,
9
- JSX_NO_CLOSING_TAG = 17008,
3
+ IS_NOT_A_MODULE = 2306,// '{0}' is not a module.
4
+ CANNOT_FIND_MODULE = 2307,// Cannot find module '{0}' or its corresponding type declarations.
5
+ DUPLICATED_JSX_ATTRIBUTES = 17001,// JSX elements cannot have multiple attributes with the same name.
6
+ CANT_RETURN_OUTSIDE_FUNC = 1108,// A 'return' statement can only be used within a function body.
7
+ ISOLATED_MODULE_COMPILE_ERR = 1208,// '{0}' cannot be compiled under '--isolatedModules' because it is considered a global script file.
8
+ TYPE_NOT_ASSIGNABLE = 2322,// Type '{0}' is not assignable to type '{1}'.
9
+ JSX_NO_CLOSING_TAG = 17008,// JSX element '{0}' has no corresponding closing tag.
10
10
  JSX_ELEMENT_NO_CALL = 2604
11
11
  }
12
12
  export declare function enhancedProvideSemanticDiagnostics(originalDiagnostics: Diagnostic[], tsxLineCount?: number | undefined): Diagnostic[];
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enhancedProvideSemanticDiagnostics = exports.DiagnosticCodes = void 0;
3
+ exports.DiagnosticCodes = void 0;
4
+ exports.enhancedProvideSemanticDiagnostics = enhancedProvideSemanticDiagnostics;
4
5
  // List of codes:
5
6
  // https://github.com/Microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json
6
7
  var DiagnosticCodes;
@@ -23,7 +24,6 @@ function enhancedProvideSemanticDiagnostics(originalDiagnostics, tsxLineCount) {
23
24
  .map((diag) => tsxLineCount ? generalEnhancements(astroEnhancements(diag)) : generalEnhancements(diag));
24
25
  return diagnostics;
25
26
  }
26
- exports.enhancedProvideSemanticDiagnostics = enhancedProvideSemanticDiagnostics;
27
27
  // General enhancements that apply to all files
28
28
  function generalEnhancements(diagnostic) {
29
29
  if (diagnostic.code === DiagnosticCodes.CANNOT_FIND_MODULE &&
@@ -1,2 +1,2 @@
1
1
  import type { LanguageServicePlugin } from '@volar/language-server';
2
- export declare const create: (ts: typeof import('typescript')) => LanguageServicePlugin[];
2
+ export declare const create: (ts: typeof import("typescript")) => LanguageServicePlugin[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapEdit = void 0;
3
+ exports.mapEdit = mapEdit;
4
4
  const utils_js_1 = require("../utils.js");
5
5
  function mapEdit(edit, code, languageId) {
6
6
  // Don't attempt to move the edit to the frontmatter if the file isn't the root TSX file, it means it's a script tag
@@ -17,5 +17,4 @@ function mapEdit(edit, code, languageId) {
17
17
  }
18
18
  return edit;
19
19
  }
20
- exports.mapEdit = mapEdit;
21
20
  //# sourceMappingURL=utils.js.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSnippetCompletions = void 0;
3
+ exports.getSnippetCompletions = getSnippetCompletions;
4
4
  const language_server_1 = require("@volar/language-server");
5
5
  function getSnippetCompletions(frontmatter) {
6
6
  if (frontmatter.status === 'doesnt-exist')
@@ -62,5 +62,4 @@ function getSnippetCompletions(frontmatter) {
62
62
  },
63
63
  ];
64
64
  }
65
- exports.getSnippetCompletions = getSnippetCompletions;
66
65
  //# sourceMappingURL=snippets.js.map
@@ -1,6 +1,7 @@
1
- import { HTMLDocument, Node, Range, TextEdit } from 'vscode-html-languageservice';
1
+ import type { HTMLDocument, Node, TextEdit } from 'vscode-html-languageservice';
2
+ import { Range } from 'vscode-html-languageservice';
2
3
  import type { AstroMetadata, FrontmatterStatus } from '../core/parseAstro.js';
3
- export declare function isJSDocument(languageId: string): boolean;
4
+ export declare function isJSDocument(languageId: string): languageId is "typescript" | "typescriptreact" | "javascript" | "javascriptreact";
4
5
  /**
5
6
  * Return true if a specific node could be a component.
6
7
  * This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
@@ -1,6 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.editShouldBeInFrontmatter = exports.getOpenFrontmatterEdit = exports.getNewFrontmatterEdit = exports.ensureRangeIsInFrontmatter = exports.ensureProperEditForFrontmatter = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInComponentStartTag = exports.isPossibleComponent = exports.isJSDocument = void 0;
3
+ exports.isJSDocument = isJSDocument;
4
+ exports.isPossibleComponent = isPossibleComponent;
5
+ exports.isInComponentStartTag = isInComponentStartTag;
6
+ exports.isInsideExpression = isInsideExpression;
7
+ exports.isInsideFrontmatter = isInsideFrontmatter;
8
+ exports.ensureProperEditForFrontmatter = ensureProperEditForFrontmatter;
9
+ exports.ensureRangeIsInFrontmatter = ensureRangeIsInFrontmatter;
10
+ exports.getNewFrontmatterEdit = getNewFrontmatterEdit;
11
+ exports.getOpenFrontmatterEdit = getOpenFrontmatterEdit;
12
+ exports.editShouldBeInFrontmatter = editShouldBeInFrontmatter;
4
13
  const vscode_html_languageservice_1 = require("vscode-html-languageservice");
5
14
  function isJSDocument(languageId) {
6
15
  return (languageId === 'javascript' ||
@@ -8,15 +17,15 @@ function isJSDocument(languageId) {
8
17
  languageId === 'javascriptreact' ||
9
18
  languageId === 'typescriptreact');
10
19
  }
11
- exports.isJSDocument = isJSDocument;
12
20
  /**
13
21
  * Return true if a specific node could be a component.
14
22
  * This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
15
23
  */
16
24
  function isPossibleComponent(node) {
17
- return !!node.tag?.[0].match(/[A-Z]/) || !!node.tag?.match(/.+[.][A-Z]?/);
25
+ if (!node.tag)
26
+ return false;
27
+ return !!/[A-Z]/.test(node.tag?.[0]) || !!/.+\.[A-Z]?/.test(node.tag);
18
28
  }
19
- exports.isPossibleComponent = isPossibleComponent;
20
29
  /**
21
30
  * Return if a given offset is inside the start tag of a component
22
31
  */
@@ -24,7 +33,6 @@ function isInComponentStartTag(html, offset) {
24
33
  const node = html.findNodeAt(offset);
25
34
  return isPossibleComponent(node) && (!node.startTagEnd || offset < node.startTagEnd);
26
35
  }
27
- exports.isInComponentStartTag = isInComponentStartTag;
28
36
  /**
29
37
  * Return if a given position is inside a JSX expression
30
38
  */
@@ -32,7 +40,6 @@ function isInsideExpression(html, tagStart, position) {
32
40
  const charactersInNode = html.substring(tagStart, position);
33
41
  return charactersInNode.lastIndexOf('{') > charactersInNode.lastIndexOf('}');
34
42
  }
35
- exports.isInsideExpression = isInsideExpression;
36
43
  /**
37
44
  * Return if a given offset is inside the frontmatter
38
45
  */
@@ -46,7 +53,6 @@ function isInsideFrontmatter(offset, frontmatter) {
46
53
  return false;
47
54
  }
48
55
  }
49
- exports.isInsideFrontmatter = isInsideFrontmatter;
50
56
  function ensureProperEditForFrontmatter(edit, metadata, newLine, position = 'top') {
51
57
  switch (metadata.frontmatter.status) {
52
58
  case 'open':
@@ -64,7 +70,6 @@ function ensureProperEditForFrontmatter(edit, metadata, newLine, position = 'top
64
70
  return getNewFrontmatterEdit(edit, metadata, newLine);
65
71
  }
66
72
  }
67
- exports.ensureProperEditForFrontmatter = ensureProperEditForFrontmatter;
68
73
  /**
69
74
  * Force a range to be at the start of the frontmatter if it is outside
70
75
  */
@@ -85,13 +90,11 @@ function ensureRangeIsInFrontmatter(range, metadata, position = 'top') {
85
90
  }
86
91
  return range;
87
92
  }
88
- exports.ensureRangeIsInFrontmatter = ensureRangeIsInFrontmatter;
89
93
  function getNewFrontmatterEdit(edit, astroMetadata, newLine) {
90
94
  edit.newText = `---${edit.newText.startsWith(newLine) ? '' : newLine}${edit.newText}---${newLine}${newLine}`;
91
95
  edit.range = vscode_html_languageservice_1.Range.create(astroMetadata.tsxRanges.frontmatter.start, astroMetadata.tsxRanges.frontmatter.start);
92
96
  return edit;
93
97
  }
94
- exports.getNewFrontmatterEdit = getNewFrontmatterEdit;
95
98
  function getOpenFrontmatterEdit(edit, astroMetadata, newLine) {
96
99
  edit.newText = edit.newText.startsWith(newLine)
97
100
  ? `${edit.newText}---`
@@ -99,7 +102,6 @@ function getOpenFrontmatterEdit(edit, astroMetadata, newLine) {
99
102
  edit.range = vscode_html_languageservice_1.Range.create(astroMetadata.tsxRanges.frontmatter.start, astroMetadata.tsxRanges.frontmatter.start);
100
103
  return edit;
101
104
  }
102
- exports.getOpenFrontmatterEdit = getOpenFrontmatterEdit;
103
105
  // Most edits that are at the beginning of the TSX, or outside the document are intended for the frontmatter
104
106
  function editShouldBeInFrontmatter(range, astroMetadata) {
105
107
  const isAtTSXStart = range.start.line < astroMetadata.tsxRanges.frontmatter.start.line;
@@ -109,5 +111,4 @@ function editShouldBeInFrontmatter(range, astroMetadata) {
109
111
  ? { itShould: true, position: isPastFile ? 'bottom' : 'top' }
110
112
  : { itShould: false, position: undefined };
111
113
  }
112
- exports.editShouldBeInFrontmatter = editShouldBeInFrontmatter;
113
114
  //# sourceMappingURL=utils.js.map
@@ -0,0 +1,3 @@
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ import type { CollectionConfig } from '../core/frontmatterHolders.js';
3
+ export declare const create: (collectionConfigs: CollectionConfig[]) => LanguageServicePlugin;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = void 0;
4
+ const language_server_1 = require("@volar/language-server");
5
+ const volar_service_yaml_1 = require("volar-service-yaml");
6
+ const vscode_uri_1 = require("vscode-uri");
7
+ const frontmatterHolders_js_1 = require("../core/frontmatterHolders.js");
8
+ const create = (collectionConfigs) => {
9
+ const yamlPlugin = (0, volar_service_yaml_1.create)({
10
+ getLanguageSettings() {
11
+ const schemas = collectionConfigs.flatMap((workspaceCollectionConfig) => {
12
+ return workspaceCollectionConfig.config.collections.flatMap((collection) => {
13
+ return {
14
+ fileMatch: frontmatterHolders_js_1.SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS.map((ext) => `volar-embedded-content://yaml_frontmatter_${collection.name}/**/*${ext}`),
15
+ uri: vscode_uri_1.Utils.joinPath(workspaceCollectionConfig.folder, '.astro/collections', `${collection.name}.schema.json`).toString(),
16
+ };
17
+ });
18
+ });
19
+ return {
20
+ completion: true,
21
+ format: false,
22
+ hover: true,
23
+ validate: true,
24
+ customTags: [],
25
+ yamlVersion: '1.2',
26
+ isKubernetes: false,
27
+ parentSkeletonSelectedFirst: false,
28
+ disableDefaultProperties: false,
29
+ schemas: schemas,
30
+ };
31
+ },
32
+ });
33
+ return {
34
+ ...yamlPlugin,
35
+ capabilities: {
36
+ ...yamlPlugin.capabilities,
37
+ codeLensProvider: undefined,
38
+ },
39
+ create(context) {
40
+ const yamlPluginInstance = yamlPlugin.create(context);
41
+ const languageService = yamlPluginInstance.provide?.['yaml/languageService']();
42
+ if (languageService && context.env.onDidChangeWatchedFiles) {
43
+ context.env.onDidChangeWatchedFiles(async (events) => {
44
+ let hasChanges = false;
45
+ for (const change of events.changes) {
46
+ if (!change.uri.endsWith('.schema.json'))
47
+ return;
48
+ if (languageService.resetSchema(change.uri)) {
49
+ hasChanges = true;
50
+ }
51
+ }
52
+ if (hasChanges) {
53
+ // TODO: Figure out how to refresh the diagnostics
54
+ }
55
+ });
56
+ }
57
+ return {
58
+ ...yamlPluginInstance,
59
+ // Disable codelenses, we'll provide our own
60
+ provideCodeLenses: undefined,
61
+ resolveCodeLens: undefined,
62
+ async provideDiagnostics(document, token) {
63
+ const originalDiagnostics = await yamlPluginInstance.provideDiagnostics(document, token);
64
+ if (!originalDiagnostics) {
65
+ return null;
66
+ }
67
+ const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(document.uri));
68
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
69
+ const root = sourceScript?.generated?.root;
70
+ if (!(root instanceof frontmatterHolders_js_1.FrontmatterHolder))
71
+ return undefined;
72
+ // If we don't have a frontmatter, but there are errors, it probably means a frontmatter was required
73
+ if (!root.hasFrontmatter && originalDiagnostics.length > 0) {
74
+ return [
75
+ language_server_1.Diagnostic.create(language_server_1.Range.create(0, 0, 0, 0), 'Frontmatter is required for this file.', language_server_1.DiagnosticSeverity.Error),
76
+ ];
77
+ }
78
+ return originalDiagnostics.map((diagnostic) => {
79
+ // The YAML schema source is not useful to users, since it's generated. Also, it's quite long.
80
+ if (diagnostic.source?.startsWith('yaml-schema:')) {
81
+ diagnostic.source = 'astro';
82
+ // In Astro, schema errors are always fatal
83
+ diagnostic.severity = language_server_1.DiagnosticSeverity.Error;
84
+ // Map missing properties to the entire frontmatte
85
+ if (diagnostic.message.startsWith('Missing property')) {
86
+ diagnostic.range = language_server_1.Range.create({ line: 0, character: 0 }, document.positionAt(document.getText().length));
87
+ }
88
+ }
89
+ return diagnostic;
90
+ });
91
+ },
92
+ async provideHover(document, position, token) {
93
+ const originalHover = await yamlPluginInstance.provideHover(document, position, token);
94
+ if (!originalHover) {
95
+ return null;
96
+ }
97
+ if (language_server_1.MarkupContent.is(originalHover.contents)) {
98
+ // Remove last line that contains the source schema, it's not useful to users since they're generated
99
+ originalHover.contents.value = originalHover.contents.value
100
+ .replace(/\nSource:.*$/, '')
101
+ .trim();
102
+ }
103
+ return originalHover;
104
+ },
105
+ };
106
+ },
107
+ };
108
+ };
109
+ exports.create = create;
110
+ //# sourceMappingURL=yaml.js.map
package/dist/utils.js CHANGED
@@ -23,13 +23,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getAstroInstall = exports.getLanguageServerTypesDir = void 0;
26
+ exports.getLanguageServerTypesDir = getLanguageServerTypesDir;
27
+ exports.getAstroInstall = getAstroInstall;
27
28
  const path = __importStar(require("node:path"));
28
29
  const importPackage_js_1 = require("./importPackage.js");
29
30
  function getLanguageServerTypesDir(ts) {
30
31
  return ts.sys.resolvePath(path.resolve(__dirname, '../types'));
31
32
  }
32
- exports.getLanguageServerTypesDir = getLanguageServerTypesDir;
33
33
  function getAstroInstall(basePaths, checkForAstro) {
34
34
  let astroPath;
35
35
  let version;
@@ -68,7 +68,7 @@ function getAstroInstall(basePaths, checkForAstro) {
68
68
  }
69
69
  version = require(path.resolve(astroPath, 'package.json')).version;
70
70
  }
71
- catch (e) {
71
+ catch {
72
72
  // If we still couldn't find it, it probably just doesn't exist
73
73
  console.error(`${basePaths[0]} seems to be an Astro project, but we couldn't find Astro or Astro is not installed`);
74
74
  return 'not-found';
@@ -92,5 +92,4 @@ function getAstroInstall(basePaths, checkForAstro) {
92
92
  },
93
93
  };
94
94
  }
95
- exports.getAstroInstall = getAstroInstall;
96
95
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/language-server",
3
- "version": "2.13.2",
3
+ "version": "2.14.0",
4
4
  "author": "withastro",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,7 +20,8 @@
20
20
  "astro-ls": "./bin/nodeServer.js"
21
21
  },
22
22
  "dependencies": {
23
- "@astrojs/compiler": "^2.10.2",
23
+ "@astrojs/compiler": "^2.10.3",
24
+ "@astrojs/yaml2ts": "^0.2.0",
24
25
  "@jridgewell/sourcemap-codec": "^1.4.15",
25
26
  "@volar/kit": "~2.4.0-alpha.15",
26
27
  "@volar/language-core": "~2.4.0-alpha.15",
@@ -35,6 +36,7 @@
35
36
  "volar-service-prettier": "0.0.59",
36
37
  "volar-service-typescript": "0.0.59",
37
38
  "volar-service-typescript-twoslash-queries": "0.0.59",
39
+ "volar-service-yaml": "0.0.59",
38
40
  "vscode-html-languageservice": "^5.2.0",
39
41
  "vscode-uri": "^3.0.8"
40
42
  },
@@ -45,12 +47,12 @@
45
47
  "@types/mocha": "^10.0.1",
46
48
  "@types/node": "^18.17.8",
47
49
  "@volar/test-utils": "~2.4.0-alpha.15",
48
- "astro": "^4.3.5",
50
+ "astro": "^4.14.0",
49
51
  "chai": "^4.3.7",
50
52
  "mocha": "^10.2.0",
51
53
  "svelte": "^4.2.10",
52
54
  "tsx": "^3.12.7",
53
- "typescript": "^5.2.2",
55
+ "typescript": "^5.5.4",
54
56
  "vscode-languageserver-protocol": "^3.17.5",
55
57
  "vscode-languageserver-textdocument": "^1.0.11"
56
58
  },
@@ -69,7 +71,8 @@
69
71
  "scripts": {
70
72
  "build": "tsc",
71
73
  "dev": "tsc --watch",
72
- "test": "mocha --timeout 10000 --require tsx --require test/takedown.ts test/misc/init.test.ts test/**/*.test.ts",
74
+ "sync-fixture": "pnpm --dir ./test/fixture sync",
75
+ "test": "pnpm run sync-fixture && mocha --timeout 10000 --require tsx --require test/takedown.ts test/misc/init.test.ts test/**/*.test.ts",
73
76
  "test:match": "pnpm run test -g"
74
77
  }
75
78
  }
@@ -14,7 +14,7 @@ declare namespace astroHTML.JSX {
14
14
  export type Children = Child | Child[];
15
15
 
16
16
  interface ElementChildrenAttribute {
17
- // eslint-disable-next-line @typescript-eslint/ban-types
17
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
18
18
  children: {};
19
19
  }
20
20
 
@@ -591,7 +591,7 @@ declare namespace astroHTML.JSX {
591
591
  referrerpolicy?: HTMLAttributeReferrerPolicy | undefined | null;
592
592
  }
593
593
 
594
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
594
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
595
595
  interface AudioHTMLAttributes extends MediaHTMLAttributes {}
596
596
 
597
597
  interface AreaHTMLAttributes extends HTMLAttributes {