@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 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="NPM Version" src="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github">
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="Github Actions" href="https://github.com/master-co/css/actions/workflows/ci-release.yml">
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/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">
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 CSSLanguageServer from '@master/css-language-server'
64
+ import { MasterCSSLanguageServer } from '@master/css-language-server'
72
65
 
73
- const languageServer = new CSSLanguageServer(connection, customSettings)
66
+ const languageServer = new MasterCSSLanguageServer(connection, customSettings)
74
67
  ```
75
68
 
76
- `CSSLanguageServer` wraps `@master/css-language-service` with LSP workspace lifecycle, completion, hover, document color, color presentation, semantic token, and directive formatting handlers.
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 `@compose` and `@safelist`.
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 `bg:transparent !` to `bg:transparent!`. It does not run the compiler and does not change generated CSS output.
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 { settings } from '@master/css-language-server'
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`, CSS files containing the lightweight `@master entry;` marker, and `package.json` files that declare Master CSS package dependencies.
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 { ClientCapabilities, ColorPresentationParams, CompletionParams, Connection, DidChangeConfigurationParams, DocumentColorParams, DocumentFormattingParams, DocumentRangeFormattingParams, HoverParams, InitializeParams, InitializeResult, RemoteConsole, SemanticTokensParams, TextDocumentChangeEvent, TextDocumentPositionParams, TextDocuments, TextEdit, WorkspaceFolder } from "vscode-languageserver/node";
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 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
- //#region src/core.d.ts
8
- declare interface Workspace {
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?: CSSLanguageService;
12
- languageServiceSettings: Settings$1;
13
- languageRuntime?: CSSLanguageRuntime;
14
- languageRuntimeResolution?: MasterCSSWorkspacePackageResolution;
15
- languageRuntimeSource?: 'workspace' | 'bundled';
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 CSSLanguageServer {
37
+ declare class MasterCSSLanguageServer implements Disposable {
22
38
  connection: Connection;
23
- customSettings?: Settings$1 | undefined;
39
+ customSettings?: MasterCSSLanguageServerSettings | undefined;
24
40
  workspaceFolders: WorkspaceFolder[];
25
- workspaces: Map<string, Workspace>;
26
- globalWorkspace: Workspace;
41
+ workspaces: Map<string, MasterCSSWorkspace>;
42
+ globalWorkspace: MasterCSSWorkspace;
27
43
  documents: TextDocuments<TextDocument>;
28
44
  initializing?: Promise<void>;
29
45
  clientCapabilities: ClientCapabilities;
30
- settings?: Settings$1;
46
+ settings?: MasterCSSLanguageServerSettings;
31
47
  console: RemoteConsole;
32
48
  private disposables;
33
- constructor(connection?: Connection, customSettings?: Settings$1 | undefined);
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<import("vscode-languageserver-protocol").Hover | undefined>;
38
- onCompletion(params: CompletionParams): Promise<import("vscode-languageserver-protocol").CompletionItem[] | undefined>;
39
- onDocumentColor(params: DocumentColorParams): Promise<import("vscode-languageserver-protocol").ColorInformation[]>;
40
- onColorPresentation(params: ColorPresentationParams): Promise<import("vscode-languageserver-protocol").ColorPresentation[]>;
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<import("vscode-languageserver-protocol").SemanticTokens>;
45
- onDocumentSemanticTokens(params: SemanticTokensParams): Promise<import("vscode-languageserver-protocol").SemanticTokens>;
46
- onActiveSemanticTokens(params: TextDocumentPositionParams): Promise<import("vscode-languageserver-protocol").SemanticTokens>;
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: Workspace): Promise<void>;
78
+ initWorkspaceLanguageService(workspace: MasterCSSWorkspace): Promise<void>;
79
+ private ensureWorkspaceLanguageService;
54
80
  private loadWorkspacePlan;
55
- private loadWorkspaceLanguageRuntime;
56
- private importWorkspaceModule;
57
- destroyLanguageService(workspace: Workspace): void;
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
- stop(): void;
93
+ dispose(): void;
94
+ [Symbol.dispose](): void;
67
95
  }
68
- //#endregion
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 settings$1 from "./settings.js";
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 { 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";
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 { 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";
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
- import { CSSDirectiveError } from "@master/css-schema/css-directives";
18
- //#region src/core.ts
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
- DECLARATION_SEPARATOR_TRIGGER_CHARACTER,
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 CSSLanguageServer = class {
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
- languageRuntime: defaultCSSLanguageRuntime,
122
- languageRuntimeSource: "bundled"
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, settings$1);
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 = new Promise(async (resolve) => {
148
- await Promise.all(this.workspaceFolders.map((folder) => this.initWorkspaceFolder(folder.uri)));
149
- resolve();
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, settings$1);
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
- 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);
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.splice(workspace.openedTextDocuments.indexOf(params.document), 1);
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, settings$1);
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, settings$1);
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") for (const workspaceDir of await findMasterCSSWorkspaceDirectories(workspaceFolderCWD)) resolvedWorkspaceDirectories.add(workspaceDir);
301
- else if (workspaces?.length) (await glob(workspaces, {
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 findCSSManifestEntryFiles(workspaceDir)
298
+ planEntries: [...await discoverManifestEntries({ root: workspaceDir })]
315
299
  });
316
300
  }
317
301
  }
318
302
  async initWorkspaceLanguageService(workspace) {
319
- workspace.languageRuntime = await this.loadWorkspaceLanguageRuntime(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.languageService = new CSSLanguageService({
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: workspacePlan
336
- }, { runtime: workspace.languageRuntime });
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 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;
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 loadWorkspaceLanguageRuntime(workspace) {
353
+ async loadWorkspaceBaseManifest(workspace) {
343
354
  if (workspace === this.globalWorkspace || !workspace.uri) {
344
- workspace.languageRuntimeSource = "bundled";
345
- return defaultCSSLanguageRuntime;
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.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;
362
+ workspace.manifestResolution = resolution;
360
363
  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}`);
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.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
- };
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.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("; ")}`);
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 defaultCSSLanguageRuntime;
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
- compileCSSManifest(source, {
460
+ compileManifestSync(source, {
436
461
  from: documentFile,
437
- baseManifest: (workspace.languageRuntime ?? defaultCSSLanguageRuntime).defaultManifest
462
+ baseManifest: workspace.baseManifest ?? defaultManifest
438
463
  });
439
464
  } catch (error) {
440
- if (!isCSSDirectiveError(error)) continue;
441
- const diagnostic = this.createCSSDirectiveDiagnostic(error, textDocument, documentFile, offset);
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.map((error) => {
450
- const directiveError = isCSSDirectiveError(error) ? error : void 0;
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
- stop() {
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
- //#endregion
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 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 };
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 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 };
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 CSSLanguageServer from "./core.js";
2
- //#region src/server.ts
3
- new CSSLanguageServer(void 0, { verbose: true }).start();
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 {};
@@ -1,10 +1,11 @@
1
- import { Settings as Settings$1 } from "@master/css-language-service";
1
+ import { MasterCSSLanguageServiceSettings } from "@master/css-language-service";
2
2
  import { Pattern } from "fast-glob";
3
- //#region src/settings.d.ts
4
- declare const settings: Settings;
5
- declare type Settings = Settings$1 & {
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
- //#endregion
10
- export { Settings, settings as default };
11
+ export { MasterCSSLanguageServerSettings, defaultLanguageServerSettings };
package/dist/settings.js CHANGED
@@ -1,9 +1,8 @@
1
- import { settings as settings$1 } from "@master/css-language-service";
2
- //#region src/settings.ts
3
- const settings = {
4
- ...settings$1,
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
- //#endregion
9
- export { settings as default };
7
+ });
8
+ export { defaultLanguageServerSettings };
package/package.json CHANGED
@@ -1,60 +1,58 @@
1
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-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
- "./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.88",
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
- }
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 };