@astrojs/language-server 2.0.14 → 2.0.16

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 CHANGED
@@ -32,10 +32,10 @@ const fast_glob_1 = __importDefault(require("fast-glob"));
32
32
  const node_url_1 = require("node:url");
33
33
  const index_js_1 = require("./core/index.js");
34
34
  const svelte_js_1 = require("./core/svelte.js");
35
- const utils_js_1 = require("./core/utils.js");
36
35
  const vue_js_1 = require("./core/vue.js");
37
36
  const astro_js_1 = __importDefault(require("./plugins/astro.js"));
38
37
  const index_js_2 = __importDefault(require("./plugins/typescript/index.js"));
38
+ const utils_js_1 = require("./utils.js");
39
39
  // Export those for downstream consumers
40
40
  var language_server_1 = require("@volar/language-server");
41
41
  Object.defineProperty(exports, "DiagnosticSeverity", { enumerable: true, get: function () { return language_server_1.DiagnosticSeverity; } });
@@ -54,9 +54,7 @@ class AstroCheck {
54
54
  async lint(fileNames = undefined, logErrors = false) {
55
55
  const files = fileNames !== undefined
56
56
  ? fileNames
57
- : this.project.languageServiceHost
58
- .getScriptFileNames()
59
- .filter((file) => file.endsWith('.astro'));
57
+ : this.project.languageHost.getScriptFileNames().filter((file) => file.endsWith('.astro'));
60
58
  const errors = [];
61
59
  for (const file of files) {
62
60
  const fileErrors = await this.linter.check(file);
@@ -64,7 +62,7 @@ class AstroCheck {
64
62
  this.linter.logErrors(file, fileErrors);
65
63
  }
66
64
  if (fileErrors.length > 0) {
67
- const fileSnapshot = this.project.languageServiceHost.getScriptSnapshot(file);
65
+ const fileSnapshot = this.project.languageHost.getScriptSnapshot(file);
68
66
  const fileContent = fileSnapshot?.getText(0, fileSnapshot.getLength());
69
67
  errors.push({
70
68
  errors: fileErrors,
@@ -105,7 +103,7 @@ class AstroCheck {
105
103
  });
106
104
  });
107
105
  }
108
- this.linter = kit.createLinter(config, this.project.languageServiceHost);
106
+ this.linter = kit.createLinter(config, this.project.languageHost);
109
107
  }
110
108
  getTsconfig() {
111
109
  const tsconfig = this.ts.findConfigFile(this.workspacePath, this.ts.sys.fileExists) ||
@@ -0,0 +1,11 @@
1
+ import type { AttributeNode, Point } from '@astrojs/compiler';
2
+ import { Position as LSPPosition } from '@volar/language-server';
3
+ /**
4
+ * Transform a Point from the Astro compiler to an LSP Position
5
+ */
6
+ export declare function PointToPosition(point: Point): LSPPosition;
7
+ type WithRequired<T, K extends keyof T> = T & {
8
+ [P in K]-?: T[P];
9
+ };
10
+ export type AttributeNodeWithPosition = WithRequired<AttributeNode, 'position'>;
11
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PointToPosition = void 0;
4
+ const language_server_1 = require("@volar/language-server");
5
+ /**
6
+ * Transform a Point from the Astro compiler to an LSP Position
7
+ */
8
+ function PointToPosition(point) {
9
+ // Columns and lines are 0-based in LSP, but the compiler's Point are 1 based.
10
+ return language_server_1.Position.create(point.line - 1, point.column - 1);
11
+ }
12
+ exports.PointToPosition = PointToPosition;
13
+ //# sourceMappingURL=compilerUtils.js.map
@@ -2,8 +2,8 @@ import type { DiagnosticMessage, ParseResult } from '@astrojs/compiler/types';
2
2
  import { FileCapabilities, FileKind, type Language, type VirtualFile } from '@volar/language-core';
3
3
  import type ts from 'typescript/lib/tsserverlibrary';
4
4
  import type { HTMLDocument } from 'vscode-html-languageservice';
5
+ import type { AstroInstall } from '../utils.js';
5
6
  import { FrontmatterStatus } from './parseAstro';
6
- import type { AstroInstall } from './utils';
7
7
  export declare function getLanguageModule(astroInstall: AstroInstall | undefined, ts: typeof import('typescript/lib/tsserverlibrary.js')): Language<AstroFile>;
8
8
  export declare class AstroFile implements VirtualFile {
9
9
  sourceFileName: string;
@@ -2,7 +2,7 @@ import type { ParseResult } from '@astrojs/compiler/types';
2
2
  import { VirtualFile } from '@volar/language-core';
3
3
  import type ts from 'typescript/lib/tsserverlibrary';
4
4
  import type { HTMLDocument } from 'vscode-html-languageservice';
5
- import type { AttributeNodeWithPosition } from '../utils.js';
5
+ import type { AttributeNodeWithPosition } from './compilerUtils.js';
6
6
  export declare function extractStylesheets(fileName: string, snapshot: ts.IScriptSnapshot, htmlDocument: HTMLDocument, ast: ParseResult['ast']): VirtualFile[];
7
7
  export declare function collectClassesAndIdsFromDocument(ast: ParseResult['ast']): string[];
8
8
  export declare function findInlineStyles(ast: ParseResult['ast']): AttributeNodeWithPosition[];
@@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.preprocessHTML = exports.parseHTML = void 0;
27
27
  const language_core_1 = require("@volar/language-core");
28
28
  const html = __importStar(require("vscode-html-languageservice"));
29
- const utils_1 = require("../utils");
29
+ const utils_1 = require("../plugins/utils");
30
30
  const htmlLs = html.getLanguageService();
31
31
  function parseHTML(fileName, snapshot, frontmatterEnd) {
32
32
  const htmlContent = preprocessHTML(snapshot.getText(0, snapshot.getLength()), frontmatterEnd);
@@ -1,14 +1,4 @@
1
1
  import { type VirtualFile } from '@volar/language-core';
2
- export interface AstroInstall {
3
- path: string;
4
- version: {
5
- full: string;
6
- major: number;
7
- minor: number;
8
- patch: number;
9
- };
10
- }
11
- export declare function getAstroInstall(basePaths: string[]): AstroInstall | undefined;
12
2
  export declare function framework2tsx(fileName: string, filePath: string, sourceCode: string, framework: 'vue' | 'svelte'): VirtualFile;
13
3
  export declare function classNameFromFilename(filename: string): string;
14
4
  export declare function patchTSX(code: string, fileName: string): string;
@@ -23,52 +23,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.patchTSX = exports.classNameFromFilename = exports.framework2tsx = exports.getAstroInstall = void 0;
26
+ exports.patchTSX = exports.classNameFromFilename = exports.framework2tsx = void 0;
27
27
  const language_core_1 = require("@volar/language-core");
28
28
  const path = __importStar(require("node:path"));
29
29
  const vscode_uri_1 = require("vscode-uri");
30
30
  const importPackage_1 = require("../importPackage");
31
- function getAstroInstall(basePaths) {
32
- let astroPath;
33
- let version;
34
- try {
35
- astroPath = (0, importPackage_1.getPackagePath)('astro', basePaths);
36
- if (!astroPath) {
37
- throw Error;
38
- }
39
- version = require(path.resolve(astroPath, 'package.json')).version;
40
- }
41
- catch {
42
- // If we couldn't find it inside the workspace's node_modules, it might means we're in the monorepo
43
- try {
44
- astroPath = (0, importPackage_1.getPackagePath)('./packages/astro', basePaths);
45
- if (!astroPath) {
46
- throw Error;
47
- }
48
- version = require(path.resolve(astroPath, 'package.json')).version;
49
- }
50
- catch (e) {
51
- // If we still couldn't find it, it probably just doesn't exist
52
- console.error(`${basePaths[0]} seems to be an Astro project, but we couldn't find Astro or Astro is not installed`);
53
- return undefined;
54
- }
55
- }
56
- let [major, minor, patch] = version.split('.');
57
- if (patch.includes('-')) {
58
- const patchParts = patch.split('-');
59
- patch = patchParts[0];
60
- }
61
- return {
62
- path: astroPath,
63
- version: {
64
- full: version,
65
- major: Number(major),
66
- minor: Number(minor),
67
- patch: Number(patch),
68
- },
69
- };
70
- }
71
- exports.getAstroInstall = getAstroInstall;
72
31
  function framework2tsx(fileName, filePath, sourceCode, framework) {
73
32
  const integrationEditorEntrypoint = framework === 'vue' ? (0, importPackage_1.importVueIntegration)(filePath) : (0, importPackage_1.importSvelteIntegration)(filePath);
74
33
  if (!integrationEditorEntrypoint) {
@@ -134,7 +93,15 @@ exports.classNameFromFilename = classNameFromFilename;
134
93
  function patchTSX(code, fileName) {
135
94
  const basename = path.basename(fileName, path.extname(fileName));
136
95
  const isDynamic = basename.startsWith('[') && basename.endsWith(']');
137
- return code.replace(/\b(\S*)__AstroComponent_/, (_, m1) => isDynamic ? `_${m1}_` : m1[0].toUpperCase() + m1.slice(1));
96
+ return code.replace(/\b(\S*)__AstroComponent_/gm, (fullMatch, m1) => {
97
+ // 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
98
+ if (!m1) {
99
+ if (basename === '404')
100
+ return 'FourOhFour';
101
+ return fullMatch;
102
+ }
103
+ return isDynamic ? `_${m1}_` : m1[0].toUpperCase() + m1.slice(1);
104
+ });
138
105
  }
139
106
  exports.patchTSX = patchTSX;
140
107
  //# sourceMappingURL=utils.js.map
@@ -7,3 +7,4 @@ export declare function importSvelteIntegration(fromPath: string): typeof svelte
7
7
  export declare function importVueIntegration(fromPath: string): typeof vue | undefined;
8
8
  export declare function importPrettier(fromPath: string): typeof prettier | undefined;
9
9
  export declare function getPrettierPluginPath(fromPath: string): string | undefined;
10
+ export declare function getWorkspacePnpPath(workspacePath: string): string | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPrettierPluginPath = exports.importPrettier = exports.importVueIntegration = exports.importSvelteIntegration = exports.getPackagePath = exports.setIsTrusted = void 0;
3
+ exports.getWorkspacePnpPath = exports.getPrettierPluginPath = exports.importPrettier = exports.importVueIntegration = exports.importSvelteIntegration = exports.getPackagePath = exports.setIsTrusted = void 0;
4
4
  const node_path_1 = require("node:path");
5
5
  let isTrusted = true;
6
6
  function setIsTrusted(_isTrusted) {
@@ -58,4 +58,15 @@ function getPrettierPluginPath(fromPath) {
58
58
  return prettierPluginPath;
59
59
  }
60
60
  exports.getPrettierPluginPath = getPrettierPluginPath;
61
+ function getWorkspacePnpPath(workspacePath) {
62
+ try {
63
+ const possiblePath = (0, node_path_1.resolve)(workspacePath, '.pnp.cjs');
64
+ require.resolve(possiblePath);
65
+ return possiblePath;
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ exports.getWorkspacePnpPath = getWorkspacePnpPath;
61
72
  //# sourceMappingURL=importPackage.js.map
@@ -11,12 +11,12 @@ const volar_service_prettier_1 = __importDefault(require("volar-service-prettier
11
11
  const volar_service_typescript_twoslash_queries_1 = __importDefault(require("volar-service-typescript-twoslash-queries"));
12
12
  const core_1 = require("./core");
13
13
  const svelte_js_1 = require("./core/svelte.js");
14
- const utils_1 = require("./core/utils");
15
14
  const vue_js_1 = require("./core/vue.js");
16
15
  const importPackage_js_1 = require("./importPackage.js");
17
16
  const astro_js_1 = __importDefault(require("./plugins/astro.js"));
18
17
  const html_js_1 = __importDefault(require("./plugins/html.js"));
19
18
  const index_js_1 = __importDefault(require("./plugins/typescript/index.js"));
19
+ const utils_js_1 = require("./utils.js");
20
20
  const plugin = (initOptions, modules) => ({
21
21
  extraFileExtensions: [
22
22
  { extension: 'astro', isMixedContent: true, scriptKind: 7 },
@@ -40,7 +40,7 @@ const plugin = (initOptions, modules) => ({
40
40
  resolveConfig(config, ctx) {
41
41
  config.languages ??= {};
42
42
  if (ctx) {
43
- const astroInstall = (0, utils_1.getAstroInstall)([ctx.project.rootUri.fsPath]);
43
+ const astroInstall = (0, utils_js_1.getAstroInstall)([ctx.project.rootUri.fsPath]);
44
44
  if (!astroInstall) {
45
45
  ctx.server.connection.sendNotification(node_1.ShowMessageNotification.type, {
46
46
  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.`,
@@ -7,7 +7,7 @@ const language_server_1 = require("@volar/language-server");
7
7
  const fast_glob_1 = __importDefault(require("fast-glob"));
8
8
  const node_path_1 = require("node:path");
9
9
  const index_js_1 = require("../core/index.js");
10
- const utils_js_1 = require("../utils.js");
10
+ const utils_js_1 = require("./utils.js");
11
11
  exports.default = () => (context, modules) => {
12
12
  return {
13
13
  triggerCharacters: ['-'],
@@ -48,10 +48,13 @@ exports.default = () => (context, modules) => {
48
48
  provideCodeLenses(document, token) {
49
49
  if (token.isCancellationRequested)
50
50
  return;
51
- if (!modules?.typescript || !context?.typescript || !(0, utils_js_1.isJSDocument)(document.languageId))
51
+ if (!context || !modules?.typescript || !(0, utils_js_1.isJSDocument)(document.languageId))
52
+ return;
53
+ const languageService = context.inject('typescript/languageService');
54
+ if (!languageService)
52
55
  return;
53
56
  const ts = modules?.typescript;
54
- const tsProgram = context.typescript.languageService.getProgram();
57
+ const tsProgram = languageService.getProgram();
55
58
  if (!tsProgram)
56
59
  return;
57
60
  const globcodeLens = [];
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const language_server_1 = require("@volar/language-server");
7
7
  const volar_service_html_1 = __importDefault(require("volar-service-html"));
8
8
  const index_js_1 = require("../core/index.js");
9
- const utils_js_1 = require("../utils.js");
10
9
  const html_data_js_1 = require("./html-data.js");
10
+ const utils_js_1 = require("./utils.js");
11
11
  exports.default = () => (context, modules) => {
12
12
  const htmlPlugin = (0, volar_service_html_1.default)()(context, modules);
13
13
  if (!context) {
@@ -1,3 +1,3 @@
1
- import { CompletionItem, CompletionList, ServiceContext } from '@volar/language-server';
1
+ import { CompletionItem, CompletionList } from '@volar/language-server';
2
2
  export declare function enhancedProvideCompletionItems(completions: CompletionList): CompletionList;
3
- export declare function enhancedResolveCompletionItem(resolvedCompletion: CompletionItem, originalItem: CompletionItem, context: ServiceContext): CompletionItem;
3
+ export declare function enhancedResolveCompletionItem(resolvedCompletion: CompletionItem): CompletionItem;
@@ -2,8 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enhancedResolveCompletionItem = exports.enhancedProvideCompletionItems = void 0;
4
4
  const language_server_1 = require("@volar/language-server");
5
- const index_js_1 = require("../../core/index.js");
6
- const utils_js_1 = require("../../utils.js");
7
5
  function enhancedProvideCompletionItems(completions) {
8
6
  completions.items = completions.items.filter(isValidCompletion).map((completion) => {
9
7
  const source = completion?.data?.originalItem?.source;
@@ -21,35 +19,11 @@ function enhancedProvideCompletionItems(completions) {
21
19
  return completions;
22
20
  }
23
21
  exports.enhancedProvideCompletionItems = enhancedProvideCompletionItems;
24
- function enhancedResolveCompletionItem(resolvedCompletion, originalItem, context) {
22
+ function enhancedResolveCompletionItem(resolvedCompletion) {
25
23
  // Make sure we keep our icons even when the completion is resolved
26
24
  if (resolvedCompletion.data.isComponent) {
27
25
  resolvedCompletion.detail = getDetailForFileCompletion(resolvedCompletion.detail ?? '', resolvedCompletion.data.originalItem.source);
28
26
  }
29
- // Properly handle completions with actions to make sure their edits end up in the frontmatter when needed
30
- const [_, source] = context.documents.getVirtualFileByUri(originalItem.data.uri);
31
- const file = source?.root;
32
- if (!(file instanceof index_js_1.AstroFile) || !context.host)
33
- return resolvedCompletion;
34
- if (file.scriptFiles.includes(originalItem.data.fileName))
35
- return resolvedCompletion;
36
- const newLine = context.host.getNewLine ? context.host.getNewLine() : '\n';
37
- resolvedCompletion.additionalTextEdits = resolvedCompletion.additionalTextEdits?.map((edit) => {
38
- // HACK: There's a weird situation sometimes where some components (especially Svelte) will get imported as type imports
39
- // for some unknown reason. This work around the problem by always ensuring a normal import for components
40
- if (resolvedCompletion.data.isComponent && edit.newText.includes('import type')) {
41
- edit.newText.replace('import type', 'import');
42
- }
43
- // Return a different edit depending on the state of the formatter
44
- if (file.astroMeta.frontmatter.status === 'doesnt-exist') {
45
- return (0, utils_js_1.getNewFrontmatterEdit)(edit, newLine);
46
- }
47
- if (file.astroMeta.frontmatter.status === 'open') {
48
- return (0, utils_js_1.getOpenFrontmatterEdit)(edit, newLine);
49
- }
50
- edit.range = (0, utils_js_1.ensureRangeIsInFrontmatter)(edit.range, file.astroMeta.frontmatter);
51
- return edit;
52
- });
53
27
  return resolvedCompletion;
54
28
  }
55
29
  exports.enhancedResolveCompletionItem = enhancedResolveCompletionItem;
@@ -13,7 +13,7 @@ var DiagnosticCodes;
13
13
  DiagnosticCodes[DiagnosticCodes["TYPE_NOT_ASSIGNABLE"] = 2322] = "TYPE_NOT_ASSIGNABLE";
14
14
  DiagnosticCodes[DiagnosticCodes["JSX_NO_CLOSING_TAG"] = 17008] = "JSX_NO_CLOSING_TAG";
15
15
  DiagnosticCodes[DiagnosticCodes["JSX_ELEMENT_NO_CALL"] = 2604] = "JSX_ELEMENT_NO_CALL";
16
- })(DiagnosticCodes = exports.DiagnosticCodes || (exports.DiagnosticCodes = {}));
16
+ })(DiagnosticCodes || (exports.DiagnosticCodes = DiagnosticCodes = {}));
17
17
  function enhancedProvideSemanticDiagnostics(originalDiagnostics, documentLineCount) {
18
18
  const diagnostics = originalDiagnostics
19
19
  .filter((diagnostic) => diagnostic.range.start.line <= documentLineCount &&
@@ -1,3 +1,3 @@
1
- import type { Service } from '@volar/language-service';
1
+ import { Service } from '@volar/language-server';
2
2
  declare const _default: () => Service;
3
3
  export default _default;
@@ -3,9 +3,10 @@ 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
+ const language_server_1 = require("@volar/language-server");
6
7
  const volar_service_typescript_1 = __importDefault(require("volar-service-typescript"));
7
8
  const index_js_1 = require("../../core/index.js");
8
- const codeActions_js_1 = require("./codeActions.js");
9
+ const utils_js_1 = require("../utils.js");
9
10
  const completions_js_1 = require("./completions.js");
10
11
  const diagnostics_js_1 = require("./diagnostics.js");
11
12
  exports.default = () => (context, modules) => {
@@ -19,6 +20,82 @@ exports.default = () => (context, modules) => {
19
20
  }
20
21
  return {
21
22
  ...typeScriptPlugin,
23
+ transformCompletionItem(item) {
24
+ const [_, source] = context.documents.getVirtualFileByUri(item.data.uri);
25
+ const file = source?.root;
26
+ if (!(file instanceof index_js_1.AstroFile) || !context.host)
27
+ return undefined;
28
+ if (file.scriptFiles.includes(item.data.fileName))
29
+ return undefined;
30
+ const newLine = context.host.getCompilationSettings().newLine?.toString() ?? '\n';
31
+ if (item.additionalTextEdits) {
32
+ item.additionalTextEdits = item.additionalTextEdits.map((edit) => {
33
+ // HACK: There's a weird situation sometimes where some components (especially Svelte) will get imported as type imports
34
+ // for some unknown reason. This work around the problem by always ensuring a normal import for components
35
+ if (item.data.isComponent && edit.newText.includes('import type')) {
36
+ edit.newText.replace('import type', 'import');
37
+ }
38
+ if ((0, utils_js_1.editShouldBeInFrontmatter)(edit.range)) {
39
+ return (0, utils_js_1.ensureProperEditForFrontmatter)(edit, file.astroMeta.frontmatter, newLine);
40
+ }
41
+ return edit;
42
+ });
43
+ }
44
+ return item;
45
+ },
46
+ transformCodeAction(item) {
47
+ if (item.kind !== 'quickfix')
48
+ return undefined;
49
+ const originalFileName = item.data.uri.replace('.tsx', '');
50
+ const [_, source] = context.documents.getVirtualFileByUri(originalFileName);
51
+ const file = source?.root;
52
+ if (!(file instanceof index_js_1.AstroFile) || !context.host)
53
+ return undefined;
54
+ if (file.scriptFiles.includes(item.diagnostics?.[0].data.documentUri.replace('file://', '')))
55
+ return undefined;
56
+ const document = context.getTextDocument(originalFileName);
57
+ if (!document)
58
+ return undefined;
59
+ const newLine = context.host.getCompilationSettings().newLine?.toString() ?? '\n';
60
+ if (!item.edit?.documentChanges)
61
+ return undefined;
62
+ item.edit.documentChanges = item.edit.documentChanges.map((change) => {
63
+ if (language_server_1.TextDocumentEdit.is(change)) {
64
+ change.textDocument.uri = originalFileName;
65
+ if (change.edits.length === 1) {
66
+ change.edits = change.edits.map((edit) => {
67
+ const editInFrontmatter = (0, utils_js_1.editShouldBeInFrontmatter)(edit.range, document);
68
+ if (editInFrontmatter.itShould) {
69
+ return (0, utils_js_1.ensureProperEditForFrontmatter)(edit, file.astroMeta.frontmatter, newLine, editInFrontmatter.position);
70
+ }
71
+ return edit;
72
+ });
73
+ }
74
+ else {
75
+ if (file.astroMeta.frontmatter.status === 'closed') {
76
+ change.edits = change.edits.map((edit) => {
77
+ const editInFrontmatter = (0, utils_js_1.editShouldBeInFrontmatter)(edit.range, document);
78
+ if (editInFrontmatter.itShould) {
79
+ edit.range = (0, utils_js_1.ensureRangeIsInFrontmatter)(edit.range, file.astroMeta.frontmatter, editInFrontmatter.position);
80
+ }
81
+ return edit;
82
+ });
83
+ }
84
+ else {
85
+ // TODO: Handle when there's multiple edits and a new frontmatter is potentially needed
86
+ if (change.edits.some((edit) => {
87
+ return (0, utils_js_1.editShouldBeInFrontmatter)(edit.range, document).itShould;
88
+ })) {
89
+ console.error('Code actions with multiple edits that require potentially creating a frontmatter are currently not implemented. In the meantime, please manually insert a frontmatter in your file before using this code action.');
90
+ change.edits = [];
91
+ }
92
+ }
93
+ }
94
+ }
95
+ return change;
96
+ });
97
+ return item;
98
+ },
22
99
  async provideCompletionItems(document, position, completionContext, token) {
23
100
  const originalCompletions = await typeScriptPlugin.provideCompletionItems(document, position, completionContext, token);
24
101
  if (!originalCompletions)
@@ -29,18 +106,7 @@ exports.default = () => (context, modules) => {
29
106
  const resolvedCompletionItem = await typeScriptPlugin.resolveCompletionItem(item, token);
30
107
  if (!resolvedCompletionItem)
31
108
  return item;
32
- return (0, completions_js_1.enhancedResolveCompletionItem)(resolvedCompletionItem, item, context);
33
- },
34
- async provideCodeActions(document, range, codeActionContext, token) {
35
- const codeActions = await typeScriptPlugin.provideCodeActions(document, range, codeActionContext, token);
36
- if (!codeActions)
37
- return null;
38
- const [_, source] = context.documents.getVirtualFileByUri(document.uri);
39
- const file = source?.root;
40
- if (!(file instanceof index_js_1.AstroFile) || !context.host)
41
- return codeActions;
42
- const newLine = context.host.getNewLine ? context.host.getNewLine() : '\n';
43
- return (0, codeActions_js_1.enhancedProvideCodeActions)(codeActions, file, context.documents.getDocumentByFileName(file.snapshot, file.sourceFileName), document, newLine);
109
+ return (0, completions_js_1.enhancedResolveCompletionItem)(resolvedCompletionItem);
44
110
  },
45
111
  async provideSemanticDiagnostics(document, token) {
46
112
  const [_, source] = context.documents.getVirtualFileByUri(document.uri);
@@ -0,0 +1,37 @@
1
+ import { HTMLDocument, Node, Range, TextDocument, TextEdit } from 'vscode-html-languageservice';
2
+ import type { FrontmatterStatus } from '../core/parseAstro.js';
3
+ export declare function isJSDocument(languageId: string): boolean;
4
+ /**
5
+ * Return true if a specific node could be a component.
6
+ * 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
7
+ */
8
+ export declare function isPossibleComponent(node: Node): boolean;
9
+ /**
10
+ * Return if a given offset is inside the start tag of a component
11
+ */
12
+ export declare function isInComponentStartTag(html: HTMLDocument, offset: number): boolean;
13
+ /**
14
+ * Return if a given position is inside a JSX expression
15
+ */
16
+ export declare function isInsideExpression(html: string, tagStart: number, position: number): boolean;
17
+ /**
18
+ * Return if a given offset is inside the frontmatter
19
+ */
20
+ export declare function isInsideFrontmatter(offset: number, frontmatter: FrontmatterStatus): boolean;
21
+ type FrontmatterEditPosition = 'top' | 'bottom';
22
+ export declare function ensureProperEditForFrontmatter(edit: TextEdit, frontmatter: FrontmatterStatus, newLine: string, position?: FrontmatterEditPosition): TextEdit;
23
+ /**
24
+ * Force a range to be at the start of the frontmatter if it is outside
25
+ */
26
+ export declare function ensureRangeIsInFrontmatter(range: Range, frontmatter: FrontmatterStatus, position?: FrontmatterEditPosition): Range;
27
+ export declare function getNewFrontmatterEdit(edit: TextEdit, newLine: string): TextEdit;
28
+ export declare function getOpenFrontmatterEdit(edit: TextEdit, newLine: string): TextEdit;
29
+ type FrontmatterEditValidity = {
30
+ itShould: false;
31
+ position: undefined;
32
+ } | {
33
+ itShould: true;
34
+ position: FrontmatterEditPosition;
35
+ };
36
+ export declare function editShouldBeInFrontmatter(range: Range, astroDocument?: TextDocument): FrontmatterEditValidity;
37
+ export {};
@@ -0,0 +1,115 @@
1
+ "use strict";
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;
4
+ const vscode_html_languageservice_1 = require("vscode-html-languageservice");
5
+ function isJSDocument(languageId) {
6
+ return (languageId === 'javascript' ||
7
+ languageId === 'typescript' ||
8
+ languageId === 'javascriptreact' ||
9
+ languageId === 'typescriptreact');
10
+ }
11
+ exports.isJSDocument = isJSDocument;
12
+ /**
13
+ * Return true if a specific node could be a component.
14
+ * 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
+ */
16
+ function isPossibleComponent(node) {
17
+ return !!node.tag?.[0].match(/[A-Z]/) || !!node.tag?.match(/.+[.][A-Z]?/);
18
+ }
19
+ exports.isPossibleComponent = isPossibleComponent;
20
+ /**
21
+ * Return if a given offset is inside the start tag of a component
22
+ */
23
+ function isInComponentStartTag(html, offset) {
24
+ const node = html.findNodeAt(offset);
25
+ return isPossibleComponent(node) && (!node.startTagEnd || offset < node.startTagEnd);
26
+ }
27
+ exports.isInComponentStartTag = isInComponentStartTag;
28
+ /**
29
+ * Return if a given position is inside a JSX expression
30
+ */
31
+ function isInsideExpression(html, tagStart, position) {
32
+ const charactersInNode = html.substring(tagStart, position);
33
+ return charactersInNode.lastIndexOf('{') > charactersInNode.lastIndexOf('}');
34
+ }
35
+ exports.isInsideExpression = isInsideExpression;
36
+ /**
37
+ * Return if a given offset is inside the frontmatter
38
+ */
39
+ function isInsideFrontmatter(offset, frontmatter) {
40
+ switch (frontmatter.status) {
41
+ case 'closed':
42
+ return offset > frontmatter.position.start.offset && offset < frontmatter.position.end.offset;
43
+ case 'open':
44
+ return offset > frontmatter.position.start.offset;
45
+ case 'doesnt-exist':
46
+ return false;
47
+ }
48
+ }
49
+ exports.isInsideFrontmatter = isInsideFrontmatter;
50
+ function ensureProperEditForFrontmatter(edit, frontmatter, newLine, position = 'top') {
51
+ switch (frontmatter.status) {
52
+ case 'open':
53
+ return getOpenFrontmatterEdit(edit, newLine);
54
+ case 'closed':
55
+ return {
56
+ newText: edit.newText,
57
+ range: ensureRangeIsInFrontmatter(edit.range, frontmatter, position),
58
+ };
59
+ case 'doesnt-exist':
60
+ return getNewFrontmatterEdit(edit, newLine);
61
+ }
62
+ }
63
+ exports.ensureProperEditForFrontmatter = ensureProperEditForFrontmatter;
64
+ /**
65
+ * Force a range to be at the start of the frontmatter if it is outside
66
+ */
67
+ function ensureRangeIsInFrontmatter(range, frontmatter, position = 'top') {
68
+ if (frontmatter.status === 'open' || frontmatter.status === 'closed') {
69
+ // Q: Why not use PointToPosition?
70
+ // A: The Astro compiler returns positions at the exact line where the frontmatter is, which is not adequate for mapping
71
+ // edits as we want edits *inside* the frontmatter and not on the same line, or you would end up with things like `---import ...`
72
+ const frontmatterStartPosition = {
73
+ line: frontmatter.position.start.line,
74
+ character: frontmatter.position.start.column - 1,
75
+ };
76
+ const frontmatterEndPosition = frontmatter.position.end
77
+ ? { line: frontmatter.position.end.line - 1, character: 0 }
78
+ : undefined;
79
+ // If the range start is outside the frontmatter, return a range at the start of the frontmatter
80
+ if (range.start.line < frontmatterStartPosition.line ||
81
+ (frontmatterEndPosition && range.start.line > frontmatterEndPosition.line)) {
82
+ if (frontmatterEndPosition && position === 'bottom') {
83
+ return vscode_html_languageservice_1.Range.create(frontmatterEndPosition, frontmatterEndPosition);
84
+ }
85
+ return vscode_html_languageservice_1.Range.create(frontmatterStartPosition, frontmatterStartPosition);
86
+ }
87
+ return range;
88
+ }
89
+ return range;
90
+ }
91
+ exports.ensureRangeIsInFrontmatter = ensureRangeIsInFrontmatter;
92
+ function getNewFrontmatterEdit(edit, newLine) {
93
+ edit.newText = `---${newLine}${edit.newText}---${newLine}${newLine}`;
94
+ edit.range = vscode_html_languageservice_1.Range.create(0, 0, 0, 0);
95
+ return edit;
96
+ }
97
+ exports.getNewFrontmatterEdit = getNewFrontmatterEdit;
98
+ function getOpenFrontmatterEdit(edit, newLine) {
99
+ edit.newText = edit.newText.startsWith(newLine)
100
+ ? `${edit.newText}---`
101
+ : `${newLine}${edit.newText}---`;
102
+ return edit;
103
+ }
104
+ exports.getOpenFrontmatterEdit = getOpenFrontmatterEdit;
105
+ // Most edits that are at 0:0, or outside the document are intended for the frontmatter
106
+ function editShouldBeInFrontmatter(range, astroDocument) {
107
+ const isAtZeroZero = range.start.line === 0 && range.start.character === 0;
108
+ const isPastFile = astroDocument && range.start.line > astroDocument.lineCount;
109
+ const shouldIt = isAtZeroZero || isPastFile;
110
+ return shouldIt
111
+ ? { itShould: true, position: isPastFile ? 'bottom' : 'top' }
112
+ : { itShould: false, position: undefined };
113
+ }
114
+ exports.editShouldBeInFrontmatter = editShouldBeInFrontmatter;
115
+ //# sourceMappingURL=utils.js.map
package/dist/utils.d.ts CHANGED
@@ -1,39 +1,10 @@
1
- import type { AttributeNode, Point, Position as CompilerPosition } from '@astrojs/compiler/types';
2
- import { HTMLDocument, Node, Position as LSPPosition, Range, TextEdit } from 'vscode-html-languageservice';
3
- import type { FrontmatterStatus } from './core/parseAstro.js';
4
- export declare function isJSDocument(languageId: string): boolean;
5
- /**
6
- * Return true if a specific node could be a component.
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
8
- */
9
- export declare function isPossibleComponent(node: Node): boolean;
10
- /**
11
- * Return if a given offset is inside the start tag of a component
12
- */
13
- export declare function isInComponentStartTag(html: HTMLDocument, offset: number): boolean;
14
- /**
15
- * Return if a given position is inside a JSX expression
16
- */
17
- export declare function isInsideExpression(html: string, tagStart: number, position: number): boolean;
18
- /**
19
- * Return if a given offset is inside the frontmatter
20
- */
21
- export declare function isInsideFrontmatter(offset: number, frontmatter: FrontmatterStatus): boolean;
22
- /**
23
- * Transform a Point from the Astro compiler to an LSP Position
24
- */
25
- export declare function PointToPosition(point: Point): LSPPosition;
26
- export declare function createCompilerPosition(start: Point, end: Point): CompilerPosition;
27
- export declare function createCompilerPoint(line: number, column: number, offset: number): Point;
28
- type WithRequired<T, K extends keyof T> = T & {
29
- [P in K]-?: T[P];
30
- };
31
- export type AttributeNodeWithPosition = WithRequired<AttributeNode, 'position'>;
32
- /**
33
- * Force a range to be at the start of the frontmatter if it is outside
34
- */
35
- export declare function ensureRangeIsInFrontmatter(range: Range, frontmatter: FrontmatterStatus): Range;
36
- export declare function getNewFrontmatterEdit(edit: TextEdit, newLine: string): TextEdit;
37
- export declare function getOpenFrontmatterEdit(edit: TextEdit, newLine: string): TextEdit;
38
- export declare function getWorkspacePnpPath(workspacePath: string): string | null;
39
- export {};
1
+ export interface AstroInstall {
2
+ path: string;
3
+ version: {
4
+ full: string;
5
+ major: number;
6
+ minor: number;
7
+ patch: number;
8
+ };
9
+ }
10
+ export declare function getAstroInstall(basePaths: string[]): AstroInstall | undefined;
package/dist/utils.js CHANGED
@@ -1,120 +1,70 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
4
24
  };
5
25
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getWorkspacePnpPath = exports.getOpenFrontmatterEdit = exports.getNewFrontmatterEdit = exports.ensureRangeIsInFrontmatter = exports.createCompilerPoint = exports.createCompilerPosition = exports.PointToPosition = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInComponentStartTag = exports.isPossibleComponent = exports.isJSDocument = void 0;
7
- const node_path_1 = __importDefault(require("node:path"));
8
- const vscode_html_languageservice_1 = require("vscode-html-languageservice");
9
- function isJSDocument(languageId) {
10
- return (languageId === 'javascript' ||
11
- languageId === 'typescript' ||
12
- languageId === 'javascriptreact' ||
13
- languageId === 'typescriptreact');
14
- }
15
- exports.isJSDocument = isJSDocument;
16
- /**
17
- * Return true if a specific node could be a component.
18
- * 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
19
- */
20
- function isPossibleComponent(node) {
21
- return !!node.tag?.[0].match(/[A-Z]/) || !!node.tag?.match(/.+[.][A-Z]?/);
22
- }
23
- exports.isPossibleComponent = isPossibleComponent;
24
- /**
25
- * Return if a given offset is inside the start tag of a component
26
- */
27
- function isInComponentStartTag(html, offset) {
28
- const node = html.findNodeAt(offset);
29
- return isPossibleComponent(node) && (!node.startTagEnd || offset < node.startTagEnd);
30
- }
31
- exports.isInComponentStartTag = isInComponentStartTag;
32
- /**
33
- * Return if a given position is inside a JSX expression
34
- */
35
- function isInsideExpression(html, tagStart, position) {
36
- const charactersInNode = html.substring(tagStart, position);
37
- return charactersInNode.lastIndexOf('{') > charactersInNode.lastIndexOf('}');
38
- }
39
- exports.isInsideExpression = isInsideExpression;
40
- /**
41
- * Return if a given offset is inside the frontmatter
42
- */
43
- function isInsideFrontmatter(offset, frontmatter) {
44
- switch (frontmatter.status) {
45
- case 'closed':
46
- return offset > frontmatter.position.start.offset && offset < frontmatter.position.end.offset;
47
- case 'open':
48
- return offset > frontmatter.position.start.offset;
49
- case 'doesnt-exist':
50
- return false;
51
- }
52
- }
53
- exports.isInsideFrontmatter = isInsideFrontmatter;
54
- /**
55
- * Transform a Point from the Astro compiler to an LSP Position
56
- */
57
- function PointToPosition(point) {
58
- // Columns are 0-based in LSP, but the compiler's Point are 1 based.
59
- return vscode_html_languageservice_1.Position.create(point.line, point.column - 1);
60
- }
61
- exports.PointToPosition = PointToPosition;
62
- function createCompilerPosition(start, end) {
63
- return {
64
- start,
65
- end,
66
- };
67
- }
68
- exports.createCompilerPosition = createCompilerPosition;
69
- function createCompilerPoint(line, column, offset) {
70
- return {
71
- line,
72
- column,
73
- offset,
74
- };
75
- }
76
- exports.createCompilerPoint = createCompilerPoint;
77
- /**
78
- * Force a range to be at the start of the frontmatter if it is outside
79
- */
80
- function ensureRangeIsInFrontmatter(range, frontmatter) {
81
- if (frontmatter.status === 'open' || frontmatter.status === 'closed') {
82
- const frontmatterStartPosition = PointToPosition(frontmatter.position.start);
83
- const frontmatterEndPosition = frontmatter.position.end
84
- ? PointToPosition(frontmatter.position.end)
85
- : undefined;
86
- // If the range start is outside the frontmatter, return a range at the start of the frontmatter
87
- if (range.start.line < frontmatterStartPosition.line ||
88
- (frontmatterEndPosition && range.start.line > frontmatterEndPosition.line)) {
89
- return vscode_html_languageservice_1.Range.create(frontmatterStartPosition, frontmatterStartPosition);
90
- }
91
- return range;
92
- }
93
- return range;
94
- }
95
- exports.ensureRangeIsInFrontmatter = ensureRangeIsInFrontmatter;
96
- function getNewFrontmatterEdit(edit, newLine) {
97
- edit.newText = `---${newLine}${edit.newText}---${newLine}${newLine}`;
98
- edit.range = vscode_html_languageservice_1.Range.create(0, 0, 0, 0);
99
- return edit;
100
- }
101
- exports.getNewFrontmatterEdit = getNewFrontmatterEdit;
102
- function getOpenFrontmatterEdit(edit, newLine) {
103
- edit.newText = edit.newText.startsWith(newLine)
104
- ? `${edit.newText}---`
105
- : `${newLine}${edit.newText}---`;
106
- return edit;
107
- }
108
- exports.getOpenFrontmatterEdit = getOpenFrontmatterEdit;
109
- function getWorkspacePnpPath(workspacePath) {
26
+ exports.getAstroInstall = void 0;
27
+ const path = __importStar(require("node:path"));
28
+ const importPackage_js_1 = require("./importPackage.js");
29
+ function getAstroInstall(basePaths) {
30
+ let astroPath;
31
+ let version;
110
32
  try {
111
- const possiblePath = node_path_1.default.resolve(workspacePath, '.pnp.cjs');
112
- require.resolve(possiblePath);
113
- return possiblePath;
33
+ astroPath = (0, importPackage_js_1.getPackagePath)('astro', basePaths);
34
+ if (!astroPath) {
35
+ throw Error;
36
+ }
37
+ version = require(path.resolve(astroPath, 'package.json')).version;
114
38
  }
115
39
  catch {
116
- return null;
40
+ // If we couldn't find it inside the workspace's node_modules, it might means we're in the monorepo
41
+ try {
42
+ astroPath = (0, importPackage_js_1.getPackagePath)('./packages/astro', basePaths);
43
+ if (!astroPath) {
44
+ throw Error;
45
+ }
46
+ version = require(path.resolve(astroPath, 'package.json')).version;
47
+ }
48
+ catch (e) {
49
+ // If we still couldn't find it, it probably just doesn't exist
50
+ console.error(`${basePaths[0]} seems to be an Astro project, but we couldn't find Astro or Astro is not installed`);
51
+ return undefined;
52
+ }
117
53
  }
54
+ let [major, minor, patch] = version.split('.');
55
+ if (patch.includes('-')) {
56
+ const patchParts = patch.split('-');
57
+ patch = patchParts[0];
58
+ }
59
+ return {
60
+ path: astroPath,
61
+ version: {
62
+ full: version,
63
+ major: Number(major),
64
+ minor: Number(minor),
65
+ patch: Number(patch),
66
+ },
67
+ };
118
68
  }
119
- exports.getWorkspacePnpPath = getWorkspacePnpPath;
69
+ exports.getAstroInstall = getAstroInstall;
120
70
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/language-server",
3
- "version": "2.0.14",
3
+ "version": "2.0.16",
4
4
  "author": "withastro",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,36 +20,37 @@
20
20
  "astro-ls": "./bin/nodeServer.js"
21
21
  },
22
22
  "dependencies": {
23
- "@astrojs/compiler": "^1.5.0",
23
+ "@astrojs/compiler": "^1.5.1",
24
24
  "@jridgewell/sourcemap-codec": "^1.4.15",
25
- "@volar/kit": "1.6.9",
26
- "@volar/language-core": "1.6.9",
27
- "@volar/language-server": "1.6.9",
28
- "@volar/language-service": "1.6.9",
29
- "@volar/source-map": "1.6.9",
25
+ "@volar/kit": "1.7.4",
26
+ "@volar/language-core": "1.7.4",
27
+ "@volar/language-server": "1.7.4",
28
+ "@volar/language-service": "1.7.4",
29
+ "@volar/source-map": "1.7.4",
30
+ "@volar/typescript": "1.7.4",
30
31
  "fast-glob": "^3.2.12",
31
32
  "muggle-string": "^0.3.1",
32
- "volar-service-css": "0.0.4",
33
- "volar-service-emmet": "0.0.4",
34
- "volar-service-html": "0.0.4",
35
- "volar-service-prettier": "0.0.4",
36
- "volar-service-typescript": "0.0.4",
37
- "volar-service-typescript-twoslash-queries": "0.0.4",
38
- "vscode-html-languageservice": "^5.0.5",
33
+ "volar-service-css": "0.0.7",
34
+ "volar-service-emmet": "0.0.7",
35
+ "volar-service-html": "0.0.7",
36
+ "volar-service-prettier": "0.0.7",
37
+ "volar-service-typescript": "0.0.7",
38
+ "volar-service-typescript-twoslash-queries": "0.0.7",
39
+ "vscode-html-languageservice": "^5.0.6",
39
40
  "vscode-uri": "^3.0.7"
40
41
  },
41
42
  "devDependencies": {
42
- "@astrojs/svelte": "^2.2.0",
43
- "@astrojs/vue": "^2.2.0",
43
+ "@astrojs/svelte": "^3.0.0",
44
+ "@astrojs/vue": "^2.2.1",
44
45
  "@types/chai": "^4.3.5",
45
46
  "@types/mocha": "^10.0.1",
46
47
  "@types/node": "^16.18.26",
47
- "@types/prettier": "^2.7.2",
48
- "astro": "^2.5.4",
48
+ "@types/prettier": "^2.7.3",
49
+ "astro": "^2.6.2",
49
50
  "chai": "^4.3.7",
50
51
  "mocha": "^10.2.0",
51
52
  "tsx": "^3.12.7",
52
- "typescript": "~5.0.4",
53
+ "typescript": "~5.1.3",
53
54
  "vscode-languageserver-protocol": "^3.17.3",
54
55
  "vscode-languageserver-textdocument": "^1.0.8"
55
56
  },
@@ -1,4 +0,0 @@
1
- import { CodeAction } from '@volar/language-server';
2
- import type { TextDocument } from 'vscode-html-languageservice';
3
- import type { AstroFile } from '../../core/index.js';
4
- export declare function enhancedProvideCodeActions(codeActions: CodeAction[], file: AstroFile, document: TextDocument, originalDocument: TextDocument, newLine: string): CodeAction[];
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enhancedProvideCodeActions = void 0;
4
- const language_server_1 = require("@volar/language-server");
5
- const vscode_uri_1 = require("vscode-uri");
6
- const utils_js_1 = require("../../utils.js");
7
- // Q: Why provideCodeActions instead of resolveCodeAction?
8
- // A: TypeScript actions are already fully resolved in provideCodeActions, so editors won't call resolveCodeAction at all.
9
- function enhancedProvideCodeActions(codeActions, file, document, originalDocument, newLine) {
10
- codeActions = codeActions.map((codeAction) => {
11
- if (!codeAction.edit)
12
- return codeAction;
13
- if (file.scriptFiles.includes(vscode_uri_1.URI.parse(originalDocument.uri).path))
14
- return codeAction;
15
- codeAction.edit.documentChanges = codeAction.edit.documentChanges?.map((change) => {
16
- if (language_server_1.TextDocumentEdit.is(change)) {
17
- change.edits = change.edits.map((edit) => {
18
- // Move code actions adding new imports to the frontmatter, as by default they'll be outside of it
19
- // TODO: This is a bit brittle, but we're unfortunately too late into the process to be able to tell the `fixName`
20
- // Maybe contribute upstream to pass the `fixName` through `data`?
21
- if (edit.newText.trim().startsWith('import ')) {
22
- if (file.astroMeta.frontmatter.status === 'doesnt-exist') {
23
- return (0, utils_js_1.getNewFrontmatterEdit)(edit, newLine);
24
- }
25
- if (file.astroMeta.frontmatter.status === 'open') {
26
- return (0, utils_js_1.getOpenFrontmatterEdit)(edit, newLine);
27
- }
28
- edit.range = (0, utils_js_1.ensureRangeIsInFrontmatter)(edit.range, file.astroMeta.frontmatter);
29
- }
30
- // Some code actions will insert code at the end of the generated TSX file, so we'll manually
31
- // redirect it to the end of the frontmatter instead, or create a frontmatter if one doesn't exist
32
- if (edit.range.start.line > document.lineCount) {
33
- switch (file.astroMeta.frontmatter.status) {
34
- case 'open':
35
- return (0, utils_js_1.getOpenFrontmatterEdit)(edit, newLine);
36
- case 'closed':
37
- const position = (0, utils_js_1.PointToPosition)(file.astroMeta.frontmatter.position.end);
38
- edit.range = language_server_1.Range.create(position, position);
39
- return edit;
40
- case 'doesnt-exist':
41
- return (0, utils_js_1.getNewFrontmatterEdit)(edit, newLine);
42
- }
43
- }
44
- return edit;
45
- });
46
- }
47
- return change;
48
- });
49
- return codeAction;
50
- });
51
- return codeActions;
52
- }
53
- exports.enhancedProvideCodeActions = enhancedProvideCodeActions;
54
- //# sourceMappingURL=codeActions.js.map