@master/css-language-server 2.0.0-rc.8 → 2.0.0-rc.80

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) Aoyue Design LLC.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ <br>
2
+ <div align="center">
3
+
4
+ <p align="center">
5
+ <a href="https://css.master.co">
6
+ <picture>
7
+ <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/33840671/201701649-3bb7d698-abec-4d5f-ac30-ccc4d7bafcd4.svg">
8
+ <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg">
9
+ <img alt="Master CSS" src="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg" width="100%">
10
+ </picture>
11
+ </a>
12
+ </p>
13
+ <p align="center">Language Server for Master CSS</p>
14
+
15
+ <p align="center">
16
+ <a aria-label="GitHub release (latest by date including pre-releases)" href="https://github.com/master-co/css/releases">
17
+ <picture>
18
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=212022&label=&style=for-the-badge&logo=github&logoColor=fff">
19
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github&logoColor=%23000">
20
+ <img alt="NPM Version" src="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github">
21
+ </picture>
22
+ </a>
23
+ <a aria-label="NPM Package" href="https://www.npmjs.com/package/@master/css-language-server">
24
+ <picture>
25
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/npm/dm/@master/css-language-server?color=212022&label=%20&logo=npm&style=for-the-badge">
26
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/npm/dm/@master/css-language-server?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
27
+ <img alt="NPM package ( download / month )" src="https://img.shields.io/npm/dm/@master/css-language-server?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
28
+ </picture>
29
+ </a>
30
+ <a aria-label="JSDelivr" href="https://www.jsdelivr.com/package/npm/@master/css-language-server">
31
+ <picture>
32
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-server?color=212022&label=%20&logo=jsdelivr&style=for-the-badge">
33
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-server?color=f6f7f8&label=%20&logo=jsdelivr&style=for-the-badge">
34
+ <img alt="JSDelivr hits (npm scoped)" src="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-server?color=f6f7f8&label=%20&logo=jsdelivr&style=for-the-badge">
35
+ </picture>
36
+ </a>
37
+ <a aria-label="Discord Community" href="https://discord.gg/sZNKpAAAw6">
38
+ <picture>
39
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/discord/917780624314613760?color=212022&label=%20&logo=discord&style=for-the-badge">
40
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
41
+ <img alt="Discord online" src="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
42
+ </picture>
43
+ </a>
44
+ <a aria-label="Follow @mastercorg" href="https://twitter.com/mastercorg">
45
+ <picture>
46
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=212022&logo=twitter&style=for-the-badge">
47
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
48
+ <img alt="Follow @mastercorg" src="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
49
+ </picture>
50
+ </a>
51
+ <a aria-label="Github Actions" href="https://github.com/master-co/css/actions/workflows/ci-release.yml">
52
+ <picture>
53
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=212022&logo=githubactions&style=for-the-badge">
54
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
55
+ <img alt="Github release actions" src="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
56
+ </picture>
57
+ </a>
58
+ </p>
59
+
60
+ </div>
61
+
62
+ ## Installation
63
+
64
+ ```bash
65
+ npm install @master/css-language-server
66
+ ```
67
+
68
+ ## Usage
69
+
70
+ ```js
71
+ import CSSLanguageServer from '@master/css-language-server'
72
+
73
+ const languageServer = new CSSLanguageServer(connection, customSettings)
74
+ ```
75
+
76
+ `CSSLanguageServer` wraps `@master/css-language-service` with LSP workspace lifecycle, completion, hover, document color, color presentation, semantic token, and directive formatting handlers.
77
+
78
+ Diagnostics are intentionally limited to language-server-owned behavior: CSS directive diagnostics and project manifest loading diagnostics. Class syntax and policy rules such as sorting, canonical class preference, conflict detection, invalid classes, and raw-value approval are owned by `@master/eslint-plugin-css`.
79
+
80
+ ## Semantic tokens
81
+
82
+ The language server supports full-document and active-position semantic tokens.
83
+
84
+ | `embeddedSyntaxHighlighting` | Behavior |
85
+ | --- | --- |
86
+ | `always` | Advertises the standard LSP `semanticTokensProvider` and handles `textDocument/semanticTokens/full`. |
87
+ | `active` | Uses the VS Code extension request for active class-context highlighting. |
88
+ | `off` | Disables embedded utility highlighting. |
89
+
90
+ CSS directive syntax is highlighted by the shared TextMate grammar. Server semantic tokens cover Master CSS class-list spans and directive class-list spans such as `@compose` and `@safelist`.
91
+
92
+ ## Formatting
93
+
94
+ The server advertises `documentFormattingProvider` and `documentRangeFormattingProvider` when `formatDirectives` is enabled. Formatting returns directive-only edits for CSS, SCSS, and LESS documents, plus CSS-family `<style>` blocks in Vue, Svelte, and Astro documents.
95
+
96
+ Directive formatting normalizes safe directive spacing and repairs class-list important markers such as `bg:transparent !` to `bg:transparent!`. It does not run the compiler and does not change generated CSS output.
97
+
98
+ ## Settings
99
+
100
+ ```js
101
+ import { settings } from '@master/css-language-server'
102
+ ```
103
+
104
+ | Setting | Type | Default | Description |
105
+ | --- | --- | --- | --- |
106
+ | `workspaces` | `FastGlobPattern[] \| 'auto'` | `'auto'` | Workspace roots where independent language services are created. The root workspace is always included. |
107
+ | `verbose` | `boolean` | `false` | Print server logs. |
108
+ | `formatDirectives` | `boolean` | `true` | Enables LSP document and range formatting for Master CSS directives. |
109
+ | `embeddedSyntaxHighlighting` | `'active' \| 'always' \| 'off'` | `'active'` | Inherited language-service semantic token mode. |
110
+
111
+ With `workspaces: 'auto'`, the server creates workspaces from CSS files importing `@master/css`, CSS files containing the lightweight `@master entry;` marker, and `package.json` files that declare Master CSS package dependencies.
package/dist/core.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ import { ClientCapabilities, ColorPresentationParams, CompletionParams, Connection, DidChangeConfigurationParams, DocumentColorParams, DocumentFormattingParams, DocumentRangeFormattingParams, HoverParams, InitializeParams, InitializeResult, RemoteConsole, SemanticTokensParams, TextDocumentChangeEvent, TextDocumentPositionParams, TextDocuments, TextEdit, WorkspaceFolder } from "vscode-languageserver/node";
2
+ import { TextDocument } from "vscode-languageserver-textdocument";
3
+ import CSSLanguageService from "@master/css-language-service";
4
+ import { MasterCSSWorkspacePackageResolution } from "@master/css-project/workspace";
5
+ import { CSSLanguageRuntime } from "@master/css-language";
6
+ import { Settings as Settings$1 } from "./settings.js";
7
+
8
+ //#region src/core.d.ts
9
+ declare interface Workspace {
10
+ uri: string;
11
+ openedTextDocuments: TextDocument[];
12
+ languageService?: CSSLanguageService;
13
+ languageServiceSettings: Settings$1;
14
+ languageRuntime?: CSSLanguageRuntime;
15
+ languageRuntimeResolution?: MasterCSSWorkspacePackageResolution;
16
+ languageRuntimeSource?: 'workspace' | 'bundled';
17
+ manifestErrors?: unknown[];
18
+ planEntries?: string[];
19
+ }
20
+ declare const ACTIVE_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderActiveSemanticTokens";
21
+ declare const DOCUMENT_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderDocumentSemanticTokens";
22
+ declare class CSSLanguageServer {
23
+ connection: Connection;
24
+ customSettings?: Settings$1 | undefined;
25
+ workspaceFolders: WorkspaceFolder[];
26
+ workspaces: Map<string, Workspace>;
27
+ globalWorkspace: Workspace;
28
+ documents: TextDocuments<TextDocument>;
29
+ initializing?: Promise<void>;
30
+ clientCapabilities: ClientCapabilities;
31
+ settings?: Settings$1;
32
+ console: RemoteConsole;
33
+ private disposables;
34
+ constructor(connection?: Connection, customSettings?: Settings$1 | undefined);
35
+ start(): void;
36
+ init(): Promise<void>;
37
+ onInitialize(params: InitializeParams): InitializeResult;
38
+ onHover(params: HoverParams): Promise<import("vscode-languageserver-protocol").Hover | undefined>;
39
+ onCompletion(params: CompletionParams): Promise<import("vscode-languageserver-protocol").CompletionItem[] | undefined>;
40
+ onDocumentColor(params: DocumentColorParams): Promise<import("vscode-languageserver-protocol").ColorInformation[]>;
41
+ onColorPresentation(params: ColorPresentationParams): Promise<import("vscode-languageserver-protocol").ColorPresentation[]>;
42
+ private getWorkspaceDocument;
43
+ onDocumentFormatting(params: DocumentFormattingParams): Promise<TextEdit[]>;
44
+ onDocumentRangeFormatting(params: DocumentRangeFormattingParams): Promise<TextEdit[]>;
45
+ onSemanticTokens(params: SemanticTokensParams): Promise<import("vscode-languageserver-protocol").SemanticTokens>;
46
+ onDocumentSemanticTokens(params: SemanticTokensParams): Promise<import("vscode-languageserver-protocol").SemanticTokens>;
47
+ onActiveSemanticTokens(params: TextDocumentPositionParams): Promise<import("vscode-languageserver-protocol").SemanticTokens>;
48
+ onDidOpen(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
49
+ onDidChangeContent(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
50
+ onDidClose(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
51
+ onDidSave(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
52
+ onDidChangeConfiguration({
53
+ settings: changedSettings
54
+ }: DidChangeConfigurationParams): Promise<void>;
55
+ private initWorkspaceFolder;
56
+ initWorkspaceLanguageService(workspace: Workspace): Promise<void>;
57
+ private loadWorkspacePlan;
58
+ private loadWorkspaceLanguageRuntime;
59
+ private importWorkspaceModule;
60
+ destroyLanguageService(workspace: Workspace): void;
61
+ findClosestWorkspace(textDocumentURI: string): Workspace;
62
+ private publishDiagnostics;
63
+ private createCSSDirectiveDiagnostics;
64
+ private createManifestLoadingDiagnostics;
65
+ private createCSSDirectiveDiagnostic;
66
+ private createCSSDirectiveRelatedInformation;
67
+ private createCSSDirectiveRange;
68
+ private refreshSemanticTokens;
69
+ stop(): void;
70
+ }
71
+ //#endregion
72
+ export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, Workspace, CSSLanguageServer as default };
package/dist/core.js ADDED
@@ -0,0 +1,533 @@
1
+ import settings$1 from "./settings.js";
2
+ import { DiagnosticSeverity, TextDocumentSyncKind, TextDocuments, createConnection } from "vscode-languageserver/node";
3
+ import { TextDocument } from "vscode-languageserver-textdocument";
4
+ import path from "node:path";
5
+ import { readFile } from "node:fs/promises";
6
+ import { pathToFileURL } from "node:url";
7
+ import CSSLanguageService from "@master/css-language-service";
8
+ import { compileCSSManifest } from "@master/css-compiler";
9
+ import { findCSSManifestEntryFiles, findMasterCSSWorkspaceDirectories } from "@master/css-project/entries";
10
+ import { loadProjectManifest } from "@master/css-project/manifest";
11
+ import { resolveMasterCSSWorkspacePackages } from "@master/css-project/workspace";
12
+ import { defu } from "defu";
13
+ import { AT_TRIGGER_CHARACTER, DECLARATION_SEPARATOR_TRIGGER_CHARACTER, GROUP_TRIGGER_CHARACTER, INVOKED_TRIGGER_CHARACTERS, QUERY_TRIGGER_CHARACTERS, SELECTOR_TRIGGER_CHARACTERS, VALUE_TRIGGER_CHARACTERS } from "@master/css-language-service/common";
14
+ import { SEMANTIC_TOKENS_LEGEND, defaultCSSLanguageRuntime, matchesLanguageServiceNativeDeclaration } from "@master/css-language";
15
+ import glob from "fast-glob";
16
+ import { URI } from "vscode-uri";
17
+ import { CSSDirectiveError } from "@master/css-schema/css-directives";
18
+ //#region src/core.ts
19
+ const ACTIVE_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderActiveSemanticTokens";
20
+ const DOCUMENT_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderDocumentSemanticTokens";
21
+ const SERVER_CAPABILITIES = {
22
+ textDocumentSync: TextDocumentSyncKind.Incremental,
23
+ completionProvider: {
24
+ resolveProvider: false,
25
+ workDoneProgress: false,
26
+ triggerCharacters: [.../* @__PURE__ */ new Set([
27
+ ...INVOKED_TRIGGER_CHARACTERS,
28
+ ...VALUE_TRIGGER_CHARACTERS,
29
+ ...SELECTOR_TRIGGER_CHARACTERS,
30
+ ...QUERY_TRIGGER_CHARACTERS,
31
+ DECLARATION_SEPARATOR_TRIGGER_CHARACTER,
32
+ AT_TRIGGER_CHARACTER,
33
+ GROUP_TRIGGER_CHARACTER
34
+ ])]
35
+ },
36
+ colorProvider: true,
37
+ hoverProvider: true,
38
+ documentFormattingProvider: true,
39
+ documentRangeFormattingProvider: true,
40
+ semanticTokensProvider: {
41
+ legend: SEMANTIC_TOKENS_LEGEND,
42
+ full: true
43
+ },
44
+ workspace: { workspaceFolders: { supported: true } }
45
+ };
46
+ const CSS_DIAGNOSTIC_LANGUAGE_IDS = /* @__PURE__ */ new Set([
47
+ "css",
48
+ "scss",
49
+ "less"
50
+ ]);
51
+ const SFC_DIAGNOSTIC_LANGUAGE_IDS = /* @__PURE__ */ new Set([
52
+ "vue",
53
+ "svelte",
54
+ "astro"
55
+ ]);
56
+ const STYLE_BLOCK_RE = /<style\b([^>]*)>([\s\S]*?)<\/style>/gi;
57
+ function isCSSDiagnosticDocument(textDocument) {
58
+ return CSS_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId) || SFC_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId);
59
+ }
60
+ function getSFCStyleLanguage(attributes) {
61
+ const match = /\blang\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s>]+))/i.exec(attributes);
62
+ return (match?.[1] || match?.[2] || match?.[3] || "css").toLowerCase();
63
+ }
64
+ function getCSSDiagnosticSources(textDocument) {
65
+ const text = textDocument.getText();
66
+ if (CSS_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId)) return [{
67
+ source: text,
68
+ offset: 0
69
+ }];
70
+ if (!SFC_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId)) return [];
71
+ const sources = [];
72
+ STYLE_BLOCK_RE.lastIndex = 0;
73
+ for (const match of text.matchAll(STYLE_BLOCK_RE)) {
74
+ const styleLanguage = getSFCStyleLanguage(match[1]);
75
+ if (!CSS_DIAGNOSTIC_LANGUAGE_IDS.has(styleLanguage)) continue;
76
+ const source = match[2];
77
+ const offset = (match.index || 0) + match[0].indexOf(source);
78
+ sources.push({
79
+ source,
80
+ offset
81
+ });
82
+ }
83
+ return sources;
84
+ }
85
+ function isCSSDirectiveError(error) {
86
+ return error instanceof CSSDirectiveError || !!error && typeof error === "object" && error.name === "CSSDirectiveError" && typeof error.code === "string";
87
+ }
88
+ function getInitializationSettings(initializationOptions) {
89
+ if (!initializationOptions || typeof initializationOptions !== "object") return;
90
+ const options = initializationOptions;
91
+ return options.masterCSS ?? options;
92
+ }
93
+ function isWindowsFilePath(fsPath) {
94
+ return /^[a-z]:[\\/]/i.test(fsPath) || fsPath.startsWith("\\\\") || fsPath.startsWith("//");
95
+ }
96
+ function getFilePathTools(...fsPaths) {
97
+ return fsPaths.some(isWindowsFilePath) ? path.win32 : path;
98
+ }
99
+ function toComparableFilePath(uri) {
100
+ const parsedURI = URI.parse(uri);
101
+ if (parsedURI.scheme !== "file") return;
102
+ const fsPath = parsedURI.fsPath;
103
+ if (!fsPath) return;
104
+ const resolvedPath = getFilePathTools(fsPath).resolve(fsPath);
105
+ return isWindowsFilePath(resolvedPath) ? resolvedPath.toLowerCase() : resolvedPath;
106
+ }
107
+ function containsFilePath(parentPath, childPath) {
108
+ const filePathTools = getFilePathTools(parentPath, childPath);
109
+ const relativePath = filePathTools.relative(parentPath, childPath);
110
+ return relativePath === "" || !!relativePath && relativePath !== ".." && !relativePath.startsWith(`..${filePathTools.sep}`) && !filePathTools.isAbsolute(relativePath);
111
+ }
112
+ var CSSLanguageServer = class {
113
+ connection;
114
+ customSettings;
115
+ workspaceFolders = [];
116
+ workspaces = /* @__PURE__ */ new Map();
117
+ globalWorkspace = {
118
+ uri: "",
119
+ openedTextDocuments: [],
120
+ languageServiceSettings: this.settings,
121
+ languageRuntime: defaultCSSLanguageRuntime,
122
+ languageRuntimeSource: "bundled"
123
+ };
124
+ documents;
125
+ initializing;
126
+ clientCapabilities = {};
127
+ settings;
128
+ console;
129
+ disposables = [];
130
+ constructor(connection = process.argv.includes("--stdio") ? createConnection(process.stdin, process.stdout) : createConnection(), customSettings) {
131
+ this.connection = connection;
132
+ this.customSettings = customSettings;
133
+ this.documents = new TextDocuments(TextDocument);
134
+ this.settings = defu(this.customSettings, settings$1);
135
+ this.globalWorkspace.languageServiceSettings = this.settings;
136
+ this.console = new Proxy(this.connection.console, { get: (target, prop) => {
137
+ if (!this.settings?.verbose) return () => {};
138
+ return this.connection.console[prop];
139
+ } });
140
+ }
141
+ start() {
142
+ this.disposables.push(this.documents.onDidSave(this.onDidSave.bind(this)), this.documents.onDidOpen(this.onDidOpen.bind(this)), this.documents.onDidChangeContent(this.onDidChangeContent.bind(this)), this.documents.onDidClose(this.onDidClose.bind(this)), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(this.onDidChangeConfiguration.bind(this)), this.connection.onHover(this.onHover.bind(this)), this.connection.onCompletion(this.onCompletion.bind(this)), this.connection.onDocumentColor(this.onDocumentColor.bind(this)), this.connection.onColorPresentation(this.onColorPresentation.bind(this)), this.connection.onDocumentFormatting(this.onDocumentFormatting.bind(this)), this.connection.onDocumentRangeFormatting(this.onDocumentRangeFormatting.bind(this)), this.connection.languages.semanticTokens.on(this.onSemanticTokens.bind(this)), this.connection.onRequest(DOCUMENT_SEMANTIC_TOKENS_REQUEST, this.onDocumentSemanticTokens.bind(this)), this.connection.onRequest(ACTIVE_SEMANTIC_TOKENS_REQUEST, this.onActiveSemanticTokens.bind(this)), this.connection.onInitialize(this.onInitialize.bind(this)), this.connection.onInitialized(() => this.init()));
143
+ this.connection.listen();
144
+ }
145
+ init() {
146
+ if (this.initializing) return this.initializing;
147
+ return this.initializing = new Promise(async (resolve) => {
148
+ await Promise.all(this.workspaceFolders.map((folder) => this.initWorkspaceFolder(folder.uri)));
149
+ resolve();
150
+ });
151
+ }
152
+ onInitialize(params) {
153
+ this.clientCapabilities = params.capabilities;
154
+ const initializationSettings = getInitializationSettings(params.initializationOptions);
155
+ if (initializationSettings) {
156
+ this.customSettings = defu(initializationSettings, this.customSettings);
157
+ this.settings = defu(this.customSettings, settings$1);
158
+ this.globalWorkspace.languageServiceSettings = this.settings;
159
+ }
160
+ if (params.workspaceFolders?.length) this.workspaceFolders = params.workspaceFolders;
161
+ const capabilities = { ...SERVER_CAPABILITIES };
162
+ if (this.settings?.embeddedSyntaxHighlighting !== "always") delete capabilities.semanticTokensProvider;
163
+ if (!this.settings?.formatDirectives) {
164
+ delete capabilities.documentFormattingProvider;
165
+ delete capabilities.documentRangeFormattingProvider;
166
+ }
167
+ return { capabilities };
168
+ }
169
+ async onHover(params) {
170
+ await this.init();
171
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
172
+ if (workspace?.languageService) {
173
+ const document = this.documents.get(params.textDocument.uri);
174
+ if (document) return workspace.languageService.inspectSyntax(document, params.position);
175
+ }
176
+ }
177
+ async onCompletion(params) {
178
+ await this.init();
179
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
180
+ if (workspace?.languageService) {
181
+ const document = this.documents.get(params.textDocument.uri);
182
+ if (document) return workspace.languageService.suggestSyntax(document, params.position, params.context);
183
+ }
184
+ }
185
+ async onDocumentColor(params) {
186
+ await this.init();
187
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
188
+ if (workspace?.languageService) {
189
+ const document = this.documents.get(params.textDocument.uri);
190
+ if (document) return await workspace.languageService.renderSyntaxColors(document) ?? [];
191
+ }
192
+ return [];
193
+ }
194
+ async onColorPresentation(params) {
195
+ await this.init();
196
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
197
+ if (workspace?.languageService) {
198
+ const document = this.documents.get(params.textDocument.uri);
199
+ if (document) return workspace.languageService.editSyntaxColors(document, params.color, params.range) ?? [];
200
+ }
201
+ return [];
202
+ }
203
+ getWorkspaceDocument(uri) {
204
+ const workspace = this.findClosestWorkspace(uri);
205
+ if (!workspace?.languageService) return;
206
+ const document = this.documents.get(uri) ?? workspace.openedTextDocuments.find((document) => document.uri === uri);
207
+ if (!document) return;
208
+ return {
209
+ workspace,
210
+ document
211
+ };
212
+ }
213
+ async onDocumentFormatting(params) {
214
+ await this.init();
215
+ const context = this.getWorkspaceDocument(params.textDocument.uri);
216
+ return context?.workspace.languageService?.formatDirectives(context.document) ?? [];
217
+ }
218
+ async onDocumentRangeFormatting(params) {
219
+ await this.init();
220
+ const context = this.getWorkspaceDocument(params.textDocument.uri);
221
+ return context?.workspace.languageService?.formatDirectives(context.document, params.range) ?? [];
222
+ }
223
+ async onSemanticTokens(params) {
224
+ await this.init();
225
+ const context = this.getWorkspaceDocument(params.textDocument.uri);
226
+ if (context) return context.workspace.languageService?.renderSemanticTokens(context.document) ?? { data: [] };
227
+ return { data: [] };
228
+ }
229
+ async onDocumentSemanticTokens(params) {
230
+ return this.onSemanticTokens(params);
231
+ }
232
+ async onActiveSemanticTokens(params) {
233
+ await this.init();
234
+ const context = this.getWorkspaceDocument(params.textDocument.uri);
235
+ if (context) return context.workspace.languageService?.renderSemanticTokensAtPosition(context.document, params.position) ?? { data: [] };
236
+ return { data: [] };
237
+ }
238
+ async onDidOpen(params) {
239
+ await this.init();
240
+ const workspace = this.findClosestWorkspace(params.document.uri);
241
+ if (!workspace) return;
242
+ if (workspace.openedTextDocuments.includes(params.document)) {
243
+ this.publishDiagnostics(params.document, workspace);
244
+ return;
245
+ }
246
+ if (!workspace.openedTextDocuments.length) await this.initWorkspaceLanguageService(workspace);
247
+ workspace.openedTextDocuments.push(params.document);
248
+ this.publishDiagnostics(params.document, workspace);
249
+ }
250
+ async onDidChangeContent(params) {
251
+ await this.init();
252
+ const workspace = this.findClosestWorkspace(params.document.uri);
253
+ if (!workspace) return;
254
+ this.publishDiagnostics(params.document, workspace);
255
+ }
256
+ async onDidClose(params) {
257
+ await this.init();
258
+ const workspace = this.findClosestWorkspace(params.document.uri);
259
+ if (!workspace) return;
260
+ workspace.openedTextDocuments.splice(workspace.openedTextDocuments.indexOf(params.document), 1);
261
+ this.connection.sendDiagnostics({
262
+ uri: params.document.uri,
263
+ diagnostics: []
264
+ });
265
+ if (!workspace.openedTextDocuments.length) this.destroyLanguageService(workspace);
266
+ }
267
+ async onDidSave(params) {
268
+ await this.init();
269
+ const workspace = this.findClosestWorkspace(params.document.uri);
270
+ if (!workspace) return;
271
+ this.publishDiagnostics(params.document, workspace);
272
+ if (path.basename(URI.parse(params.document.uri).fsPath).endsWith(".css")) {
273
+ this.refreshSemanticTokens();
274
+ this.connection.sendRequest("masterCSS/restart", { title: "Updating Master CSS configuration" });
275
+ }
276
+ }
277
+ async onDidChangeConfiguration({ settings: changedSettings }) {
278
+ await this.init();
279
+ if (changedSettings?.masterCSS) {
280
+ this.connection.sendNotification("masterCSS/globalSettingsChanged", changedSettings.masterCSS);
281
+ this.customSettings = changedSettings.masterCSS;
282
+ this.settings = defu(this.customSettings, settings$1);
283
+ this.globalWorkspace.languageServiceSettings = this.settings;
284
+ this.refreshSemanticTokens();
285
+ this.connection.sendRequest("masterCSS/restart", { title: "Updating Master CSS settings" });
286
+ for (const workspace of [this.globalWorkspace, ...this.workspaces.values()]) for (const document of workspace.openedTextDocuments) this.publishDiagnostics(document, workspace);
287
+ }
288
+ }
289
+ async initWorkspaceFolder(workspaceFolderURI) {
290
+ const workspaceFolderCWD = URI.parse(workspaceFolderURI).fsPath;
291
+ let customWorkspaceFolderSettings;
292
+ if (this.clientCapabilities.workspace?.configuration) customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
293
+ scopeUri: workspaceFolderURI,
294
+ section: "masterCSS"
295
+ });
296
+ const { workspaces, ...languageServiceSettings } = defu(customWorkspaceFolderSettings, this.customSettings, settings$1);
297
+ const resolvedWorkspaceDirectories = /* @__PURE__ */ new Set([workspaceFolderCWD]);
298
+ if (workspaceFolderCWD) this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
299
+ else this.console.info(`Registered global workspace folder`);
300
+ if (workspaces === "auto") for (const workspaceDir of await findMasterCSSWorkspaceDirectories(workspaceFolderCWD)) resolvedWorkspaceDirectories.add(workspaceDir);
301
+ else if (workspaces?.length) (await glob(workspaces, {
302
+ cwd: workspaceFolderCWD,
303
+ absolute: true,
304
+ onlyDirectories: true,
305
+ ignore: ["**/node_modules/**"]
306
+ })).forEach((workspaceDir) => resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
307
+ for (const workspaceDir of resolvedWorkspaceDirectories) {
308
+ const workspaceURI = URI.file(workspaceDir).toString();
309
+ this.console.info(`Added workspace ${workspaceURI}`);
310
+ this.workspaces.set(workspaceURI, {
311
+ uri: workspaceURI,
312
+ openedTextDocuments: [],
313
+ languageServiceSettings,
314
+ planEntries: await findCSSManifestEntryFiles(workspaceDir)
315
+ });
316
+ }
317
+ }
318
+ async initWorkspaceLanguageService(workspace) {
319
+ workspace.languageRuntime = await this.loadWorkspaceLanguageRuntime(workspace);
320
+ let workspacePlan;
321
+ workspace.manifestErrors = [];
322
+ if (workspace !== this.globalWorkspace) {
323
+ try {
324
+ workspacePlan = await this.loadWorkspacePlan(workspace);
325
+ } catch (e) {
326
+ workspace.manifestErrors = [e];
327
+ this.console.info(`Failed to load manifest from ${workspace.uri}`);
328
+ this.console.error(e instanceof Error ? e.stack : e.toString());
329
+ }
330
+ if (workspacePlan) this.console.info(`Initialized workspace ${workspace.planEntries?.length ? "(with manifest entry)" : "(with manifest)"} ${workspace.uri}`);
331
+ else this.console.info(`Initialized workspace ${workspace.uri}`);
332
+ }
333
+ workspace.languageService = new CSSLanguageService({
334
+ ...workspace.languageServiceSettings,
335
+ manifest: workspacePlan
336
+ }, { runtime: workspace.languageRuntime });
337
+ }
338
+ async loadWorkspacePlan(workspace) {
339
+ const result = await loadProjectManifest(workspace.uri ? URI.parse(workspace.uri).fsPath : process.cwd(), { baseManifest: (workspace.languageRuntime ?? defaultCSSLanguageRuntime).defaultManifest });
340
+ return result.entries.length ? result.manifest : workspace.languageServiceSettings.manifest;
341
+ }
342
+ async loadWorkspaceLanguageRuntime(workspace) {
343
+ if (workspace === this.globalWorkspace || !workspace.uri) {
344
+ workspace.languageRuntimeSource = "bundled";
345
+ return defaultCSSLanguageRuntime;
346
+ }
347
+ const cwd = URI.parse(workspace.uri).fsPath;
348
+ let resolution;
349
+ try {
350
+ resolution = resolveMasterCSSWorkspacePackages(cwd);
351
+ workspace.languageRuntimeResolution = resolution;
352
+ const missingPackages = [
353
+ !resolution.css && "@master/css",
354
+ !resolution.engine && "@master/css-engine",
355
+ !resolution.presetManifest && "@master/css-preset/default-manifest.json"
356
+ ].filter(Boolean);
357
+ if (missingPackages.length) throw new Error(`Missing workspace package(s): ${missingPackages.join(", ")}`);
358
+ const cssPackage = resolution.css;
359
+ const enginePackage = resolution.engine;
360
+ const presetManifestPackage = resolution.presetManifest;
361
+ if (!cssPackage || !enginePackage || !presetManifestPackage) throw new Error("Missing required workspace Master CSS runtime packages.");
362
+ const [cssModule, engineModule, utilityTypeModule] = await Promise.all([
363
+ this.importWorkspaceModule(cssPackage.entry),
364
+ this.importWorkspaceModule(enginePackage.entry),
365
+ resolution.utilityType ? this.importWorkspaceModule(resolution.utilityType.entry) : void 0
366
+ ]);
367
+ const MasterCSS = cssModule.MasterCSS || cssModule.default;
368
+ const builtinKeyAliases = engineModule.builtinKeyAliases;
369
+ const builtinNativeValueNamespaces = engineModule.builtinNativeValueNamespaces;
370
+ if (!MasterCSS) throw new Error(`Missing MasterCSS export from ${cssPackage.entry}`);
371
+ if (!builtinKeyAliases) throw new Error(`Missing builtinKeyAliases export from ${enginePackage.entry}`);
372
+ if (!builtinNativeValueNamespaces) throw new Error(`Missing builtinNativeValueNamespaces export from ${enginePackage.entry}`);
373
+ const manifest = JSON.parse(await readFile(presetManifestPackage.entry, "utf8"));
374
+ workspace.languageRuntimeSource = "workspace";
375
+ this.console.info(`Using workspace Master CSS runtime ${cssPackage.version ?? "(unknown version)"} from ${cssPackage.directory}`);
376
+ if (resolution.errors.length) this.console.info(`Workspace Master CSS runtime optional resolution warnings: ${resolution.errors.map(({ name, message }) => `${name}: ${message}`).join("; ")}`);
377
+ return {
378
+ MasterCSS,
379
+ UtilityType: utilityTypeModule?.UtilityType || utilityTypeModule?.default || defaultCSSLanguageRuntime.UtilityType,
380
+ defaultManifest: manifest,
381
+ builtinKeyAliases,
382
+ builtinNativeValueNamespaces,
383
+ nativeDeclarationMatcher: matchesLanguageServiceNativeDeclaration
384
+ };
385
+ } catch (error) {
386
+ workspace.languageRuntimeSource = "bundled";
387
+ this.console.info(`Using bundled Master CSS runtime for ${workspace.uri}`);
388
+ if (resolution?.errors.length) this.console.info(`Workspace Master CSS package resolution errors: ${resolution.errors.map(({ name, message }) => `${name}: ${message}`).join("; ")}`);
389
+ this.console.error(error instanceof Error ? error.stack || error.message : String(error));
390
+ return defaultCSSLanguageRuntime;
391
+ }
392
+ }
393
+ async importWorkspaceModule(path) {
394
+ return await import(pathToFileURL(path).href);
395
+ }
396
+ destroyLanguageService(workspace) {
397
+ this.console.info(`Destroyed workspace ${workspace.uri}`);
398
+ delete workspace.languageService;
399
+ }
400
+ findClosestWorkspace(textDocumentURI) {
401
+ const documentPath = toComparableFilePath(textDocumentURI);
402
+ if (!documentPath) {
403
+ this.console.info(`This is an external document ${textDocumentURI} with the global workspace`);
404
+ return this.globalWorkspace;
405
+ }
406
+ let foundWorkspace;
407
+ let foundWorkspacePath = "";
408
+ for (const [uri, workspace] of this.workspaces) {
409
+ if (!uri) continue;
410
+ const workspacePath = toComparableFilePath(uri);
411
+ if (!workspacePath) continue;
412
+ if (containsFilePath(workspacePath, documentPath) && workspacePath.length > foundWorkspacePath.length) {
413
+ foundWorkspace = workspace;
414
+ foundWorkspacePath = workspacePath;
415
+ }
416
+ }
417
+ if (foundWorkspace) return foundWorkspace;
418
+ this.console.info(`This is an external document ${textDocumentURI} with the global workspace`);
419
+ return this.globalWorkspace;
420
+ }
421
+ publishDiagnostics(textDocument, workspace) {
422
+ const diagnostics = [];
423
+ diagnostics.push(...this.createManifestLoadingDiagnostics(textDocument, workspace));
424
+ diagnostics.push(...this.createCSSDirectiveDiagnostics(textDocument, workspace));
425
+ this.connection.sendDiagnostics({
426
+ uri: textDocument.uri,
427
+ diagnostics
428
+ });
429
+ }
430
+ createCSSDirectiveDiagnostics(textDocument, workspace) {
431
+ if (!isCSSDiagnosticDocument(textDocument)) return [];
432
+ const diagnostics = [];
433
+ const documentFile = path.resolve(URI.parse(textDocument.uri).fsPath);
434
+ for (const { source, offset } of getCSSDiagnosticSources(textDocument)) try {
435
+ compileCSSManifest(source, {
436
+ from: documentFile,
437
+ baseManifest: (workspace.languageRuntime ?? defaultCSSLanguageRuntime).defaultManifest
438
+ });
439
+ } catch (error) {
440
+ if (!isCSSDirectiveError(error)) continue;
441
+ const diagnostic = this.createCSSDirectiveDiagnostic(error, textDocument, documentFile, offset);
442
+ if (diagnostic) diagnostics.push(diagnostic);
443
+ }
444
+ return diagnostics;
445
+ }
446
+ createManifestLoadingDiagnostics(textDocument, workspace) {
447
+ if (!workspace.manifestErrors?.length) return [];
448
+ const documentFile = path.resolve(URI.parse(textDocument.uri).fsPath);
449
+ return workspace.manifestErrors.map((error) => {
450
+ const directiveError = isCSSDirectiveError(error) ? error : void 0;
451
+ const source = directiveError?.source;
452
+ return {
453
+ range: source && (!source.file || path.resolve(source.file) === documentFile) ? this.createCSSDirectiveRange(source, textDocument, documentFile, 0) : {
454
+ start: {
455
+ line: 0,
456
+ character: 0
457
+ },
458
+ end: {
459
+ line: 0,
460
+ character: 0
461
+ }
462
+ },
463
+ severity: DiagnosticSeverity.Error,
464
+ code: "manifest-loading-error",
465
+ source: "Master CSS",
466
+ message: `Failed to load Master CSS manifest: ${error instanceof Error ? error.message : String(error)}`,
467
+ relatedInformation: directiveError ? this.createCSSDirectiveRelatedInformation(directiveError.related, textDocument, documentFile, 0) : void 0
468
+ };
469
+ });
470
+ }
471
+ createCSSDirectiveDiagnostic(error, textDocument, documentFile, sourceOffset) {
472
+ if (error.source?.file && path.resolve(error.source.file) !== documentFile) return;
473
+ return {
474
+ range: this.createCSSDirectiveRange(error.source, textDocument, documentFile, sourceOffset),
475
+ severity: DiagnosticSeverity.Error,
476
+ code: error.code,
477
+ source: "Master CSS",
478
+ message: error.message,
479
+ relatedInformation: this.createCSSDirectiveRelatedInformation(error.related, textDocument, documentFile, sourceOffset)
480
+ };
481
+ }
482
+ createCSSDirectiveRelatedInformation(related, textDocument, documentFile, sourceOffset) {
483
+ if (!related?.length) return;
484
+ return related.map(({ message, source }) => ({
485
+ message,
486
+ location: {
487
+ uri: source?.file ? URI.file(source.file).toString() : textDocument.uri,
488
+ range: this.createCSSDirectiveRange(source, textDocument, documentFile, sourceOffset)
489
+ }
490
+ }));
491
+ }
492
+ createCSSDirectiveRange(source, textDocument, documentFile, sourceOffset) {
493
+ if (source?.file && path.resolve(source.file) !== documentFile) return source.loc ? {
494
+ start: {
495
+ line: Math.max(0, source.loc.start.line - 1),
496
+ character: Math.max(0, source.loc.start.column - 1)
497
+ },
498
+ end: {
499
+ line: Math.max(0, source.loc.end.line - 1),
500
+ character: Math.max(0, source.loc.end.column - 1)
501
+ }
502
+ } : {
503
+ start: {
504
+ line: 0,
505
+ character: 0
506
+ },
507
+ end: {
508
+ line: 0,
509
+ character: 0
510
+ }
511
+ };
512
+ const start = Math.max(0, (source?.range.start || 0) + sourceOffset);
513
+ const end = Math.max(start, (source?.range.end || 0) + sourceOffset);
514
+ return {
515
+ start: textDocument.positionAt(start),
516
+ end: textDocument.positionAt(end)
517
+ };
518
+ }
519
+ refreshSemanticTokens() {
520
+ if (this.settings?.embeddedSyntaxHighlighting !== "always") return;
521
+ if (!this.clientCapabilities.workspace?.semanticTokens?.refreshSupport) return;
522
+ this.connection.languages.semanticTokens.refresh();
523
+ }
524
+ stop() {
525
+ this.connection.sendNotification("masterCSS/dispose");
526
+ this.disposables.forEach((disposable) => disposable.dispose());
527
+ this.disposables.length = 0;
528
+ this.connection.dispose();
529
+ this.initializing = void 0;
530
+ }
531
+ };
532
+ //#endregion
533
+ export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, CSSLanguageServer as default };
@@ -0,0 +1,3 @@
1
+ import settings, { Settings } from "./settings.js";
2
+ import CSSLanguageServer, { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, Workspace, default as core_default } from "./core.js";
3
+ export { ACTIVE_SEMANTIC_TOKENS_REQUEST, CSSLanguageServer, DOCUMENT_SEMANTIC_TOKENS_REQUEST, type Settings, type Workspace, core_default as default, settings };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import settings from "./settings.js";
2
+ import CSSLanguageServer, { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST } from "./core.js";
3
+ export { ACTIVE_SEMANTIC_TOKENS_REQUEST, CSSLanguageServer, DOCUMENT_SEMANTIC_TOKENS_REQUEST, CSSLanguageServer as default, settings };
package/dist/server.d.ts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export { };
package/dist/server.js ADDED
@@ -0,0 +1,8 @@
1
+ import CSSLanguageServer from "./core.js";
2
+ //#region src/server.ts
3
+ new CSSLanguageServer(void 0, { verbose: true }).start();
4
+ process.on("unhandledRejection", (error) => {
5
+ console.error("Unhandled rejection", error);
6
+ });
7
+ //#endregion
8
+ export {};
@@ -0,0 +1,11 @@
1
+ import { Settings as Settings$1 } from "@master/css-language-service";
2
+ import { Pattern } from "fast-glob";
3
+
4
+ //#region src/settings.d.ts
5
+ declare const settings: Settings;
6
+ declare type Settings = Settings$1 & {
7
+ workspaces?: Pattern[] | 'auto';
8
+ verbose?: boolean;
9
+ };
10
+ //#endregion
11
+ export { Settings, settings as default };
@@ -0,0 +1,9 @@
1
+ import { settings as settings$1 } from "@master/css-language-service";
2
+ //#region src/settings.ts
3
+ const settings = {
4
+ ...settings$1,
5
+ workspaces: "auto",
6
+ verbose: false
7
+ };
8
+ //#endregion
9
+ export { settings as default };
@@ -0,0 +1,9 @@
1
+ import { TextDocument } from "vscode-languageserver-textdocument";
2
+
3
+ //#region src/utils/create-document.d.ts
4
+ declare function createDocument(text: string, options?: {
5
+ lang?: string;
6
+ dir?: string;
7
+ }): TextDocument;
8
+ //#endregion
9
+ export { createDocument as default };
@@ -0,0 +1,28 @@
1
+ import { TextDocument } from "vscode-languageserver-textdocument";
2
+ import { URI } from "vscode-uri";
3
+ import { nanoid } from "nanoid";
4
+ import path from "path";
5
+ //#region src/utils/create-document.ts
6
+ const extOfLang = {
7
+ typescript: "ts",
8
+ typescriptreact: "tsx",
9
+ javascript: "js",
10
+ javascriptreact: "jsx",
11
+ css: "css",
12
+ scss: "scss",
13
+ less: "less",
14
+ html: "html",
15
+ json: "json",
16
+ vue: "vue",
17
+ svelte: "svelte",
18
+ astro: "astro"
19
+ };
20
+ function createDocument(text, options) {
21
+ const lang = options?.lang || "html";
22
+ const dir = options?.dir || "./";
23
+ const filePath = path.join(dir, `${nanoid()}.${extOfLang[lang]}`);
24
+ const fileURI = URI.file(filePath).toString();
25
+ return TextDocument.create(fileURI, lang, 0, text);
26
+ }
27
+ //#endregion
28
+ export { createDocument as default };
package/package.json CHANGED
@@ -1 +1,60 @@
1
- {"name":"@master/css-language-server","scripts":{"build":"techor pack --platform node --declare","dev":"pnpm run build --watch","type-check":"tsc --noEmit","lint":"eslint src","test":"jest"},"description":"Master CSS Language Server","author":"Aoyue Design LLC.","license":"MIT","dependencies":{"@master/css":"^2.0.0-rc.8","@master/css-language-service":"^2.0.0-rc.8","explore-config":"^2.5.24","js-beautify":"^1.14.7","minimatch":"^9.0.1","vscode-languageserver":"^7.0.0","vscode-languageserver-textdocument":"^1.0.9"},"main":"./dist/server.bundle.js","types":"./dist/server.d.ts","files":["dist"],"publishConfig":{"access":"public"},"version":"2.0.0-rc.8"}
1
+ {
2
+ "name": "@master/css-language-server",
3
+ "type": "module",
4
+ "description": "Master CSS Language Server",
5
+ "author": "Aoyue Design LLC.",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/master-co/css.git",
10
+ "directory": "packages/language-server"
11
+ },
12
+ "dependencies": {
13
+ "defu": "^6.1.7",
14
+ "fast-glob": "^3.3.3",
15
+ "js-beautify": "^1.15.4",
16
+ "nanoid": "^5.1.15",
17
+ "vscode-languageserver": "^10.0.0",
18
+ "vscode-languageserver-textdocument": "^1.0.12",
19
+ "vscode-uri": "^3.1.0",
20
+ "@master/css": "^2.0.0-rc.80",
21
+ "@master/css-language": "^2.0.0-rc.80",
22
+ "@master/css-language-service": "^2.0.0-rc.80",
23
+ "@master/css-project": "^2.0.0-rc.80",
24
+ "@master/css-compiler": "^2.0.0-rc.80",
25
+ "@master/css-schema": "^2.0.0-rc.80"
26
+ },
27
+ "sideEffects": false,
28
+ "main": "./dist/index.js",
29
+ "module": "./dist/index.js",
30
+ "jsnext:main": "./dist/index.js",
31
+ "esnext": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js",
37
+ "default": "./dist/index.js"
38
+ },
39
+ "./server": {
40
+ "types": "./dist/server.d.ts",
41
+ "import": "./dist/server.js",
42
+ "default": "./dist/server.js"
43
+ }
44
+ },
45
+ "files": [
46
+ "dist"
47
+ ],
48
+ "publishConfig": {
49
+ "access": "public",
50
+ "provenance": true
51
+ },
52
+ "version": "2.0.0-rc.80",
53
+ "scripts": {
54
+ "build": "tsdown --config ../../shared/tsdown-package.config.ts",
55
+ "dev": "tsdown --config ../../shared/tsdown-package.config.ts --watch",
56
+ "type-check": "tsc -b tsconfig.typecheck.json",
57
+ "lint": "eslint",
58
+ "test": "vitest"
59
+ }
60
+ }
@@ -1 +0,0 @@
1
- "use strict";var W=Object.create;var S=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var E=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of H(e))!L.call(t,i)&&i!==n&&S(t,i,{get:()=>e[i],enumerable:!(s=U(e,i))||s.enumerable});return t};var h=(t,e,n)=>(n=t!=null?W(K(t)):{},E(e||!t||!t.__esModule?S(n,"default",{value:t,enumerable:!0}):n,t));var u=require("vscode-languageserver/node"),w=require("@master/css"),b=require("minimatch"),P=require("vscode-languageserver-textdocument"),k=h(require("path")),T=require("url"),o=require("@master/css-language-service"),v=h(require("explore-config")),a=(0,u.createConnection)(u.ProposedFeatures.all),f=new u.TextDocuments(P.TextDocument),C=!1,D=!1,O=!1,l,g,I;var M=o.settings,p=new Map;a.onDidChangeConfiguration(t=>{C?p.clear():M=t.settings.masterCSS||o.settings,f.all().forEach(y)});async function B(t){if(!C)return Promise.resolve(M);let e=p.get(t);return e||(e=a.workspace.getConfiguration({scopeUri:t,section:"masterCSS"}),p.set(t,e)),e}f.onDidClose(t=>{p.delete(t.document.uri)});f.onDidOpen(t=>{y(t.document)});f.onDidSave(async t=>{k.default.parse(t.document.uri).name==="master.css"&&await A(t.document.uri)});async function y(t){l=await B(t.uri),await A(t.uri)}async function A(t){let e=await a.workspace.getWorkspaceFolders(),n;if(e?.length===1?n=e[0]:n=e?.find(s=>t.includes(s.uri)),n?.uri){let s=(0,T.fileURLToPath)(n.uri.replace("%3A",":"));I=(0,v.default)(l.config||"master.css.*",{cwd:s}),g=new w.MasterCSS(I)}}a.onInitialize(t=>{let e=t.capabilities;C=!!(e.workspace&&e.workspace.configuration),D=!!(e.workspace&&e.workspace.workspaceFolders),O=!!(e.textDocument&&e.textDocument.publishDiagnostics&&e.textDocument.publishDiagnostics.relatedInformation);let n={capabilities:{textDocumentSync:u.TextDocumentSyncKind.Incremental,completionProvider:{resolveProvider:!0,workDoneProgress:!1,triggerCharacters:[":","@","'"]},colorProvider:{},hoverProvider:!0}};return D&&(n.capabilities.workspace={workspaceFolders:{supported:!0}}),n});a.onInitialized(()=>{C&&a.client.register(u.DidChangeConfigurationNotification.type,void 0)});a.onCompletion(t=>{if(l.suggestions==!0&&x(t.textDocument.uri)){let e=t.textDocument.uri,n=f.get(e),s=e.substring(e.lastIndexOf(".")+1),i=t.position;if(n){let c=n.getText(),d=n.offsetAt(i)??0,r=n.offsetAt({line:i.line-100,character:0})??0,F=n.offsetAt({line:i.line+100,character:0})??void 0,R=(0,o.positionCheck)(c.substring(r,F),d,r,l.classMatch).IsMatch,z=n.getText({start:{line:i.line,character:0},end:{line:i.line,character:i.character}}).trim(),m=(0,o.getLastInstance)(z,i,s);if(m.isInstance==!0&&R==!0)return(0,o.getCompletionItem)(m.lastKey,m.triggerKey,m.isStart,m.language,g);if(m.isInstance==!0&&(0,o.checkConfigColorsBlock)(n,t.position)==!0)return(0,o.getConfigColorsCompletionItem)(g)}}return[]});a.onCompletionResolve(t=>t);a.onDocumentColor(async t=>{if(l==null)return[];if(l.previewColors==!0&&x(t.textDocument.uri)){let e=t.textDocument.uri,n=f.get(e);if(n){let s=n.getText()??"";if(typeof n==null)return[];let i=await(0,o.getDocumentColors)(s,g),c=new Set;return i.filter(r=>c.has(r.index.start)?!1:(c.add(r.index.start),!0)).map(r=>({range:{start:n.positionAt(r.index.start),end:n.positionAt(r.index.end)},color:r.color}))}}return[]});a.onColorPresentation(t=>{if(l.previewColors==!0&&x(t.textDocument.uri)){let e=f.get(t.textDocument.uri);if(e){let n=e.getText(),s=["(?<=colors:\\s*{\\s*.*)([^}]*)}"],i=e.offsetAt(t.range.start)??0,c=e.offsetAt({line:t.range.start.line-100,character:0})??0,d=e.offsetAt({line:t.range.start.line+100,character:0})??void 0,r=(0,o.positionCheck)(n.substring(c,d),i,c,s);return(0,o.getColorPresentation)(t,r.IsMatch)}}return[]});a.onHover(t=>{if(l.inspect==!0&&x(t.textDocument.uri)){let e=f.get(t.textDocument.uri),n=t.position;if(e){let s=e.getText(),i=e.offsetAt(n)??0,c=e.offsetAt({line:n.line-100,character:0})??0,d=e.offsetAt({line:n.line+100,character:0})??void 0,r=(0,o.positionCheck)(s.substring(c,d),i,c,l.classMatch);if(r.IsMatch)return(0,o.doHover)(r.instance.instanceString,N(r.instance.index,e),I)}}return null});function x(t){for(let e of l.files.exclude)if((0,b.minimatch)(t,e))return!1;return!0}function N(t,e){return{start:e.positionAt(t.start),end:e.positionAt(t.end)}}f.listen(a);a.listen();