@astrojs/language-server 2.5.1 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/check.js +4 -3
- package/dist/core/astro2tsx.js +1 -1
- package/dist/core/index.js +6 -2
- package/dist/core/parseAstro.d.ts +2 -2
- package/dist/core/parseAstro.js +25 -2
- package/dist/core/parseJS.js +27 -16
- package/dist/languageServerPlugin.js +7 -3
- package/dist/utils.d.ts +4 -1
- package/dist/utils.js +24 -2
- package/package.json +17 -17
package/dist/check.js
CHANGED
|
@@ -72,9 +72,9 @@ class AstroCheck {
|
|
|
72
72
|
// Filter diagnostics based on the logErrors level
|
|
73
73
|
const fileDiagnosticsToPrint = fileDiagnostics.filter((diag) => {
|
|
74
74
|
const severity = diag.severity ?? language_server_1.DiagnosticSeverity.Error;
|
|
75
|
-
switch (logErrors?.level ?? '
|
|
75
|
+
switch (logErrors?.level ?? 'hint') {
|
|
76
76
|
case 'error':
|
|
77
|
-
return
|
|
77
|
+
return severity <= language_server_1.DiagnosticSeverity.Error;
|
|
78
78
|
case 'warning':
|
|
79
79
|
return severity <= language_server_1.DiagnosticSeverity.Warning;
|
|
80
80
|
case 'hint':
|
|
@@ -106,9 +106,10 @@ class AstroCheck {
|
|
|
106
106
|
initialize() {
|
|
107
107
|
this.ts = this.typescriptPath ? require(this.typescriptPath) : require('typescript');
|
|
108
108
|
const tsconfigPath = this.getTsconfig();
|
|
109
|
+
const astroInstall = (0, utils_js_1.getAstroInstall)([this.workspacePath]);
|
|
109
110
|
const config = {
|
|
110
111
|
languages: {
|
|
111
|
-
astro: (0, index_js_1.getLanguageModule)(
|
|
112
|
+
astro: (0, index_js_1.getLanguageModule)(typeof astroInstall === 'string' ? undefined : astroInstall, this.ts),
|
|
112
113
|
svelte: (0, svelte_js_1.getSvelteLanguageModule)(),
|
|
113
114
|
vue: (0, vue_js_1.getVueLanguageModule)(),
|
|
114
115
|
},
|
package/dist/core/astro2tsx.js
CHANGED
|
@@ -28,7 +28,7 @@ function safeConvertToTSX(content, options) {
|
|
|
28
28
|
code: 1000,
|
|
29
29
|
location: { file: options.filename, line: 1, column: 1, length: content.length },
|
|
30
30
|
severity: 1,
|
|
31
|
-
text: `The Astro compiler encountered an unknown error while
|
|
31
|
+
text: `The Astro compiler encountered an unknown error while transform this file to TSX. Please create an issue with your code and the error shown in the server's logs: https://github.com/withastro/language-tools/issues`,
|
|
32
32
|
},
|
|
33
33
|
],
|
|
34
34
|
};
|
package/dist/core/index.js
CHANGED
|
@@ -111,7 +111,11 @@ class AstroFile {
|
|
|
111
111
|
data: language_core_1.FileRangeCapabilities.full,
|
|
112
112
|
},
|
|
113
113
|
];
|
|
114
|
-
this.
|
|
114
|
+
this.compilerDiagnostics = [];
|
|
115
|
+
this.astroMeta = (0, parseAstro_1.getAstroMetadata)(this.fileName, this.snapshot.getText(0, this.snapshot.getLength()));
|
|
116
|
+
if (this.astroMeta.diagnostics.length > 0) {
|
|
117
|
+
this.compilerDiagnostics.push(...this.astroMeta.diagnostics);
|
|
118
|
+
}
|
|
115
119
|
const { htmlDocument, virtualFile: htmlVirtualFile } = (0, parseHTML_1.parseHTML)(this.fileName, this.snapshot, this.astroMeta.frontmatter.status === 'closed'
|
|
116
120
|
? this.astroMeta.frontmatter.position.end.offset
|
|
117
121
|
: 0);
|
|
@@ -122,7 +126,7 @@ class AstroFile {
|
|
|
122
126
|
this.embeddedFiles = [];
|
|
123
127
|
this.embeddedFiles.push(htmlVirtualFile);
|
|
124
128
|
const tsx = (0, astro2tsx_1.astro2tsx)(this.snapshot.getText(0, this.snapshot.getLength()), this.fileName, this.ts, htmlDocument);
|
|
125
|
-
this.compilerDiagnostics
|
|
129
|
+
this.compilerDiagnostics.push(...tsx.diagnostics);
|
|
126
130
|
this.embeddedFiles.push(tsx.virtualFile);
|
|
127
131
|
}
|
|
128
132
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ParseResult, Point } from '@astrojs/compiler/types';
|
|
1
|
+
import type { ParseOptions, ParseResult, Point } from '@astrojs/compiler/types';
|
|
2
2
|
type AstroMetadata = ParseResult & {
|
|
3
3
|
frontmatter: FrontmatterStatus;
|
|
4
4
|
};
|
|
5
|
-
export declare function getAstroMetadata(input: string,
|
|
5
|
+
export declare function getAstroMetadata(fileName: string, input: string, options?: ParseOptions): AstroMetadata;
|
|
6
6
|
interface FrontmatterOpen {
|
|
7
7
|
status: 'open';
|
|
8
8
|
position: {
|
package/dist/core/parseAstro.js
CHANGED
|
@@ -2,14 +2,37 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getAstroMetadata = void 0;
|
|
4
4
|
const sync_1 = require("@astrojs/compiler/sync");
|
|
5
|
-
function getAstroMetadata(input,
|
|
6
|
-
const parseResult = (
|
|
5
|
+
function getAstroMetadata(fileName, input, options = { position: true }) {
|
|
6
|
+
const parseResult = safeParseAst(fileName, input, options);
|
|
7
7
|
return {
|
|
8
8
|
...parseResult,
|
|
9
9
|
frontmatter: getFrontmatterStatus(parseResult.ast, input),
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
exports.getAstroMetadata = getAstroMetadata;
|
|
13
|
+
function safeParseAst(fileName, input, parseOptions) {
|
|
14
|
+
try {
|
|
15
|
+
const parseResult = (0, sync_1.parse)(input, parseOptions);
|
|
16
|
+
return parseResult;
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
console.error(`There was an error parsing ${fileName}'s AST. An empty AST will be returned instead to avoid breaking the server. Please create an issue: https://github.com/withastro/language-tools/issues\nError: ${e}.`);
|
|
20
|
+
return {
|
|
21
|
+
ast: {
|
|
22
|
+
type: 'root',
|
|
23
|
+
children: [],
|
|
24
|
+
},
|
|
25
|
+
diagnostics: [
|
|
26
|
+
{
|
|
27
|
+
code: 1000,
|
|
28
|
+
location: { file: fileName, line: 1, column: 1, length: input.length },
|
|
29
|
+
severity: 1,
|
|
30
|
+
text: `The Astro compiler encountered an unknown error while parsing this file's AST. Please create an issue with your code and the error shown in the server's logs: https://github.com/withastro/language-tools/issues`,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
13
36
|
function getFrontmatterStatus(ast, text) {
|
|
14
37
|
if (!ast.children || (ast.children && ast.children.length === 0)) {
|
|
15
38
|
return {
|
package/dist/core/parseJS.js
CHANGED
|
@@ -29,32 +29,35 @@ const language_core_1 = require("@volar/language-core");
|
|
|
29
29
|
const SourceMap = __importStar(require("@volar/source-map"));
|
|
30
30
|
const muggle = __importStar(require("muggle-string"));
|
|
31
31
|
function extractScriptTags(fileName, snapshot, htmlDocument, ast) {
|
|
32
|
-
const embeddedJSFiles =
|
|
32
|
+
const embeddedJSFiles = findModuleScripts(fileName, snapshot, htmlDocument.roots);
|
|
33
33
|
const javascriptContexts = [
|
|
34
|
-
...
|
|
34
|
+
...findClassicScripts(htmlDocument, snapshot),
|
|
35
35
|
...findEventAttributes(ast),
|
|
36
36
|
].sort((a, b) => a.startOffset - b.startOffset);
|
|
37
37
|
if (javascriptContexts.length > 0) {
|
|
38
|
+
// classic scripts share the same scope
|
|
39
|
+
// merging them brings about redeclaration errors
|
|
38
40
|
embeddedJSFiles.push(mergeJSContexts(fileName, javascriptContexts));
|
|
39
41
|
}
|
|
40
42
|
return embeddedJSFiles;
|
|
41
43
|
}
|
|
42
44
|
exports.extractScriptTags = extractScriptTags;
|
|
43
|
-
function
|
|
44
|
-
//
|
|
45
|
-
if (!scriptTag.attributes ||
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
function getScriptType(scriptTag) {
|
|
46
|
+
// script tags without attributes are processed and converted into module scripts
|
|
47
|
+
if (!scriptTag.attributes || Object.entries(scriptTag.attributes).length === 0)
|
|
48
|
+
return 'processed module';
|
|
49
|
+
// even when it is not processed by vite, scripts with type=module remain modules
|
|
50
|
+
if (scriptTag.attributes['type']?.includes('module') === true)
|
|
51
|
+
return 'module';
|
|
52
|
+
// whenever there are attributes, is:inline is implied and in the absence of type=module, the script is classic
|
|
53
|
+
return 'classic';
|
|
51
54
|
}
|
|
52
55
|
/**
|
|
53
56
|
* Get all the isolated scripts in the HTML document
|
|
54
57
|
* Isolated scripts are scripts that are hoisted by Astro and as such, are isolated from the rest of the code because of the implicit `type="module"`
|
|
55
58
|
* All the isolated scripts are passed to the TypeScript language server as separate `.mts` files.
|
|
56
59
|
*/
|
|
57
|
-
function
|
|
60
|
+
function findModuleScripts(fileName, snapshot, roots) {
|
|
58
61
|
const embeddedScripts = [];
|
|
59
62
|
let scriptIndex = 0;
|
|
60
63
|
getEmbeddedScriptsInNodes(roots);
|
|
@@ -63,10 +66,11 @@ function findIsolatedScripts(fileName, snapshot, roots) {
|
|
|
63
66
|
if (node.tag === 'script' &&
|
|
64
67
|
node.startTagEnd !== undefined &&
|
|
65
68
|
node.endTagStart !== undefined &&
|
|
66
|
-
|
|
69
|
+
getScriptType(node) !== 'classic') {
|
|
67
70
|
const scriptText = snapshot.getText(node.startTagEnd, node.endTagStart);
|
|
71
|
+
const extension = getScriptType(node) === 'processed module' ? 'mts' : 'mjs';
|
|
68
72
|
embeddedScripts.push({
|
|
69
|
-
fileName: fileName + `.${scriptIndex}
|
|
73
|
+
fileName: fileName + `.${scriptIndex}.${extension}`,
|
|
70
74
|
kind: language_core_1.FileKind.TypeScriptHostFile,
|
|
71
75
|
snapshot: {
|
|
72
76
|
getText: (start, end) => scriptText.substring(start, end),
|
|
@@ -104,7 +108,7 @@ function findIsolatedScripts(fileName, snapshot, roots) {
|
|
|
104
108
|
* Inline scripts are scripts that are not hoisted by Astro and as such, are not isolated from the rest of the code.
|
|
105
109
|
* All the inline scripts are concatenated into a single `.mjs` file and passed to the TypeScript language server.
|
|
106
110
|
*/
|
|
107
|
-
function
|
|
111
|
+
function findClassicScripts(htmlDocument, snapshot) {
|
|
108
112
|
const inlineScripts = [];
|
|
109
113
|
getInlineScriptsInNodes(htmlDocument.roots);
|
|
110
114
|
function getInlineScriptsInNodes(nodes) {
|
|
@@ -113,7 +117,7 @@ function findInlineScripts(htmlDocument, snapshot) {
|
|
|
113
117
|
node.startTagEnd !== undefined &&
|
|
114
118
|
node.endTagStart !== undefined &&
|
|
115
119
|
!isJSON(node.attributes?.type) &&
|
|
116
|
-
|
|
120
|
+
getScriptType(node) === 'classic') {
|
|
117
121
|
const scriptText = snapshot.getText(node.startTagEnd, node.endTagStart);
|
|
118
122
|
inlineScripts.push({
|
|
119
123
|
startOffset: node.startTagEnd,
|
|
@@ -189,7 +193,14 @@ function mergeJSContexts(fileName, javascriptContexts) {
|
|
|
189
193
|
getLength: () => text.length,
|
|
190
194
|
getChangeRange: () => undefined,
|
|
191
195
|
},
|
|
192
|
-
capabilities:
|
|
196
|
+
capabilities: {
|
|
197
|
+
codeAction: true,
|
|
198
|
+
diagnostic: true,
|
|
199
|
+
documentFormatting: false,
|
|
200
|
+
documentSymbol: true,
|
|
201
|
+
foldingRange: true,
|
|
202
|
+
inlayHint: true,
|
|
203
|
+
},
|
|
193
204
|
embeddedFiles: [],
|
|
194
205
|
kind: language_core_1.FileKind.TypeScriptHostFile,
|
|
195
206
|
mappings,
|
|
@@ -39,14 +39,18 @@ const plugin = (initOptions, modules) => ({
|
|
|
39
39
|
resolveConfig(config, ctx) {
|
|
40
40
|
config.languages ??= {};
|
|
41
41
|
if (ctx) {
|
|
42
|
-
const
|
|
43
|
-
|
|
42
|
+
const nearestPackageJson = modules.typescript?.findConfigFile(ctx.project.rootUri.fsPath, modules.typescript.sys.fileExists, 'package.json');
|
|
43
|
+
const astroInstall = (0, utils_js_1.getAstroInstall)([ctx.project.rootUri.fsPath], {
|
|
44
|
+
nearestPackageJson: nearestPackageJson,
|
|
45
|
+
readDirectory: modules.typescript.sys.readDirectory,
|
|
46
|
+
});
|
|
47
|
+
if (astroInstall === 'not-found') {
|
|
44
48
|
ctx.server.connection.sendNotification(node_1.ShowMessageNotification.type, {
|
|
45
49
|
message: `Couldn't find Astro in workspace "${ctx.project.rootUri.fsPath}". Experience might be degraded. For the best experience, please make sure Astro is installed into your project and restart the language server.`,
|
|
46
50
|
type: node_1.MessageType.Warning,
|
|
47
51
|
});
|
|
48
52
|
}
|
|
49
|
-
config.languages.astro = (0, core_1.getLanguageModule)(astroInstall, modules.typescript);
|
|
53
|
+
config.languages.astro = (0, core_1.getLanguageModule)(typeof astroInstall === 'string' ? undefined : astroInstall, modules.typescript);
|
|
50
54
|
config.languages.vue = (0, vue_js_1.getVueLanguageModule)();
|
|
51
55
|
config.languages.svelte = (0, svelte_js_1.getSvelteLanguageModule)();
|
|
52
56
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -7,4 +7,7 @@ export interface AstroInstall {
|
|
|
7
7
|
patch: number;
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
|
-
export declare function getAstroInstall(basePaths: string[]
|
|
10
|
+
export declare function getAstroInstall(basePaths: string[], checkForAstro?: {
|
|
11
|
+
nearestPackageJson: string | undefined;
|
|
12
|
+
readDirectory: typeof import('typescript/lib/tsserverlibrary.js').sys.readDirectory;
|
|
13
|
+
}): AstroInstall | 'not-an-astro-project' | 'not-found';
|
package/dist/utils.js
CHANGED
|
@@ -26,9 +26,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.getAstroInstall = void 0;
|
|
27
27
|
const path = __importStar(require("node:path"));
|
|
28
28
|
const importPackage_js_1 = require("./importPackage.js");
|
|
29
|
-
function getAstroInstall(basePaths) {
|
|
29
|
+
function getAstroInstall(basePaths, checkForAstro) {
|
|
30
30
|
let astroPath;
|
|
31
31
|
let version;
|
|
32
|
+
if (checkForAstro && checkForAstro.nearestPackageJson) {
|
|
33
|
+
basePaths.push(path.dirname(checkForAstro.nearestPackageJson));
|
|
34
|
+
let deps = new Set();
|
|
35
|
+
try {
|
|
36
|
+
const packageJSON = require(checkForAstro.nearestPackageJson);
|
|
37
|
+
[
|
|
38
|
+
...Object.keys(packageJSON.dependencies ?? {}),
|
|
39
|
+
...Object.keys(packageJSON.devDependencies ?? {}),
|
|
40
|
+
...Object.keys(packageJSON.peerDependencies ?? {}),
|
|
41
|
+
].forEach((dep) => deps.add(dep));
|
|
42
|
+
}
|
|
43
|
+
catch { }
|
|
44
|
+
if (!deps.has('astro')) {
|
|
45
|
+
const directoryContent = checkForAstro.readDirectory(path.dirname(checkForAstro.nearestPackageJson), ['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'], undefined, undefined, 1);
|
|
46
|
+
if (!directoryContent.some((file) => path.basename(file).startsWith('astro.config'))) {
|
|
47
|
+
return 'not-an-astro-project';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
32
51
|
try {
|
|
33
52
|
astroPath = (0, importPackage_js_1.getPackagePath)('astro', basePaths);
|
|
34
53
|
if (!astroPath) {
|
|
@@ -48,9 +67,12 @@ function getAstroInstall(basePaths) {
|
|
|
48
67
|
catch (e) {
|
|
49
68
|
// If we still couldn't find it, it probably just doesn't exist
|
|
50
69
|
console.error(`${basePaths[0]} seems to be an Astro project, but we couldn't find Astro or Astro is not installed`);
|
|
51
|
-
return
|
|
70
|
+
return 'not-found';
|
|
52
71
|
}
|
|
53
72
|
}
|
|
73
|
+
if (!version) {
|
|
74
|
+
return 'not-found';
|
|
75
|
+
}
|
|
54
76
|
let [major, minor, patch] = version.split('.');
|
|
55
77
|
if (patch.includes('-')) {
|
|
56
78
|
const patchParts = patch.split('-');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/language-server",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"author": "withastro",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -20,22 +20,22 @@
|
|
|
20
20
|
"astro-ls": "./bin/nodeServer.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@astrojs/compiler": "^2.2.
|
|
23
|
+
"@astrojs/compiler": "^2.2.2",
|
|
24
24
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
25
|
-
"@volar/kit": "~1.10.
|
|
26
|
-
"@volar/language-core": "~1.10.
|
|
27
|
-
"@volar/language-server": "~1.10.
|
|
28
|
-
"@volar/language-service": "~1.10.
|
|
29
|
-
"@volar/source-map": "~1.10.
|
|
30
|
-
"@volar/typescript": "~1.10.
|
|
25
|
+
"@volar/kit": "~1.10.9",
|
|
26
|
+
"@volar/language-core": "~1.10.9",
|
|
27
|
+
"@volar/language-server": "~1.10.9",
|
|
28
|
+
"@volar/language-service": "~1.10.9",
|
|
29
|
+
"@volar/source-map": "~1.10.9",
|
|
30
|
+
"@volar/typescript": "~1.10.9",
|
|
31
31
|
"fast-glob": "^3.2.12",
|
|
32
32
|
"muggle-string": "^0.3.1",
|
|
33
|
-
"volar-service-css": "0.0.
|
|
34
|
-
"volar-service-emmet": "0.0.
|
|
35
|
-
"volar-service-html": "0.0.
|
|
36
|
-
"volar-service-prettier": "0.0.
|
|
37
|
-
"volar-service-typescript": "0.0.
|
|
38
|
-
"volar-service-typescript-twoslash-queries": "0.0.
|
|
33
|
+
"volar-service-css": "0.0.16",
|
|
34
|
+
"volar-service-emmet": "0.0.16",
|
|
35
|
+
"volar-service-html": "0.0.16",
|
|
36
|
+
"volar-service-prettier": "0.0.16",
|
|
37
|
+
"volar-service-typescript": "0.0.16",
|
|
38
|
+
"volar-service-typescript-twoslash-queries": "0.0.16",
|
|
39
39
|
"vscode-html-languageservice": "^5.1.0",
|
|
40
40
|
"vscode-uri": "^3.0.8"
|
|
41
41
|
},
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"@astrojs/vue": "^3.0.1",
|
|
45
45
|
"@types/chai": "^4.3.5",
|
|
46
46
|
"@types/mocha": "^10.0.1",
|
|
47
|
-
"@types/node": "^
|
|
47
|
+
"@types/node": "^18.17.8",
|
|
48
48
|
"astro": "^3.3.0",
|
|
49
49
|
"chai": "^4.3.7",
|
|
50
50
|
"mocha": "^10.2.0",
|
|
51
51
|
"tsx": "^3.12.7",
|
|
52
|
-
"typescript": "~5.1.3",
|
|
53
52
|
"vscode-languageserver-protocol": "^3.17.5",
|
|
54
|
-
"vscode-languageserver-textdocument": "^1.0.11"
|
|
53
|
+
"vscode-languageserver-textdocument": "^1.0.11",
|
|
54
|
+
"typescript": "^5.2.2"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"prettier": "^3.0.0",
|