@astrojs/language-server 0.20.0 → 0.21.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.
- package/CHANGELOG.md +24 -0
- package/dist/core/documents/utils.d.ts +4 -0
- package/dist/core/documents/utils.js +9 -1
- package/dist/plugins/PluginHost.js +3 -8
- package/dist/plugins/html/HTMLPlugin.js +8 -4
- package/dist/plugins/html/features/astro-attributes.d.ts +1 -0
- package/dist/plugins/html/features/astro-attributes.js +51 -26
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +2 -0
- package/dist/plugins/typescript/TypeScriptPlugin.js +5 -0
- package/dist/plugins/typescript/astro2tsx.d.ts +1 -2
- package/dist/plugins/typescript/astro2tsx.js +0 -4
- package/dist/plugins/typescript/features/CompletionsProvider.d.ts +0 -1
- package/dist/plugins/typescript/features/CompletionsProvider.js +29 -26
- package/dist/plugins/typescript/features/DiagnosticsProvider.d.ts +0 -1
- package/dist/plugins/typescript/features/DiagnosticsProvider.js +3 -12
- package/dist/plugins/typescript/features/FoldingRangesProvider.js +1 -1
- package/dist/plugins/typescript/language-service.js +9 -28
- package/dist/plugins/typescript/snapshots/utils.d.ts +1 -0
- package/dist/plugins/typescript/snapshots/utils.js +2 -1
- package/dist/server.js +18 -7
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +19 -2
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @astrojs/language-server
|
|
2
2
|
|
|
3
|
+
## 0.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 574b75d: Remove support for the Markdown component
|
|
8
|
+
- d23ba22: Changed how Astro's types are consumed to avoid making type acquisition explicit inside Astro files
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- 81f3aa5: Added a debug command to show the currently opened document's TSX output
|
|
13
|
+
|
|
14
|
+
## 0.20.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 081cf24: Fix completions not working inside script tags, fix duplicate completions in some cases, added completions for the slot element
|
|
19
|
+
|
|
20
|
+
## 0.20.1
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- e6996f5: Fixed many situations where the language server would warn abusively about not being able to find Astro
|
|
25
|
+
- 4589c2b: Fix the language server not warning properly when a package is implicitely any due to missing types
|
|
26
|
+
|
|
3
27
|
## 0.20.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -21,6 +21,10 @@ export declare function getLineAtPosition(position: Position, text: string): str
|
|
|
21
21
|
* Return if a given offset is inside the start tag of a component
|
|
22
22
|
*/
|
|
23
23
|
export declare function isInComponentStartTag(html: HTMLDocument, offset: number): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Return if a given offset is inside the name of a tag
|
|
26
|
+
*/
|
|
27
|
+
export declare function isInTagName(html: HTMLDocument, offset: number): boolean;
|
|
24
28
|
/**
|
|
25
29
|
* Return true if a specific node could be a component.
|
|
26
30
|
* 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,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFirstNonWhitespaceIndex = exports.getLineOffsets = exports.offsetAt = exports.positionAt = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInTag = exports.isPossibleComponent = exports.isInComponentStartTag = exports.getLineAtPosition = exports.extractScriptTags = exports.extractStyleTags = exports.walk = void 0;
|
|
3
|
+
exports.getFirstNonWhitespaceIndex = exports.getLineOffsets = exports.offsetAt = exports.positionAt = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInTag = exports.isPossibleComponent = exports.isInTagName = exports.isInComponentStartTag = exports.getLineAtPosition = exports.extractScriptTags = exports.extractStyleTags = exports.walk = void 0;
|
|
4
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
6
|
const parseHtml_1 = require("./parseHtml");
|
|
@@ -105,6 +105,14 @@ function isInComponentStartTag(html, offset) {
|
|
|
105
105
|
return isPossibleComponent(node) && (!node.startTagEnd || offset < node.startTagEnd);
|
|
106
106
|
}
|
|
107
107
|
exports.isInComponentStartTag = isInComponentStartTag;
|
|
108
|
+
/**
|
|
109
|
+
* Return if a given offset is inside the name of a tag
|
|
110
|
+
*/
|
|
111
|
+
function isInTagName(html, offset) {
|
|
112
|
+
const node = html.findNodeAt(offset);
|
|
113
|
+
return offset > node.start && offset < node.start + (node.tag?.length ?? 0);
|
|
114
|
+
}
|
|
115
|
+
exports.isInTagName = isInTagName;
|
|
108
116
|
/**
|
|
109
117
|
* Return true if a specific node could be a component.
|
|
110
118
|
* 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
|
|
@@ -38,19 +38,14 @@ class PluginHost {
|
|
|
38
38
|
const astro = completions.find((completion) => completion.plugin === 'astro');
|
|
39
39
|
if (html && ts) {
|
|
40
40
|
const inComponentStartTag = (0, documents_1.isInComponentStartTag)(document.html, document.offsetAt(position));
|
|
41
|
-
|
|
41
|
+
// If the HTML plugin returned completions, it's highly likely that TS ones are duplicate
|
|
42
|
+
if (html.result.items.length > 0) {
|
|
42
43
|
ts.result.items = [];
|
|
43
44
|
}
|
|
44
|
-
//
|
|
45
|
+
// Inside components, if the Astro plugin has completions we don't want the TS ones are they're duplicates
|
|
45
46
|
if (astro && astro.result.items.length > 0 && inComponentStartTag) {
|
|
46
47
|
ts.result.items = [];
|
|
47
48
|
}
|
|
48
|
-
ts.result.items = ts.result.items.map((item) => {
|
|
49
|
-
if (item.sortText != '-1') {
|
|
50
|
-
item.sortText = 'Z' + (item.sortText || '');
|
|
51
|
-
}
|
|
52
|
-
return item;
|
|
53
|
-
});
|
|
54
49
|
}
|
|
55
50
|
let flattenedCompletions = completions.flatMap((completion) => completion.result.items);
|
|
56
51
|
const isIncomplete = completions.reduce((incomplete, completion) => incomplete || completion.result.isIncomplete, false);
|
|
@@ -11,7 +11,7 @@ class HTMLPlugin {
|
|
|
11
11
|
constructor(configManager) {
|
|
12
12
|
this.__name = 'html';
|
|
13
13
|
this.lang = (0, vscode_html_languageservice_1.getLanguageService)({
|
|
14
|
-
customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.classListAttribute],
|
|
14
|
+
customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.astroElements, astro_attributes_1.classListAttribute],
|
|
15
15
|
});
|
|
16
16
|
this.attributeOnlyLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
|
17
17
|
customDataProviders: [astro_attributes_1.astroAttributes],
|
|
@@ -72,10 +72,14 @@ class HTMLPlugin {
|
|
|
72
72
|
}
|
|
73
73
|
// If we're in a component starting tag, we do not want HTML language completions
|
|
74
74
|
// as HTML attributes are not valid for components
|
|
75
|
-
const
|
|
75
|
+
const inComponentTag = (0, utils_1.isInComponentStartTag)(html, offset);
|
|
76
|
+
const inTagName = (0, utils_1.isInTagName)(html, offset);
|
|
77
|
+
const results = inComponentTag && !inTagName
|
|
76
78
|
? (0, utils_2.removeDataAttrCompletion)(this.attributeOnlyLang.doComplete(document, position, html).items)
|
|
77
|
-
:
|
|
78
|
-
|
|
79
|
+
: // We filter items with no documentation to prevent duplicates with our own defined script and style tags
|
|
80
|
+
this.lang.doComplete(document, position, html).items.filter((item) => item.documentation !== undefined);
|
|
81
|
+
const langCompletions = inComponentTag ? [] : this.getLangCompletions(results);
|
|
82
|
+
return vscode_languageserver_1.CompletionList.create([...results, ...langCompletions, ...emmetResults.items],
|
|
79
83
|
// Emmet completions change on every keystroke, so they are never complete
|
|
80
84
|
emmetResults.items.length > 0);
|
|
81
85
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare const classListAttribute: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
2
|
+
export declare const astroElements: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
2
3
|
export declare const astroAttributes: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
3
4
|
export declare const astroDirectives: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.astroDirectives = exports.astroAttributes = exports.classListAttribute = void 0;
|
|
3
|
+
exports.astroDirectives = exports.astroAttributes = exports.astroElements = exports.classListAttribute = void 0;
|
|
4
4
|
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
|
5
5
|
exports.classListAttribute = (0, vscode_html_languageservice_1.newHTMLDataProvider)('class-list', {
|
|
6
6
|
version: 1,
|
|
@@ -17,42 +17,31 @@ exports.classListAttribute = (0, vscode_html_languageservice_1.newHTMLDataProvid
|
|
|
17
17
|
},
|
|
18
18
|
],
|
|
19
19
|
});
|
|
20
|
-
exports.
|
|
20
|
+
exports.astroElements = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-elements', {
|
|
21
21
|
version: 1,
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
name: 'set:html',
|
|
25
|
-
description: 'Inject unescaped HTML into this tag',
|
|
26
|
-
references: [
|
|
27
|
-
{
|
|
28
|
-
name: 'Astro reference',
|
|
29
|
-
url: 'https://docs.astro.build/en/reference/directives-reference/#sethtml',
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
22
|
+
tags: [
|
|
33
23
|
{
|
|
34
|
-
name: '
|
|
35
|
-
description: '
|
|
24
|
+
name: 'slot',
|
|
25
|
+
description: 'The slot element is a placeholder for external HTML content, allowing you to inject (or “slot”) child elements from other files into your component template.',
|
|
36
26
|
references: [
|
|
37
27
|
{
|
|
38
28
|
name: 'Astro reference',
|
|
39
|
-
url: 'https://docs.astro.build/en/
|
|
29
|
+
url: 'https://docs.astro.build/en/core-concepts/astro-components/#slots',
|
|
40
30
|
},
|
|
41
31
|
],
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
name: 'is:raw',
|
|
45
|
-
description: 'Instructs the Astro compiler to treat any children of this element as text',
|
|
46
|
-
valueSet: 'v',
|
|
47
|
-
references: [
|
|
32
|
+
attributes: [
|
|
48
33
|
{
|
|
49
|
-
name: '
|
|
50
|
-
|
|
34
|
+
name: 'name',
|
|
35
|
+
description: 'The name attribute allows you to pass only HTML elements with the corresponding slot name into a slot’s location.',
|
|
36
|
+
references: [
|
|
37
|
+
{
|
|
38
|
+
name: 'Astro reference',
|
|
39
|
+
url: 'https://docs.astro.build/en/core-concepts/astro-components/#named-slots',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
51
42
|
},
|
|
52
43
|
],
|
|
53
44
|
},
|
|
54
|
-
],
|
|
55
|
-
tags: [
|
|
56
45
|
{
|
|
57
46
|
name: 'script',
|
|
58
47
|
attributes: [
|
|
@@ -146,6 +135,42 @@ exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
146
135
|
},
|
|
147
136
|
],
|
|
148
137
|
});
|
|
138
|
+
exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-attributes', {
|
|
139
|
+
version: 1,
|
|
140
|
+
globalAttributes: [
|
|
141
|
+
{
|
|
142
|
+
name: 'set:html',
|
|
143
|
+
description: 'Inject unescaped HTML into this tag',
|
|
144
|
+
references: [
|
|
145
|
+
{
|
|
146
|
+
name: 'Astro reference',
|
|
147
|
+
url: 'https://docs.astro.build/en/reference/directives-reference/#sethtml',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'set:text',
|
|
153
|
+
description: 'Inject escaped text into this tag',
|
|
154
|
+
references: [
|
|
155
|
+
{
|
|
156
|
+
name: 'Astro reference',
|
|
157
|
+
url: 'https://docs.astro.build/en/reference/directives-reference/#settext',
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'is:raw',
|
|
163
|
+
description: 'Instructs the Astro compiler to treat any children of this element as text',
|
|
164
|
+
valueSet: 'v',
|
|
165
|
+
references: [
|
|
166
|
+
{
|
|
167
|
+
name: 'Astro reference',
|
|
168
|
+
url: 'https://docs.astro.build/en/reference/directives-reference/#israw',
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
});
|
|
149
174
|
exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-directives', {
|
|
150
175
|
version: 1,
|
|
151
176
|
globalAttributes: [
|
|
@@ -3,6 +3,7 @@ import { ConfigManager } from '../../core/config';
|
|
|
3
3
|
import { AstroDocument, DocumentManager } from '../../core/documents';
|
|
4
4
|
import { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
|
|
5
5
|
import { CompletionItemData } from './features/CompletionsProvider';
|
|
6
|
+
import { Astro2TSXResult } from './astro2tsx';
|
|
6
7
|
export declare class TypeScriptPlugin implements Plugin {
|
|
7
8
|
__name: string;
|
|
8
9
|
private configManager;
|
|
@@ -34,5 +35,6 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
34
35
|
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesParam[]): Promise<void>;
|
|
35
36
|
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): Promise<void>;
|
|
36
37
|
getSignatureHelp(document: AstroDocument, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
|
38
|
+
getTSXForDocument(document: AstroDocument): Astro2TSXResult;
|
|
37
39
|
private featureEnabled;
|
|
38
40
|
}
|
|
@@ -19,6 +19,8 @@ const CodeActionsProvider_1 = require("./features/CodeActionsProvider");
|
|
|
19
19
|
const DefinitionsProvider_1 = require("./features/DefinitionsProvider");
|
|
20
20
|
const InlayHintsProvider_1 = require("./features/InlayHintsProvider");
|
|
21
21
|
const FormattingProvider_1 = require("./features/FormattingProvider");
|
|
22
|
+
const astro2tsx_1 = __importDefault(require("./astro2tsx"));
|
|
23
|
+
const utils_2 = require("./snapshots/utils");
|
|
22
24
|
class TypeScriptPlugin {
|
|
23
25
|
constructor(docManager, configManager, workspaceUris) {
|
|
24
26
|
this.__name = 'typescript';
|
|
@@ -137,6 +139,9 @@ class TypeScriptPlugin {
|
|
|
137
139
|
async getSignatureHelp(document, position, context, cancellationToken) {
|
|
138
140
|
return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken);
|
|
139
141
|
}
|
|
142
|
+
getTSXForDocument(document) {
|
|
143
|
+
return (0, astro2tsx_1.default)(document.getText(), (0, utils_2.classNameFromFilename)(document.getURL()));
|
|
144
|
+
}
|
|
140
145
|
async featureEnabled(document, feature) {
|
|
141
146
|
return ((await this.configManager.isEnabled(document, 'typescript')) &&
|
|
142
147
|
(await this.configManager.isEnabled(document, 'typescript', feature)));
|
|
@@ -41,10 +41,6 @@ function default_1(content, className) {
|
|
|
41
41
|
// Turn styles tags into internal strings
|
|
42
42
|
.replace(/<\s*style([^>]*)>(.*?)<\s*\/\s*style>/gs, (_whole, attrs, children) => {
|
|
43
43
|
return `<style${attrs}>{\`${escapeTemplateLiteralContent(children)}\`}</style>`;
|
|
44
|
-
})
|
|
45
|
-
// Turn Markdown tags into internal strings
|
|
46
|
-
.replace(/<\s*Markdown([^>]*)>(.*?)<\s*\/\s*Markdown>/gs, (_whole, attrs, children) => {
|
|
47
|
-
return `<Markdown${attrs}>{\`${escapeTemplateLiteralContent(children)}\`}</Markdown>`;
|
|
48
44
|
})
|
|
49
45
|
// Turn scripts into function calls
|
|
50
46
|
.replace(/<\s*script([^\/>]*)>(.*?)<\s*\/\s*script>/gs, (_whole, attrs, children, offset) => {
|
|
@@ -21,7 +21,6 @@ export declare class CompletionsProviderImpl implements CompletionsProvider<Comp
|
|
|
21
21
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<AppCompletionList<CompletionItemData> | null>;
|
|
22
22
|
resolveCompletion(document: AstroDocument, item: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
|
23
23
|
private toCompletionItem;
|
|
24
|
-
private isValidCompletion;
|
|
25
24
|
private getCompletionDocument;
|
|
26
25
|
/**
|
|
27
26
|
* If the textEdit is out of the word range of the triggered position
|
|
@@ -78,26 +78,8 @@ class CompletionsProviderImpl {
|
|
|
78
78
|
scriptTagIndex = scriptIndex;
|
|
79
79
|
completions = lang.getCompletionsAtPosition(scriptFilePath, scriptOffset, {
|
|
80
80
|
...tsPreferences,
|
|
81
|
-
// File extensions are required inside script tags, however TypeScript can't return completions with the `ts`
|
|
82
|
-
// extension, so what we'll do instead is force `minimal` (aka, no extension) and manually add the extensions
|
|
83
|
-
importModuleSpecifierEnding: 'minimal',
|
|
84
81
|
triggerCharacter: validTriggerCharacter,
|
|
85
82
|
}, formatOptions);
|
|
86
|
-
if (completions) {
|
|
87
|
-
// Manually adds file extensions to js and ts files
|
|
88
|
-
completions.entries = completions?.entries.map((comp) => {
|
|
89
|
-
if (comp.kind === typescript_1.ScriptElementKind.scriptElement &&
|
|
90
|
-
(comp.kindModifiers === '.js' || comp.kindModifiers === '.ts')) {
|
|
91
|
-
return {
|
|
92
|
-
...comp,
|
|
93
|
-
name: comp.name + comp.kindModifiers,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
return comp;
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
83
|
}
|
|
102
84
|
else {
|
|
103
85
|
// PERF: Getting TS completions is fairly slow and I am currently not sure how to speed it up
|
|
@@ -132,7 +114,7 @@ class CompletionsProviderImpl {
|
|
|
132
114
|
const fragment = await tsDoc.createFragment();
|
|
133
115
|
const existingImports = this.getExistingImports(document);
|
|
134
116
|
const completionItems = completions.entries
|
|
135
|
-
.filter(
|
|
117
|
+
.filter(isValidCompletion)
|
|
136
118
|
.map((entry) => this.toCompletionItem(fragment, entry, filePath, offset, isCompletionInsideFrontmatter, scriptTagIndex, existingImports))
|
|
137
119
|
.filter(utils_3.isNotNullOrUndefined)
|
|
138
120
|
.map((comp) => this.fixTextEditRange(wordRangeStartPosition, comp));
|
|
@@ -250,13 +232,6 @@ class CompletionsProviderImpl {
|
|
|
250
232
|
},
|
|
251
233
|
};
|
|
252
234
|
}
|
|
253
|
-
isValidCompletion(completion) {
|
|
254
|
-
// Remove completion for default exported function
|
|
255
|
-
if (completion.name === 'default' && completion.kindModifiers == typescript_1.ScriptElementKindModifier.exportedModifier) {
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
return true;
|
|
259
|
-
}
|
|
260
235
|
getCompletionDocument(compDetail) {
|
|
261
236
|
const { sourceDisplay, documentation: tsDocumentation, displayParts } = compDetail;
|
|
262
237
|
let detail = (0, utils_2.removeAstroComponentSuffix)(typescript_1.default.displayPartsToString(displayParts));
|
|
@@ -355,3 +330,31 @@ function codeActionChangeToTextEdit(document, fragment, isInsideScriptTag, chang
|
|
|
355
330
|
return vscode_languageserver_1.TextEdit.replace(range, change.newText);
|
|
356
331
|
}
|
|
357
332
|
exports.codeActionChangeToTextEdit = codeActionChangeToTextEdit;
|
|
333
|
+
// When Svelte components are imported, we have to reference the svelte2tsx's types to properly type the component
|
|
334
|
+
// An unfortunate downside of this is that it polutes completions, so let's filter those internal types manually
|
|
335
|
+
const svelte2tsxTypes = new Set([
|
|
336
|
+
'Svelte2TsxComponent',
|
|
337
|
+
'Svelte2TsxComponentConstructorParameters',
|
|
338
|
+
'SvelteComponentConstructor',
|
|
339
|
+
'SvelteActionReturnType',
|
|
340
|
+
'SvelteTransitionConfig',
|
|
341
|
+
'SvelteTransitionReturnType',
|
|
342
|
+
'SvelteAnimationReturnType',
|
|
343
|
+
'SvelteWithOptionalProps',
|
|
344
|
+
'SvelteAllProps',
|
|
345
|
+
'SveltePropsAnyFallback',
|
|
346
|
+
'SvelteSlotsAnyFallback',
|
|
347
|
+
'SvelteRestProps',
|
|
348
|
+
'SvelteSlots',
|
|
349
|
+
'SvelteStore',
|
|
350
|
+
]);
|
|
351
|
+
function isValidCompletion(completion) {
|
|
352
|
+
// Remove completion for default exported function
|
|
353
|
+
const isDefaultExport = completion.name === 'default' && completion.kindModifiers == typescript_1.ScriptElementKindModifier.exportedModifier;
|
|
354
|
+
// Remove completion for svelte2tsx internal types
|
|
355
|
+
const isSvelte2tsxCompletion = completion.name.startsWith('__sveltets_') || svelte2tsxTypes.has(completion.name);
|
|
356
|
+
if (isDefaultExport || isSvelte2tsxCompletion) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
@@ -12,7 +12,6 @@ export declare enum DiagnosticCodes {
|
|
|
12
12
|
ISOLATED_MODULE_COMPILE_ERR = 1208,
|
|
13
13
|
TYPE_NOT_ASSIGNABLE = 2322,
|
|
14
14
|
JSX_NO_CLOSING_TAG = 17008,
|
|
15
|
-
NO_DECL_IMPLICIT_ANY_TYPE = 7016,
|
|
16
15
|
JSX_ELEMENT_NO_CALL = 2604
|
|
17
16
|
}
|
|
18
17
|
export declare class DiagnosticsProviderImpl implements DiagnosticsProvider {
|
|
@@ -20,7 +20,6 @@ var DiagnosticCodes;
|
|
|
20
20
|
DiagnosticCodes[DiagnosticCodes["ISOLATED_MODULE_COMPILE_ERR"] = 1208] = "ISOLATED_MODULE_COMPILE_ERR";
|
|
21
21
|
DiagnosticCodes[DiagnosticCodes["TYPE_NOT_ASSIGNABLE"] = 2322] = "TYPE_NOT_ASSIGNABLE";
|
|
22
22
|
DiagnosticCodes[DiagnosticCodes["JSX_NO_CLOSING_TAG"] = 17008] = "JSX_NO_CLOSING_TAG";
|
|
23
|
-
DiagnosticCodes[DiagnosticCodes["NO_DECL_IMPLICIT_ANY_TYPE"] = 7016] = "NO_DECL_IMPLICIT_ANY_TYPE";
|
|
24
23
|
DiagnosticCodes[DiagnosticCodes["JSX_ELEMENT_NO_CALL"] = 2604] = "JSX_ELEMENT_NO_CALL";
|
|
25
24
|
})(DiagnosticCodes = exports.DiagnosticCodes || (exports.DiagnosticCodes = {}));
|
|
26
25
|
class DiagnosticsProviderImpl {
|
|
@@ -87,7 +86,6 @@ class DiagnosticsProviderImpl {
|
|
|
87
86
|
isNoSpreadExpected(diag, document) &&
|
|
88
87
|
isNoCantReturnOutsideFunction(diag) &&
|
|
89
88
|
isNoIsolatedModuleError(diag) &&
|
|
90
|
-
isNoImportImplicitAnyType(diag) &&
|
|
91
89
|
isNoJsxCannotHaveMultipleAttrsError(diag));
|
|
92
90
|
})
|
|
93
91
|
.map(enhanceIfNecessary);
|
|
@@ -97,7 +95,6 @@ class DiagnosticsProviderImpl {
|
|
|
97
95
|
const sourceFile = program?.getSourceFile(tsFilePath);
|
|
98
96
|
const boundaries = {
|
|
99
97
|
script: [],
|
|
100
|
-
markdown: [],
|
|
101
98
|
};
|
|
102
99
|
if (!sourceFile) {
|
|
103
100
|
return boundaries;
|
|
@@ -112,10 +109,6 @@ class DiagnosticsProviderImpl {
|
|
|
112
109
|
boundaries.script.push([node.getStart(), node.getEnd()]);
|
|
113
110
|
break;
|
|
114
111
|
}
|
|
115
|
-
case 'Markdown': {
|
|
116
|
-
boundaries.markdown.push([node.getStart(), node.getEnd()]);
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
112
|
}
|
|
120
113
|
}
|
|
121
114
|
findTags(node);
|
|
@@ -173,9 +166,6 @@ function isNoJsxCannotHaveMultipleAttrsError(diagnostic) {
|
|
|
173
166
|
function isNoJSXMustHaveOneParent(diagnostic) {
|
|
174
167
|
return diagnostic.code !== DiagnosticCodes.MUST_HAVE_PARENT_ELEMENT;
|
|
175
168
|
}
|
|
176
|
-
function isNoImportImplicitAnyType(diagnostic) {
|
|
177
|
-
return diagnostic.code !== DiagnosticCodes.NO_DECL_IMPLICIT_ANY_TYPE;
|
|
178
|
-
}
|
|
179
169
|
/**
|
|
180
170
|
* When using the shorthand syntax for props TSX expects you to use the spread operator
|
|
181
171
|
* Since the shorthand syntax works differently in Astro and this is not required, hide this message
|
|
@@ -191,7 +181,7 @@ function isNoSpreadExpected(diagnostic, document) {
|
|
|
191
181
|
}
|
|
192
182
|
/**
|
|
193
183
|
* Ignore "Can't return outside of function body"
|
|
194
|
-
* Since the frontmatter is at the top level, users trying to return a Response
|
|
184
|
+
* Since the frontmatter is at the top level, users trying to return a Response for SSR mode run into this
|
|
195
185
|
*/
|
|
196
186
|
function isNoCantReturnOutsideFunction(diagnostic) {
|
|
197
187
|
return diagnostic.code !== DiagnosticCodes.CANT_RETURN_OUTSIDE_FUNC;
|
|
@@ -218,6 +208,7 @@ function enhanceIfNecessary(diagnostic) {
|
|
|
218
208
|
diagnostic.message +=
|
|
219
209
|
'\n\nIs the `@astrojs/vue` package installed? You can add it to your project by running the following command: `astro add vue`. If already installed, restarting the language server might be necessary in order for the change to take effect';
|
|
220
210
|
}
|
|
211
|
+
return diagnostic;
|
|
221
212
|
}
|
|
222
213
|
// JSX element has no closing tag. JSX -> HTML
|
|
223
214
|
if (diagnostic.code === DiagnosticCodes.JSX_NO_CLOSING_TAG) {
|
|
@@ -237,7 +228,7 @@ function enhanceIfNecessary(diagnostic) {
|
|
|
237
228
|
}
|
|
238
229
|
// For the rare case where an user might try to put a client directive on something that is not a component
|
|
239
230
|
if (diagnostic.code === DiagnosticCodes.TYPE_NOT_ASSIGNABLE) {
|
|
240
|
-
if (diagnostic.message.includes("Property 'client:") && diagnostic.message.includes("to type '
|
|
231
|
+
if (diagnostic.message.includes("Property 'client:") && diagnostic.message.includes("to type 'HTMLAttributes")) {
|
|
241
232
|
return {
|
|
242
233
|
...diagnostic,
|
|
243
234
|
message: 'Client directives are only available on framework components',
|
|
@@ -19,7 +19,7 @@ class FoldingRangesProviderImpl {
|
|
|
19
19
|
const node = html.findNodeAt(span.textSpan.start);
|
|
20
20
|
// Due to how our TSX output transform those tags into function calls or template literals
|
|
21
21
|
// TypeScript thinks of those as outlining spans, which is fine but we don't want folding ranges for those
|
|
22
|
-
return node.tag !== 'script' && node.tag !== 'style'
|
|
22
|
+
return node.tag !== 'script' && node.tag !== 'style';
|
|
23
23
|
});
|
|
24
24
|
const scriptOutliningSpans = [];
|
|
25
25
|
document.scriptTags.forEach((scriptTag) => {
|
|
@@ -80,6 +80,11 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
80
80
|
let projectVersion = 0;
|
|
81
81
|
const snapshotManager = new SnapshotManager_1.SnapshotManager(docContext.globalSnapshotManager, files, fullConfig, tsconfigRoot || process.cwd());
|
|
82
82
|
const astroModuleLoader = (0, module_loader_1.createAstroModuleLoader)(getScriptSnapshot, compilerOptions);
|
|
83
|
+
const scriptFileNames = [];
|
|
84
|
+
if (astroVersion.exist) {
|
|
85
|
+
const astroDir = (0, path_1.dirname)(require.resolve('astro', { paths: [workspacePath] }));
|
|
86
|
+
scriptFileNames.push(...['./env.d.ts', './astro-jsx.d.ts'].map((f) => typescript_1.default.sys.resolvePath((0, path_1.resolve)(astroDir, f))));
|
|
87
|
+
}
|
|
83
88
|
let languageServerDirectory;
|
|
84
89
|
try {
|
|
85
90
|
languageServerDirectory = (0, path_1.dirname)(require.resolve('@astrojs/language-server'));
|
|
@@ -87,10 +92,11 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
87
92
|
catch (e) {
|
|
88
93
|
languageServerDirectory = __dirname;
|
|
89
94
|
}
|
|
90
|
-
const scriptFileNames = [];
|
|
91
95
|
// Before Astro 1.0, JSX definitions were inside of the language-server instead of inside Astro
|
|
92
96
|
// TODO: Remove this and astro-jsx.d.ts in types when we consider having support for Astro < 1.0 unnecessary
|
|
93
|
-
if (astroVersion.major === 0 || astroVersion.full === '1.0.0-beta.0')
|
|
97
|
+
if ((astroVersion.major === 0 || astroVersion.full === '1.0.0-beta.0') &&
|
|
98
|
+
!astroVersion.full.startsWith('0.0.0-rc-') // 1.0.0's RC is considered to be 0.0.0, so we have to check for it
|
|
99
|
+
) {
|
|
94
100
|
const astroTSXFile = typescript_1.default.sys.resolvePath((0, path_1.resolve)(languageServerDirectory, '../types/astro-jsx.d.ts'));
|
|
95
101
|
scriptFileNames.push(astroTSXFile);
|
|
96
102
|
console.warn("Version lower than 1.0 detected, using internal types instead of Astro's");
|
|
@@ -220,18 +226,6 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
220
226
|
}
|
|
221
227
|
function getParsedTSConfig() {
|
|
222
228
|
let configJson = (tsconfigPath && typescript_1.default.readConfigFile(tsconfigPath, typescript_1.default.sys.readFile).config) || {};
|
|
223
|
-
// If our user has types in their config but it doesn't include the types needed for Astro, add them to the config
|
|
224
|
-
if (configJson.compilerOptions?.types) {
|
|
225
|
-
if (!configJson.compilerOptions?.types.includes('astro/env')) {
|
|
226
|
-
configJson.compilerOptions.types.push('astro/env');
|
|
227
|
-
}
|
|
228
|
-
if (astroVersion.major >= 1 &&
|
|
229
|
-
astroVersion.full !== '1.0.0-beta.0' &&
|
|
230
|
-
!configJson.compilerOptions?.types.includes('astro/astro-jsx')) {
|
|
231
|
-
configJson.compilerOptions.types.push('astro/astro-jsx');
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
configJson.compilerOptions = Object.assign(getDefaultCompilerOptions(astroVersion), configJson.compilerOptions);
|
|
235
229
|
// Delete include so that .astro files don't get mistakenly excluded by the user
|
|
236
230
|
delete configJson.include;
|
|
237
231
|
// If the user supplied exclude, let's use theirs otherwise, use ours
|
|
@@ -241,6 +235,7 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
241
235
|
noEmit: true,
|
|
242
236
|
declaration: false,
|
|
243
237
|
resolveJsonModule: true,
|
|
238
|
+
allowSyntheticDefaultImports: true,
|
|
244
239
|
allowNonTsExtensions: true,
|
|
245
240
|
allowJs: true,
|
|
246
241
|
jsx: typescript_1.default.JsxEmit.Preserve,
|
|
@@ -266,20 +261,6 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
266
261
|
};
|
|
267
262
|
}
|
|
268
263
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Default configuration used as a base and when the user doesn't have any
|
|
271
|
-
*/
|
|
272
|
-
function getDefaultCompilerOptions(astroVersion) {
|
|
273
|
-
const types = ['astro/env'];
|
|
274
|
-
if (astroVersion.major >= 1 && astroVersion.full !== '1.0.0-beta.0') {
|
|
275
|
-
types.push('astro/astro-jsx');
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
maxNodeModuleJsDepth: 2,
|
|
279
|
-
allowSyntheticDefaultImports: true,
|
|
280
|
-
types: types,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
264
|
function getDefaultExclude() {
|
|
284
265
|
return ['dist', 'node_modules'];
|
|
285
266
|
}
|
|
@@ -26,3 +26,4 @@ export declare function createFromTSFilePath(filePath: string): TypeScriptDocume
|
|
|
26
26
|
*/
|
|
27
27
|
export declare function createFromAstroFilePath(filePath: string, createDocument: (filePath: string, text: string) => AstroDocument): AstroSnapshot;
|
|
28
28
|
export declare function createFromFrameworkFilePath(filePath: string, framework: FrameworkExt): TypeScriptDocumentSnapshot;
|
|
29
|
+
export declare function classNameFromFilename(filename: string): string;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createFromFrameworkFilePath = exports.createFromAstroFilePath = exports.createFromTSFilePath = exports.createFromNonAstroFilePath = exports.createFromFilePath = exports.createFromDocument = void 0;
|
|
6
|
+
exports.classNameFromFilename = exports.createFromFrameworkFilePath = exports.createFromAstroFilePath = exports.createFromTSFilePath = exports.createFromNonAstroFilePath = exports.createFromFilePath = exports.createFromDocument = void 0;
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const astro2tsx_1 = __importDefault(require("../astro2tsx"));
|
|
9
9
|
const vscode_uri_1 = require("vscode-uri");
|
|
@@ -106,3 +106,4 @@ function classNameFromFilename(filename) {
|
|
|
106
106
|
const finalName = firstValidCharIdx === -1 ? `A${inPascalCase}` : inPascalCase;
|
|
107
107
|
return finalName;
|
|
108
108
|
}
|
|
109
|
+
exports.classNameFromFilename = classNameFromFilename;
|
package/dist/server.js
CHANGED
|
@@ -44,11 +44,17 @@ function startLanguageServer(connection) {
|
|
|
44
44
|
const documentManager = new DocumentManager_1.DocumentManager();
|
|
45
45
|
const pluginHost = new PluginHost_1.PluginHost(documentManager);
|
|
46
46
|
const configManager = new ConfigManager_1.ConfigManager(connection);
|
|
47
|
+
let typescriptPlugin = undefined;
|
|
47
48
|
let hasConfigurationCapability = false;
|
|
48
49
|
connection.onInitialize((params) => {
|
|
49
50
|
const workspaceUris = params.workspaceFolders?.map((folder) => folder.uri.toString()) ?? [params.rootUri ?? ''];
|
|
50
51
|
workspaceUris.forEach((uri) => {
|
|
51
52
|
uri = (0, utils_1.urlToPath)(uri);
|
|
53
|
+
// If the workspace is not an Astro project, we shouldn't warn about not finding Astro
|
|
54
|
+
// Unless the extension enabled itself in an untitled workspace, in which case the warning is valid
|
|
55
|
+
if (!(0, utils_1.isAstroWorkspace)(uri) && uri !== '/' && uri !== '') {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
52
58
|
const astroVersion = (0, utils_1.getUserAstroVersion)(uri);
|
|
53
59
|
if (astroVersion.exist === false) {
|
|
54
60
|
connection.sendNotification(vscode_languageserver_1.ShowMessageNotification.type, {
|
|
@@ -56,12 +62,6 @@ function startLanguageServer(connection) {
|
|
|
56
62
|
type: vscode_languageserver_1.MessageType.Warning,
|
|
57
63
|
});
|
|
58
64
|
}
|
|
59
|
-
if (astroVersion.exist && astroVersion.major === 0 && astroVersion.minor < 24 && astroVersion.patch < 5) {
|
|
60
|
-
connection.sendNotification(vscode_languageserver_1.ShowMessageNotification.type, {
|
|
61
|
-
message: `The version of Astro you're using (${astroVersion.full}) is not supported by this version of the Astro language server. Please upgrade Astro to any version higher than 0.23.4 or if using the VS Code extension, downgrade the extension to 0.8.10`,
|
|
62
|
-
type: vscode_languageserver_1.MessageType.Error,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
65
|
});
|
|
66
66
|
hasConfigurationCapability = !!(params.capabilities.workspace && !!params.capabilities.workspace.configuration);
|
|
67
67
|
pluginHost.initialize({
|
|
@@ -73,8 +73,9 @@ function startLanguageServer(connection) {
|
|
|
73
73
|
pluginHost.registerPlugin(new CSSPlugin_1.CSSPlugin(configManager));
|
|
74
74
|
// We don't currently support running the TypeScript and Astro plugin in the browser
|
|
75
75
|
if (params.initializationOptions.environment !== 'browser') {
|
|
76
|
+
typescriptPlugin = new plugins_1.TypeScriptPlugin(documentManager, configManager, workspaceUris);
|
|
76
77
|
pluginHost.registerPlugin(new AstroPlugin_1.AstroPlugin(documentManager, configManager, workspaceUris));
|
|
77
|
-
pluginHost.registerPlugin(
|
|
78
|
+
pluginHost.registerPlugin(typescriptPlugin);
|
|
78
79
|
}
|
|
79
80
|
return {
|
|
80
81
|
capabilities: {
|
|
@@ -213,6 +214,16 @@ function startLanguageServer(connection) {
|
|
|
213
214
|
}
|
|
214
215
|
updateAllDiagnostics();
|
|
215
216
|
});
|
|
217
|
+
connection.onRequest('$/getTSXOutput', async (uri) => {
|
|
218
|
+
const doc = documentManager.get(uri);
|
|
219
|
+
if (!doc) {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
if (doc) {
|
|
223
|
+
const tsxOutput = typescriptPlugin.getTSXForDocument(doc);
|
|
224
|
+
return tsxOutput.code;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
216
227
|
documentManager.on('documentChange', (0, utils_1.debounceThrottle)(async (document) => diagnosticsManager.update(document), 1000));
|
|
217
228
|
documentManager.on('documentClose', (document) => {
|
|
218
229
|
diagnosticsManager.removeDiagnostics(document);
|
package/dist/utils.d.ts
CHANGED
|
@@ -65,6 +65,10 @@ export declare function debounceSameArg<T>(fn: (arg: T) => void, shouldCancelPre
|
|
|
65
65
|
* @param milliseconds Number of milliseconds to debounce/throttle
|
|
66
66
|
*/
|
|
67
67
|
export declare function debounceThrottle<T extends (...args: any) => void>(fn: T, milliseconds: number): T;
|
|
68
|
+
/**
|
|
69
|
+
* Try to determine if a workspace could be an Astro project based on the content of `package.json`
|
|
70
|
+
*/
|
|
71
|
+
export declare function isAstroWorkspace(workspacePath: string): boolean;
|
|
68
72
|
export interface AstroVersion {
|
|
69
73
|
full: string;
|
|
70
74
|
major: number;
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getUserAstroVersion = exports.debounceThrottle = exports.debounceSameArg = exports.getRegExpMatches = exports.regexLastIndexOf = exports.isBeforeOrEqualToPosition = exports.isInRange = exports.isNotNullOrUndefined = exports.clamp = exports.modifyLines = exports.toPascalCase = exports.mergeDeep = exports.get = exports.getLastPartOfPath = exports.pathToUrl = exports.urlToPath = exports.normalizePath = exports.normalizeUri = void 0;
|
|
3
|
+
exports.getUserAstroVersion = exports.isAstroWorkspace = exports.debounceThrottle = exports.debounceSameArg = exports.getRegExpMatches = exports.regexLastIndexOf = exports.isBeforeOrEqualToPosition = exports.isInRange = exports.isNotNullOrUndefined = exports.clamp = exports.modifyLines = exports.toPascalCase = exports.mergeDeep = exports.get = exports.getLastPartOfPath = exports.pathToUrl = exports.urlToPath = exports.normalizePath = exports.normalizeUri = void 0;
|
|
4
4
|
const vscode_uri_1 = require("vscode-uri");
|
|
5
5
|
/** Normalizes a document URI */
|
|
6
6
|
function normalizeUri(uri) {
|
|
@@ -197,6 +197,23 @@ function debounceThrottle(fn, milliseconds) {
|
|
|
197
197
|
return maybeCall;
|
|
198
198
|
}
|
|
199
199
|
exports.debounceThrottle = debounceThrottle;
|
|
200
|
+
/**
|
|
201
|
+
* Try to determine if a workspace could be an Astro project based on the content of `package.json`
|
|
202
|
+
*/
|
|
203
|
+
function isAstroWorkspace(workspacePath) {
|
|
204
|
+
try {
|
|
205
|
+
const astroPackageJson = require.resolve('./package.json', { paths: [workspacePath] });
|
|
206
|
+
const deps = Object.assign(require(astroPackageJson).dependencies ?? {}, require(astroPackageJson).devDependencies ?? {});
|
|
207
|
+
if (Object.keys(deps).includes('astro')) {
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (e) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
exports.isAstroWorkspace = isAstroWorkspace;
|
|
200
217
|
function getUserAstroVersion(basePath) {
|
|
201
218
|
let version = '0.0.0';
|
|
202
219
|
let exist = true;
|
|
@@ -213,7 +230,7 @@ function getUserAstroVersion(basePath) {
|
|
|
213
230
|
catch (e) {
|
|
214
231
|
// If we still couldn't find it, it probably just doesn't exist
|
|
215
232
|
exist = false;
|
|
216
|
-
console.error(
|
|
233
|
+
console.error(`${basePath} seems to be an Astro project, but we couldn't find Astro or Astro is not installed`);
|
|
217
234
|
}
|
|
218
235
|
}
|
|
219
236
|
let [major, minor, patch] = version.split('.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/language-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"author": "withastro",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"vscode-uri": "^3.0.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@astrojs/svelte": "^0.
|
|
35
|
-
"@astrojs/vue": "^0.
|
|
34
|
+
"@astrojs/svelte": "^0.5.0",
|
|
35
|
+
"@astrojs/vue": "^0.5.0",
|
|
36
36
|
"@types/chai": "^4.3.0",
|
|
37
37
|
"@types/mocha": "^9.1.0",
|
|
38
38
|
"@types/sinon": "^10.0.11",
|
|
39
|
-
"astro": "^1.0.0-beta.
|
|
39
|
+
"astro": "^1.0.0-beta.72",
|
|
40
40
|
"astro-scripts": "0.0.1",
|
|
41
41
|
"chai": "^4.3.6",
|
|
42
42
|
"cross-env": "^7.0.3",
|