@master/css-language-server 2.0.0-rc.88 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -19
- package/dist/core.d.ts +60 -33
- package/dist/core.js +210 -138
- package/dist/diagnostics.js +78 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/internal/src/workspace-directories.js +63 -0
- package/dist/internal/src/workspace.js +70 -0
- package/dist/server.js +3 -4
- package/dist/settings.d.ts +8 -7
- package/dist/settings.js +6 -7
- package/package.json +56 -58
- package/LICENSE +0 -21
- package/dist/utils/create-document.d.ts +0 -8
- package/dist/utils/create-document.js +0 -28
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<picture>
|
|
18
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
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="
|
|
20
|
+
<img alt="GitHub release" src="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github">
|
|
21
21
|
</picture>
|
|
22
22
|
</a>
|
|
23
23
|
<a aria-label="NPM Package" href="https://www.npmjs.com/package/@master/css-language-server">
|
|
@@ -34,13 +34,6 @@
|
|
|
34
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
35
|
</picture>
|
|
36
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
37
|
<a aria-label="Follow @mastercorg" href="https://twitter.com/mastercorg">
|
|
45
38
|
<picture>
|
|
46
39
|
<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">
|
|
@@ -48,11 +41,11 @@
|
|
|
48
41
|
<img alt="Follow @mastercorg" src="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
|
|
49
42
|
</picture>
|
|
50
43
|
</a>
|
|
51
|
-
<a aria-label="
|
|
44
|
+
<a aria-label="GitHub Actions" href="https://github.com/master-co/css/actions/workflows/release.yml">
|
|
52
45
|
<picture>
|
|
53
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/
|
|
54
|
-
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/
|
|
55
|
-
<img alt="
|
|
46
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=main&label=%20&color=212022&logo=githubactions&style=for-the-badge">
|
|
47
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=main&label=%20&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
|
48
|
+
<img alt="GitHub release workflow" src="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=main&label=%20&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
|
56
49
|
</picture>
|
|
57
50
|
</a>
|
|
58
51
|
</p>
|
|
@@ -68,12 +61,12 @@ npm install @master/css-language-server
|
|
|
68
61
|
## Usage
|
|
69
62
|
|
|
70
63
|
```js
|
|
71
|
-
import
|
|
64
|
+
import { MasterCSSLanguageServer } from '@master/css-language-server'
|
|
72
65
|
|
|
73
|
-
const languageServer = new
|
|
66
|
+
const languageServer = new MasterCSSLanguageServer(connection, customSettings)
|
|
74
67
|
```
|
|
75
68
|
|
|
76
|
-
`
|
|
69
|
+
`MasterCSSLanguageServer` wraps `@master/css-language-service` with LSP workspace lifecycle, completion, hover, document color, color presentation, semantic token, and directive formatting handlers. Call `dispose()` when the transport shuts down.
|
|
77
70
|
|
|
78
71
|
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
72
|
|
|
@@ -87,18 +80,18 @@ The language server supports full-document and active-position semantic tokens.
|
|
|
87
80
|
| `active` | Uses the VS Code extension request for active class-context highlighting. |
|
|
88
81
|
| `off` | Disables embedded utility highlighting. |
|
|
89
82
|
|
|
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 `@
|
|
83
|
+
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 `@safelist`.
|
|
91
84
|
|
|
92
85
|
## Formatting
|
|
93
86
|
|
|
94
87
|
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
88
|
|
|
96
|
-
Directive formatting normalizes safe directive spacing and repairs class-list important markers such as `
|
|
89
|
+
Directive formatting normalizes safe directive spacing and repairs class-list important markers such as `(background-color:transparent) !` to `(background-color:transparent)!`. It does not run the compiler and does not change generated CSS output.
|
|
97
90
|
|
|
98
91
|
## Settings
|
|
99
92
|
|
|
100
93
|
```js
|
|
101
|
-
import {
|
|
94
|
+
import { defaultLanguageServerSettings } from '@master/css-language-server'
|
|
102
95
|
```
|
|
103
96
|
|
|
104
97
|
| Setting | Type | Default | Description |
|
|
@@ -108,4 +101,4 @@ import { settings } from '@master/css-language-server'
|
|
|
108
101
|
| `formatDirectives` | `boolean` | `true` | Enables LSP document and range formatting for Master CSS directives. |
|
|
109
102
|
| `embeddedSyntaxHighlighting` | `'active' \| 'always' \| 'off'` | `'active'` | Inherited language-service semantic token mode. |
|
|
110
103
|
|
|
111
|
-
With `workspaces: 'auto'`, the server creates workspaces from CSS files importing `@master/css`,
|
|
104
|
+
With `workspaces: 'auto'`, the server creates workspaces from CSS files importing `@master/css`, and `package.json` files that declare Master CSS package dependencies.
|
package/dist/core.d.ts
CHANGED
|
@@ -1,69 +1,96 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MasterCSSLanguageServerSettings } from "./settings.js";
|
|
2
|
+
import { ClientCapabilities, ColorInformation, ColorPresentation, ColorPresentationParams, CompletionItem, CompletionParams, Connection, DidChangeConfigurationParams, DocumentColorParams, DocumentFormattingParams, DocumentRangeFormattingParams, Hover, HoverParams, InitializeParams, InitializeResult, RemoteConsole, SemanticTokens, SemanticTokensParams, TextDocumentChangeEvent, TextDocumentPositionParams, TextDocuments, TextEdit, WorkspaceFolder } from "vscode-languageserver/node";
|
|
2
3
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { MasterCSSLanguageService } from "@master/css-language-service";
|
|
5
|
+
import { MasterCSSManifest } from "@master/css-schema/manifest";
|
|
6
|
+
interface MasterCSSResolvedWorkspacePackage {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly entry: string;
|
|
9
|
+
readonly directory: string;
|
|
10
|
+
readonly packageJSON?: string;
|
|
11
|
+
readonly version?: string;
|
|
12
|
+
}
|
|
13
|
+
interface MasterCSSWorkspacePackageResolution {
|
|
14
|
+
readonly workspaceDir: string;
|
|
15
|
+
readonly css?: MasterCSSResolvedWorkspacePackage;
|
|
16
|
+
readonly presetManifest?: MasterCSSResolvedWorkspacePackage;
|
|
17
|
+
readonly languageServer?: MasterCSSResolvedWorkspacePackage;
|
|
18
|
+
readonly errors: readonly {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly message: string;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
declare interface MasterCSSWorkspace {
|
|
9
24
|
uri: string;
|
|
10
25
|
openedTextDocuments: TextDocument[];
|
|
11
|
-
languageService?:
|
|
12
|
-
languageServiceSettings:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
languageService?: MasterCSSLanguageService;
|
|
27
|
+
languageServiceSettings: MasterCSSLanguageServerSettings;
|
|
28
|
+
baseManifest?: MasterCSSManifest;
|
|
29
|
+
manifestResolution?: MasterCSSWorkspacePackageResolution;
|
|
30
|
+
manifestSource?: 'workspace' | 'bundled';
|
|
16
31
|
manifestErrors?: unknown[];
|
|
17
32
|
planEntries?: string[];
|
|
33
|
+
designSystemFiles?: readonly string[];
|
|
18
34
|
}
|
|
19
35
|
declare const ACTIVE_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderActiveSemanticTokens";
|
|
20
36
|
declare const DOCUMENT_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderDocumentSemanticTokens";
|
|
21
|
-
declare class
|
|
37
|
+
declare class MasterCSSLanguageServer implements Disposable {
|
|
22
38
|
connection: Connection;
|
|
23
|
-
customSettings?:
|
|
39
|
+
customSettings?: MasterCSSLanguageServerSettings | undefined;
|
|
24
40
|
workspaceFolders: WorkspaceFolder[];
|
|
25
|
-
workspaces: Map<string,
|
|
26
|
-
globalWorkspace:
|
|
41
|
+
workspaces: Map<string, MasterCSSWorkspace>;
|
|
42
|
+
globalWorkspace: MasterCSSWorkspace;
|
|
27
43
|
documents: TextDocuments<TextDocument>;
|
|
28
44
|
initializing?: Promise<void>;
|
|
29
45
|
clientCapabilities: ClientCapabilities;
|
|
30
|
-
settings?:
|
|
46
|
+
settings?: MasterCSSLanguageServerSettings;
|
|
31
47
|
console: RemoteConsole;
|
|
32
48
|
private disposables;
|
|
33
|
-
|
|
49
|
+
private workspaceLanguageServiceInitializations;
|
|
50
|
+
private disposed;
|
|
51
|
+
constructor(connection?: Connection, customSettings?: MasterCSSLanguageServerSettings | undefined);
|
|
34
52
|
start(): void;
|
|
35
53
|
init(): Promise<void>;
|
|
36
54
|
onInitialize(params: InitializeParams): InitializeResult;
|
|
37
|
-
onHover(params: HoverParams): Promise<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
onHover(params: HoverParams): Promise<Hover | undefined>;
|
|
56
|
+
onDefinition(params: TextDocumentPositionParams): Promise<{
|
|
57
|
+
uri: string;
|
|
58
|
+
range: {
|
|
59
|
+
start: import("vscode-languageserver-textdocument").Position;
|
|
60
|
+
end: import("vscode-languageserver-textdocument").Position;
|
|
61
|
+
};
|
|
62
|
+
} | undefined>;
|
|
63
|
+
onCompletion(params: CompletionParams): Promise<CompletionItem[] | undefined>;
|
|
64
|
+
onDocumentColor(params: DocumentColorParams): Promise<ColorInformation[]>;
|
|
65
|
+
onColorPresentation(params: ColorPresentationParams): Promise<ColorPresentation[]>;
|
|
41
66
|
private getWorkspaceDocument;
|
|
42
67
|
onDocumentFormatting(params: DocumentFormattingParams): Promise<TextEdit[]>;
|
|
43
68
|
onDocumentRangeFormatting(params: DocumentRangeFormattingParams): Promise<TextEdit[]>;
|
|
44
|
-
onSemanticTokens(params: SemanticTokensParams): Promise<
|
|
45
|
-
onDocumentSemanticTokens(params: SemanticTokensParams): Promise<
|
|
46
|
-
onActiveSemanticTokens(params: TextDocumentPositionParams): Promise<
|
|
69
|
+
onSemanticTokens(params: SemanticTokensParams): Promise<SemanticTokens>;
|
|
70
|
+
onDocumentSemanticTokens(params: SemanticTokensParams): Promise<SemanticTokens>;
|
|
71
|
+
onActiveSemanticTokens(params: TextDocumentPositionParams): Promise<SemanticTokens>;
|
|
47
72
|
onDidOpen(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
|
|
48
73
|
onDidChangeContent(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
|
|
49
74
|
onDidClose(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
|
|
50
75
|
onDidSave(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
|
|
51
76
|
onDidChangeConfiguration({ settings: changedSettings }: DidChangeConfigurationParams): Promise<void>;
|
|
52
77
|
private initWorkspaceFolder;
|
|
53
|
-
initWorkspaceLanguageService(workspace:
|
|
78
|
+
initWorkspaceLanguageService(workspace: MasterCSSWorkspace): Promise<void>;
|
|
79
|
+
private ensureWorkspaceLanguageService;
|
|
54
80
|
private loadWorkspacePlan;
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
findClosestWorkspace(textDocumentURI: string): Workspace;
|
|
81
|
+
private loadWorkspaceBaseManifest;
|
|
82
|
+
destroyLanguageService(workspace: MasterCSSWorkspace): void;
|
|
83
|
+
findClosestWorkspace(textDocumentURI: string): MasterCSSWorkspace;
|
|
59
84
|
private publishDiagnostics;
|
|
85
|
+
private createDesignSystemDiagnostics;
|
|
60
86
|
private createCSSDirectiveDiagnostics;
|
|
61
87
|
private createManifestLoadingDiagnostics;
|
|
88
|
+
private createMasterCSSDiagnostic;
|
|
62
89
|
private createCSSDirectiveDiagnostic;
|
|
63
90
|
private createCSSDirectiveRelatedInformation;
|
|
64
91
|
private createCSSDirectiveRange;
|
|
65
92
|
private refreshSemanticTokens;
|
|
66
|
-
|
|
93
|
+
dispose(): void;
|
|
94
|
+
[Symbol.dispose](): void;
|
|
67
95
|
}
|
|
68
|
-
|
|
69
|
-
export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, Workspace, CSSLanguageServer as default };
|
|
96
|
+
export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, MasterCSSLanguageServer, MasterCSSWorkspace };
|
package/dist/core.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { discoverBuildWorkspaceDirectories } from "./internal/src/workspace-directories.js";
|
|
2
|
+
import { resolveMasterCSSWorkspacePackages } from "./internal/src/workspace.js";
|
|
3
|
+
import { defaultLanguageServerSettings } from "./settings.js";
|
|
4
|
+
import { getCSSDiagnosticSources, getMasterCSSDiagnostics, isCSSDiagnosticDocument, toCSSDirectiveError, toLSPDiagnosticSeverity } from "./diagnostics.js";
|
|
2
5
|
import { DiagnosticSeverity, TextDocumentSyncKind, TextDocuments, createConnection } from "vscode-languageserver/node";
|
|
3
6
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
4
7
|
import path from "node:path";
|
|
5
8
|
import { readFile } from "node:fs/promises";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
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";
|
|
9
|
+
import { MasterCSSLanguageService } from "@master/css-language-service";
|
|
10
|
+
import { compileManifestSync } from "@master/css-compiler/node";
|
|
11
|
+
import { discoverManifestEntries, loadProjectManifest } from "@master/css-compiler/project";
|
|
12
12
|
import { defu } from "defu";
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
13
|
+
import defaultManifestJSON from "@master/css-preset/default-manifest.json" with { type: "json" };
|
|
14
|
+
import { AT_TRIGGER_CHARACTER, INVOKED_TRIGGER_CHARACTERS, QUERY_TRIGGER_CHARACTERS, SELECTOR_TRIGGER_CHARACTERS, VALUE_TRIGGER_CHARACTERS } from "@master/css-language-service/common";
|
|
15
|
+
import { createToolingSession } from "@master/css-tooling";
|
|
16
|
+
import { SEMANTIC_TOKENS_LEGEND } from "@master/css-tooling/language";
|
|
15
17
|
import glob from "fast-glob";
|
|
16
18
|
import { URI } from "vscode-uri";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
// src/core.ts
|
|
20
|
+
const defaultManifest = defaultManifestJSON;
|
|
19
21
|
const ACTIVE_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderActiveSemanticTokens";
|
|
20
22
|
const DOCUMENT_SEMANTIC_TOKENS_REQUEST = "masterCSS/renderDocumentSemanticTokens";
|
|
21
23
|
const SERVER_CAPABILITIES = {
|
|
@@ -28,13 +30,12 @@ const SERVER_CAPABILITIES = {
|
|
|
28
30
|
...VALUE_TRIGGER_CHARACTERS,
|
|
29
31
|
...SELECTOR_TRIGGER_CHARACTERS,
|
|
30
32
|
...QUERY_TRIGGER_CHARACTERS,
|
|
31
|
-
|
|
32
|
-
AT_TRIGGER_CHARACTER,
|
|
33
|
-
GROUP_TRIGGER_CHARACTER
|
|
33
|
+
AT_TRIGGER_CHARACTER
|
|
34
34
|
])]
|
|
35
35
|
},
|
|
36
36
|
colorProvider: true,
|
|
37
37
|
hoverProvider: true,
|
|
38
|
+
definitionProvider: true,
|
|
38
39
|
documentFormattingProvider: true,
|
|
39
40
|
documentRangeFormattingProvider: true,
|
|
40
41
|
semanticTokensProvider: {
|
|
@@ -43,48 +44,6 @@ const SERVER_CAPABILITIES = {
|
|
|
43
44
|
},
|
|
44
45
|
workspace: { workspaceFolders: { supported: true } }
|
|
45
46
|
};
|
|
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
47
|
function getInitializationSettings(initializationOptions) {
|
|
89
48
|
if (!initializationOptions || typeof initializationOptions !== "object") return;
|
|
90
49
|
const options = initializationOptions;
|
|
@@ -109,7 +68,7 @@ function containsFilePath(parentPath, childPath) {
|
|
|
109
68
|
const relativePath = filePathTools.relative(parentPath, childPath);
|
|
110
69
|
return relativePath === "" || !!relativePath && relativePath !== ".." && !relativePath.startsWith(`..${filePathTools.sep}`) && !filePathTools.isAbsolute(relativePath);
|
|
111
70
|
}
|
|
112
|
-
var
|
|
71
|
+
var MasterCSSLanguageServer = class {
|
|
113
72
|
connection;
|
|
114
73
|
customSettings;
|
|
115
74
|
workspaceFolders = [];
|
|
@@ -118,8 +77,8 @@ var CSSLanguageServer = class {
|
|
|
118
77
|
uri: "",
|
|
119
78
|
openedTextDocuments: [],
|
|
120
79
|
languageServiceSettings: this.settings,
|
|
121
|
-
|
|
122
|
-
|
|
80
|
+
baseManifest: defaultManifest,
|
|
81
|
+
manifestSource: "bundled"
|
|
123
82
|
};
|
|
124
83
|
documents;
|
|
125
84
|
initializing;
|
|
@@ -127,11 +86,13 @@ var CSSLanguageServer = class {
|
|
|
127
86
|
settings;
|
|
128
87
|
console;
|
|
129
88
|
disposables = [];
|
|
89
|
+
workspaceLanguageServiceInitializations = /* @__PURE__ */ new Map();
|
|
90
|
+
disposed = false;
|
|
130
91
|
constructor(connection = process.argv.includes("--stdio") ? createConnection(process.stdin, process.stdout) : createConnection(), customSettings) {
|
|
131
92
|
this.connection = connection;
|
|
132
93
|
this.customSettings = customSettings;
|
|
133
94
|
this.documents = new TextDocuments(TextDocument);
|
|
134
|
-
this.settings = defu(this.customSettings,
|
|
95
|
+
this.settings = defu(this.customSettings, defaultLanguageServerSettings);
|
|
135
96
|
this.globalWorkspace.languageServiceSettings = this.settings;
|
|
136
97
|
this.console = new Proxy(this.connection.console, { get: (target, prop) => {
|
|
137
98
|
if (!this.settings?.verbose) return () => {};
|
|
@@ -139,14 +100,14 @@ var CSSLanguageServer = class {
|
|
|
139
100
|
} });
|
|
140
101
|
}
|
|
141
102
|
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()));
|
|
103
|
+
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.onDefinition(this.onDefinition.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
104
|
this.connection.listen();
|
|
144
105
|
}
|
|
145
106
|
init() {
|
|
146
107
|
if (this.initializing) return this.initializing;
|
|
147
|
-
return this.initializing =
|
|
148
|
-
|
|
149
|
-
|
|
108
|
+
return this.initializing = Promise.all(this.workspaceFolders.map((folder) => this.initWorkspaceFolder(folder.uri))).then(() => void 0).catch((error) => {
|
|
109
|
+
this.initializing = void 0;
|
|
110
|
+
throw error;
|
|
150
111
|
});
|
|
151
112
|
}
|
|
152
113
|
onInitialize(params) {
|
|
@@ -154,7 +115,7 @@ var CSSLanguageServer = class {
|
|
|
154
115
|
const initializationSettings = getInitializationSettings(params.initializationOptions);
|
|
155
116
|
if (initializationSettings) {
|
|
156
117
|
this.customSettings = defu(initializationSettings, this.customSettings);
|
|
157
|
-
this.settings = defu(this.customSettings,
|
|
118
|
+
this.settings = defu(this.customSettings, defaultLanguageServerSettings);
|
|
158
119
|
this.globalWorkspace.languageServiceSettings = this.settings;
|
|
159
120
|
}
|
|
160
121
|
if (params.workspaceFolders?.length) this.workspaceFolders = params.workspaceFolders;
|
|
@@ -174,6 +135,25 @@ var CSSLanguageServer = class {
|
|
|
174
135
|
if (document) return workspace.languageService.inspectSyntax(document, params.position);
|
|
175
136
|
}
|
|
176
137
|
}
|
|
138
|
+
async onDefinition(params) {
|
|
139
|
+
await this.init();
|
|
140
|
+
const service = this.findClosestWorkspace(params.textDocument.uri)?.languageService;
|
|
141
|
+
const document = this.documents.get(params.textDocument.uri);
|
|
142
|
+
if (!service || !document) return;
|
|
143
|
+
const position = service.getClassPosition(document, params.position);
|
|
144
|
+
if (!position) return;
|
|
145
|
+
const source = service.session.inspectClassName(position.token).definitionSource;
|
|
146
|
+
if (!source?.file) return;
|
|
147
|
+
const uri = URI.file(source.file).toString();
|
|
148
|
+
const target = this.documents.get(uri) ?? TextDocument.create(uri, "css", 0, await readFile(source.file, "utf8"));
|
|
149
|
+
return {
|
|
150
|
+
uri,
|
|
151
|
+
range: {
|
|
152
|
+
start: target.positionAt(source.range.start),
|
|
153
|
+
end: target.positionAt(source.range.end)
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
177
157
|
async onCompletion(params) {
|
|
178
158
|
await this.init();
|
|
179
159
|
const workspace = this.findClosestWorkspace(params.textDocument.uri);
|
|
@@ -239,25 +219,27 @@ var CSSLanguageServer = class {
|
|
|
239
219
|
await this.init();
|
|
240
220
|
const workspace = this.findClosestWorkspace(params.document.uri);
|
|
241
221
|
if (!workspace) return;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (!workspace.openedTextDocuments.
|
|
247
|
-
workspace.openedTextDocuments.push(params.document);
|
|
222
|
+
const documentIndex = workspace.openedTextDocuments.findIndex(({ uri }) => uri === params.document.uri);
|
|
223
|
+
if (documentIndex < 0) workspace.openedTextDocuments.push(params.document);
|
|
224
|
+
else workspace.openedTextDocuments[documentIndex] = params.document;
|
|
225
|
+
await this.ensureWorkspaceLanguageService(workspace);
|
|
226
|
+
if (!workspace.openedTextDocuments.some(({ uri }) => uri === params.document.uri)) return;
|
|
248
227
|
this.publishDiagnostics(params.document, workspace);
|
|
249
228
|
}
|
|
250
229
|
async onDidChangeContent(params) {
|
|
251
230
|
await this.init();
|
|
252
231
|
const workspace = this.findClosestWorkspace(params.document.uri);
|
|
253
232
|
if (!workspace) return;
|
|
233
|
+
const documentIndex = workspace.openedTextDocuments.findIndex(({ uri }) => uri === params.document.uri);
|
|
234
|
+
if (documentIndex >= 0) workspace.openedTextDocuments[documentIndex] = params.document;
|
|
254
235
|
this.publishDiagnostics(params.document, workspace);
|
|
255
236
|
}
|
|
256
237
|
async onDidClose(params) {
|
|
257
238
|
await this.init();
|
|
258
239
|
const workspace = this.findClosestWorkspace(params.document.uri);
|
|
259
240
|
if (!workspace) return;
|
|
260
|
-
workspace.openedTextDocuments.
|
|
241
|
+
const documentIndex = workspace.openedTextDocuments.findIndex(({ uri }) => uri === params.document.uri);
|
|
242
|
+
if (documentIndex >= 0) workspace.openedTextDocuments.splice(documentIndex, 1);
|
|
261
243
|
this.connection.sendDiagnostics({
|
|
262
244
|
uri: params.document.uri,
|
|
263
245
|
diagnostics: []
|
|
@@ -279,7 +261,7 @@ var CSSLanguageServer = class {
|
|
|
279
261
|
if (changedSettings?.masterCSS) {
|
|
280
262
|
this.connection.sendNotification("masterCSS/globalSettingsChanged", changedSettings.masterCSS);
|
|
281
263
|
this.customSettings = changedSettings.masterCSS;
|
|
282
|
-
this.settings = defu(this.customSettings,
|
|
264
|
+
this.settings = defu(this.customSettings, defaultLanguageServerSettings);
|
|
283
265
|
this.globalWorkspace.languageServiceSettings = this.settings;
|
|
284
266
|
this.refreshSemanticTokens();
|
|
285
267
|
this.connection.sendRequest("masterCSS/restart", { title: "Updating Master CSS settings" });
|
|
@@ -293,12 +275,14 @@ var CSSLanguageServer = class {
|
|
|
293
275
|
scopeUri: workspaceFolderURI,
|
|
294
276
|
section: "masterCSS"
|
|
295
277
|
});
|
|
296
|
-
const { workspaces, ...languageServiceSettings } = defu(customWorkspaceFolderSettings, this.customSettings,
|
|
278
|
+
const { workspaces, ...languageServiceSettings } = defu(customWorkspaceFolderSettings, this.customSettings, defaultLanguageServerSettings);
|
|
297
279
|
const resolvedWorkspaceDirectories = /* @__PURE__ */ new Set([workspaceFolderCWD]);
|
|
298
280
|
if (workspaceFolderCWD) this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
|
|
299
281
|
else this.console.info(`Registered global workspace folder`);
|
|
300
|
-
if (workspaces === "auto")
|
|
301
|
-
|
|
282
|
+
if (workspaces === "auto") {
|
|
283
|
+
const manifestEntries = await discoverManifestEntries({ root: workspaceFolderCWD });
|
|
284
|
+
for (const workspaceDir of await discoverBuildWorkspaceDirectories(workspaceFolderCWD, manifestEntries)) resolvedWorkspaceDirectories.add(workspaceDir);
|
|
285
|
+
} else if (workspaces?.length) (await glob([...workspaces], {
|
|
302
286
|
cwd: workspaceFolderCWD,
|
|
303
287
|
absolute: true,
|
|
304
288
|
onlyDirectories: true,
|
|
@@ -311,17 +295,18 @@ var CSSLanguageServer = class {
|
|
|
311
295
|
uri: workspaceURI,
|
|
312
296
|
openedTextDocuments: [],
|
|
313
297
|
languageServiceSettings,
|
|
314
|
-
planEntries: await
|
|
298
|
+
planEntries: [...await discoverManifestEntries({ root: workspaceDir })]
|
|
315
299
|
});
|
|
316
300
|
}
|
|
317
301
|
}
|
|
318
302
|
async initWorkspaceLanguageService(workspace) {
|
|
319
|
-
workspace.
|
|
303
|
+
workspace.baseManifest = await this.loadWorkspaceBaseManifest(workspace);
|
|
320
304
|
let workspacePlan;
|
|
321
305
|
workspace.manifestErrors = [];
|
|
306
|
+
workspace.designSystemFiles = [];
|
|
322
307
|
if (workspace !== this.globalWorkspace) {
|
|
323
308
|
try {
|
|
324
|
-
workspacePlan = await this.loadWorkspacePlan(workspace);
|
|
309
|
+
workspacePlan = await this.loadWorkspacePlan(workspace, workspace.baseManifest);
|
|
325
310
|
} catch (e) {
|
|
326
311
|
workspace.manifestErrors = [e];
|
|
327
312
|
this.console.info(`Failed to load manifest from ${workspace.uri}`);
|
|
@@ -330,71 +315,69 @@ var CSSLanguageServer = class {
|
|
|
330
315
|
if (workspacePlan) this.console.info(`Initialized workspace ${workspace.planEntries?.length ? "(with manifest entry)" : "(with manifest)"} ${workspace.uri}`);
|
|
331
316
|
else this.console.info(`Initialized workspace ${workspace.uri}`);
|
|
332
317
|
}
|
|
333
|
-
workspace.
|
|
318
|
+
const manifest = workspacePlan?.manifest ?? workspace.languageServiceSettings.manifest ?? workspace.baseManifest;
|
|
319
|
+
workspace.designSystemFiles = workspacePlan?.sourceGraph?.files.filter((file) => file.projectOwned).map((file) => file.source) ?? [];
|
|
320
|
+
workspace.languageService = new MasterCSSLanguageService({
|
|
334
321
|
...workspace.languageServiceSettings,
|
|
335
|
-
manifest
|
|
336
|
-
}, {
|
|
322
|
+
manifest
|
|
323
|
+
}, { session: await createToolingSession({
|
|
324
|
+
manifest,
|
|
325
|
+
nativeClassNames: workspacePlan?.nativeClassNames
|
|
326
|
+
}) });
|
|
327
|
+
}
|
|
328
|
+
async ensureWorkspaceLanguageService(workspace) {
|
|
329
|
+
if (workspace.languageService) return;
|
|
330
|
+
let initialization = this.workspaceLanguageServiceInitializations.get(workspace);
|
|
331
|
+
if (!initialization) {
|
|
332
|
+
initialization = this.initWorkspaceLanguageService(workspace);
|
|
333
|
+
this.workspaceLanguageServiceInitializations.set(workspace, initialization);
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
await initialization;
|
|
337
|
+
} finally {
|
|
338
|
+
if (this.workspaceLanguageServiceInitializations.get(workspace) === initialization) this.workspaceLanguageServiceInitializations.delete(workspace);
|
|
339
|
+
if ((this.disposed || !workspace.openedTextDocuments.length) && workspace.languageService) this.destroyLanguageService(workspace);
|
|
340
|
+
}
|
|
337
341
|
}
|
|
338
|
-
async loadWorkspacePlan(workspace) {
|
|
339
|
-
const
|
|
340
|
-
|
|
342
|
+
async loadWorkspacePlan(workspace, baseManifest) {
|
|
343
|
+
const entries = workspace.planEntries ?? [];
|
|
344
|
+
if (!entries.length) return void 0;
|
|
345
|
+
const cwd = workspace.uri ? URI.parse(workspace.uri).fsPath : process.cwd();
|
|
346
|
+
return await loadProjectManifest({
|
|
347
|
+
root: cwd,
|
|
348
|
+
entries,
|
|
349
|
+
baseManifest,
|
|
350
|
+
includeSourceGraph: Boolean(workspace.languageServiceSettings.designSystem)
|
|
351
|
+
});
|
|
341
352
|
}
|
|
342
|
-
async
|
|
353
|
+
async loadWorkspaceBaseManifest(workspace) {
|
|
343
354
|
if (workspace === this.globalWorkspace || !workspace.uri) {
|
|
344
|
-
workspace.
|
|
345
|
-
return
|
|
355
|
+
workspace.manifestSource = "bundled";
|
|
356
|
+
return defaultManifest;
|
|
346
357
|
}
|
|
347
358
|
const cwd = URI.parse(workspace.uri).fsPath;
|
|
348
359
|
let resolution;
|
|
349
360
|
try {
|
|
350
361
|
resolution = resolveMasterCSSWorkspacePackages(cwd);
|
|
351
|
-
workspace.
|
|
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;
|
|
362
|
+
workspace.manifestResolution = resolution;
|
|
360
363
|
const presetManifestPackage = resolution.presetManifest;
|
|
361
|
-
if (!
|
|
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}`);
|
|
364
|
+
if (!presetManifestPackage) throw new Error("Missing workspace package @master/css-preset/default-manifest.json.");
|
|
373
365
|
const manifest = JSON.parse(await readFile(presetManifestPackage.entry, "utf8"));
|
|
374
|
-
workspace.
|
|
375
|
-
this.console.info(`Using workspace Master CSS
|
|
376
|
-
if (resolution.errors.length) this.console.info(`
|
|
377
|
-
return
|
|
378
|
-
MasterCSS,
|
|
379
|
-
UtilityType: utilityTypeModule?.UtilityType || utilityTypeModule?.default || defaultCSSLanguageRuntime.UtilityType,
|
|
380
|
-
defaultManifest: manifest,
|
|
381
|
-
builtinKeyAliases,
|
|
382
|
-
builtinNativeValueNamespaces,
|
|
383
|
-
nativeDeclarationMatcher: matchesLanguageServiceNativeDeclaration
|
|
384
|
-
};
|
|
366
|
+
workspace.manifestSource = "workspace";
|
|
367
|
+
this.console.info(`Using workspace Master CSS manifest ${presetManifestPackage.version ?? "(unknown version)"} from ${presetManifestPackage.directory}`);
|
|
368
|
+
if (resolution.errors.length) this.console.info(`MasterCSSWorkspace Master CSS manifest optional resolution warnings: ${resolution.errors.map(({ name, message }) => `${name}: ${message}`).join("; ")}`);
|
|
369
|
+
return manifest;
|
|
385
370
|
} catch (error) {
|
|
386
|
-
workspace.
|
|
387
|
-
this.console.info(`Using bundled Master CSS
|
|
388
|
-
if (resolution?.errors.length) this.console.info(`
|
|
371
|
+
workspace.manifestSource = "bundled";
|
|
372
|
+
this.console.info(`Using bundled Master CSS manifest for ${workspace.uri}`);
|
|
373
|
+
if (resolution?.errors.length) this.console.info(`MasterCSSWorkspace Master CSS package resolution errors: ${resolution.errors.map(({ name, message }) => `${name}: ${message}`).join("; ")}`);
|
|
389
374
|
this.console.error(error instanceof Error ? error.stack || error.message : String(error));
|
|
390
|
-
return
|
|
375
|
+
return defaultManifest;
|
|
391
376
|
}
|
|
392
377
|
}
|
|
393
|
-
async importWorkspaceModule(path) {
|
|
394
|
-
return await import(pathToFileURL(path).href);
|
|
395
|
-
}
|
|
396
378
|
destroyLanguageService(workspace) {
|
|
397
379
|
this.console.info(`Destroyed workspace ${workspace.uri}`);
|
|
380
|
+
workspace.languageService?.dispose();
|
|
398
381
|
delete workspace.languageService;
|
|
399
382
|
}
|
|
400
383
|
findClosestWorkspace(textDocumentURI) {
|
|
@@ -422,23 +405,74 @@ var CSSLanguageServer = class {
|
|
|
422
405
|
const diagnostics = [];
|
|
423
406
|
diagnostics.push(...this.createManifestLoadingDiagnostics(textDocument, workspace));
|
|
424
407
|
diagnostics.push(...this.createCSSDirectiveDiagnostics(textDocument, workspace));
|
|
408
|
+
diagnostics.push(...this.createDesignSystemDiagnostics(textDocument, workspace));
|
|
425
409
|
this.connection.sendDiagnostics({
|
|
426
410
|
uri: textDocument.uri,
|
|
427
411
|
diagnostics
|
|
428
412
|
});
|
|
429
413
|
}
|
|
414
|
+
createDesignSystemDiagnostics(document, workspace) {
|
|
415
|
+
const options = workspace.languageServiceSettings.designSystem;
|
|
416
|
+
if (!options || !workspace.languageService || workspace.manifestErrors?.length || document.languageId !== "css") return [];
|
|
417
|
+
const source = path.resolve(URI.parse(document.uri).fsPath);
|
|
418
|
+
if (!workspace.designSystemFiles?.includes(source)) return [];
|
|
419
|
+
try {
|
|
420
|
+
const report = workspace.languageService.session.inspectDesignSystem({
|
|
421
|
+
...options,
|
|
422
|
+
stylesheets: [{
|
|
423
|
+
source,
|
|
424
|
+
content: document.getText()
|
|
425
|
+
}]
|
|
426
|
+
});
|
|
427
|
+
return report.diagnostics.map((item) => ({
|
|
428
|
+
range: {
|
|
429
|
+
start: document.positionAt(item.range?.start ?? 0),
|
|
430
|
+
end: document.positionAt(item.range?.end ?? 0)
|
|
431
|
+
},
|
|
432
|
+
severity: item.severity === "error" ? DiagnosticSeverity.Error : item.severity === "warning" ? DiagnosticSeverity.Warning : DiagnosticSeverity.Information,
|
|
433
|
+
source: "Master CSS",
|
|
434
|
+
code: item.code,
|
|
435
|
+
message: item.message,
|
|
436
|
+
data: {
|
|
437
|
+
version: report.version,
|
|
438
|
+
coverage: report.coverage,
|
|
439
|
+
...item.data
|
|
440
|
+
}
|
|
441
|
+
}));
|
|
442
|
+
} catch (error) {
|
|
443
|
+
return [{
|
|
444
|
+
range: {
|
|
445
|
+
start: document.positionAt(0),
|
|
446
|
+
end: document.positionAt(0)
|
|
447
|
+
},
|
|
448
|
+
severity: DiagnosticSeverity.Error,
|
|
449
|
+
source: "Master CSS",
|
|
450
|
+
code: "DESIGN_SYSTEM_INSPECTION_ERROR",
|
|
451
|
+
message: error instanceof Error ? error.message : String(error)
|
|
452
|
+
}];
|
|
453
|
+
}
|
|
454
|
+
}
|
|
430
455
|
createCSSDirectiveDiagnostics(textDocument, workspace) {
|
|
431
456
|
if (!isCSSDiagnosticDocument(textDocument)) return [];
|
|
432
457
|
const diagnostics = [];
|
|
433
458
|
const documentFile = path.resolve(URI.parse(textDocument.uri).fsPath);
|
|
434
459
|
for (const { source, offset } of getCSSDiagnosticSources(textDocument)) try {
|
|
435
|
-
|
|
460
|
+
compileManifestSync(source, {
|
|
436
461
|
from: documentFile,
|
|
437
|
-
baseManifest:
|
|
462
|
+
baseManifest: workspace.baseManifest ?? defaultManifest
|
|
438
463
|
});
|
|
439
464
|
} catch (error) {
|
|
440
|
-
|
|
441
|
-
|
|
465
|
+
const structuredDiagnostics = getMasterCSSDiagnostics(error);
|
|
466
|
+
if (structuredDiagnostics?.length) {
|
|
467
|
+
for (const structuredDiagnostic of structuredDiagnostics) {
|
|
468
|
+
const diagnostic = this.createMasterCSSDiagnostic(structuredDiagnostic, textDocument, documentFile, source, offset);
|
|
469
|
+
if (diagnostic) diagnostics.push(diagnostic);
|
|
470
|
+
}
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
const directiveError = toCSSDirectiveError(error);
|
|
474
|
+
if (!directiveError) continue;
|
|
475
|
+
const diagnostic = this.createCSSDirectiveDiagnostic(directiveError, textDocument, documentFile, offset);
|
|
442
476
|
if (diagnostic) diagnostics.push(diagnostic);
|
|
443
477
|
}
|
|
444
478
|
return diagnostics;
|
|
@@ -446,10 +480,15 @@ var CSSLanguageServer = class {
|
|
|
446
480
|
createManifestLoadingDiagnostics(textDocument, workspace) {
|
|
447
481
|
if (!workspace.manifestErrors?.length) return [];
|
|
448
482
|
const documentFile = path.resolve(URI.parse(textDocument.uri).fsPath);
|
|
449
|
-
return workspace.manifestErrors.
|
|
450
|
-
const
|
|
483
|
+
return workspace.manifestErrors.flatMap((error) => {
|
|
484
|
+
const structuredDiagnostics = getMasterCSSDiagnostics(error);
|
|
485
|
+
if (structuredDiagnostics?.length) return structuredDiagnostics.map((diagnostic) => this.createMasterCSSDiagnostic(diagnostic, textDocument, documentFile, textDocument.getText(), 0, {
|
|
486
|
+
allowExternalSource: true,
|
|
487
|
+
messagePrefix: "Failed to load Master CSS manifest: "
|
|
488
|
+
})).filter((diagnostic) => !!diagnostic);
|
|
489
|
+
const directiveError = toCSSDirectiveError(error);
|
|
451
490
|
const source = directiveError?.source;
|
|
452
|
-
return {
|
|
491
|
+
return [{
|
|
453
492
|
range: source && (!source.file || path.resolve(source.file) === documentFile) ? this.createCSSDirectiveRange(source, textDocument, documentFile, 0) : {
|
|
454
493
|
start: {
|
|
455
494
|
line: 0,
|
|
@@ -465,9 +504,36 @@ var CSSLanguageServer = class {
|
|
|
465
504
|
source: "Master CSS",
|
|
466
505
|
message: `Failed to load Master CSS manifest: ${error instanceof Error ? error.message : String(error)}`,
|
|
467
506
|
relatedInformation: directiveError ? this.createCSSDirectiveRelatedInformation(directiveError.related, textDocument, documentFile, 0) : void 0
|
|
468
|
-
};
|
|
507
|
+
}];
|
|
469
508
|
});
|
|
470
509
|
}
|
|
510
|
+
createMasterCSSDiagnostic(diagnostic, textDocument, documentFile, sourceText, sourceOffset, options = {}) {
|
|
511
|
+
const externalSource = !!diagnostic.source && path.resolve(diagnostic.source) !== documentFile;
|
|
512
|
+
if (externalSource && !options.allowExternalSource) return;
|
|
513
|
+
const sourceDocument = TextDocument.create("inmemory://master-css/diagnostic.css", "css", 0, sourceText);
|
|
514
|
+
const range = diagnostic.range && !externalSource ? {
|
|
515
|
+
start: textDocument.positionAt(sourceOffset + sourceDocument.offsetAt(diagnostic.range.start)),
|
|
516
|
+
end: textDocument.positionAt(sourceOffset + sourceDocument.offsetAt(diagnostic.range.end))
|
|
517
|
+
} : {
|
|
518
|
+
start: textDocument.positionAt(sourceOffset),
|
|
519
|
+
end: textDocument.positionAt(sourceOffset)
|
|
520
|
+
};
|
|
521
|
+
const relatedMessages = [...diagnostic.notes ?? [], ...diagnostic.help ? [diagnostic.help] : []];
|
|
522
|
+
return {
|
|
523
|
+
range,
|
|
524
|
+
severity: toLSPDiagnosticSeverity(diagnostic.severity),
|
|
525
|
+
code: diagnostic.code,
|
|
526
|
+
source: "Master CSS",
|
|
527
|
+
message: `${options.messagePrefix ?? ""}${diagnostic.message}`,
|
|
528
|
+
relatedInformation: relatedMessages.length ? relatedMessages.map((message) => ({
|
|
529
|
+
message,
|
|
530
|
+
location: {
|
|
531
|
+
uri: textDocument.uri,
|
|
532
|
+
range
|
|
533
|
+
}
|
|
534
|
+
})) : void 0
|
|
535
|
+
};
|
|
536
|
+
}
|
|
471
537
|
createCSSDirectiveDiagnostic(error, textDocument, documentFile, sourceOffset) {
|
|
472
538
|
if (error.source?.file && path.resolve(error.source.file) !== documentFile) return;
|
|
473
539
|
return {
|
|
@@ -521,13 +587,19 @@ var CSSLanguageServer = class {
|
|
|
521
587
|
if (!this.clientCapabilities.workspace?.semanticTokens?.refreshSupport) return;
|
|
522
588
|
this.connection.languages.semanticTokens.refresh();
|
|
523
589
|
}
|
|
524
|
-
|
|
590
|
+
dispose() {
|
|
591
|
+
if (this.disposed) return;
|
|
592
|
+
this.disposed = true;
|
|
525
593
|
this.connection.sendNotification("masterCSS/dispose");
|
|
594
|
+
for (const workspace of [this.globalWorkspace, ...this.workspaces.values()]) this.destroyLanguageService(workspace);
|
|
526
595
|
this.disposables.forEach((disposable) => disposable.dispose());
|
|
527
596
|
this.disposables.length = 0;
|
|
597
|
+
this.workspaceLanguageServiceInitializations.clear();
|
|
528
598
|
this.connection.dispose();
|
|
529
599
|
this.initializing = void 0;
|
|
530
600
|
}
|
|
601
|
+
[Symbol.dispose]() {
|
|
602
|
+
this.dispose();
|
|
603
|
+
}
|
|
531
604
|
};
|
|
532
|
-
|
|
533
|
-
export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, CSSLanguageServer as default };
|
|
605
|
+
export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, MasterCSSLanguageServer };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DiagnosticSeverity } from "vscode-languageserver/node";
|
|
2
|
+
import { CSSDirectiveError } from "@master/css-schema/css-directives";
|
|
3
|
+
import { MasterCSSError } from "@master/css-schema";
|
|
4
|
+
// src/diagnostics.ts
|
|
5
|
+
const CSS_DIAGNOSTIC_LANGUAGE_IDS = /* @__PURE__ */ new Set([
|
|
6
|
+
"css",
|
|
7
|
+
"scss",
|
|
8
|
+
"less"
|
|
9
|
+
]);
|
|
10
|
+
const SFC_DIAGNOSTIC_LANGUAGE_IDS = /* @__PURE__ */ new Set([
|
|
11
|
+
"vue",
|
|
12
|
+
"svelte",
|
|
13
|
+
"astro"
|
|
14
|
+
]);
|
|
15
|
+
const STYLE_BLOCK_RE = /<style\b([^>]*)>([\s\S]*?)<\/style>/gi;
|
|
16
|
+
function getMasterCSSDiagnostics(error) {
|
|
17
|
+
if (error instanceof MasterCSSError) return error.diagnostics;
|
|
18
|
+
if (!error || typeof error !== "object" || error.name !== "MasterCSSError") return;
|
|
19
|
+
const diagnostics = error.diagnostics;
|
|
20
|
+
if (!Array.isArray(diagnostics)) return;
|
|
21
|
+
return diagnostics;
|
|
22
|
+
}
|
|
23
|
+
function toLSPDiagnosticSeverity(severity) {
|
|
24
|
+
switch (severity) {
|
|
25
|
+
case "warning": return DiagnosticSeverity.Warning;
|
|
26
|
+
case "information": return DiagnosticSeverity.Information;
|
|
27
|
+
default: return DiagnosticSeverity.Error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function isCSSDiagnosticDocument(textDocument) {
|
|
31
|
+
return CSS_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId) || SFC_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId);
|
|
32
|
+
}
|
|
33
|
+
function getSFCStyleLanguage(attributes) {
|
|
34
|
+
const match = /\blang\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s>]+))/i.exec(attributes);
|
|
35
|
+
return (match?.[1] || match?.[2] || match?.[3] || "css").toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
function getCSSDiagnosticSources(textDocument) {
|
|
38
|
+
const text = textDocument.getText();
|
|
39
|
+
if (CSS_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId)) return [{
|
|
40
|
+
source: text,
|
|
41
|
+
offset: 0
|
|
42
|
+
}];
|
|
43
|
+
if (!SFC_DIAGNOSTIC_LANGUAGE_IDS.has(textDocument.languageId)) return [];
|
|
44
|
+
const sources = [];
|
|
45
|
+
STYLE_BLOCK_RE.lastIndex = 0;
|
|
46
|
+
for (const match of text.matchAll(STYLE_BLOCK_RE)) {
|
|
47
|
+
const styleLanguage = getSFCStyleLanguage(match[1]);
|
|
48
|
+
if (!CSS_DIAGNOSTIC_LANGUAGE_IDS.has(styleLanguage)) continue;
|
|
49
|
+
const source = match[2];
|
|
50
|
+
const offset = (match.index || 0) + match[0].indexOf(">") + 1;
|
|
51
|
+
sources.push({
|
|
52
|
+
source,
|
|
53
|
+
offset
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return sources;
|
|
57
|
+
}
|
|
58
|
+
function isCSSDirectiveError(error) {
|
|
59
|
+
return error instanceof CSSDirectiveError || !!error && typeof error === "object" && error.name === "CSSDirectiveError" && typeof error.code === "string";
|
|
60
|
+
}
|
|
61
|
+
function toCSSDirectiveError(error) {
|
|
62
|
+
if (isCSSDirectiveError(error)) return error;
|
|
63
|
+
if (!error || typeof error !== "object") return;
|
|
64
|
+
const diagnostic = error;
|
|
65
|
+
if (typeof diagnostic.code !== "string" || typeof diagnostic.message !== "string") return;
|
|
66
|
+
const range = diagnostic.range;
|
|
67
|
+
if (!range || typeof range !== "object") return;
|
|
68
|
+
const { start, end } = range;
|
|
69
|
+
if (typeof start !== "number" || typeof end !== "number") return;
|
|
70
|
+
return new CSSDirectiveError(diagnostic.code, diagnostic.message, {
|
|
71
|
+
...typeof diagnostic.source === "string" && diagnostic.source ? { file: diagnostic.source } : {},
|
|
72
|
+
range: {
|
|
73
|
+
start,
|
|
74
|
+
end
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
export { getCSSDiagnosticSources, getMasterCSSDiagnostics, isCSSDiagnosticDocument, toCSSDirectiveError, toLSPDiagnosticSeverity };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
export { ACTIVE_SEMANTIC_TOKENS_REQUEST,
|
|
1
|
+
import { MasterCSSLanguageServerSettings, defaultLanguageServerSettings } from "./settings.js";
|
|
2
|
+
import { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, MasterCSSLanguageServer, MasterCSSWorkspace } from "./core.js";
|
|
3
|
+
export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, MasterCSSLanguageServer, type MasterCSSLanguageServerSettings, type MasterCSSWorkspace, defaultLanguageServerSettings };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
export { ACTIVE_SEMANTIC_TOKENS_REQUEST,
|
|
1
|
+
import { defaultLanguageServerSettings } from "./settings.js";
|
|
2
|
+
import { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, MasterCSSLanguageServer } from "./core.js";
|
|
3
|
+
export { ACTIVE_SEMANTIC_TOKENS_REQUEST, DOCUMENT_SEMANTIC_TOKENS_REQUEST, MasterCSSLanguageServer, defaultLanguageServerSettings };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
2
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
3
|
+
import "node:fs";
|
|
4
|
+
// ../internal/src/workspace-directories.ts
|
|
5
|
+
const IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
6
|
+
"node_modules",
|
|
7
|
+
"dist",
|
|
8
|
+
"out",
|
|
9
|
+
".master",
|
|
10
|
+
".next",
|
|
11
|
+
".nuxt",
|
|
12
|
+
".svelte-kit"
|
|
13
|
+
]);
|
|
14
|
+
const MASTER_CSS_PACKAGE_NAME = /^@master\/css(?:$|[.-])/;
|
|
15
|
+
const DEPENDENCY_FIELDS = [
|
|
16
|
+
"dependencies",
|
|
17
|
+
"devDependencies",
|
|
18
|
+
"peerDependencies",
|
|
19
|
+
"optionalDependencies"
|
|
20
|
+
];
|
|
21
|
+
function hasMasterCSSDependency(packageJSON) {
|
|
22
|
+
return DEPENDENCY_FIELDS.some((field) => {
|
|
23
|
+
const dependencies = packageJSON[field];
|
|
24
|
+
return dependencies && typeof dependencies === "object" && Object.keys(dependencies).some((dependency) => MASTER_CSS_PACKAGE_NAME.test(dependency));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function collectPackageDirectories(directory, directories) {
|
|
28
|
+
try {
|
|
29
|
+
for (const dirent of await readdir(directory, { withFileTypes: true })) {
|
|
30
|
+
const file = join(directory, dirent.name);
|
|
31
|
+
if (dirent.isDirectory()) {
|
|
32
|
+
if (!IGNORED_DIRECTORIES.has(dirent.name)) await collectPackageDirectories(file, directories);
|
|
33
|
+
} else if (dirent.isFile() && dirent.name === "package.json") try {
|
|
34
|
+
if (hasMasterCSSDependency(JSON.parse(await readFile(file, "utf8")))) directories.add(dirname(file));
|
|
35
|
+
} catch {}
|
|
36
|
+
}
|
|
37
|
+
} catch {}
|
|
38
|
+
}
|
|
39
|
+
function isSameOrChildPath(parent, child) {
|
|
40
|
+
const path = relative(parent, child);
|
|
41
|
+
return path === "" || path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
|
|
42
|
+
}
|
|
43
|
+
function resolveEntryWorkspace(entry, directories) {
|
|
44
|
+
const absoluteEntry = resolve(entry);
|
|
45
|
+
let closest;
|
|
46
|
+
for (const directory of directories) {
|
|
47
|
+
const absoluteDirectory = resolve(directory);
|
|
48
|
+
if (isSameOrChildPath(absoluteDirectory, absoluteEntry) && (!closest || absoluteDirectory.length > closest.length)) closest = absoluteDirectory;
|
|
49
|
+
}
|
|
50
|
+
return closest ?? dirname(absoluteEntry);
|
|
51
|
+
}
|
|
52
|
+
function finalizeWorkspaceDirectories(root, packageDirectories, manifestEntries) {
|
|
53
|
+
const directories = /* @__PURE__ */ new Set([root, ...packageDirectories]);
|
|
54
|
+
for (const entry of manifestEntries) directories.add(resolveEntryWorkspace(entry, packageDirectories));
|
|
55
|
+
return Object.freeze([...directories].sort());
|
|
56
|
+
}
|
|
57
|
+
async function discoverBuildWorkspaceDirectories(rootDirectory, manifestEntries = []) {
|
|
58
|
+
const root = resolve(rootDirectory);
|
|
59
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
60
|
+
await collectPackageDirectories(root, packageDirectories);
|
|
61
|
+
return finalizeWorkspaceDirectories(root, packageDirectories, manifestEntries);
|
|
62
|
+
}
|
|
63
|
+
export { discoverBuildWorkspaceDirectories };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
4
|
+
// ../internal/src/workspace.ts
|
|
5
|
+
function readPackageJSON(file) {
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
8
|
+
} catch {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function findPackageDir(entry, packageName) {
|
|
13
|
+
let current = statSync(entry).isDirectory() ? entry : dirname(entry);
|
|
14
|
+
while (current !== dirname(current)) {
|
|
15
|
+
const packageJSONPath = join(current, "package.json");
|
|
16
|
+
if (existsSync(packageJSONPath)) {
|
|
17
|
+
const packageJSON = readPackageJSON(packageJSONPath);
|
|
18
|
+
if (packageJSON?.name === packageName) return {
|
|
19
|
+
directory: current,
|
|
20
|
+
packageJSONPath,
|
|
21
|
+
version: typeof packageJSON.version === "string" ? packageJSON.version : void 0
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
current = dirname(current);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function resolvePackage(name, resolver) {
|
|
28
|
+
const entry = resolver.resolve(name);
|
|
29
|
+
const packageRoot = findPackageDir(entry, name.startsWith("@master/css-preset/") ? "@master/css-preset" : name.startsWith("@master/css-schema/") ? "@master/css-schema" : name.startsWith("@master/css-language-server/") ? "@master/css-language-server" : name);
|
|
30
|
+
if (!packageRoot) throw new Error(`Unable to find package root for ${name} from ${entry}`);
|
|
31
|
+
return {
|
|
32
|
+
name,
|
|
33
|
+
entry,
|
|
34
|
+
directory: packageRoot.directory,
|
|
35
|
+
packageJSON: packageRoot.packageJSONPath,
|
|
36
|
+
version: packageRoot.version
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function tryResolvePackage(name, resolver, errors) {
|
|
40
|
+
try {
|
|
41
|
+
return resolvePackage(name, resolver);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
errors.push({
|
|
44
|
+
name,
|
|
45
|
+
message: error instanceof Error ? error.message : String(error)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function createWorkspaceRequire(workspaceDir) {
|
|
50
|
+
return createRequire(join(resolve(workspaceDir), "package.json"));
|
|
51
|
+
}
|
|
52
|
+
function createPackageRequire(resolvedPackage) {
|
|
53
|
+
return createRequire(resolvedPackage.packageJSON || join(resolvedPackage.directory, "package.json"));
|
|
54
|
+
}
|
|
55
|
+
function resolveMasterCSSWorkspacePackages(workspaceDir = process.cwd()) {
|
|
56
|
+
const errors = [];
|
|
57
|
+
const workspaceRequire = createWorkspaceRequire(workspaceDir);
|
|
58
|
+
const css = tryResolvePackage("@master/css", workspaceRequire, errors);
|
|
59
|
+
const result = {
|
|
60
|
+
workspaceDir: resolve(workspaceDir),
|
|
61
|
+
errors,
|
|
62
|
+
...css ? { css } : {}
|
|
63
|
+
};
|
|
64
|
+
if (css) result.presetManifest = tryResolvePackage("@master/css-preset/default-manifest.json", createPackageRequire(css), errors);
|
|
65
|
+
try {
|
|
66
|
+
result.languageServer = resolvePackage("@master/css-language-server/server", workspaceRequire);
|
|
67
|
+
} catch {}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
export { resolveMasterCSSWorkspacePackages };
|
package/dist/server.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
new
|
|
1
|
+
import { MasterCSSLanguageServer } from "./core.js";
|
|
2
|
+
// src/server.ts
|
|
3
|
+
new MasterCSSLanguageServer(void 0, { verbose: true }).start();
|
|
4
4
|
process.on("unhandledRejection", (error) => {
|
|
5
5
|
console.error("Unhandled rejection", error);
|
|
6
6
|
});
|
|
7
|
-
//#endregion
|
|
8
7
|
export {};
|
package/dist/settings.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MasterCSSLanguageServiceSettings } from "@master/css-language-service";
|
|
2
2
|
import { Pattern } from "fast-glob";
|
|
3
|
-
|
|
4
|
-
declare const
|
|
5
|
-
|
|
6
|
-
workspaces?: Pattern[] | 'auto';
|
|
3
|
+
import { MasterCSSDesignSystemOptions } from "@master/css-tooling/lint";
|
|
4
|
+
declare const defaultLanguageServerSettings: Readonly<MasterCSSLanguageServerSettings>;
|
|
5
|
+
type MasterCSSLanguageServerSettings = MasterCSSLanguageServiceSettings & {
|
|
6
|
+
workspaces?: readonly Pattern[] | 'auto';
|
|
7
7
|
verbose?: boolean;
|
|
8
|
+
/** Opt-in checks for authored CSS in this workspace's managed stylesheet graph. */
|
|
9
|
+
designSystem?: MasterCSSDesignSystemOptions;
|
|
8
10
|
};
|
|
9
|
-
|
|
10
|
-
export { Settings, settings as default };
|
|
11
|
+
export { MasterCSSLanguageServerSettings, defaultLanguageServerSettings };
|
package/dist/settings.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
...
|
|
1
|
+
import { defaultLanguageServiceSettings } from "@master/css-language-service";
|
|
2
|
+
// src/settings.ts
|
|
3
|
+
const defaultLanguageServerSettings = Object.freeze({
|
|
4
|
+
...defaultLanguageServiceSettings,
|
|
5
5
|
workspaces: "auto",
|
|
6
6
|
verbose: false
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export { settings as default };
|
|
7
|
+
});
|
|
8
|
+
export { defaultLanguageServerSettings };
|
package/package.json
CHANGED
|
@@ -1,60 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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-compiler": "^2.0.0-rc.88",
|
|
21
|
-
"@master/css": "^2.0.0-rc.88",
|
|
22
|
-
"@master/css-language-service": "^2.0.0-rc.88",
|
|
23
|
-
"@master/css-language": "^2.0.0-rc.88",
|
|
24
|
-
"@master/css-project": "^2.0.0-rc.88",
|
|
25
|
-
"@master/css-schema": "^2.0.0-rc.88"
|
|
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"
|
|
2
|
+
"name": "@master/css-language-server",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": "^24"
|
|
38
6
|
},
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "bun --bun tsdown --config ../../shared/tsdown-package.config.ts",
|
|
9
|
+
"dev": "bun --bun tsdown --config ../../shared/tsdown-package.config.ts --watch",
|
|
10
|
+
"type-check": "bun --bun tsc -b tsconfig.typecheck.json",
|
|
11
|
+
"lint": "bun --bun eslint",
|
|
12
|
+
"test": "bun --bun vitest run"
|
|
13
|
+
},
|
|
14
|
+
"description": "Master CSS Language Server",
|
|
15
|
+
"author": "Aoyue Design LLC.",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/master-co/css.git",
|
|
20
|
+
"directory": "packages/language-server"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@master/css-compiler": "2.0.0",
|
|
24
|
+
"@master/css-language-service": "2.0.0",
|
|
25
|
+
"@master/css-preset": "2.0.0",
|
|
26
|
+
"@master/css-tooling": "2.0.0",
|
|
27
|
+
"defu": "^6.1.7",
|
|
28
|
+
"fast-glob": "^3.3.3",
|
|
29
|
+
"nanoid": "^6.0.2",
|
|
30
|
+
"vscode-languageserver": "^11.0.0",
|
|
31
|
+
"vscode-languageserver-textdocument": "^1.0.16",
|
|
32
|
+
"vscode-uri": "^3.2.0",
|
|
33
|
+
"@master/css-schema": "2.0.0"
|
|
34
|
+
},
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"import": "./dist/index.js",
|
|
41
|
+
"default": "./dist/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./server": {
|
|
44
|
+
"types": "./dist/server.d.ts",
|
|
45
|
+
"import": "./dist/server.js",
|
|
46
|
+
"default": "./dist/server.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist"
|
|
51
|
+
],
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"provenance": true
|
|
55
|
+
},
|
|
56
|
+
"version": "2.0.0",
|
|
57
|
+
"gitHead": "6bf9adc4432b67e62613caea59d3b554711b4d54"
|
|
58
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
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.
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
2
|
-
//#region src/utils/create-document.d.ts
|
|
3
|
-
declare function createDocument(text: string, options?: {
|
|
4
|
-
lang?: string;
|
|
5
|
-
dir?: string;
|
|
6
|
-
}): TextDocument;
|
|
7
|
-
//#endregion
|
|
8
|
-
export { createDocument as default };
|
|
@@ -1,28 +0,0 @@
|
|
|
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 };
|