@nvl/sveltex-language-server 0.2.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +288 -0
  3. package/bin/server.js +10 -0
  4. package/dist/core/config.d.ts +126 -0
  5. package/dist/core/config.js +569 -0
  6. package/dist/core/diagnostics.d.ts +34 -0
  7. package/dist/core/diagnostics.js +67 -0
  8. package/dist/core/frontmatter-data.d.ts +74 -0
  9. package/dist/core/frontmatter-data.js +323 -0
  10. package/dist/core/frontmatter.d.ts +25 -0
  11. package/dist/core/frontmatter.js +348 -0
  12. package/dist/core/lsp-proxy.d.ts +77 -0
  13. package/dist/core/lsp-proxy.js +165 -0
  14. package/dist/core/mapper.d.ts +86 -0
  15. package/dist/core/mapper.js +223 -0
  16. package/dist/core/mapping.d.ts +59 -0
  17. package/dist/core/mapping.js +37 -0
  18. package/dist/core/markdown.d.ts +34 -0
  19. package/dist/core/markdown.js +215 -0
  20. package/dist/core/region-forwarding.d.ts +90 -0
  21. package/dist/core/region-forwarding.js +428 -0
  22. package/dist/core/region-virtual.d.ts +71 -0
  23. package/dist/core/region-virtual.js +131 -0
  24. package/dist/core/regions.d.ts +56 -0
  25. package/dist/core/regions.js +221 -0
  26. package/dist/core/remap.d.ts +84 -0
  27. package/dist/core/remap.js +272 -0
  28. package/dist/core/server-helpers.d.ts +109 -0
  29. package/dist/core/server-helpers.js +182 -0
  30. package/dist/core/server.d.ts +13 -0
  31. package/dist/core/server.js +604 -0
  32. package/dist/core/svelte-proxy.d.ts +100 -0
  33. package/dist/core/svelte-proxy.js +144 -0
  34. package/dist/core/texlab.d.ts +26 -0
  35. package/dist/core/texlab.js +121 -0
  36. package/dist/core/virtual-svelte.d.ts +32 -0
  37. package/dist/core/virtual-svelte.js +67 -0
  38. package/dist/index.d.ts +29 -0
  39. package/dist/index.js +46 -0
  40. package/package.json +73 -0
@@ -0,0 +1,74 @@
1
+ /** Documentation for one recognised frontmatter key or `<meta>` value. */
2
+ export interface FrontmatterEntryDoc {
3
+ /** A one-line description of what the key or value does. */
4
+ readonly summary: string;
5
+ /**
6
+ * The bare HTML element this key relates to, used only for the
7
+ * "[`<X>`] on MDN" link label. Set to the element type (e.g.
8
+ * `<title>`, `<base>`) or an attribute reference (e.g. `<base href>`).
9
+ */
10
+ readonly element?: string;
11
+ /** A documentation URL — MDN for HTML entries, the SvelTeX site else. */
12
+ readonly docUrl: string;
13
+ /**
14
+ * The sentence shown in a top-level key's hover describing what SvelTeX
15
+ * inserts into `<svelte:head>` for this key. Omitted for keys that
16
+ * produce no `<svelte:head>` output (e.g. `imports`). For `<meta>` /
17
+ * `<meta http-equiv>` entries the sentence is derived from `element`
18
+ * (see {@link metaHeadEffect}); for structural keys it is given here
19
+ * explicitly because the head insertion is structure-, not value-,
20
+ * shaped.
21
+ */
22
+ readonly headEffect?: string;
23
+ /**
24
+ * The HTML SvelTeX renders for this key, with `〈value〉` /
25
+ * `〈href〉` / `…` placeholders for the parts that come from the
26
+ * user's frontmatter. Shown in the hover heading
27
+ * ("renders `<title>〈value〉</title>`"). For `<meta name>` /
28
+ * `<meta http-equiv>` / `<meta charset>` keys the value is derived
29
+ * from `element` when omitted (see {@link metaRenderedHtml}). When
30
+ * no `rendersAs` resolves — e.g. for structural list keys
31
+ * (`meta` / `link`), or for `imports` — the heading is the bare
32
+ * key name with no "renders" suffix.
33
+ */
34
+ readonly rendersAs?: string;
35
+ }
36
+ /**
37
+ * Standard `<meta name="…">` values. Mirrors `@nvl/sveltex`'s `MetaName`
38
+ * type. SvelTeX accepts a metadata name as a `name:` value (array form), a
39
+ * `meta` mapping key, or a top-level key, so these are valid both as values
40
+ * and as keys.
41
+ */
42
+ export declare const META_NAMES: Readonly<Record<string, FrontmatterEntryDoc>>;
43
+ /**
44
+ * Standard `<meta http-equiv="…">` values. Mirrors `@nvl/sveltex`'s
45
+ * `MetaHttpEquiv` type. Valid as an `http-equiv:` value or written as a key.
46
+ */
47
+ export declare const META_HTTP_EQUIV: Readonly<Record<string, FrontmatterEntryDoc>>;
48
+ /**
49
+ * Returns the keys valid in a frontmatter block.
50
+ *
51
+ * @param where - The enclosing block from {@link frontmatterContext} —
52
+ * `meta` / `base` / `link`, or `undefined` for the top level.
53
+ */
54
+ export declare function keysForContext(where: string | undefined): Readonly<Record<string, FrontmatterEntryDoc>>;
55
+ /**
56
+ * Derive the HTML SvelTeX renders for a `<meta>` entry from its `element`
57
+ * string — the metadata-name and pragma-directive keys all follow one of
58
+ * two templates:
59
+ *
60
+ * - `<meta name="…">` / `<meta http-equiv="…">` — slot a
61
+ * `content="〈value〉"` attribute in before the closing `>`;
62
+ * - `<meta charset>` — the value sits in the `charset` attribute itself.
63
+ *
64
+ * @returns The rendered HTML, or `undefined` when `element` doesn't fit
65
+ * either template — structural keys (`<title>`, `<base>`, …) supply their
66
+ * own `rendersAs`.
67
+ */
68
+ export declare function metaRenderedHtml(element: string): string | undefined;
69
+ /**
70
+ * Build the head-section sentence for a `<meta>` entry; wraps
71
+ * {@link metaRenderedHtml} in a "Inserts `…` into `<svelte:head>`"
72
+ * sentence used in the per-effect sections of a top-level key's hover.
73
+ */
74
+ export declare function metaHeadEffect(element: string): string | undefined;
@@ -0,0 +1,323 @@
1
+ // File description: Static documentation tables for the SvelTeX frontmatter
2
+ // hover / completion implementation in `frontmatter.ts`.
3
+ //
4
+ // Each table maps a recognised frontmatter key (or `<meta>` name / pragma
5
+ // directive) to a {@link FrontmatterEntryDoc}: a one-line summary, an MDN
6
+ // URL, and -- for keys that render into `<svelte:head>` -- the HTML template
7
+ // SvelTeX inserts. Together these power the hover heading
8
+ // ("renders `<title>〈value〉</title>`") and the completion-item details.
9
+ //
10
+ // The tables are split out from `frontmatter.ts` because that file would
11
+ // otherwise be dominated by data: the actual hover/completion logic is only
12
+ // a few hundred lines, but the prose summaries push the combined file past
13
+ // 800 lines, which is hard to skim when looking for the algorithm rather
14
+ // than for what one specific key does.
15
+ /** Base URL of the MDN HTML element reference. */
16
+ const MDN = 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element';
17
+ /** The structural keys valid at the frontmatter top level. */
18
+ const TOP_LEVEL_STRUCTURAL = {
19
+ title: {
20
+ summary: "Sets the document's title — rendered as the page's `<title>` " +
21
+ 'element, shown in the browser tab and used by search engines ' +
22
+ 'and bookmarks.',
23
+ element: '<title>',
24
+ rendersAs: '<title>〈value〉</title>',
25
+ docUrl: `${MDN}/title`,
26
+ headEffect: "Inserts `<title>〈value〉</title>` into the page's " +
27
+ '`<svelte:head>`, where `〈value〉` is the value you set this ' +
28
+ 'property to.',
29
+ },
30
+ noscript: {
31
+ summary: 'Fallback content rendered inside a `<noscript>` element, shown ' +
32
+ 'only to browsers that have scripting disabled.',
33
+ element: '<noscript>',
34
+ rendersAs: '<noscript>〈value〉</noscript>',
35
+ docUrl: `${MDN}/noscript`,
36
+ headEffect: "Inserts `<noscript>〈value〉</noscript>` into the page's " +
37
+ '`<svelte:head>`, where `〈value〉` is the value you set this ' +
38
+ 'property to.',
39
+ },
40
+ base: {
41
+ summary: "Configures the document's `<base>` element: the base URL and " +
42
+ 'default browsing context against which relative URLs on the ' +
43
+ 'page are resolved. Set this to the URL as a shorthand for ' +
44
+ '`{ href: <url> }`, or to an object with `href` and/or ' +
45
+ '`target`; at least one of the two must be present.',
46
+ element: '<base>',
47
+ rendersAs: '<base href="〈href〉" target="〈target〉">',
48
+ docUrl: `${MDN}/base`,
49
+ headEffect: "Inserts a `<base>` element into the page's `<svelte:head>`, " +
50
+ 'with `href` and (optionally) `target` attributes taken from ' +
51
+ 'this object.',
52
+ },
53
+ meta: {
54
+ summary: 'A list of `<meta>` elements — document-level metadata such as ' +
55
+ 'the description, viewport, character set and social/Open Graph ' +
56
+ 'tags. Use the mapping form (`description: …`) where each key ' +
57
+ 'is a metadata name, or the array form (`- name: …` / ' +
58
+ '`- http-equiv: …`) where each item must include `content` ' +
59
+ 'plus either `name` or `http-equiv` (items without that pair ' +
60
+ 'are dropped).',
61
+ element: '<meta>',
62
+ docUrl: `${MDN}/meta`,
63
+ headEffect: "Inserts a `<meta>` element into the page's `<svelte:head>` " +
64
+ 'for each entry — both the array form (`- name: …`) and the ' +
65
+ 'mapping form (`description: …`) are supported.',
66
+ },
67
+ link: {
68
+ summary: 'A list of `<link>` elements — relationships to external ' +
69
+ 'resources such as stylesheets, icons and preloaded assets. ' +
70
+ 'Each item must include a `rel` attribute (items without ' +
71
+ 'one are dropped).',
72
+ element: '<link>',
73
+ docUrl: `${MDN}/link`,
74
+ headEffect: "Inserts a `<link>` element into the page's `<svelte:head>` " +
75
+ 'for each entry in the array.',
76
+ },
77
+ imports: {
78
+ summary: 'Svelte components and modules to import into the document — a ' +
79
+ 'SvelTeX convenience equivalent to writing the imports in a ' +
80
+ "`<script>` block. Each entry's key is the module path; its " +
81
+ 'value is either the binding name (default import) or an array ' +
82
+ 'of binding names (named imports).',
83
+ docUrl: 'https://sveltex.dev',
84
+ },
85
+ };
86
+ /**
87
+ * Standard `<meta name="…">` values. Mirrors `@nvl/sveltex`'s `MetaName`
88
+ * type. SvelTeX accepts a metadata name as a `name:` value (array form), a
89
+ * `meta` mapping key, or a top-level key, so these are valid both as values
90
+ * and as keys.
91
+ */
92
+ export const META_NAMES = {
93
+ charset: {
94
+ summary: "Declares the document's character encoding, emitted as " +
95
+ '`<meta charset>`. In practice this is always `utf-8`.',
96
+ element: '<meta charset>',
97
+ docUrl: `${MDN}/meta`,
98
+ },
99
+ author: {
100
+ summary: "The name of the document's author.",
101
+ element: '<meta name="author">',
102
+ docUrl: `${MDN}/meta/name`,
103
+ },
104
+ 'application-name': {
105
+ summary: 'The name of the web application the page represents; used by ' +
106
+ 'browsers when the site is pinned or installed.',
107
+ element: '<meta name="application-name">',
108
+ docUrl: `${MDN}/meta/name`,
109
+ },
110
+ description: {
111
+ summary: "A short, accurate summary of the page's content. Search " +
112
+ 'engines often show it beneath the title in results.',
113
+ element: '<meta name="description">',
114
+ docUrl: `${MDN}/meta/name`,
115
+ },
116
+ generator: {
117
+ summary: 'The identifier of the software that generated the page.',
118
+ element: '<meta name="generator">',
119
+ docUrl: `${MDN}/meta/name`,
120
+ },
121
+ keywords: {
122
+ summary: 'A comma-separated list of keywords relevant to the page — ' +
123
+ 'largely ignored by modern search engines.',
124
+ element: '<meta name="keywords">',
125
+ docUrl: `${MDN}/meta/name`,
126
+ },
127
+ viewport: {
128
+ summary: 'Hints to the browser on how to size and scale the viewport — ' +
129
+ 'essential for a page to render well on mobile devices.',
130
+ element: '<meta name="viewport">',
131
+ docUrl: `${MDN}/meta/name`,
132
+ },
133
+ referrer: {
134
+ summary: 'Controls the `Referer` header sent for requests the page ' +
135
+ 'initiates.',
136
+ element: '<meta name="referrer">',
137
+ docUrl: `${MDN}/meta/name`,
138
+ },
139
+ 'theme-color': {
140
+ summary: 'Suggests a colour for browsers to tint surrounding UI with, ' +
141
+ 'such as the address bar or the task switcher.',
142
+ element: '<meta name="theme-color">',
143
+ docUrl: `${MDN}/meta/name`,
144
+ },
145
+ 'color-scheme': {
146
+ summary: 'Declares which colour schemes (e.g. `light`, `dark`) the ' +
147
+ 'document is comfortable being rendered in.',
148
+ element: '<meta name="color-scheme">',
149
+ docUrl: `${MDN}/meta/name`,
150
+ },
151
+ };
152
+ /**
153
+ * Standard `<meta http-equiv="…">` values. Mirrors `@nvl/sveltex`'s
154
+ * `MetaHttpEquiv` type. Valid as an `http-equiv:` value or written as a key.
155
+ */
156
+ export const META_HTTP_EQUIV = {
157
+ 'content-security-policy': {
158
+ summary: 'Defines a Content Security Policy for the document, ' +
159
+ 'restricting which resources it may load and execute.',
160
+ element: '<meta http-equiv="content-security-policy">',
161
+ docUrl: `${MDN}/meta`,
162
+ },
163
+ 'default-style': {
164
+ summary: 'Sets the name of the preferred (default) stylesheet.',
165
+ element: '<meta http-equiv="default-style">',
166
+ docUrl: `${MDN}/meta`,
167
+ },
168
+ };
169
+ /** The object keys of a `meta: [{ … }]` array item. */
170
+ const META_ITEM_KEYS = {
171
+ name: {
172
+ summary: 'The kind of metadata a `<meta>` element carries ' +
173
+ '(`<meta name>`) — e.g. `description`, `viewport`, `keywords`, ' +
174
+ '`author`, `theme-color`. Must be paired with a `content`.',
175
+ element: '<meta name>',
176
+ rendersAs: '<meta name="〈value〉" content="…">',
177
+ docUrl: `${MDN}/meta#name`,
178
+ },
179
+ 'http-equiv': {
180
+ summary: 'A pragma directive — a `<meta http-equiv>` element that acts ' +
181
+ 'like the equivalent HTTP response header. Must be paired ' +
182
+ 'with a `content`.',
183
+ element: '<meta http-equiv>',
184
+ rendersAs: '<meta http-equiv="〈value〉" content="…">',
185
+ docUrl: `${MDN}/meta#http-equiv`,
186
+ },
187
+ content: {
188
+ summary: 'The value of a `<meta>` element, paired with its `name` or ' +
189
+ '`http-equiv`.',
190
+ element: '<meta content>',
191
+ rendersAs: '<meta name="…" content="〈value〉">',
192
+ docUrl: `${MDN}/meta#content`,
193
+ },
194
+ };
195
+ /** Keys valid inside a `base` block. */
196
+ const BASE_KEYS = {
197
+ href: {
198
+ summary: 'The base URL for the document (`<base href>`). Every relative ' +
199
+ 'URL on the page is resolved against it.',
200
+ element: '<base href>',
201
+ rendersAs: '<base href="〈value〉">',
202
+ docUrl: `${MDN}/base#href`,
203
+ },
204
+ target: {
205
+ summary: 'The default browsing context for links and forms ' +
206
+ '(`<base target>`) — e.g. `_blank`, `_self`, `_parent`, `_top`.',
207
+ element: '<base target>',
208
+ rendersAs: '<base target="〈value〉">',
209
+ docUrl: `${MDN}/base#target`,
210
+ },
211
+ };
212
+ /** Keys valid inside a `link` item. */
213
+ const LINK_KEYS = {
214
+ rel: {
215
+ summary: 'The relationship between the document and a linked resource ' +
216
+ '(`<link rel>`) — e.g. `stylesheet`, `icon`, `preload`, ' +
217
+ '`canonical`. Required — items without it are dropped.',
218
+ element: '<link rel>',
219
+ rendersAs: '<link rel="〈value〉">',
220
+ docUrl: `${MDN}/link#rel`,
221
+ },
222
+ href: {
223
+ summary: 'The URL of the linked resource (`<link href>`) — the ' +
224
+ 'stylesheet, icon or asset the `<link>` points to.',
225
+ element: '<link href>',
226
+ rendersAs: '<link href="〈value〉">',
227
+ docUrl: `${MDN}/link#href`,
228
+ },
229
+ as: {
230
+ summary: 'For `rel="preload"` / `rel="modulepreload"`, the kind of ' +
231
+ 'content being fetched (`<link as>`) — e.g. `script`, `style`, ' +
232
+ '`font`, `image`.',
233
+ element: '<link as>',
234
+ rendersAs: '<link as="〈value〉">',
235
+ docUrl: `${MDN}/link#as`,
236
+ },
237
+ type: {
238
+ summary: 'The MIME type of the linked resource (`<link type>`) — e.g. ' +
239
+ '`text/css` for a stylesheet.',
240
+ element: '<link type>',
241
+ rendersAs: '<link type="〈value〉">',
242
+ docUrl: `${MDN}/link#type`,
243
+ },
244
+ crossorigin: {
245
+ summary: 'The CORS policy used when fetching the linked resource ' +
246
+ '(`<link crossorigin>`) — `anonymous` or `use-credentials`.',
247
+ element: '<link crossorigin>',
248
+ rendersAs: '<link crossorigin="〈value〉">',
249
+ docUrl: `${MDN}/link#crossorigin`,
250
+ },
251
+ };
252
+ /**
253
+ * Every key valid at the frontmatter top level: the structural keys, plus the
254
+ * metadata names — which SvelTeX also accepts written directly as top-level
255
+ * keys (`description: …`), not only inside `meta`.
256
+ */
257
+ const TOP_LEVEL_KEYS = {
258
+ ...TOP_LEVEL_STRUCTURAL,
259
+ ...META_NAMES,
260
+ ...META_HTTP_EQUIV,
261
+ };
262
+ /**
263
+ * Every key valid inside a `meta` block: the metadata names and pragma
264
+ * directives (the `meta: { description: … }` mapping form) plus the object
265
+ * keys of the `meta: [{ name: … }]` array form.
266
+ */
267
+ const META_KEYS = {
268
+ ...META_NAMES,
269
+ ...META_HTTP_EQUIV,
270
+ ...META_ITEM_KEYS,
271
+ };
272
+ /**
273
+ * Returns the keys valid in a frontmatter block.
274
+ *
275
+ * @param where - The enclosing block from {@link frontmatterContext} —
276
+ * `meta` / `base` / `link`, or `undefined` for the top level.
277
+ */
278
+ export function keysForContext(where) {
279
+ switch (where) {
280
+ case 'meta':
281
+ return META_KEYS;
282
+ case 'base':
283
+ return BASE_KEYS;
284
+ case 'link':
285
+ return LINK_KEYS;
286
+ default:
287
+ return TOP_LEVEL_KEYS;
288
+ }
289
+ }
290
+ /**
291
+ * Derive the HTML SvelTeX renders for a `<meta>` entry from its `element`
292
+ * string — the metadata-name and pragma-directive keys all follow one of
293
+ * two templates:
294
+ *
295
+ * - `<meta name="…">` / `<meta http-equiv="…">` — slot a
296
+ * `content="〈value〉"` attribute in before the closing `>`;
297
+ * - `<meta charset>` — the value sits in the `charset` attribute itself.
298
+ *
299
+ * @returns The rendered HTML, or `undefined` when `element` doesn't fit
300
+ * either template — structural keys (`<title>`, `<base>`, …) supply their
301
+ * own `rendersAs`.
302
+ */
303
+ export function metaRenderedHtml(element) {
304
+ if (/^<meta (?:name|http-equiv)="[^"]+">$/u.test(element)) {
305
+ return element.replace(/>$/u, ' content="〈value〉">');
306
+ }
307
+ if (element === '<meta charset>') {
308
+ return '<meta charset="〈value〉">';
309
+ }
310
+ return undefined;
311
+ }
312
+ /**
313
+ * Build the head-section sentence for a `<meta>` entry; wraps
314
+ * {@link metaRenderedHtml} in a "Inserts `…` into `<svelte:head>`"
315
+ * sentence used in the per-effect sections of a top-level key's hover.
316
+ */
317
+ export function metaHeadEffect(element) {
318
+ const rendered = metaRenderedHtml(element);
319
+ if (rendered === undefined)
320
+ return undefined;
321
+ return (`Inserts \`${rendered}\` into the page's \`<svelte:head>\`, ` +
322
+ 'where `〈value〉` is the value you set this property to.');
323
+ }
@@ -0,0 +1,25 @@
1
+ import { type CompletionList, type Hover, type Position } from 'vscode-languageserver-protocol';
2
+ /**
3
+ * Computes the hover for a caret inside a `.sveltex` frontmatter region.
4
+ *
5
+ * @param source - Full text of the `.sveltex` document.
6
+ * @param position - The caret position, in `.sveltex` coordinates. The caller
7
+ * guarantees it falls inside a `frontmatter` region.
8
+ * @returns A {@link Hover} describing the frontmatter key — or, on a `name:` /
9
+ * `http-equiv:` line, the standard `<meta>` value — under the caret, or `null`
10
+ * when the caret is not on a token recognised in that block.
11
+ */
12
+ export declare function computeFrontmatterHover(source: string, position: Position): Hover | null;
13
+ /**
14
+ * Computes the completion list for a caret inside a `.sveltex` frontmatter
15
+ * region: the keys valid in the enclosing block when a key is being typed, or
16
+ * the standard `<meta>` `name` / `http-equiv` values when the caret is on the
17
+ * value of such an entry.
18
+ *
19
+ * @param source - Full text of the `.sveltex` document.
20
+ * @param position - The caret position, in `.sveltex` coordinates. The caller
21
+ * guarantees it falls inside a `frontmatter` region.
22
+ * @returns A {@link CompletionList} — empty (but never `null`) when nothing
23
+ * sensible can be suggested.
24
+ */
25
+ export declare function computeFrontmatterCompletion(source: string, position: Position): CompletionList;