@soda-gql/lsp 0.12.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.
@@ -0,0 +1,4408 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+ let node_module = require("node:module");
29
+ let node_url = require("node:url");
30
+ let __soda_gql_common = require("@soda-gql/common");
31
+ let graphql = require("graphql");
32
+ let node_fs = require("node:fs");
33
+ let node_path = require("node:path");
34
+ let __soda_gql_codegen = require("@soda-gql/codegen");
35
+ let neverthrow = require("neverthrow");
36
+ let __soda_gql_config = require("@soda-gql/config");
37
+ let vscode_languageserver_node = require("vscode-languageserver/node");
38
+ let vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
39
+ let __soda_gql_builder = require("@soda-gql/builder");
40
+ let typescript = require("typescript");
41
+ typescript = __toESM(typescript);
42
+ let graphql_language_service = require("graphql-language-service");
43
+
44
+ //#region packages/lsp/src/fragment-args-preprocessor.ts
45
+ /**
46
+ * Find the matching closing parenthesis for a balanced group.
47
+ * Handles nested parentheses, string literals, and comments.
48
+ * Returns the index of the closing ')' or -1 if not found.
49
+ */
50
+ const findMatchingParen = (content, openIndex) => {
51
+ let depth = 1;
52
+ let inString = false;
53
+ for (let i = openIndex + 1; i < content.length; i++) {
54
+ const ch = content[i];
55
+ if (ch === undefined) break;
56
+ if (inString) {
57
+ if (ch === inString) {
58
+ let backslashes = 0;
59
+ for (let j = i - 1; j >= 0 && content[j] === "\\"; j--) {
60
+ backslashes++;
61
+ }
62
+ if (backslashes % 2 === 0) {
63
+ inString = false;
64
+ }
65
+ }
66
+ continue;
67
+ }
68
+ if (ch === "\"" || ch === "'") {
69
+ inString = ch;
70
+ continue;
71
+ }
72
+ if (ch === "(") {
73
+ depth++;
74
+ } else if (ch === ")") {
75
+ depth--;
76
+ if (depth === 0) {
77
+ return i;
78
+ }
79
+ }
80
+ }
81
+ return -1;
82
+ };
83
+ /**
84
+ * Replace a range [start, end] (inclusive) with spaces, preserving newlines.
85
+ */
86
+ const replaceWithSpaces = (content, start, end) => {
87
+ let result = content.slice(0, start);
88
+ for (let i = start; i <= end; i++) {
89
+ result += content[i] === "\n" ? "\n" : " ";
90
+ }
91
+ result += content.slice(end + 1);
92
+ return result;
93
+ };
94
+ const FRAGMENT_DEF_PATTERN = /\bfragment\s+(\w+)\s*\(/g;
95
+ const FRAGMENT_DEF_CURRIED_PATTERN = /\bfragment\s+\w+\s+on\s+\w+\s*\(/g;
96
+ const FRAGMENT_SPREAD_PATTERN = /\.\.\.(\w+)\s*\(/g;
97
+ /**
98
+ * Preprocess Fragment Arguments RFC syntax by replacing argument lists with spaces.
99
+ *
100
+ * Transforms:
101
+ * - `fragment UserProfile($showEmail: Boolean = false) on User` → `fragment UserProfile on User`
102
+ * - `...UserProfile(showEmail: true)` → `...UserProfile `
103
+ */
104
+ const preprocessFragmentArgs = (content) => {
105
+ let result = content;
106
+ let modified = false;
107
+ let match;
108
+ FRAGMENT_DEF_PATTERN.lastIndex = 0;
109
+ while ((match = FRAGMENT_DEF_PATTERN.exec(result)) !== null) {
110
+ const openParenIndex = match.index + match[0].length - 1;
111
+ const closeParenIndex = findMatchingParen(result, openParenIndex);
112
+ if (closeParenIndex === -1) {
113
+ continue;
114
+ }
115
+ const afterParen = result.slice(closeParenIndex + 1).trimStart();
116
+ if (!afterParen.startsWith("on")) {
117
+ continue;
118
+ }
119
+ result = replaceWithSpaces(result, openParenIndex, closeParenIndex);
120
+ modified = true;
121
+ FRAGMENT_DEF_PATTERN.lastIndex = 0;
122
+ }
123
+ FRAGMENT_DEF_CURRIED_PATTERN.lastIndex = 0;
124
+ while ((match = FRAGMENT_DEF_CURRIED_PATTERN.exec(result)) !== null) {
125
+ const openParenIndex = match.index + match[0].length - 1;
126
+ const closeParenIndex = findMatchingParen(result, openParenIndex);
127
+ if (closeParenIndex === -1) {
128
+ continue;
129
+ }
130
+ const afterParen = result.slice(closeParenIndex + 1).trimStart();
131
+ if (!afterParen.startsWith("{")) {
132
+ continue;
133
+ }
134
+ result = replaceWithSpaces(result, openParenIndex, closeParenIndex);
135
+ modified = true;
136
+ FRAGMENT_DEF_CURRIED_PATTERN.lastIndex = 0;
137
+ }
138
+ FRAGMENT_SPREAD_PATTERN.lastIndex = 0;
139
+ while ((match = FRAGMENT_SPREAD_PATTERN.exec(result)) !== null) {
140
+ const openParenIndex = match.index + match[0].length - 1;
141
+ const closeParenIndex = findMatchingParen(result, openParenIndex);
142
+ if (closeParenIndex === -1) {
143
+ continue;
144
+ }
145
+ result = replaceWithSpaces(result, openParenIndex, closeParenIndex);
146
+ modified = true;
147
+ FRAGMENT_SPREAD_PATTERN.lastIndex = 0;
148
+ }
149
+ return {
150
+ preprocessed: result,
151
+ modified
152
+ };
153
+ };
154
+
155
+ //#endregion
156
+ //#region packages/lsp/src/document-manager.ts
157
+ /**
158
+ * Document manager: tracks open documents and extracts tagged templates using SWC.
159
+ * @module
160
+ */
161
+ const OPERATION_KINDS = new Set([
162
+ "query",
163
+ "mutation",
164
+ "subscription",
165
+ "fragment"
166
+ ]);
167
+ const isOperationKind = (value) => OPERATION_KINDS.has(value);
168
+ /**
169
+ * Collect gql identifiers from import declarations.
170
+ * Adapted from builder's collectGqlIdentifiers pattern.
171
+ */
172
+ const collectGqlIdentifiers = (module$1, filePath, helper) => {
173
+ const identifiers = new Set();
174
+ for (const item of module$1.body) {
175
+ let declaration = null;
176
+ if (item.type === "ImportDeclaration") {
177
+ declaration = item;
178
+ } else if ("declaration" in item && item.declaration && item.declaration.type === "ImportDeclaration") {
179
+ declaration = item.declaration;
180
+ }
181
+ if (!declaration) {
182
+ continue;
183
+ }
184
+ if (!helper.isGraphqlSystemImportSpecifier({
185
+ filePath,
186
+ specifier: declaration.source.value
187
+ })) {
188
+ continue;
189
+ }
190
+ for (const specifier of declaration.specifiers ?? []) {
191
+ if (specifier.type === "ImportSpecifier") {
192
+ const imported = specifier.imported ? specifier.imported.value : specifier.local.value;
193
+ if (imported === "gql" && !specifier.imported) {
194
+ identifiers.add(specifier.local.value);
195
+ }
196
+ }
197
+ }
198
+ }
199
+ return identifiers;
200
+ };
201
+ /**
202
+ * Check if a call expression is a gql.{schemaName}(...) call.
203
+ * Returns the schema name if it is, null otherwise.
204
+ */
205
+ const getGqlCallSchemaName = (identifiers, call) => {
206
+ const callee = call.callee;
207
+ if (callee.type !== "MemberExpression") {
208
+ return null;
209
+ }
210
+ const member = callee;
211
+ if (member.object.type !== "Identifier" || !identifiers.has(member.object.value)) {
212
+ return null;
213
+ }
214
+ if (member.property.type !== "Identifier") {
215
+ return null;
216
+ }
217
+ const firstArg = call.arguments[0];
218
+ if (!firstArg?.expression || firstArg.expression.type !== "ArrowFunctionExpression") {
219
+ return null;
220
+ }
221
+ return member.property.value;
222
+ };
223
+ /**
224
+ * Extract templates from a gql callback's arrow function body.
225
+ * Handles both expression bodies and block bodies with return statements.
226
+ */
227
+ const extractTemplatesFromCallback = (arrow, schemaName, spanOffset, converter) => {
228
+ const templates = [];
229
+ const processExpression = (expr) => {
230
+ if (expr.type === "TaggedTemplateExpression") {
231
+ const tagged = expr;
232
+ extractFromTaggedTemplate(tagged, schemaName, spanOffset, converter, templates);
233
+ return;
234
+ }
235
+ if (expr.type === "CallExpression") {
236
+ const call = expr;
237
+ if (call.callee.type === "TaggedTemplateExpression") {
238
+ extractFromTaggedTemplate(call.callee, schemaName, spanOffset, converter, templates);
239
+ }
240
+ }
241
+ };
242
+ if (arrow.body.type !== "BlockStatement") {
243
+ processExpression(arrow.body);
244
+ return templates;
245
+ }
246
+ for (const stmt of arrow.body.stmts) {
247
+ if (stmt.type === "ReturnStatement" && stmt.argument) {
248
+ processExpression(stmt.argument);
249
+ }
250
+ }
251
+ return templates;
252
+ };
253
+ const extractFromTaggedTemplate = (tagged, schemaName, spanOffset, converter, templates) => {
254
+ if (tagged.tag.type !== "CallExpression") {
255
+ return;
256
+ }
257
+ const tagCall = tagged.tag;
258
+ if (tagCall.callee.type !== "Identifier") {
259
+ return;
260
+ }
261
+ const kind = tagCall.callee.value;
262
+ if (!isOperationKind(kind)) {
263
+ return;
264
+ }
265
+ let elementName;
266
+ let typeName;
267
+ const firstArg = tagCall.arguments[0]?.expression;
268
+ if (firstArg?.type === "StringLiteral") {
269
+ elementName = firstArg.value;
270
+ }
271
+ const secondArg = tagCall.arguments[1]?.expression;
272
+ if (secondArg?.type === "StringLiteral") {
273
+ typeName = secondArg.value;
274
+ }
275
+ const { quasis, expressions } = tagged.template;
276
+ if (quasis.length === 0) {
277
+ return;
278
+ }
279
+ const parts = [];
280
+ let contentStart = -1;
281
+ let contentEnd = -1;
282
+ for (let i = 0; i < quasis.length; i++) {
283
+ const quasi = quasis[i];
284
+ if (!quasi) {
285
+ continue;
286
+ }
287
+ const quasiStart = converter.byteOffsetToCharIndex(quasi.span.start - spanOffset);
288
+ const quasiEnd = converter.byteOffsetToCharIndex(quasi.span.end - spanOffset);
289
+ if (contentStart === -1) {
290
+ contentStart = quasiStart;
291
+ }
292
+ contentEnd = quasiEnd;
293
+ const quasiContent = quasi.cooked ?? quasi.raw;
294
+ parts.push(quasiContent);
295
+ if (i < expressions.length) {
296
+ parts.push(`__FRAG_SPREAD_${i}__`);
297
+ }
298
+ }
299
+ if (contentStart === -1 || contentEnd === -1) {
300
+ return;
301
+ }
302
+ const content = parts.join("");
303
+ templates.push({
304
+ contentRange: {
305
+ start: contentStart,
306
+ end: contentEnd
307
+ },
308
+ schemaName,
309
+ kind,
310
+ content,
311
+ ...elementName !== undefined ? { elementName } : {},
312
+ ...typeName !== undefined ? { typeName } : {}
313
+ });
314
+ };
315
+ /**
316
+ * Walk AST to find gql calls and extract templates.
317
+ * Adapted from builder's unwrapMethodChains + visit pattern.
318
+ */
319
+ const walkAndExtract = (node, identifiers, spanOffset, converter) => {
320
+ const templates = [];
321
+ const visit$3 = (n) => {
322
+ if (!n || typeof n !== "object") {
323
+ return;
324
+ }
325
+ if ("type" in n && n.type === "CallExpression") {
326
+ const gqlCall = findGqlCall(identifiers, n);
327
+ if (gqlCall) {
328
+ const schemaName = getGqlCallSchemaName(identifiers, gqlCall);
329
+ if (schemaName) {
330
+ const arrow = gqlCall.arguments[0]?.expression;
331
+ templates.push(...extractTemplatesFromCallback(arrow, schemaName, spanOffset, converter));
332
+ }
333
+ return;
334
+ }
335
+ }
336
+ if (Array.isArray(n)) {
337
+ for (const item of n) {
338
+ visit$3(item);
339
+ }
340
+ return;
341
+ }
342
+ for (const key of Object.keys(n)) {
343
+ if (key === "span" || key === "type") {
344
+ continue;
345
+ }
346
+ const value = n[key];
347
+ if (value && typeof value === "object") {
348
+ visit$3(value);
349
+ }
350
+ }
351
+ };
352
+ visit$3(node);
353
+ return templates;
354
+ };
355
+ /**
356
+ * Find the innermost gql call, unwrapping method chains like .attach().
357
+ */
358
+ const findGqlCall = (identifiers, node) => {
359
+ if (!node || node.type !== "CallExpression") {
360
+ return null;
361
+ }
362
+ const call = node;
363
+ if (getGqlCallSchemaName(identifiers, call) !== null) {
364
+ return call;
365
+ }
366
+ const callee = call.callee;
367
+ if (callee.type !== "MemberExpression") {
368
+ return null;
369
+ }
370
+ return findGqlCall(identifiers, callee.object);
371
+ };
372
+ /**
373
+ * Index fragment definitions from extracted templates.
374
+ * Parses each fragment template to extract FragmentDefinitionNode for cross-file resolution.
375
+ */
376
+ /**
377
+ * Reconstruct full GraphQL source from an extracted template.
378
+ * Prepends the definition header from curried tag call arguments.
379
+ */
380
+ const reconstructGraphql = (template) => {
381
+ const content = template.content;
382
+ if (template.elementName) {
383
+ if (template.kind === "fragment" && template.typeName) {
384
+ return `fragment ${template.elementName} on ${template.typeName} ${content}`;
385
+ }
386
+ return `${template.kind} ${template.elementName} ${content}`;
387
+ }
388
+ return content;
389
+ };
390
+ const indexFragments = (uri, templates, source) => {
391
+ const fragments = [];
392
+ for (const template of templates) {
393
+ if (template.kind !== "fragment") {
394
+ continue;
395
+ }
396
+ const reconstructed = reconstructGraphql(template);
397
+ const headerLen = reconstructed.length - template.content.length;
398
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
399
+ try {
400
+ const ast = (0, graphql.parse)(preprocessed, { noLocation: false });
401
+ for (const def of ast.definitions) {
402
+ if (def.kind === "FragmentDefinition") {
403
+ fragments.push({
404
+ uri,
405
+ schemaName: template.schemaName,
406
+ fragmentName: def.name.value,
407
+ definition: def,
408
+ content: preprocessed,
409
+ contentRange: template.contentRange,
410
+ tsSource: source,
411
+ headerLen
412
+ });
413
+ }
414
+ }
415
+ } catch {}
416
+ }
417
+ return fragments;
418
+ };
419
+ /** Create a document manager that tracks open documents and extracts templates. */
420
+ const createDocumentManager = (helper, swcOptions) => {
421
+ let parseSyncFn = swcOptions?.parseSync !== undefined ? swcOptions.parseSync ?? null : null;
422
+ let swcLoadAttempted = swcOptions?.parseSync !== undefined;
423
+ let swcUnavailable = swcOptions?.parseSync === null;
424
+ const getParseSync = () => {
425
+ if (!swcLoadAttempted) {
426
+ swcLoadAttempted = true;
427
+ const resolveBases = swcOptions?.resolveFrom ? [swcOptions.resolveFrom, require("url").pathToFileURL(__filename).href] : [require("url").pathToFileURL(__filename).href];
428
+ for (const base of resolveBases) {
429
+ try {
430
+ const localRequire = (0, node_module.createRequire)(base);
431
+ const candidate = localRequire("@swc/core")?.parseSync;
432
+ if (typeof candidate === "function") {
433
+ parseSyncFn = candidate;
434
+ return parseSyncFn;
435
+ }
436
+ } catch {}
437
+ }
438
+ swcUnavailable = true;
439
+ }
440
+ return parseSyncFn;
441
+ };
442
+ /** Wrap SWC parseSync (which throws) to return null on failure. */
443
+ const safeParseSync = (source, tsx) => {
444
+ const parseSync = getParseSync();
445
+ if (!parseSync) return null;
446
+ try {
447
+ const result = parseSync(source, {
448
+ syntax: "typescript",
449
+ tsx,
450
+ decorators: false,
451
+ dynamicImport: true
452
+ });
453
+ return result.type === "Module" ? result : null;
454
+ } catch {
455
+ return null;
456
+ }
457
+ };
458
+ const cache = new Map();
459
+ const fragmentIndex = new Map();
460
+ const extractTemplates = (uri, source) => {
461
+ const isTsx = uri.endsWith(".tsx");
462
+ const program = safeParseSync(source, isTsx);
463
+ if (!program) {
464
+ return [];
465
+ }
466
+ const converter = (0, __soda_gql_common.createSwcSpanConverter)(source);
467
+ const spanOffset = program.span.end - converter.byteLength + 1;
468
+ const filePath = uri.startsWith("file://") ? (0, node_url.fileURLToPath)(uri) : uri;
469
+ const gqlIdentifiers = collectGqlIdentifiers(program, filePath, helper);
470
+ if (gqlIdentifiers.size === 0) {
471
+ return [];
472
+ }
473
+ return walkAndExtract(program, gqlIdentifiers, spanOffset, converter);
474
+ };
475
+ return {
476
+ update: (uri, version, source) => {
477
+ const templates = extractTemplates(uri, source);
478
+ const state = {
479
+ uri,
480
+ version,
481
+ source,
482
+ templates,
483
+ ...swcUnavailable ? { swcUnavailable: true } : {}
484
+ };
485
+ cache.set(uri, state);
486
+ if (swcUnavailable) {
487
+ fragmentIndex.delete(uri);
488
+ } else {
489
+ fragmentIndex.set(uri, indexFragments(uri, templates, source));
490
+ }
491
+ return state;
492
+ },
493
+ get: (uri) => cache.get(uri),
494
+ remove: (uri) => {
495
+ cache.delete(uri);
496
+ fragmentIndex.delete(uri);
497
+ },
498
+ findTemplateAtOffset: (uri, offset) => {
499
+ const state = cache.get(uri);
500
+ if (!state) {
501
+ return undefined;
502
+ }
503
+ return state.templates.find((t) => offset >= t.contentRange.start && offset <= t.contentRange.end);
504
+ },
505
+ getExternalFragments: (uri, schemaName) => {
506
+ const result = [];
507
+ for (const [fragmentUri, fragments] of fragmentIndex) {
508
+ if (fragmentUri === uri) {
509
+ continue;
510
+ }
511
+ for (const fragment of fragments) {
512
+ if (fragment.schemaName === schemaName) {
513
+ result.push(fragment);
514
+ }
515
+ }
516
+ }
517
+ return result;
518
+ },
519
+ getAllFragments: (schemaName) => {
520
+ const result = [];
521
+ for (const [, fragments] of fragmentIndex) {
522
+ for (const fragment of fragments) {
523
+ if (fragment.schemaName === schemaName) {
524
+ result.push(fragment);
525
+ }
526
+ }
527
+ }
528
+ return result;
529
+ },
530
+ findFragmentSpreadLocations: (fragmentName, schemaName) => {
531
+ const locations = [];
532
+ for (const [uri, state] of cache) {
533
+ for (const template of state.templates) {
534
+ if (template.schemaName !== schemaName) {
535
+ continue;
536
+ }
537
+ const reconstructed = reconstructGraphql(template);
538
+ const headerLen = reconstructed.length - template.content.length;
539
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
540
+ try {
541
+ const ast = (0, graphql.parse)(preprocessed, { noLocation: false });
542
+ (0, graphql.visit)(ast, { FragmentSpread(node) {
543
+ if (node.name.value === fragmentName && node.name.loc) {
544
+ locations.push({
545
+ uri,
546
+ tsSource: state.source,
547
+ template,
548
+ nameOffset: node.name.loc.start - headerLen,
549
+ nameLength: fragmentName.length
550
+ });
551
+ }
552
+ } });
553
+ } catch {
554
+ const pattern = new RegExp(`\\.\\.\\.${fragmentName}\\b`, "g");
555
+ let match = null;
556
+ while ((match = pattern.exec(preprocessed)) !== null) {
557
+ locations.push({
558
+ uri,
559
+ tsSource: state.source,
560
+ template,
561
+ nameOffset: match.index + 3 - headerLen,
562
+ nameLength: fragmentName.length
563
+ });
564
+ }
565
+ }
566
+ }
567
+ }
568
+ return locations;
569
+ }
570
+ };
571
+ };
572
+
573
+ //#endregion
574
+ //#region packages/lsp/src/errors.ts
575
+ /** Error constructor helpers for concise error creation. */
576
+ const lspErrors = {
577
+ configLoadFailed: (message, cause) => ({
578
+ code: "CONFIG_LOAD_FAILED",
579
+ message,
580
+ cause
581
+ }),
582
+ schemaLoadFailed: (schemaName, message, cause) => ({
583
+ code: "SCHEMA_LOAD_FAILED",
584
+ message: message ?? `Failed to load schema: ${schemaName}`,
585
+ schemaName,
586
+ cause
587
+ }),
588
+ schemaBuildFailed: (schemaName, message, cause) => ({
589
+ code: "SCHEMA_BUILD_FAILED",
590
+ message: message ?? `Failed to build schema: ${schemaName}`,
591
+ schemaName,
592
+ cause
593
+ }),
594
+ schemaNotConfigured: (schemaName) => ({
595
+ code: "SCHEMA_NOT_CONFIGURED",
596
+ message: `Schema "${schemaName}" is not configured in soda-gql.config`,
597
+ schemaName
598
+ }),
599
+ parseFailed: (uri, message, cause) => ({
600
+ code: "PARSE_FAILED",
601
+ message: message ?? `Failed to parse: ${uri}`,
602
+ uri,
603
+ cause
604
+ }),
605
+ internalInvariant: (message, context, cause) => ({
606
+ code: "INTERNAL_INVARIANT",
607
+ message,
608
+ context,
609
+ cause
610
+ }),
611
+ swcResolutionFailed: (message) => ({
612
+ code: "SWC_RESOLUTION_FAILED",
613
+ message: message ?? "@swc/core not found. Install @soda-gql/builder (which provides @swc/core) in your project and restart the LSP server to enable template extraction."
614
+ })
615
+ };
616
+
617
+ //#endregion
618
+ //#region packages/lsp/src/position-mapping.ts
619
+ /** Compute byte offsets for the start of each line in the source text. */
620
+ const computeLineOffsets = (source) => {
621
+ const offsets = [0];
622
+ for (let i = 0; i < source.length; i++) {
623
+ if (source.charCodeAt(i) === 10) {
624
+ offsets.push(i + 1);
625
+ }
626
+ }
627
+ return offsets;
628
+ };
629
+ /** Convert a Position to a byte offset within the source text. */
630
+ const positionToOffset$1 = (lineOffsets, position) => {
631
+ if (position.line < 0 || position.line >= lineOffsets.length) {
632
+ return -1;
633
+ }
634
+ return (lineOffsets[position.line] ?? 0) + position.character;
635
+ };
636
+ /** Convert a byte offset to a Position within the source text. */
637
+ const offsetToPosition = (lineOffsets, offset) => {
638
+ let low = 0;
639
+ let high = lineOffsets.length - 1;
640
+ while (low < high) {
641
+ const mid = Math.ceil((low + high) / 2);
642
+ if ((lineOffsets[mid] ?? 0) <= offset) {
643
+ low = mid;
644
+ } else {
645
+ high = mid - 1;
646
+ }
647
+ }
648
+ return {
649
+ line: low,
650
+ character: offset - (lineOffsets[low] ?? 0)
651
+ };
652
+ };
653
+ /** Convert a Position to an IPosition compatible with graphql-language-service. */
654
+ const toIPosition = (pos) => {
655
+ const p = {
656
+ line: pos.line,
657
+ character: pos.character,
658
+ setLine: (l) => {
659
+ p.line = l;
660
+ },
661
+ setCharacter: (c) => {
662
+ p.character = c;
663
+ },
664
+ lessThanOrEqualTo: (other) => p.line < other.line || p.line === other.line && p.character <= other.character
665
+ };
666
+ return p;
667
+ };
668
+ /** Create a bidirectional position mapper between TS file and GraphQL content. */
669
+ const createPositionMapper = (input) => {
670
+ const { tsSource, contentStartOffset, graphqlContent } = input;
671
+ const tsLineOffsets = computeLineOffsets(tsSource);
672
+ const gqlLineOffsets = computeLineOffsets(graphqlContent);
673
+ return {
674
+ tsToGraphql: (tsPosition) => {
675
+ const tsOffset = positionToOffset$1(tsLineOffsets, tsPosition);
676
+ if (tsOffset < 0) {
677
+ return null;
678
+ }
679
+ const gqlOffset = tsOffset - contentStartOffset;
680
+ if (gqlOffset < 0 || gqlOffset > graphqlContent.length) {
681
+ return null;
682
+ }
683
+ return offsetToPosition(gqlLineOffsets, gqlOffset);
684
+ },
685
+ graphqlToTs: (gqlPosition) => {
686
+ const gqlOffset = positionToOffset$1(gqlLineOffsets, gqlPosition);
687
+ const tsOffset = gqlOffset + contentStartOffset;
688
+ return offsetToPosition(tsLineOffsets, tsOffset);
689
+ }
690
+ };
691
+ };
692
+
693
+ //#endregion
694
+ //#region packages/lsp/src/schema-resolver.ts
695
+ /**
696
+ * Schema resolver: maps schema names to GraphQLSchema objects.
697
+ * @module
698
+ */
699
+ /** Wrap buildASTSchema (which throws) in a Result. */
700
+ const safeBuildASTSchema = (schemaName, documentNode) => {
701
+ try {
702
+ return (0, neverthrow.ok)((0, graphql.buildASTSchema)(documentNode));
703
+ } catch (e) {
704
+ return (0, neverthrow.err)(lspErrors.schemaBuildFailed(schemaName, e instanceof Error ? e.message : String(e), e));
705
+ }
706
+ };
707
+ const loadAndBuildSchema = (schemaName, schemaPaths) => {
708
+ const documents = [];
709
+ const files = [];
710
+ for (const schemaPath of schemaPaths) {
711
+ const resolvedPath = (0, node_path.resolve)(schemaPath);
712
+ try {
713
+ const content = (0, node_fs.readFileSync)(resolvedPath, "utf8");
714
+ documents.push((0, graphql.parse)(content));
715
+ files.push({
716
+ filePath: resolvedPath,
717
+ content
718
+ });
719
+ } catch (e) {
720
+ return (0, neverthrow.err)(lspErrors.schemaLoadFailed(schemaName, e instanceof Error ? e.message : String(e)));
721
+ }
722
+ }
723
+ const documentNode = (0, graphql.concatAST)(documents);
724
+ const hash = (0, __soda_gql_codegen.hashSchema)(documentNode);
725
+ const buildResult = safeBuildASTSchema(schemaName, documentNode);
726
+ if (buildResult.isErr()) {
727
+ return (0, neverthrow.err)(buildResult.error);
728
+ }
729
+ return (0, neverthrow.ok)({
730
+ name: schemaName,
731
+ schema: buildResult.value,
732
+ documentNode,
733
+ hash,
734
+ files
735
+ });
736
+ };
737
+ /** Create a schema resolver from config. Loads all schemas eagerly. */
738
+ const createSchemaResolver = (config) => {
739
+ const cache = new Map();
740
+ for (const [name, schemaConfig] of Object.entries(config.schemas)) {
741
+ const result = loadAndBuildSchema(name, schemaConfig.schema);
742
+ if (result.isErr()) {
743
+ return (0, neverthrow.err)(result.error);
744
+ }
745
+ cache.set(name, result.value);
746
+ }
747
+ const resolver = {
748
+ getSchema: (schemaName) => cache.get(schemaName),
749
+ getSchemaNames: () => [...cache.keys()],
750
+ reloadSchema: (schemaName) => {
751
+ const schemaConfig = config.schemas[schemaName];
752
+ if (!schemaConfig) {
753
+ return (0, neverthrow.err)(lspErrors.schemaNotConfigured(schemaName));
754
+ }
755
+ const result = loadAndBuildSchema(schemaName, schemaConfig.schema);
756
+ if (result.isErr()) {
757
+ return (0, neverthrow.err)(result.error);
758
+ }
759
+ cache.set(schemaName, result.value);
760
+ return (0, neverthrow.ok)(result.value);
761
+ },
762
+ reloadAll: () => {
763
+ const errors = [];
764
+ for (const [name, schemaConfig] of Object.entries(config.schemas)) {
765
+ const result = loadAndBuildSchema(name, schemaConfig.schema);
766
+ if (result.isErr()) {
767
+ errors.push(result.error);
768
+ } else {
769
+ cache.set(name, result.value);
770
+ }
771
+ }
772
+ return errors.length > 0 ? (0, neverthrow.err)(errors) : (0, neverthrow.ok)(undefined);
773
+ }
774
+ };
775
+ return (0, neverthrow.ok)(resolver);
776
+ };
777
+
778
+ //#endregion
779
+ //#region packages/lsp/src/config-registry.ts
780
+ /**
781
+ * Config registry: maps document URIs to their nearest config context.
782
+ * Supports multiple soda-gql configs in a monorepo workspace.
783
+ * @module
784
+ */
785
+ const createConfigRegistry = (configPaths) => {
786
+ const sortedPaths = [...configPaths].sort((a, b) => b.length - a.length);
787
+ const contexts = new Map();
788
+ for (const configPath of sortedPaths) {
789
+ const configResult = (0, __soda_gql_config.loadConfig)(configPath);
790
+ if (configResult.isErr()) {
791
+ return (0, neverthrow.err)(lspErrors.configLoadFailed(`Failed to load config ${configPath}: ${configResult.error.message}`, configResult.error));
792
+ }
793
+ const config = configResult.value;
794
+ const helper = (0, __soda_gql_builder.createGraphqlSystemIdentifyHelper)(config);
795
+ const resolverResult = createSchemaResolver(config);
796
+ if (resolverResult.isErr()) {
797
+ return (0, neverthrow.err)(resolverResult.error);
798
+ }
799
+ contexts.set(configPath, {
800
+ configPath,
801
+ config,
802
+ helper,
803
+ schemaResolver: resolverResult.value,
804
+ documentManager: createDocumentManager(helper, { resolveFrom: configPath })
805
+ });
806
+ }
807
+ const uriCache = new Map();
808
+ const resolveConfigPath = (dirPath) => {
809
+ const cached = uriCache.get(dirPath);
810
+ if (cached !== undefined) {
811
+ return cached;
812
+ }
813
+ for (const configPath of sortedPaths) {
814
+ const configDir = (0, node_path.dirname)(configPath);
815
+ if (dirPath === configDir || dirPath.startsWith(`${configDir}${node_path.sep}`)) {
816
+ uriCache.set(dirPath, configPath);
817
+ return configPath;
818
+ }
819
+ }
820
+ uriCache.set(dirPath, null);
821
+ return null;
822
+ };
823
+ return (0, neverthrow.ok)({
824
+ resolveForUri: (uri) => {
825
+ const filePath = uri.startsWith("file://") ? (0, node_url.fileURLToPath)(uri) : uri;
826
+ const dirPath = (0, node_path.dirname)(filePath);
827
+ const configPath = resolveConfigPath(dirPath);
828
+ return configPath ? contexts.get(configPath) : undefined;
829
+ },
830
+ getAllContexts: () => [...contexts.values()],
831
+ reloadSchemas: (configPath) => {
832
+ const ctx = contexts.get(configPath);
833
+ if (!ctx) {
834
+ return (0, neverthrow.err)([lspErrors.configLoadFailed(`Config not found: ${configPath}`)]);
835
+ }
836
+ return ctx.schemaResolver.reloadAll();
837
+ },
838
+ reloadAllSchemas: () => {
839
+ const errors = [];
840
+ for (const ctx of contexts.values()) {
841
+ const result = ctx.schemaResolver.reloadAll();
842
+ if (result.isErr()) {
843
+ errors.push(...result.error);
844
+ }
845
+ }
846
+ return errors.length > 0 ? (0, neverthrow.err)(errors) : (0, neverthrow.ok)(undefined);
847
+ }
848
+ });
849
+ };
850
+
851
+ //#endregion
852
+ //#region node_modules/vscode-languageserver-types/lib/esm/main.js
853
+ var DocumentUri;
854
+ (function(DocumentUri$1) {
855
+ function is(value) {
856
+ return typeof value === "string";
857
+ }
858
+ DocumentUri$1.is = is;
859
+ })(DocumentUri || (DocumentUri = {}));
860
+ var URI;
861
+ (function(URI$1) {
862
+ function is(value) {
863
+ return typeof value === "string";
864
+ }
865
+ URI$1.is = is;
866
+ })(URI || (URI = {}));
867
+ var integer;
868
+ (function(integer$1) {
869
+ integer$1.MIN_VALUE = -2147483648;
870
+ integer$1.MAX_VALUE = 2147483647;
871
+ function is(value) {
872
+ return typeof value === "number" && integer$1.MIN_VALUE <= value && value <= integer$1.MAX_VALUE;
873
+ }
874
+ integer$1.is = is;
875
+ })(integer || (integer = {}));
876
+ var uinteger;
877
+ (function(uinteger$1) {
878
+ uinteger$1.MIN_VALUE = 0;
879
+ uinteger$1.MAX_VALUE = 2147483647;
880
+ function is(value) {
881
+ return typeof value === "number" && uinteger$1.MIN_VALUE <= value && value <= uinteger$1.MAX_VALUE;
882
+ }
883
+ uinteger$1.is = is;
884
+ })(uinteger || (uinteger = {}));
885
+ /**
886
+ * The Position namespace provides helper functions to work with
887
+ * {@link Position} literals.
888
+ */
889
+ var Position;
890
+ (function(Position$1) {
891
+ /**
892
+ * Creates a new Position literal from the given line and character.
893
+ * @param line The position's line.
894
+ * @param character The position's character.
895
+ */
896
+ function create(line, character) {
897
+ if (line === Number.MAX_VALUE) {
898
+ line = uinteger.MAX_VALUE;
899
+ }
900
+ if (character === Number.MAX_VALUE) {
901
+ character = uinteger.MAX_VALUE;
902
+ }
903
+ return {
904
+ line,
905
+ character
906
+ };
907
+ }
908
+ Position$1.create = create;
909
+ /**
910
+ * Checks whether the given literal conforms to the {@link Position} interface.
911
+ */
912
+ function is(value) {
913
+ let candidate = value;
914
+ return Is.objectLiteral(candidate) && Is.uinteger(candidate.line) && Is.uinteger(candidate.character);
915
+ }
916
+ Position$1.is = is;
917
+ })(Position || (Position = {}));
918
+ /**
919
+ * The Range namespace provides helper functions to work with
920
+ * {@link Range} literals.
921
+ */
922
+ var Range;
923
+ (function(Range$1) {
924
+ function create(one, two, three, four) {
925
+ if (Is.uinteger(one) && Is.uinteger(two) && Is.uinteger(three) && Is.uinteger(four)) {
926
+ return {
927
+ start: Position.create(one, two),
928
+ end: Position.create(three, four)
929
+ };
930
+ } else if (Position.is(one) && Position.is(two)) {
931
+ return {
932
+ start: one,
933
+ end: two
934
+ };
935
+ } else {
936
+ throw new Error(`Range#create called with invalid arguments[${one}, ${two}, ${three}, ${four}]`);
937
+ }
938
+ }
939
+ Range$1.create = create;
940
+ /**
941
+ * Checks whether the given literal conforms to the {@link Range} interface.
942
+ */
943
+ function is(value) {
944
+ let candidate = value;
945
+ return Is.objectLiteral(candidate) && Position.is(candidate.start) && Position.is(candidate.end);
946
+ }
947
+ Range$1.is = is;
948
+ })(Range || (Range = {}));
949
+ /**
950
+ * The Location namespace provides helper functions to work with
951
+ * {@link Location} literals.
952
+ */
953
+ var Location;
954
+ (function(Location$1) {
955
+ /**
956
+ * Creates a Location literal.
957
+ * @param uri The location's uri.
958
+ * @param range The location's range.
959
+ */
960
+ function create(uri, range) {
961
+ return {
962
+ uri,
963
+ range
964
+ };
965
+ }
966
+ Location$1.create = create;
967
+ /**
968
+ * Checks whether the given literal conforms to the {@link Location} interface.
969
+ */
970
+ function is(value) {
971
+ let candidate = value;
972
+ return Is.objectLiteral(candidate) && Range.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri));
973
+ }
974
+ Location$1.is = is;
975
+ })(Location || (Location = {}));
976
+ /**
977
+ * The LocationLink namespace provides helper functions to work with
978
+ * {@link LocationLink} literals.
979
+ */
980
+ var LocationLink;
981
+ (function(LocationLink$1) {
982
+ /**
983
+ * Creates a LocationLink literal.
984
+ * @param targetUri The definition's uri.
985
+ * @param targetRange The full range of the definition.
986
+ * @param targetSelectionRange The span of the symbol definition at the target.
987
+ * @param originSelectionRange The span of the symbol being defined in the originating source file.
988
+ */
989
+ function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) {
990
+ return {
991
+ targetUri,
992
+ targetRange,
993
+ targetSelectionRange,
994
+ originSelectionRange
995
+ };
996
+ }
997
+ LocationLink$1.create = create;
998
+ /**
999
+ * Checks whether the given literal conforms to the {@link LocationLink} interface.
1000
+ */
1001
+ function is(value) {
1002
+ let candidate = value;
1003
+ return Is.objectLiteral(candidate) && Range.is(candidate.targetRange) && Is.string(candidate.targetUri) && Range.is(candidate.targetSelectionRange) && (Range.is(candidate.originSelectionRange) || Is.undefined(candidate.originSelectionRange));
1004
+ }
1005
+ LocationLink$1.is = is;
1006
+ })(LocationLink || (LocationLink = {}));
1007
+ /**
1008
+ * The Color namespace provides helper functions to work with
1009
+ * {@link Color} literals.
1010
+ */
1011
+ var Color;
1012
+ (function(Color$1) {
1013
+ /**
1014
+ * Creates a new Color literal.
1015
+ */
1016
+ function create(red, green, blue, alpha) {
1017
+ return {
1018
+ red,
1019
+ green,
1020
+ blue,
1021
+ alpha
1022
+ };
1023
+ }
1024
+ Color$1.create = create;
1025
+ /**
1026
+ * Checks whether the given literal conforms to the {@link Color} interface.
1027
+ */
1028
+ function is(value) {
1029
+ const candidate = value;
1030
+ return Is.objectLiteral(candidate) && Is.numberRange(candidate.red, 0, 1) && Is.numberRange(candidate.green, 0, 1) && Is.numberRange(candidate.blue, 0, 1) && Is.numberRange(candidate.alpha, 0, 1);
1031
+ }
1032
+ Color$1.is = is;
1033
+ })(Color || (Color = {}));
1034
+ /**
1035
+ * The ColorInformation namespace provides helper functions to work with
1036
+ * {@link ColorInformation} literals.
1037
+ */
1038
+ var ColorInformation;
1039
+ (function(ColorInformation$1) {
1040
+ /**
1041
+ * Creates a new ColorInformation literal.
1042
+ */
1043
+ function create(range, color) {
1044
+ return {
1045
+ range,
1046
+ color
1047
+ };
1048
+ }
1049
+ ColorInformation$1.create = create;
1050
+ /**
1051
+ * Checks whether the given literal conforms to the {@link ColorInformation} interface.
1052
+ */
1053
+ function is(value) {
1054
+ const candidate = value;
1055
+ return Is.objectLiteral(candidate) && Range.is(candidate.range) && Color.is(candidate.color);
1056
+ }
1057
+ ColorInformation$1.is = is;
1058
+ })(ColorInformation || (ColorInformation = {}));
1059
+ /**
1060
+ * The Color namespace provides helper functions to work with
1061
+ * {@link ColorPresentation} literals.
1062
+ */
1063
+ var ColorPresentation;
1064
+ (function(ColorPresentation$1) {
1065
+ /**
1066
+ * Creates a new ColorInformation literal.
1067
+ */
1068
+ function create(label, textEdit, additionalTextEdits) {
1069
+ return {
1070
+ label,
1071
+ textEdit,
1072
+ additionalTextEdits
1073
+ };
1074
+ }
1075
+ ColorPresentation$1.create = create;
1076
+ /**
1077
+ * Checks whether the given literal conforms to the {@link ColorInformation} interface.
1078
+ */
1079
+ function is(value) {
1080
+ const candidate = value;
1081
+ return Is.objectLiteral(candidate) && Is.string(candidate.label) && (Is.undefined(candidate.textEdit) || TextEdit.is(candidate)) && (Is.undefined(candidate.additionalTextEdits) || Is.typedArray(candidate.additionalTextEdits, TextEdit.is));
1082
+ }
1083
+ ColorPresentation$1.is = is;
1084
+ })(ColorPresentation || (ColorPresentation = {}));
1085
+ /**
1086
+ * A set of predefined range kinds.
1087
+ */
1088
+ var FoldingRangeKind;
1089
+ (function(FoldingRangeKind$1) {
1090
+ /**
1091
+ * Folding range for a comment
1092
+ */
1093
+ FoldingRangeKind$1.Comment = "comment";
1094
+ /**
1095
+ * Folding range for an import or include
1096
+ */
1097
+ FoldingRangeKind$1.Imports = "imports";
1098
+ /**
1099
+ * Folding range for a region (e.g. `#region`)
1100
+ */
1101
+ FoldingRangeKind$1.Region = "region";
1102
+ })(FoldingRangeKind || (FoldingRangeKind = {}));
1103
+ /**
1104
+ * The folding range namespace provides helper functions to work with
1105
+ * {@link FoldingRange} literals.
1106
+ */
1107
+ var FoldingRange;
1108
+ (function(FoldingRange$1) {
1109
+ /**
1110
+ * Creates a new FoldingRange literal.
1111
+ */
1112
+ function create(startLine, endLine, startCharacter, endCharacter, kind, collapsedText) {
1113
+ const result = {
1114
+ startLine,
1115
+ endLine
1116
+ };
1117
+ if (Is.defined(startCharacter)) {
1118
+ result.startCharacter = startCharacter;
1119
+ }
1120
+ if (Is.defined(endCharacter)) {
1121
+ result.endCharacter = endCharacter;
1122
+ }
1123
+ if (Is.defined(kind)) {
1124
+ result.kind = kind;
1125
+ }
1126
+ if (Is.defined(collapsedText)) {
1127
+ result.collapsedText = collapsedText;
1128
+ }
1129
+ return result;
1130
+ }
1131
+ FoldingRange$1.create = create;
1132
+ /**
1133
+ * Checks whether the given literal conforms to the {@link FoldingRange} interface.
1134
+ */
1135
+ function is(value) {
1136
+ const candidate = value;
1137
+ return Is.objectLiteral(candidate) && Is.uinteger(candidate.startLine) && Is.uinteger(candidate.startLine) && (Is.undefined(candidate.startCharacter) || Is.uinteger(candidate.startCharacter)) && (Is.undefined(candidate.endCharacter) || Is.uinteger(candidate.endCharacter)) && (Is.undefined(candidate.kind) || Is.string(candidate.kind));
1138
+ }
1139
+ FoldingRange$1.is = is;
1140
+ })(FoldingRange || (FoldingRange = {}));
1141
+ /**
1142
+ * The DiagnosticRelatedInformation namespace provides helper functions to work with
1143
+ * {@link DiagnosticRelatedInformation} literals.
1144
+ */
1145
+ var DiagnosticRelatedInformation;
1146
+ (function(DiagnosticRelatedInformation$1) {
1147
+ /**
1148
+ * Creates a new DiagnosticRelatedInformation literal.
1149
+ */
1150
+ function create(location, message) {
1151
+ return {
1152
+ location,
1153
+ message
1154
+ };
1155
+ }
1156
+ DiagnosticRelatedInformation$1.create = create;
1157
+ /**
1158
+ * Checks whether the given literal conforms to the {@link DiagnosticRelatedInformation} interface.
1159
+ */
1160
+ function is(value) {
1161
+ let candidate = value;
1162
+ return Is.defined(candidate) && Location.is(candidate.location) && Is.string(candidate.message);
1163
+ }
1164
+ DiagnosticRelatedInformation$1.is = is;
1165
+ })(DiagnosticRelatedInformation || (DiagnosticRelatedInformation = {}));
1166
+ /**
1167
+ * The diagnostic's severity.
1168
+ */
1169
+ var DiagnosticSeverity;
1170
+ (function(DiagnosticSeverity$1) {
1171
+ /**
1172
+ * Reports an error.
1173
+ */
1174
+ DiagnosticSeverity$1.Error = 1;
1175
+ /**
1176
+ * Reports a warning.
1177
+ */
1178
+ DiagnosticSeverity$1.Warning = 2;
1179
+ /**
1180
+ * Reports an information.
1181
+ */
1182
+ DiagnosticSeverity$1.Information = 3;
1183
+ /**
1184
+ * Reports a hint.
1185
+ */
1186
+ DiagnosticSeverity$1.Hint = 4;
1187
+ })(DiagnosticSeverity || (DiagnosticSeverity = {}));
1188
+ /**
1189
+ * The diagnostic tags.
1190
+ *
1191
+ * @since 3.15.0
1192
+ */
1193
+ var DiagnosticTag;
1194
+ (function(DiagnosticTag$1) {
1195
+ /**
1196
+ * Unused or unnecessary code.
1197
+ *
1198
+ * Clients are allowed to render diagnostics with this tag faded out instead of having
1199
+ * an error squiggle.
1200
+ */
1201
+ DiagnosticTag$1.Unnecessary = 1;
1202
+ /**
1203
+ * Deprecated or obsolete code.
1204
+ *
1205
+ * Clients are allowed to rendered diagnostics with this tag strike through.
1206
+ */
1207
+ DiagnosticTag$1.Deprecated = 2;
1208
+ })(DiagnosticTag || (DiagnosticTag = {}));
1209
+ /**
1210
+ * The CodeDescription namespace provides functions to deal with descriptions for diagnostic codes.
1211
+ *
1212
+ * @since 3.16.0
1213
+ */
1214
+ var CodeDescription;
1215
+ (function(CodeDescription$1) {
1216
+ function is(value) {
1217
+ const candidate = value;
1218
+ return Is.objectLiteral(candidate) && Is.string(candidate.href);
1219
+ }
1220
+ CodeDescription$1.is = is;
1221
+ })(CodeDescription || (CodeDescription = {}));
1222
+ /**
1223
+ * The Diagnostic namespace provides helper functions to work with
1224
+ * {@link Diagnostic} literals.
1225
+ */
1226
+ var Diagnostic;
1227
+ (function(Diagnostic$1) {
1228
+ /**
1229
+ * Creates a new Diagnostic literal.
1230
+ */
1231
+ function create(range, message, severity, code, source, relatedInformation) {
1232
+ let result = {
1233
+ range,
1234
+ message
1235
+ };
1236
+ if (Is.defined(severity)) {
1237
+ result.severity = severity;
1238
+ }
1239
+ if (Is.defined(code)) {
1240
+ result.code = code;
1241
+ }
1242
+ if (Is.defined(source)) {
1243
+ result.source = source;
1244
+ }
1245
+ if (Is.defined(relatedInformation)) {
1246
+ result.relatedInformation = relatedInformation;
1247
+ }
1248
+ return result;
1249
+ }
1250
+ Diagnostic$1.create = create;
1251
+ /**
1252
+ * Checks whether the given literal conforms to the {@link Diagnostic} interface.
1253
+ */
1254
+ function is(value) {
1255
+ var _a;
1256
+ let candidate = value;
1257
+ return Is.defined(candidate) && Range.is(candidate.range) && Is.string(candidate.message) && (Is.number(candidate.severity) || Is.undefined(candidate.severity)) && (Is.integer(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code)) && (Is.undefined(candidate.codeDescription) || Is.string((_a = candidate.codeDescription) === null || _a === void 0 ? void 0 : _a.href)) && (Is.string(candidate.source) || Is.undefined(candidate.source)) && (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is));
1258
+ }
1259
+ Diagnostic$1.is = is;
1260
+ })(Diagnostic || (Diagnostic = {}));
1261
+ /**
1262
+ * The Command namespace provides helper functions to work with
1263
+ * {@link Command} literals.
1264
+ */
1265
+ var Command;
1266
+ (function(Command$1) {
1267
+ /**
1268
+ * Creates a new Command literal.
1269
+ */
1270
+ function create(title, command, ...args) {
1271
+ let result = {
1272
+ title,
1273
+ command
1274
+ };
1275
+ if (Is.defined(args) && args.length > 0) {
1276
+ result.arguments = args;
1277
+ }
1278
+ return result;
1279
+ }
1280
+ Command$1.create = create;
1281
+ /**
1282
+ * Checks whether the given literal conforms to the {@link Command} interface.
1283
+ */
1284
+ function is(value) {
1285
+ let candidate = value;
1286
+ return Is.defined(candidate) && Is.string(candidate.title) && Is.string(candidate.command);
1287
+ }
1288
+ Command$1.is = is;
1289
+ })(Command || (Command = {}));
1290
+ /**
1291
+ * The TextEdit namespace provides helper function to create replace,
1292
+ * insert and delete edits more easily.
1293
+ */
1294
+ var TextEdit;
1295
+ (function(TextEdit$1) {
1296
+ /**
1297
+ * Creates a replace text edit.
1298
+ * @param range The range of text to be replaced.
1299
+ * @param newText The new text.
1300
+ */
1301
+ function replace(range, newText) {
1302
+ return {
1303
+ range,
1304
+ newText
1305
+ };
1306
+ }
1307
+ TextEdit$1.replace = replace;
1308
+ /**
1309
+ * Creates an insert text edit.
1310
+ * @param position The position to insert the text at.
1311
+ * @param newText The text to be inserted.
1312
+ */
1313
+ function insert(position, newText) {
1314
+ return {
1315
+ range: {
1316
+ start: position,
1317
+ end: position
1318
+ },
1319
+ newText
1320
+ };
1321
+ }
1322
+ TextEdit$1.insert = insert;
1323
+ /**
1324
+ * Creates a delete text edit.
1325
+ * @param range The range of text to be deleted.
1326
+ */
1327
+ function del(range) {
1328
+ return {
1329
+ range,
1330
+ newText: ""
1331
+ };
1332
+ }
1333
+ TextEdit$1.del = del;
1334
+ function is(value) {
1335
+ const candidate = value;
1336
+ return Is.objectLiteral(candidate) && Is.string(candidate.newText) && Range.is(candidate.range);
1337
+ }
1338
+ TextEdit$1.is = is;
1339
+ })(TextEdit || (TextEdit = {}));
1340
+ var ChangeAnnotation;
1341
+ (function(ChangeAnnotation$1) {
1342
+ function create(label, needsConfirmation, description) {
1343
+ const result = { label };
1344
+ if (needsConfirmation !== undefined) {
1345
+ result.needsConfirmation = needsConfirmation;
1346
+ }
1347
+ if (description !== undefined) {
1348
+ result.description = description;
1349
+ }
1350
+ return result;
1351
+ }
1352
+ ChangeAnnotation$1.create = create;
1353
+ function is(value) {
1354
+ const candidate = value;
1355
+ return Is.objectLiteral(candidate) && Is.string(candidate.label) && (Is.boolean(candidate.needsConfirmation) || candidate.needsConfirmation === undefined) && (Is.string(candidate.description) || candidate.description === undefined);
1356
+ }
1357
+ ChangeAnnotation$1.is = is;
1358
+ })(ChangeAnnotation || (ChangeAnnotation = {}));
1359
+ var ChangeAnnotationIdentifier;
1360
+ (function(ChangeAnnotationIdentifier$1) {
1361
+ function is(value) {
1362
+ const candidate = value;
1363
+ return Is.string(candidate);
1364
+ }
1365
+ ChangeAnnotationIdentifier$1.is = is;
1366
+ })(ChangeAnnotationIdentifier || (ChangeAnnotationIdentifier = {}));
1367
+ var AnnotatedTextEdit;
1368
+ (function(AnnotatedTextEdit$1) {
1369
+ /**
1370
+ * Creates an annotated replace text edit.
1371
+ *
1372
+ * @param range The range of text to be replaced.
1373
+ * @param newText The new text.
1374
+ * @param annotation The annotation.
1375
+ */
1376
+ function replace(range, newText, annotation) {
1377
+ return {
1378
+ range,
1379
+ newText,
1380
+ annotationId: annotation
1381
+ };
1382
+ }
1383
+ AnnotatedTextEdit$1.replace = replace;
1384
+ /**
1385
+ * Creates an annotated insert text edit.
1386
+ *
1387
+ * @param position The position to insert the text at.
1388
+ * @param newText The text to be inserted.
1389
+ * @param annotation The annotation.
1390
+ */
1391
+ function insert(position, newText, annotation) {
1392
+ return {
1393
+ range: {
1394
+ start: position,
1395
+ end: position
1396
+ },
1397
+ newText,
1398
+ annotationId: annotation
1399
+ };
1400
+ }
1401
+ AnnotatedTextEdit$1.insert = insert;
1402
+ /**
1403
+ * Creates an annotated delete text edit.
1404
+ *
1405
+ * @param range The range of text to be deleted.
1406
+ * @param annotation The annotation.
1407
+ */
1408
+ function del(range, annotation) {
1409
+ return {
1410
+ range,
1411
+ newText: "",
1412
+ annotationId: annotation
1413
+ };
1414
+ }
1415
+ AnnotatedTextEdit$1.del = del;
1416
+ function is(value) {
1417
+ const candidate = value;
1418
+ return TextEdit.is(candidate) && (ChangeAnnotation.is(candidate.annotationId) || ChangeAnnotationIdentifier.is(candidate.annotationId));
1419
+ }
1420
+ AnnotatedTextEdit$1.is = is;
1421
+ })(AnnotatedTextEdit || (AnnotatedTextEdit = {}));
1422
+ /**
1423
+ * The TextDocumentEdit namespace provides helper function to create
1424
+ * an edit that manipulates a text document.
1425
+ */
1426
+ var TextDocumentEdit;
1427
+ (function(TextDocumentEdit$1) {
1428
+ /**
1429
+ * Creates a new `TextDocumentEdit`
1430
+ */
1431
+ function create(textDocument, edits) {
1432
+ return {
1433
+ textDocument,
1434
+ edits
1435
+ };
1436
+ }
1437
+ TextDocumentEdit$1.create = create;
1438
+ function is(value) {
1439
+ let candidate = value;
1440
+ return Is.defined(candidate) && OptionalVersionedTextDocumentIdentifier.is(candidate.textDocument) && Array.isArray(candidate.edits);
1441
+ }
1442
+ TextDocumentEdit$1.is = is;
1443
+ })(TextDocumentEdit || (TextDocumentEdit = {}));
1444
+ var CreateFile;
1445
+ (function(CreateFile$1) {
1446
+ function create(uri, options, annotation) {
1447
+ let result = {
1448
+ kind: "create",
1449
+ uri
1450
+ };
1451
+ if (options !== undefined && (options.overwrite !== undefined || options.ignoreIfExists !== undefined)) {
1452
+ result.options = options;
1453
+ }
1454
+ if (annotation !== undefined) {
1455
+ result.annotationId = annotation;
1456
+ }
1457
+ return result;
1458
+ }
1459
+ CreateFile$1.create = create;
1460
+ function is(value) {
1461
+ let candidate = value;
1462
+ return candidate && candidate.kind === "create" && Is.string(candidate.uri) && (candidate.options === undefined || (candidate.options.overwrite === undefined || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === undefined || Is.boolean(candidate.options.ignoreIfExists))) && (candidate.annotationId === undefined || ChangeAnnotationIdentifier.is(candidate.annotationId));
1463
+ }
1464
+ CreateFile$1.is = is;
1465
+ })(CreateFile || (CreateFile = {}));
1466
+ var RenameFile;
1467
+ (function(RenameFile$1) {
1468
+ function create(oldUri, newUri, options, annotation) {
1469
+ let result = {
1470
+ kind: "rename",
1471
+ oldUri,
1472
+ newUri
1473
+ };
1474
+ if (options !== undefined && (options.overwrite !== undefined || options.ignoreIfExists !== undefined)) {
1475
+ result.options = options;
1476
+ }
1477
+ if (annotation !== undefined) {
1478
+ result.annotationId = annotation;
1479
+ }
1480
+ return result;
1481
+ }
1482
+ RenameFile$1.create = create;
1483
+ function is(value) {
1484
+ let candidate = value;
1485
+ return candidate && candidate.kind === "rename" && Is.string(candidate.oldUri) && Is.string(candidate.newUri) && (candidate.options === undefined || (candidate.options.overwrite === undefined || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === undefined || Is.boolean(candidate.options.ignoreIfExists))) && (candidate.annotationId === undefined || ChangeAnnotationIdentifier.is(candidate.annotationId));
1486
+ }
1487
+ RenameFile$1.is = is;
1488
+ })(RenameFile || (RenameFile = {}));
1489
+ var DeleteFile;
1490
+ (function(DeleteFile$1) {
1491
+ function create(uri, options, annotation) {
1492
+ let result = {
1493
+ kind: "delete",
1494
+ uri
1495
+ };
1496
+ if (options !== undefined && (options.recursive !== undefined || options.ignoreIfNotExists !== undefined)) {
1497
+ result.options = options;
1498
+ }
1499
+ if (annotation !== undefined) {
1500
+ result.annotationId = annotation;
1501
+ }
1502
+ return result;
1503
+ }
1504
+ DeleteFile$1.create = create;
1505
+ function is(value) {
1506
+ let candidate = value;
1507
+ return candidate && candidate.kind === "delete" && Is.string(candidate.uri) && (candidate.options === undefined || (candidate.options.recursive === undefined || Is.boolean(candidate.options.recursive)) && (candidate.options.ignoreIfNotExists === undefined || Is.boolean(candidate.options.ignoreIfNotExists))) && (candidate.annotationId === undefined || ChangeAnnotationIdentifier.is(candidate.annotationId));
1508
+ }
1509
+ DeleteFile$1.is = is;
1510
+ })(DeleteFile || (DeleteFile = {}));
1511
+ var WorkspaceEdit;
1512
+ (function(WorkspaceEdit$1) {
1513
+ function is(value) {
1514
+ let candidate = value;
1515
+ return candidate && (candidate.changes !== undefined || candidate.documentChanges !== undefined) && (candidate.documentChanges === undefined || candidate.documentChanges.every((change) => {
1516
+ if (Is.string(change.kind)) {
1517
+ return CreateFile.is(change) || RenameFile.is(change) || DeleteFile.is(change);
1518
+ } else {
1519
+ return TextDocumentEdit.is(change);
1520
+ }
1521
+ }));
1522
+ }
1523
+ WorkspaceEdit$1.is = is;
1524
+ })(WorkspaceEdit || (WorkspaceEdit = {}));
1525
+ var TextEditChangeImpl = class {
1526
+ constructor(edits, changeAnnotations) {
1527
+ this.edits = edits;
1528
+ this.changeAnnotations = changeAnnotations;
1529
+ }
1530
+ insert(position, newText, annotation) {
1531
+ let edit;
1532
+ let id;
1533
+ if (annotation === undefined) {
1534
+ edit = TextEdit.insert(position, newText);
1535
+ } else if (ChangeAnnotationIdentifier.is(annotation)) {
1536
+ id = annotation;
1537
+ edit = AnnotatedTextEdit.insert(position, newText, annotation);
1538
+ } else {
1539
+ this.assertChangeAnnotations(this.changeAnnotations);
1540
+ id = this.changeAnnotations.manage(annotation);
1541
+ edit = AnnotatedTextEdit.insert(position, newText, id);
1542
+ }
1543
+ this.edits.push(edit);
1544
+ if (id !== undefined) {
1545
+ return id;
1546
+ }
1547
+ }
1548
+ replace(range, newText, annotation) {
1549
+ let edit;
1550
+ let id;
1551
+ if (annotation === undefined) {
1552
+ edit = TextEdit.replace(range, newText);
1553
+ } else if (ChangeAnnotationIdentifier.is(annotation)) {
1554
+ id = annotation;
1555
+ edit = AnnotatedTextEdit.replace(range, newText, annotation);
1556
+ } else {
1557
+ this.assertChangeAnnotations(this.changeAnnotations);
1558
+ id = this.changeAnnotations.manage(annotation);
1559
+ edit = AnnotatedTextEdit.replace(range, newText, id);
1560
+ }
1561
+ this.edits.push(edit);
1562
+ if (id !== undefined) {
1563
+ return id;
1564
+ }
1565
+ }
1566
+ delete(range, annotation) {
1567
+ let edit;
1568
+ let id;
1569
+ if (annotation === undefined) {
1570
+ edit = TextEdit.del(range);
1571
+ } else if (ChangeAnnotationIdentifier.is(annotation)) {
1572
+ id = annotation;
1573
+ edit = AnnotatedTextEdit.del(range, annotation);
1574
+ } else {
1575
+ this.assertChangeAnnotations(this.changeAnnotations);
1576
+ id = this.changeAnnotations.manage(annotation);
1577
+ edit = AnnotatedTextEdit.del(range, id);
1578
+ }
1579
+ this.edits.push(edit);
1580
+ if (id !== undefined) {
1581
+ return id;
1582
+ }
1583
+ }
1584
+ add(edit) {
1585
+ this.edits.push(edit);
1586
+ }
1587
+ all() {
1588
+ return this.edits;
1589
+ }
1590
+ clear() {
1591
+ this.edits.splice(0, this.edits.length);
1592
+ }
1593
+ assertChangeAnnotations(value) {
1594
+ if (value === undefined) {
1595
+ throw new Error(`Text edit change is not configured to manage change annotations.`);
1596
+ }
1597
+ }
1598
+ };
1599
+ /**
1600
+ * A helper class
1601
+ */
1602
+ var ChangeAnnotations = class {
1603
+ constructor(annotations) {
1604
+ this._annotations = annotations === undefined ? Object.create(null) : annotations;
1605
+ this._counter = 0;
1606
+ this._size = 0;
1607
+ }
1608
+ all() {
1609
+ return this._annotations;
1610
+ }
1611
+ get size() {
1612
+ return this._size;
1613
+ }
1614
+ manage(idOrAnnotation, annotation) {
1615
+ let id;
1616
+ if (ChangeAnnotationIdentifier.is(idOrAnnotation)) {
1617
+ id = idOrAnnotation;
1618
+ } else {
1619
+ id = this.nextId();
1620
+ annotation = idOrAnnotation;
1621
+ }
1622
+ if (this._annotations[id] !== undefined) {
1623
+ throw new Error(`Id ${id} is already in use.`);
1624
+ }
1625
+ if (annotation === undefined) {
1626
+ throw new Error(`No annotation provided for id ${id}`);
1627
+ }
1628
+ this._annotations[id] = annotation;
1629
+ this._size++;
1630
+ return id;
1631
+ }
1632
+ nextId() {
1633
+ this._counter++;
1634
+ return this._counter.toString();
1635
+ }
1636
+ };
1637
+ /**
1638
+ * A workspace change helps constructing changes to a workspace.
1639
+ */
1640
+ var WorkspaceChange = class {
1641
+ constructor(workspaceEdit) {
1642
+ this._textEditChanges = Object.create(null);
1643
+ if (workspaceEdit !== undefined) {
1644
+ this._workspaceEdit = workspaceEdit;
1645
+ if (workspaceEdit.documentChanges) {
1646
+ this._changeAnnotations = new ChangeAnnotations(workspaceEdit.changeAnnotations);
1647
+ workspaceEdit.changeAnnotations = this._changeAnnotations.all();
1648
+ workspaceEdit.documentChanges.forEach((change) => {
1649
+ if (TextDocumentEdit.is(change)) {
1650
+ const textEditChange = new TextEditChangeImpl(change.edits, this._changeAnnotations);
1651
+ this._textEditChanges[change.textDocument.uri] = textEditChange;
1652
+ }
1653
+ });
1654
+ } else if (workspaceEdit.changes) {
1655
+ Object.keys(workspaceEdit.changes).forEach((key) => {
1656
+ const textEditChange = new TextEditChangeImpl(workspaceEdit.changes[key]);
1657
+ this._textEditChanges[key] = textEditChange;
1658
+ });
1659
+ }
1660
+ } else {
1661
+ this._workspaceEdit = {};
1662
+ }
1663
+ }
1664
+ /**
1665
+ * Returns the underlying {@link WorkspaceEdit} literal
1666
+ * use to be returned from a workspace edit operation like rename.
1667
+ */
1668
+ get edit() {
1669
+ this.initDocumentChanges();
1670
+ if (this._changeAnnotations !== undefined) {
1671
+ if (this._changeAnnotations.size === 0) {
1672
+ this._workspaceEdit.changeAnnotations = undefined;
1673
+ } else {
1674
+ this._workspaceEdit.changeAnnotations = this._changeAnnotations.all();
1675
+ }
1676
+ }
1677
+ return this._workspaceEdit;
1678
+ }
1679
+ getTextEditChange(key) {
1680
+ if (OptionalVersionedTextDocumentIdentifier.is(key)) {
1681
+ this.initDocumentChanges();
1682
+ if (this._workspaceEdit.documentChanges === undefined) {
1683
+ throw new Error("Workspace edit is not configured for document changes.");
1684
+ }
1685
+ const textDocument = {
1686
+ uri: key.uri,
1687
+ version: key.version
1688
+ };
1689
+ let result = this._textEditChanges[textDocument.uri];
1690
+ if (!result) {
1691
+ const edits = [];
1692
+ const textDocumentEdit = {
1693
+ textDocument,
1694
+ edits
1695
+ };
1696
+ this._workspaceEdit.documentChanges.push(textDocumentEdit);
1697
+ result = new TextEditChangeImpl(edits, this._changeAnnotations);
1698
+ this._textEditChanges[textDocument.uri] = result;
1699
+ }
1700
+ return result;
1701
+ } else {
1702
+ this.initChanges();
1703
+ if (this._workspaceEdit.changes === undefined) {
1704
+ throw new Error("Workspace edit is not configured for normal text edit changes.");
1705
+ }
1706
+ let result = this._textEditChanges[key];
1707
+ if (!result) {
1708
+ let edits = [];
1709
+ this._workspaceEdit.changes[key] = edits;
1710
+ result = new TextEditChangeImpl(edits);
1711
+ this._textEditChanges[key] = result;
1712
+ }
1713
+ return result;
1714
+ }
1715
+ }
1716
+ initDocumentChanges() {
1717
+ if (this._workspaceEdit.documentChanges === undefined && this._workspaceEdit.changes === undefined) {
1718
+ this._changeAnnotations = new ChangeAnnotations();
1719
+ this._workspaceEdit.documentChanges = [];
1720
+ this._workspaceEdit.changeAnnotations = this._changeAnnotations.all();
1721
+ }
1722
+ }
1723
+ initChanges() {
1724
+ if (this._workspaceEdit.documentChanges === undefined && this._workspaceEdit.changes === undefined) {
1725
+ this._workspaceEdit.changes = Object.create(null);
1726
+ }
1727
+ }
1728
+ createFile(uri, optionsOrAnnotation, options) {
1729
+ this.initDocumentChanges();
1730
+ if (this._workspaceEdit.documentChanges === undefined) {
1731
+ throw new Error("Workspace edit is not configured for document changes.");
1732
+ }
1733
+ let annotation;
1734
+ if (ChangeAnnotation.is(optionsOrAnnotation) || ChangeAnnotationIdentifier.is(optionsOrAnnotation)) {
1735
+ annotation = optionsOrAnnotation;
1736
+ } else {
1737
+ options = optionsOrAnnotation;
1738
+ }
1739
+ let operation;
1740
+ let id;
1741
+ if (annotation === undefined) {
1742
+ operation = CreateFile.create(uri, options);
1743
+ } else {
1744
+ id = ChangeAnnotationIdentifier.is(annotation) ? annotation : this._changeAnnotations.manage(annotation);
1745
+ operation = CreateFile.create(uri, options, id);
1746
+ }
1747
+ this._workspaceEdit.documentChanges.push(operation);
1748
+ if (id !== undefined) {
1749
+ return id;
1750
+ }
1751
+ }
1752
+ renameFile(oldUri, newUri, optionsOrAnnotation, options) {
1753
+ this.initDocumentChanges();
1754
+ if (this._workspaceEdit.documentChanges === undefined) {
1755
+ throw new Error("Workspace edit is not configured for document changes.");
1756
+ }
1757
+ let annotation;
1758
+ if (ChangeAnnotation.is(optionsOrAnnotation) || ChangeAnnotationIdentifier.is(optionsOrAnnotation)) {
1759
+ annotation = optionsOrAnnotation;
1760
+ } else {
1761
+ options = optionsOrAnnotation;
1762
+ }
1763
+ let operation;
1764
+ let id;
1765
+ if (annotation === undefined) {
1766
+ operation = RenameFile.create(oldUri, newUri, options);
1767
+ } else {
1768
+ id = ChangeAnnotationIdentifier.is(annotation) ? annotation : this._changeAnnotations.manage(annotation);
1769
+ operation = RenameFile.create(oldUri, newUri, options, id);
1770
+ }
1771
+ this._workspaceEdit.documentChanges.push(operation);
1772
+ if (id !== undefined) {
1773
+ return id;
1774
+ }
1775
+ }
1776
+ deleteFile(uri, optionsOrAnnotation, options) {
1777
+ this.initDocumentChanges();
1778
+ if (this._workspaceEdit.documentChanges === undefined) {
1779
+ throw new Error("Workspace edit is not configured for document changes.");
1780
+ }
1781
+ let annotation;
1782
+ if (ChangeAnnotation.is(optionsOrAnnotation) || ChangeAnnotationIdentifier.is(optionsOrAnnotation)) {
1783
+ annotation = optionsOrAnnotation;
1784
+ } else {
1785
+ options = optionsOrAnnotation;
1786
+ }
1787
+ let operation;
1788
+ let id;
1789
+ if (annotation === undefined) {
1790
+ operation = DeleteFile.create(uri, options);
1791
+ } else {
1792
+ id = ChangeAnnotationIdentifier.is(annotation) ? annotation : this._changeAnnotations.manage(annotation);
1793
+ operation = DeleteFile.create(uri, options, id);
1794
+ }
1795
+ this._workspaceEdit.documentChanges.push(operation);
1796
+ if (id !== undefined) {
1797
+ return id;
1798
+ }
1799
+ }
1800
+ };
1801
+ /**
1802
+ * The TextDocumentIdentifier namespace provides helper functions to work with
1803
+ * {@link TextDocumentIdentifier} literals.
1804
+ */
1805
+ var TextDocumentIdentifier;
1806
+ (function(TextDocumentIdentifier$1) {
1807
+ /**
1808
+ * Creates a new TextDocumentIdentifier literal.
1809
+ * @param uri The document's uri.
1810
+ */
1811
+ function create(uri) {
1812
+ return { uri };
1813
+ }
1814
+ TextDocumentIdentifier$1.create = create;
1815
+ /**
1816
+ * Checks whether the given literal conforms to the {@link TextDocumentIdentifier} interface.
1817
+ */
1818
+ function is(value) {
1819
+ let candidate = value;
1820
+ return Is.defined(candidate) && Is.string(candidate.uri);
1821
+ }
1822
+ TextDocumentIdentifier$1.is = is;
1823
+ })(TextDocumentIdentifier || (TextDocumentIdentifier = {}));
1824
+ /**
1825
+ * The VersionedTextDocumentIdentifier namespace provides helper functions to work with
1826
+ * {@link VersionedTextDocumentIdentifier} literals.
1827
+ */
1828
+ var VersionedTextDocumentIdentifier;
1829
+ (function(VersionedTextDocumentIdentifier$1) {
1830
+ /**
1831
+ * Creates a new VersionedTextDocumentIdentifier literal.
1832
+ * @param uri The document's uri.
1833
+ * @param version The document's version.
1834
+ */
1835
+ function create(uri, version) {
1836
+ return {
1837
+ uri,
1838
+ version
1839
+ };
1840
+ }
1841
+ VersionedTextDocumentIdentifier$1.create = create;
1842
+ /**
1843
+ * Checks whether the given literal conforms to the {@link VersionedTextDocumentIdentifier} interface.
1844
+ */
1845
+ function is(value) {
1846
+ let candidate = value;
1847
+ return Is.defined(candidate) && Is.string(candidate.uri) && Is.integer(candidate.version);
1848
+ }
1849
+ VersionedTextDocumentIdentifier$1.is = is;
1850
+ })(VersionedTextDocumentIdentifier || (VersionedTextDocumentIdentifier = {}));
1851
+ /**
1852
+ * The OptionalVersionedTextDocumentIdentifier namespace provides helper functions to work with
1853
+ * {@link OptionalVersionedTextDocumentIdentifier} literals.
1854
+ */
1855
+ var OptionalVersionedTextDocumentIdentifier;
1856
+ (function(OptionalVersionedTextDocumentIdentifier$1) {
1857
+ /**
1858
+ * Creates a new OptionalVersionedTextDocumentIdentifier literal.
1859
+ * @param uri The document's uri.
1860
+ * @param version The document's version.
1861
+ */
1862
+ function create(uri, version) {
1863
+ return {
1864
+ uri,
1865
+ version
1866
+ };
1867
+ }
1868
+ OptionalVersionedTextDocumentIdentifier$1.create = create;
1869
+ /**
1870
+ * Checks whether the given literal conforms to the {@link OptionalVersionedTextDocumentIdentifier} interface.
1871
+ */
1872
+ function is(value) {
1873
+ let candidate = value;
1874
+ return Is.defined(candidate) && Is.string(candidate.uri) && (candidate.version === null || Is.integer(candidate.version));
1875
+ }
1876
+ OptionalVersionedTextDocumentIdentifier$1.is = is;
1877
+ })(OptionalVersionedTextDocumentIdentifier || (OptionalVersionedTextDocumentIdentifier = {}));
1878
+ /**
1879
+ * The TextDocumentItem namespace provides helper functions to work with
1880
+ * {@link TextDocumentItem} literals.
1881
+ */
1882
+ var TextDocumentItem;
1883
+ (function(TextDocumentItem$1) {
1884
+ /**
1885
+ * Creates a new TextDocumentItem literal.
1886
+ * @param uri The document's uri.
1887
+ * @param languageId The document's language identifier.
1888
+ * @param version The document's version number.
1889
+ * @param text The document's text.
1890
+ */
1891
+ function create(uri, languageId, version, text) {
1892
+ return {
1893
+ uri,
1894
+ languageId,
1895
+ version,
1896
+ text
1897
+ };
1898
+ }
1899
+ TextDocumentItem$1.create = create;
1900
+ /**
1901
+ * Checks whether the given literal conforms to the {@link TextDocumentItem} interface.
1902
+ */
1903
+ function is(value) {
1904
+ let candidate = value;
1905
+ return Is.defined(candidate) && Is.string(candidate.uri) && Is.string(candidate.languageId) && Is.integer(candidate.version) && Is.string(candidate.text);
1906
+ }
1907
+ TextDocumentItem$1.is = is;
1908
+ })(TextDocumentItem || (TextDocumentItem = {}));
1909
+ /**
1910
+ * Describes the content type that a client supports in various
1911
+ * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
1912
+ *
1913
+ * Please note that `MarkupKinds` must not start with a `$`. This kinds
1914
+ * are reserved for internal usage.
1915
+ */
1916
+ var MarkupKind;
1917
+ (function(MarkupKind$1) {
1918
+ /**
1919
+ * Plain text is supported as a content format
1920
+ */
1921
+ MarkupKind$1.PlainText = "plaintext";
1922
+ /**
1923
+ * Markdown is supported as a content format
1924
+ */
1925
+ MarkupKind$1.Markdown = "markdown";
1926
+ /**
1927
+ * Checks whether the given value is a value of the {@link MarkupKind} type.
1928
+ */
1929
+ function is(value) {
1930
+ const candidate = value;
1931
+ return candidate === MarkupKind$1.PlainText || candidate === MarkupKind$1.Markdown;
1932
+ }
1933
+ MarkupKind$1.is = is;
1934
+ })(MarkupKind || (MarkupKind = {}));
1935
+ var MarkupContent;
1936
+ (function(MarkupContent$1) {
1937
+ /**
1938
+ * Checks whether the given value conforms to the {@link MarkupContent} interface.
1939
+ */
1940
+ function is(value) {
1941
+ const candidate = value;
1942
+ return Is.objectLiteral(value) && MarkupKind.is(candidate.kind) && Is.string(candidate.value);
1943
+ }
1944
+ MarkupContent$1.is = is;
1945
+ })(MarkupContent || (MarkupContent = {}));
1946
+ /**
1947
+ * The kind of a completion entry.
1948
+ */
1949
+ var CompletionItemKind;
1950
+ (function(CompletionItemKind$1) {
1951
+ CompletionItemKind$1.Text = 1;
1952
+ CompletionItemKind$1.Method = 2;
1953
+ CompletionItemKind$1.Function = 3;
1954
+ CompletionItemKind$1.Constructor = 4;
1955
+ CompletionItemKind$1.Field = 5;
1956
+ CompletionItemKind$1.Variable = 6;
1957
+ CompletionItemKind$1.Class = 7;
1958
+ CompletionItemKind$1.Interface = 8;
1959
+ CompletionItemKind$1.Module = 9;
1960
+ CompletionItemKind$1.Property = 10;
1961
+ CompletionItemKind$1.Unit = 11;
1962
+ CompletionItemKind$1.Value = 12;
1963
+ CompletionItemKind$1.Enum = 13;
1964
+ CompletionItemKind$1.Keyword = 14;
1965
+ CompletionItemKind$1.Snippet = 15;
1966
+ CompletionItemKind$1.Color = 16;
1967
+ CompletionItemKind$1.File = 17;
1968
+ CompletionItemKind$1.Reference = 18;
1969
+ CompletionItemKind$1.Folder = 19;
1970
+ CompletionItemKind$1.EnumMember = 20;
1971
+ CompletionItemKind$1.Constant = 21;
1972
+ CompletionItemKind$1.Struct = 22;
1973
+ CompletionItemKind$1.Event = 23;
1974
+ CompletionItemKind$1.Operator = 24;
1975
+ CompletionItemKind$1.TypeParameter = 25;
1976
+ })(CompletionItemKind || (CompletionItemKind = {}));
1977
+ /**
1978
+ * Defines whether the insert text in a completion item should be interpreted as
1979
+ * plain text or a snippet.
1980
+ */
1981
+ var InsertTextFormat;
1982
+ (function(InsertTextFormat$1) {
1983
+ /**
1984
+ * The primary text to be inserted is treated as a plain string.
1985
+ */
1986
+ InsertTextFormat$1.PlainText = 1;
1987
+ /**
1988
+ * The primary text to be inserted is treated as a snippet.
1989
+ *
1990
+ * A snippet can define tab stops and placeholders with `$1`, `$2`
1991
+ * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
1992
+ * the end of the snippet. Placeholders with equal identifiers are linked,
1993
+ * that is typing in one will update others too.
1994
+ *
1995
+ * See also: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
1996
+ */
1997
+ InsertTextFormat$1.Snippet = 2;
1998
+ })(InsertTextFormat || (InsertTextFormat = {}));
1999
+ /**
2000
+ * Completion item tags are extra annotations that tweak the rendering of a completion
2001
+ * item.
2002
+ *
2003
+ * @since 3.15.0
2004
+ */
2005
+ var CompletionItemTag;
2006
+ (function(CompletionItemTag$1) {
2007
+ /**
2008
+ * Render a completion as obsolete, usually using a strike-out.
2009
+ */
2010
+ CompletionItemTag$1.Deprecated = 1;
2011
+ })(CompletionItemTag || (CompletionItemTag = {}));
2012
+ /**
2013
+ * The InsertReplaceEdit namespace provides functions to deal with insert / replace edits.
2014
+ *
2015
+ * @since 3.16.0
2016
+ */
2017
+ var InsertReplaceEdit;
2018
+ (function(InsertReplaceEdit$1) {
2019
+ /**
2020
+ * Creates a new insert / replace edit
2021
+ */
2022
+ function create(newText, insert, replace) {
2023
+ return {
2024
+ newText,
2025
+ insert,
2026
+ replace
2027
+ };
2028
+ }
2029
+ InsertReplaceEdit$1.create = create;
2030
+ /**
2031
+ * Checks whether the given literal conforms to the {@link InsertReplaceEdit} interface.
2032
+ */
2033
+ function is(value) {
2034
+ const candidate = value;
2035
+ return candidate && Is.string(candidate.newText) && Range.is(candidate.insert) && Range.is(candidate.replace);
2036
+ }
2037
+ InsertReplaceEdit$1.is = is;
2038
+ })(InsertReplaceEdit || (InsertReplaceEdit = {}));
2039
+ /**
2040
+ * How whitespace and indentation is handled during completion
2041
+ * item insertion.
2042
+ *
2043
+ * @since 3.16.0
2044
+ */
2045
+ var InsertTextMode;
2046
+ (function(InsertTextMode$1) {
2047
+ /**
2048
+ * The insertion or replace strings is taken as it is. If the
2049
+ * value is multi line the lines below the cursor will be
2050
+ * inserted using the indentation defined in the string value.
2051
+ * The client will not apply any kind of adjustments to the
2052
+ * string.
2053
+ */
2054
+ InsertTextMode$1.asIs = 1;
2055
+ /**
2056
+ * The editor adjusts leading whitespace of new lines so that
2057
+ * they match the indentation up to the cursor of the line for
2058
+ * which the item is accepted.
2059
+ *
2060
+ * Consider a line like this: <2tabs><cursor><3tabs>foo. Accepting a
2061
+ * multi line completion item is indented using 2 tabs and all
2062
+ * following lines inserted will be indented using 2 tabs as well.
2063
+ */
2064
+ InsertTextMode$1.adjustIndentation = 2;
2065
+ })(InsertTextMode || (InsertTextMode = {}));
2066
+ var CompletionItemLabelDetails;
2067
+ (function(CompletionItemLabelDetails$1) {
2068
+ function is(value) {
2069
+ const candidate = value;
2070
+ return candidate && (Is.string(candidate.detail) || candidate.detail === undefined) && (Is.string(candidate.description) || candidate.description === undefined);
2071
+ }
2072
+ CompletionItemLabelDetails$1.is = is;
2073
+ })(CompletionItemLabelDetails || (CompletionItemLabelDetails = {}));
2074
+ /**
2075
+ * The CompletionItem namespace provides functions to deal with
2076
+ * completion items.
2077
+ */
2078
+ var CompletionItem;
2079
+ (function(CompletionItem$1) {
2080
+ /**
2081
+ * Create a completion item and seed it with a label.
2082
+ * @param label The completion item's label
2083
+ */
2084
+ function create(label) {
2085
+ return { label };
2086
+ }
2087
+ CompletionItem$1.create = create;
2088
+ })(CompletionItem || (CompletionItem = {}));
2089
+ /**
2090
+ * The CompletionList namespace provides functions to deal with
2091
+ * completion lists.
2092
+ */
2093
+ var CompletionList;
2094
+ (function(CompletionList$1) {
2095
+ /**
2096
+ * Creates a new completion list.
2097
+ *
2098
+ * @param items The completion items.
2099
+ * @param isIncomplete The list is not complete.
2100
+ */
2101
+ function create(items, isIncomplete) {
2102
+ return {
2103
+ items: items ? items : [],
2104
+ isIncomplete: !!isIncomplete
2105
+ };
2106
+ }
2107
+ CompletionList$1.create = create;
2108
+ })(CompletionList || (CompletionList = {}));
2109
+ var MarkedString;
2110
+ (function(MarkedString$1) {
2111
+ /**
2112
+ * Creates a marked string from plain text.
2113
+ *
2114
+ * @param plainText The plain text.
2115
+ */
2116
+ function fromPlainText(plainText) {
2117
+ return plainText.replace(/[\\`*_{}[\]()#+\-.!]/g, "\\$&");
2118
+ }
2119
+ MarkedString$1.fromPlainText = fromPlainText;
2120
+ /**
2121
+ * Checks whether the given value conforms to the {@link MarkedString} type.
2122
+ */
2123
+ function is(value) {
2124
+ const candidate = value;
2125
+ return Is.string(candidate) || Is.objectLiteral(candidate) && Is.string(candidate.language) && Is.string(candidate.value);
2126
+ }
2127
+ MarkedString$1.is = is;
2128
+ })(MarkedString || (MarkedString = {}));
2129
+ var Hover;
2130
+ (function(Hover$1) {
2131
+ /**
2132
+ * Checks whether the given value conforms to the {@link Hover} interface.
2133
+ */
2134
+ function is(value) {
2135
+ let candidate = value;
2136
+ return !!candidate && Is.objectLiteral(candidate) && (MarkupContent.is(candidate.contents) || MarkedString.is(candidate.contents) || Is.typedArray(candidate.contents, MarkedString.is)) && (value.range === undefined || Range.is(value.range));
2137
+ }
2138
+ Hover$1.is = is;
2139
+ })(Hover || (Hover = {}));
2140
+ /**
2141
+ * The ParameterInformation namespace provides helper functions to work with
2142
+ * {@link ParameterInformation} literals.
2143
+ */
2144
+ var ParameterInformation;
2145
+ (function(ParameterInformation$1) {
2146
+ /**
2147
+ * Creates a new parameter information literal.
2148
+ *
2149
+ * @param label A label string.
2150
+ * @param documentation A doc string.
2151
+ */
2152
+ function create(label, documentation) {
2153
+ return documentation ? {
2154
+ label,
2155
+ documentation
2156
+ } : { label };
2157
+ }
2158
+ ParameterInformation$1.create = create;
2159
+ })(ParameterInformation || (ParameterInformation = {}));
2160
+ /**
2161
+ * The SignatureInformation namespace provides helper functions to work with
2162
+ * {@link SignatureInformation} literals.
2163
+ */
2164
+ var SignatureInformation;
2165
+ (function(SignatureInformation$1) {
2166
+ function create(label, documentation, ...parameters) {
2167
+ let result = { label };
2168
+ if (Is.defined(documentation)) {
2169
+ result.documentation = documentation;
2170
+ }
2171
+ if (Is.defined(parameters)) {
2172
+ result.parameters = parameters;
2173
+ } else {
2174
+ result.parameters = [];
2175
+ }
2176
+ return result;
2177
+ }
2178
+ SignatureInformation$1.create = create;
2179
+ })(SignatureInformation || (SignatureInformation = {}));
2180
+ /**
2181
+ * A document highlight kind.
2182
+ */
2183
+ var DocumentHighlightKind;
2184
+ (function(DocumentHighlightKind$1) {
2185
+ /**
2186
+ * A textual occurrence.
2187
+ */
2188
+ DocumentHighlightKind$1.Text = 1;
2189
+ /**
2190
+ * Read-access of a symbol, like reading a variable.
2191
+ */
2192
+ DocumentHighlightKind$1.Read = 2;
2193
+ /**
2194
+ * Write-access of a symbol, like writing to a variable.
2195
+ */
2196
+ DocumentHighlightKind$1.Write = 3;
2197
+ })(DocumentHighlightKind || (DocumentHighlightKind = {}));
2198
+ /**
2199
+ * DocumentHighlight namespace to provide helper functions to work with
2200
+ * {@link DocumentHighlight} literals.
2201
+ */
2202
+ var DocumentHighlight;
2203
+ (function(DocumentHighlight$1) {
2204
+ /**
2205
+ * Create a DocumentHighlight object.
2206
+ * @param range The range the highlight applies to.
2207
+ * @param kind The highlight kind
2208
+ */
2209
+ function create(range, kind) {
2210
+ let result = { range };
2211
+ if (Is.number(kind)) {
2212
+ result.kind = kind;
2213
+ }
2214
+ return result;
2215
+ }
2216
+ DocumentHighlight$1.create = create;
2217
+ })(DocumentHighlight || (DocumentHighlight = {}));
2218
+ /**
2219
+ * A symbol kind.
2220
+ */
2221
+ var SymbolKind;
2222
+ (function(SymbolKind$1) {
2223
+ SymbolKind$1.File = 1;
2224
+ SymbolKind$1.Module = 2;
2225
+ SymbolKind$1.Namespace = 3;
2226
+ SymbolKind$1.Package = 4;
2227
+ SymbolKind$1.Class = 5;
2228
+ SymbolKind$1.Method = 6;
2229
+ SymbolKind$1.Property = 7;
2230
+ SymbolKind$1.Field = 8;
2231
+ SymbolKind$1.Constructor = 9;
2232
+ SymbolKind$1.Enum = 10;
2233
+ SymbolKind$1.Interface = 11;
2234
+ SymbolKind$1.Function = 12;
2235
+ SymbolKind$1.Variable = 13;
2236
+ SymbolKind$1.Constant = 14;
2237
+ SymbolKind$1.String = 15;
2238
+ SymbolKind$1.Number = 16;
2239
+ SymbolKind$1.Boolean = 17;
2240
+ SymbolKind$1.Array = 18;
2241
+ SymbolKind$1.Object = 19;
2242
+ SymbolKind$1.Key = 20;
2243
+ SymbolKind$1.Null = 21;
2244
+ SymbolKind$1.EnumMember = 22;
2245
+ SymbolKind$1.Struct = 23;
2246
+ SymbolKind$1.Event = 24;
2247
+ SymbolKind$1.Operator = 25;
2248
+ SymbolKind$1.TypeParameter = 26;
2249
+ })(SymbolKind || (SymbolKind = {}));
2250
+ /**
2251
+ * Symbol tags are extra annotations that tweak the rendering of a symbol.
2252
+ *
2253
+ * @since 3.16
2254
+ */
2255
+ var SymbolTag;
2256
+ (function(SymbolTag$1) {
2257
+ /**
2258
+ * Render a symbol as obsolete, usually using a strike-out.
2259
+ */
2260
+ SymbolTag$1.Deprecated = 1;
2261
+ })(SymbolTag || (SymbolTag = {}));
2262
+ var SymbolInformation;
2263
+ (function(SymbolInformation$1) {
2264
+ /**
2265
+ * Creates a new symbol information literal.
2266
+ *
2267
+ * @param name The name of the symbol.
2268
+ * @param kind The kind of the symbol.
2269
+ * @param range The range of the location of the symbol.
2270
+ * @param uri The resource of the location of symbol.
2271
+ * @param containerName The name of the symbol containing the symbol.
2272
+ */
2273
+ function create(name, kind, range, uri, containerName) {
2274
+ let result = {
2275
+ name,
2276
+ kind,
2277
+ location: {
2278
+ uri,
2279
+ range
2280
+ }
2281
+ };
2282
+ if (containerName) {
2283
+ result.containerName = containerName;
2284
+ }
2285
+ return result;
2286
+ }
2287
+ SymbolInformation$1.create = create;
2288
+ })(SymbolInformation || (SymbolInformation = {}));
2289
+ var WorkspaceSymbol;
2290
+ (function(WorkspaceSymbol$1) {
2291
+ /**
2292
+ * Create a new workspace symbol.
2293
+ *
2294
+ * @param name The name of the symbol.
2295
+ * @param kind The kind of the symbol.
2296
+ * @param uri The resource of the location of the symbol.
2297
+ * @param range An options range of the location.
2298
+ * @returns A WorkspaceSymbol.
2299
+ */
2300
+ function create(name, kind, uri, range) {
2301
+ return range !== undefined ? {
2302
+ name,
2303
+ kind,
2304
+ location: {
2305
+ uri,
2306
+ range
2307
+ }
2308
+ } : {
2309
+ name,
2310
+ kind,
2311
+ location: { uri }
2312
+ };
2313
+ }
2314
+ WorkspaceSymbol$1.create = create;
2315
+ })(WorkspaceSymbol || (WorkspaceSymbol = {}));
2316
+ var DocumentSymbol;
2317
+ (function(DocumentSymbol$1) {
2318
+ /**
2319
+ * Creates a new symbol information literal.
2320
+ *
2321
+ * @param name The name of the symbol.
2322
+ * @param detail The detail of the symbol.
2323
+ * @param kind The kind of the symbol.
2324
+ * @param range The range of the symbol.
2325
+ * @param selectionRange The selectionRange of the symbol.
2326
+ * @param children Children of the symbol.
2327
+ */
2328
+ function create(name, detail, kind, range, selectionRange, children) {
2329
+ let result = {
2330
+ name,
2331
+ detail,
2332
+ kind,
2333
+ range,
2334
+ selectionRange
2335
+ };
2336
+ if (children !== undefined) {
2337
+ result.children = children;
2338
+ }
2339
+ return result;
2340
+ }
2341
+ DocumentSymbol$1.create = create;
2342
+ /**
2343
+ * Checks whether the given literal conforms to the {@link DocumentSymbol} interface.
2344
+ */
2345
+ function is(value) {
2346
+ let candidate = value;
2347
+ return candidate && Is.string(candidate.name) && Is.number(candidate.kind) && Range.is(candidate.range) && Range.is(candidate.selectionRange) && (candidate.detail === undefined || Is.string(candidate.detail)) && (candidate.deprecated === undefined || Is.boolean(candidate.deprecated)) && (candidate.children === undefined || Array.isArray(candidate.children)) && (candidate.tags === undefined || Array.isArray(candidate.tags));
2348
+ }
2349
+ DocumentSymbol$1.is = is;
2350
+ })(DocumentSymbol || (DocumentSymbol = {}));
2351
+ /**
2352
+ * A set of predefined code action kinds
2353
+ */
2354
+ var CodeActionKind;
2355
+ (function(CodeActionKind$1) {
2356
+ /**
2357
+ * Empty kind.
2358
+ */
2359
+ CodeActionKind$1.Empty = "";
2360
+ /**
2361
+ * Base kind for quickfix actions: 'quickfix'
2362
+ */
2363
+ CodeActionKind$1.QuickFix = "quickfix";
2364
+ /**
2365
+ * Base kind for refactoring actions: 'refactor'
2366
+ */
2367
+ CodeActionKind$1.Refactor = "refactor";
2368
+ /**
2369
+ * Base kind for refactoring extraction actions: 'refactor.extract'
2370
+ *
2371
+ * Example extract actions:
2372
+ *
2373
+ * - Extract method
2374
+ * - Extract function
2375
+ * - Extract variable
2376
+ * - Extract interface from class
2377
+ * - ...
2378
+ */
2379
+ CodeActionKind$1.RefactorExtract = "refactor.extract";
2380
+ /**
2381
+ * Base kind for refactoring inline actions: 'refactor.inline'
2382
+ *
2383
+ * Example inline actions:
2384
+ *
2385
+ * - Inline function
2386
+ * - Inline variable
2387
+ * - Inline constant
2388
+ * - ...
2389
+ */
2390
+ CodeActionKind$1.RefactorInline = "refactor.inline";
2391
+ /**
2392
+ * Base kind for refactoring rewrite actions: 'refactor.rewrite'
2393
+ *
2394
+ * Example rewrite actions:
2395
+ *
2396
+ * - Convert JavaScript function to class
2397
+ * - Add or remove parameter
2398
+ * - Encapsulate field
2399
+ * - Make method static
2400
+ * - Move method to base class
2401
+ * - ...
2402
+ */
2403
+ CodeActionKind$1.RefactorRewrite = "refactor.rewrite";
2404
+ /**
2405
+ * Base kind for source actions: `source`
2406
+ *
2407
+ * Source code actions apply to the entire file.
2408
+ */
2409
+ CodeActionKind$1.Source = "source";
2410
+ /**
2411
+ * Base kind for an organize imports source action: `source.organizeImports`
2412
+ */
2413
+ CodeActionKind$1.SourceOrganizeImports = "source.organizeImports";
2414
+ /**
2415
+ * Base kind for auto-fix source actions: `source.fixAll`.
2416
+ *
2417
+ * Fix all actions automatically fix errors that have a clear fix that do not require user input.
2418
+ * They should not suppress errors or perform unsafe fixes such as generating new types or classes.
2419
+ *
2420
+ * @since 3.15.0
2421
+ */
2422
+ CodeActionKind$1.SourceFixAll = "source.fixAll";
2423
+ })(CodeActionKind || (CodeActionKind = {}));
2424
+ /**
2425
+ * The reason why code actions were requested.
2426
+ *
2427
+ * @since 3.17.0
2428
+ */
2429
+ var CodeActionTriggerKind;
2430
+ (function(CodeActionTriggerKind$1) {
2431
+ /**
2432
+ * Code actions were explicitly requested by the user or by an extension.
2433
+ */
2434
+ CodeActionTriggerKind$1.Invoked = 1;
2435
+ /**
2436
+ * Code actions were requested automatically.
2437
+ *
2438
+ * This typically happens when current selection in a file changes, but can
2439
+ * also be triggered when file content changes.
2440
+ */
2441
+ CodeActionTriggerKind$1.Automatic = 2;
2442
+ })(CodeActionTriggerKind || (CodeActionTriggerKind = {}));
2443
+ /**
2444
+ * The CodeActionContext namespace provides helper functions to work with
2445
+ * {@link CodeActionContext} literals.
2446
+ */
2447
+ var CodeActionContext;
2448
+ (function(CodeActionContext$1) {
2449
+ /**
2450
+ * Creates a new CodeActionContext literal.
2451
+ */
2452
+ function create(diagnostics, only, triggerKind) {
2453
+ let result = { diagnostics };
2454
+ if (only !== undefined && only !== null) {
2455
+ result.only = only;
2456
+ }
2457
+ if (triggerKind !== undefined && triggerKind !== null) {
2458
+ result.triggerKind = triggerKind;
2459
+ }
2460
+ return result;
2461
+ }
2462
+ CodeActionContext$1.create = create;
2463
+ /**
2464
+ * Checks whether the given literal conforms to the {@link CodeActionContext} interface.
2465
+ */
2466
+ function is(value) {
2467
+ let candidate = value;
2468
+ return Is.defined(candidate) && Is.typedArray(candidate.diagnostics, Diagnostic.is) && (candidate.only === undefined || Is.typedArray(candidate.only, Is.string)) && (candidate.triggerKind === undefined || candidate.triggerKind === CodeActionTriggerKind.Invoked || candidate.triggerKind === CodeActionTriggerKind.Automatic);
2469
+ }
2470
+ CodeActionContext$1.is = is;
2471
+ })(CodeActionContext || (CodeActionContext = {}));
2472
+ var CodeAction;
2473
+ (function(CodeAction$1) {
2474
+ function create(title, kindOrCommandOrEdit, kind) {
2475
+ let result = { title };
2476
+ let checkKind = true;
2477
+ if (typeof kindOrCommandOrEdit === "string") {
2478
+ checkKind = false;
2479
+ result.kind = kindOrCommandOrEdit;
2480
+ } else if (Command.is(kindOrCommandOrEdit)) {
2481
+ result.command = kindOrCommandOrEdit;
2482
+ } else {
2483
+ result.edit = kindOrCommandOrEdit;
2484
+ }
2485
+ if (checkKind && kind !== undefined) {
2486
+ result.kind = kind;
2487
+ }
2488
+ return result;
2489
+ }
2490
+ CodeAction$1.create = create;
2491
+ function is(value) {
2492
+ let candidate = value;
2493
+ return candidate && Is.string(candidate.title) && (candidate.diagnostics === undefined || Is.typedArray(candidate.diagnostics, Diagnostic.is)) && (candidate.kind === undefined || Is.string(candidate.kind)) && (candidate.edit !== undefined || candidate.command !== undefined) && (candidate.command === undefined || Command.is(candidate.command)) && (candidate.isPreferred === undefined || Is.boolean(candidate.isPreferred)) && (candidate.edit === undefined || WorkspaceEdit.is(candidate.edit));
2494
+ }
2495
+ CodeAction$1.is = is;
2496
+ })(CodeAction || (CodeAction = {}));
2497
+ /**
2498
+ * The CodeLens namespace provides helper functions to work with
2499
+ * {@link CodeLens} literals.
2500
+ */
2501
+ var CodeLens;
2502
+ (function(CodeLens$1) {
2503
+ /**
2504
+ * Creates a new CodeLens literal.
2505
+ */
2506
+ function create(range, data) {
2507
+ let result = { range };
2508
+ if (Is.defined(data)) {
2509
+ result.data = data;
2510
+ }
2511
+ return result;
2512
+ }
2513
+ CodeLens$1.create = create;
2514
+ /**
2515
+ * Checks whether the given literal conforms to the {@link CodeLens} interface.
2516
+ */
2517
+ function is(value) {
2518
+ let candidate = value;
2519
+ return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.command) || Command.is(candidate.command));
2520
+ }
2521
+ CodeLens$1.is = is;
2522
+ })(CodeLens || (CodeLens = {}));
2523
+ /**
2524
+ * The FormattingOptions namespace provides helper functions to work with
2525
+ * {@link FormattingOptions} literals.
2526
+ */
2527
+ var FormattingOptions;
2528
+ (function(FormattingOptions$1) {
2529
+ /**
2530
+ * Creates a new FormattingOptions literal.
2531
+ */
2532
+ function create(tabSize, insertSpaces) {
2533
+ return {
2534
+ tabSize,
2535
+ insertSpaces
2536
+ };
2537
+ }
2538
+ FormattingOptions$1.create = create;
2539
+ /**
2540
+ * Checks whether the given literal conforms to the {@link FormattingOptions} interface.
2541
+ */
2542
+ function is(value) {
2543
+ let candidate = value;
2544
+ return Is.defined(candidate) && Is.uinteger(candidate.tabSize) && Is.boolean(candidate.insertSpaces);
2545
+ }
2546
+ FormattingOptions$1.is = is;
2547
+ })(FormattingOptions || (FormattingOptions = {}));
2548
+ /**
2549
+ * The DocumentLink namespace provides helper functions to work with
2550
+ * {@link DocumentLink} literals.
2551
+ */
2552
+ var DocumentLink;
2553
+ (function(DocumentLink$1) {
2554
+ /**
2555
+ * Creates a new DocumentLink literal.
2556
+ */
2557
+ function create(range, target, data) {
2558
+ return {
2559
+ range,
2560
+ target,
2561
+ data
2562
+ };
2563
+ }
2564
+ DocumentLink$1.create = create;
2565
+ /**
2566
+ * Checks whether the given literal conforms to the {@link DocumentLink} interface.
2567
+ */
2568
+ function is(value) {
2569
+ let candidate = value;
2570
+ return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.target) || Is.string(candidate.target));
2571
+ }
2572
+ DocumentLink$1.is = is;
2573
+ })(DocumentLink || (DocumentLink = {}));
2574
+ /**
2575
+ * The SelectionRange namespace provides helper function to work with
2576
+ * SelectionRange literals.
2577
+ */
2578
+ var SelectionRange;
2579
+ (function(SelectionRange$1) {
2580
+ /**
2581
+ * Creates a new SelectionRange
2582
+ * @param range the range.
2583
+ * @param parent an optional parent.
2584
+ */
2585
+ function create(range, parent) {
2586
+ return {
2587
+ range,
2588
+ parent
2589
+ };
2590
+ }
2591
+ SelectionRange$1.create = create;
2592
+ function is(value) {
2593
+ let candidate = value;
2594
+ return Is.objectLiteral(candidate) && Range.is(candidate.range) && (candidate.parent === undefined || SelectionRange$1.is(candidate.parent));
2595
+ }
2596
+ SelectionRange$1.is = is;
2597
+ })(SelectionRange || (SelectionRange = {}));
2598
+ /**
2599
+ * A set of predefined token types. This set is not fixed
2600
+ * an clients can specify additional token types via the
2601
+ * corresponding client capabilities.
2602
+ *
2603
+ * @since 3.16.0
2604
+ */
2605
+ var SemanticTokenTypes;
2606
+ (function(SemanticTokenTypes$1) {
2607
+ SemanticTokenTypes$1["namespace"] = "namespace";
2608
+ /**
2609
+ * Represents a generic type. Acts as a fallback for types which can't be mapped to
2610
+ * a specific type like class or enum.
2611
+ */
2612
+ SemanticTokenTypes$1["type"] = "type";
2613
+ SemanticTokenTypes$1["class"] = "class";
2614
+ SemanticTokenTypes$1["enum"] = "enum";
2615
+ SemanticTokenTypes$1["interface"] = "interface";
2616
+ SemanticTokenTypes$1["struct"] = "struct";
2617
+ SemanticTokenTypes$1["typeParameter"] = "typeParameter";
2618
+ SemanticTokenTypes$1["parameter"] = "parameter";
2619
+ SemanticTokenTypes$1["variable"] = "variable";
2620
+ SemanticTokenTypes$1["property"] = "property";
2621
+ SemanticTokenTypes$1["enumMember"] = "enumMember";
2622
+ SemanticTokenTypes$1["event"] = "event";
2623
+ SemanticTokenTypes$1["function"] = "function";
2624
+ SemanticTokenTypes$1["method"] = "method";
2625
+ SemanticTokenTypes$1["macro"] = "macro";
2626
+ SemanticTokenTypes$1["keyword"] = "keyword";
2627
+ SemanticTokenTypes$1["modifier"] = "modifier";
2628
+ SemanticTokenTypes$1["comment"] = "comment";
2629
+ SemanticTokenTypes$1["string"] = "string";
2630
+ SemanticTokenTypes$1["number"] = "number";
2631
+ SemanticTokenTypes$1["regexp"] = "regexp";
2632
+ SemanticTokenTypes$1["operator"] = "operator";
2633
+ /**
2634
+ * @since 3.17.0
2635
+ */
2636
+ SemanticTokenTypes$1["decorator"] = "decorator";
2637
+ })(SemanticTokenTypes || (SemanticTokenTypes = {}));
2638
+ /**
2639
+ * A set of predefined token modifiers. This set is not fixed
2640
+ * an clients can specify additional token types via the
2641
+ * corresponding client capabilities.
2642
+ *
2643
+ * @since 3.16.0
2644
+ */
2645
+ var SemanticTokenModifiers;
2646
+ (function(SemanticTokenModifiers$1) {
2647
+ SemanticTokenModifiers$1["declaration"] = "declaration";
2648
+ SemanticTokenModifiers$1["definition"] = "definition";
2649
+ SemanticTokenModifiers$1["readonly"] = "readonly";
2650
+ SemanticTokenModifiers$1["static"] = "static";
2651
+ SemanticTokenModifiers$1["deprecated"] = "deprecated";
2652
+ SemanticTokenModifiers$1["abstract"] = "abstract";
2653
+ SemanticTokenModifiers$1["async"] = "async";
2654
+ SemanticTokenModifiers$1["modification"] = "modification";
2655
+ SemanticTokenModifiers$1["documentation"] = "documentation";
2656
+ SemanticTokenModifiers$1["defaultLibrary"] = "defaultLibrary";
2657
+ })(SemanticTokenModifiers || (SemanticTokenModifiers = {}));
2658
+ /**
2659
+ * @since 3.16.0
2660
+ */
2661
+ var SemanticTokens;
2662
+ (function(SemanticTokens$1) {
2663
+ function is(value) {
2664
+ const candidate = value;
2665
+ return Is.objectLiteral(candidate) && (candidate.resultId === undefined || typeof candidate.resultId === "string") && Array.isArray(candidate.data) && (candidate.data.length === 0 || typeof candidate.data[0] === "number");
2666
+ }
2667
+ SemanticTokens$1.is = is;
2668
+ })(SemanticTokens || (SemanticTokens = {}));
2669
+ /**
2670
+ * The InlineValueText namespace provides functions to deal with InlineValueTexts.
2671
+ *
2672
+ * @since 3.17.0
2673
+ */
2674
+ var InlineValueText;
2675
+ (function(InlineValueText$1) {
2676
+ /**
2677
+ * Creates a new InlineValueText literal.
2678
+ */
2679
+ function create(range, text) {
2680
+ return {
2681
+ range,
2682
+ text
2683
+ };
2684
+ }
2685
+ InlineValueText$1.create = create;
2686
+ function is(value) {
2687
+ const candidate = value;
2688
+ return candidate !== undefined && candidate !== null && Range.is(candidate.range) && Is.string(candidate.text);
2689
+ }
2690
+ InlineValueText$1.is = is;
2691
+ })(InlineValueText || (InlineValueText = {}));
2692
+ /**
2693
+ * The InlineValueVariableLookup namespace provides functions to deal with InlineValueVariableLookups.
2694
+ *
2695
+ * @since 3.17.0
2696
+ */
2697
+ var InlineValueVariableLookup;
2698
+ (function(InlineValueVariableLookup$1) {
2699
+ /**
2700
+ * Creates a new InlineValueText literal.
2701
+ */
2702
+ function create(range, variableName, caseSensitiveLookup) {
2703
+ return {
2704
+ range,
2705
+ variableName,
2706
+ caseSensitiveLookup
2707
+ };
2708
+ }
2709
+ InlineValueVariableLookup$1.create = create;
2710
+ function is(value) {
2711
+ const candidate = value;
2712
+ return candidate !== undefined && candidate !== null && Range.is(candidate.range) && Is.boolean(candidate.caseSensitiveLookup) && (Is.string(candidate.variableName) || candidate.variableName === undefined);
2713
+ }
2714
+ InlineValueVariableLookup$1.is = is;
2715
+ })(InlineValueVariableLookup || (InlineValueVariableLookup = {}));
2716
+ /**
2717
+ * The InlineValueEvaluatableExpression namespace provides functions to deal with InlineValueEvaluatableExpression.
2718
+ *
2719
+ * @since 3.17.0
2720
+ */
2721
+ var InlineValueEvaluatableExpression;
2722
+ (function(InlineValueEvaluatableExpression$1) {
2723
+ /**
2724
+ * Creates a new InlineValueEvaluatableExpression literal.
2725
+ */
2726
+ function create(range, expression) {
2727
+ return {
2728
+ range,
2729
+ expression
2730
+ };
2731
+ }
2732
+ InlineValueEvaluatableExpression$1.create = create;
2733
+ function is(value) {
2734
+ const candidate = value;
2735
+ return candidate !== undefined && candidate !== null && Range.is(candidate.range) && (Is.string(candidate.expression) || candidate.expression === undefined);
2736
+ }
2737
+ InlineValueEvaluatableExpression$1.is = is;
2738
+ })(InlineValueEvaluatableExpression || (InlineValueEvaluatableExpression = {}));
2739
+ /**
2740
+ * The InlineValueContext namespace provides helper functions to work with
2741
+ * {@link InlineValueContext} literals.
2742
+ *
2743
+ * @since 3.17.0
2744
+ */
2745
+ var InlineValueContext;
2746
+ (function(InlineValueContext$1) {
2747
+ /**
2748
+ * Creates a new InlineValueContext literal.
2749
+ */
2750
+ function create(frameId, stoppedLocation) {
2751
+ return {
2752
+ frameId,
2753
+ stoppedLocation
2754
+ };
2755
+ }
2756
+ InlineValueContext$1.create = create;
2757
+ /**
2758
+ * Checks whether the given literal conforms to the {@link InlineValueContext} interface.
2759
+ */
2760
+ function is(value) {
2761
+ const candidate = value;
2762
+ return Is.defined(candidate) && Range.is(value.stoppedLocation);
2763
+ }
2764
+ InlineValueContext$1.is = is;
2765
+ })(InlineValueContext || (InlineValueContext = {}));
2766
+ /**
2767
+ * Inlay hint kinds.
2768
+ *
2769
+ * @since 3.17.0
2770
+ */
2771
+ var InlayHintKind;
2772
+ (function(InlayHintKind$1) {
2773
+ /**
2774
+ * An inlay hint that for a type annotation.
2775
+ */
2776
+ InlayHintKind$1.Type = 1;
2777
+ /**
2778
+ * An inlay hint that is for a parameter.
2779
+ */
2780
+ InlayHintKind$1.Parameter = 2;
2781
+ function is(value) {
2782
+ return value === 1 || value === 2;
2783
+ }
2784
+ InlayHintKind$1.is = is;
2785
+ })(InlayHintKind || (InlayHintKind = {}));
2786
+ var InlayHintLabelPart;
2787
+ (function(InlayHintLabelPart$1) {
2788
+ function create(value) {
2789
+ return { value };
2790
+ }
2791
+ InlayHintLabelPart$1.create = create;
2792
+ function is(value) {
2793
+ const candidate = value;
2794
+ return Is.objectLiteral(candidate) && (candidate.tooltip === undefined || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.location === undefined || Location.is(candidate.location)) && (candidate.command === undefined || Command.is(candidate.command));
2795
+ }
2796
+ InlayHintLabelPart$1.is = is;
2797
+ })(InlayHintLabelPart || (InlayHintLabelPart = {}));
2798
+ var InlayHint;
2799
+ (function(InlayHint$1) {
2800
+ function create(position, label, kind) {
2801
+ const result = {
2802
+ position,
2803
+ label
2804
+ };
2805
+ if (kind !== undefined) {
2806
+ result.kind = kind;
2807
+ }
2808
+ return result;
2809
+ }
2810
+ InlayHint$1.create = create;
2811
+ function is(value) {
2812
+ const candidate = value;
2813
+ return Is.objectLiteral(candidate) && Position.is(candidate.position) && (Is.string(candidate.label) || Is.typedArray(candidate.label, InlayHintLabelPart.is)) && (candidate.kind === undefined || InlayHintKind.is(candidate.kind)) && candidate.textEdits === undefined || Is.typedArray(candidate.textEdits, TextEdit.is) && (candidate.tooltip === undefined || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.paddingLeft === undefined || Is.boolean(candidate.paddingLeft)) && (candidate.paddingRight === undefined || Is.boolean(candidate.paddingRight));
2814
+ }
2815
+ InlayHint$1.is = is;
2816
+ })(InlayHint || (InlayHint = {}));
2817
+ var StringValue;
2818
+ (function(StringValue$1) {
2819
+ function createSnippet(value) {
2820
+ return {
2821
+ kind: "snippet",
2822
+ value
2823
+ };
2824
+ }
2825
+ StringValue$1.createSnippet = createSnippet;
2826
+ })(StringValue || (StringValue = {}));
2827
+ var InlineCompletionItem;
2828
+ (function(InlineCompletionItem$1) {
2829
+ function create(insertText, filterText, range, command) {
2830
+ return {
2831
+ insertText,
2832
+ filterText,
2833
+ range,
2834
+ command
2835
+ };
2836
+ }
2837
+ InlineCompletionItem$1.create = create;
2838
+ })(InlineCompletionItem || (InlineCompletionItem = {}));
2839
+ var InlineCompletionList;
2840
+ (function(InlineCompletionList$1) {
2841
+ function create(items) {
2842
+ return { items };
2843
+ }
2844
+ InlineCompletionList$1.create = create;
2845
+ })(InlineCompletionList || (InlineCompletionList = {}));
2846
+ /**
2847
+ * Describes how an {@link InlineCompletionItemProvider inline completion provider} was triggered.
2848
+ *
2849
+ * @since 3.18.0
2850
+ * @proposed
2851
+ */
2852
+ var InlineCompletionTriggerKind;
2853
+ (function(InlineCompletionTriggerKind$1) {
2854
+ /**
2855
+ * Completion was triggered explicitly by a user gesture.
2856
+ */
2857
+ InlineCompletionTriggerKind$1.Invoked = 0;
2858
+ /**
2859
+ * Completion was triggered automatically while editing.
2860
+ */
2861
+ InlineCompletionTriggerKind$1.Automatic = 1;
2862
+ })(InlineCompletionTriggerKind || (InlineCompletionTriggerKind = {}));
2863
+ var SelectedCompletionInfo;
2864
+ (function(SelectedCompletionInfo$1) {
2865
+ function create(range, text) {
2866
+ return {
2867
+ range,
2868
+ text
2869
+ };
2870
+ }
2871
+ SelectedCompletionInfo$1.create = create;
2872
+ })(SelectedCompletionInfo || (SelectedCompletionInfo = {}));
2873
+ var InlineCompletionContext;
2874
+ (function(InlineCompletionContext$1) {
2875
+ function create(triggerKind, selectedCompletionInfo) {
2876
+ return {
2877
+ triggerKind,
2878
+ selectedCompletionInfo
2879
+ };
2880
+ }
2881
+ InlineCompletionContext$1.create = create;
2882
+ })(InlineCompletionContext || (InlineCompletionContext = {}));
2883
+ var WorkspaceFolder;
2884
+ (function(WorkspaceFolder$1) {
2885
+ function is(value) {
2886
+ const candidate = value;
2887
+ return Is.objectLiteral(candidate) && URI.is(candidate.uri) && Is.string(candidate.name);
2888
+ }
2889
+ WorkspaceFolder$1.is = is;
2890
+ })(WorkspaceFolder || (WorkspaceFolder = {}));
2891
+ const EOL = [
2892
+ "\n",
2893
+ "\r\n",
2894
+ "\r"
2895
+ ];
2896
+ /**
2897
+ * @deprecated Use the text document from the new vscode-languageserver-textdocument package.
2898
+ */
2899
+ var TextDocument$1;
2900
+ (function(TextDocument$2) {
2901
+ /**
2902
+ * Creates a new ITextDocument literal from the given uri and content.
2903
+ * @param uri The document's uri.
2904
+ * @param languageId The document's language Id.
2905
+ * @param version The document's version.
2906
+ * @param content The document's content.
2907
+ */
2908
+ function create(uri, languageId, version, content) {
2909
+ return new FullTextDocument(uri, languageId, version, content);
2910
+ }
2911
+ TextDocument$2.create = create;
2912
+ /**
2913
+ * Checks whether the given literal conforms to the {@link ITextDocument} interface.
2914
+ */
2915
+ function is(value) {
2916
+ let candidate = value;
2917
+ return Is.defined(candidate) && Is.string(candidate.uri) && (Is.undefined(candidate.languageId) || Is.string(candidate.languageId)) && Is.uinteger(candidate.lineCount) && Is.func(candidate.getText) && Is.func(candidate.positionAt) && Is.func(candidate.offsetAt) ? true : false;
2918
+ }
2919
+ TextDocument$2.is = is;
2920
+ function applyEdits(document, edits) {
2921
+ let text = document.getText();
2922
+ let sortedEdits = mergeSort(edits, (a, b) => {
2923
+ let diff = a.range.start.line - b.range.start.line;
2924
+ if (diff === 0) {
2925
+ return a.range.start.character - b.range.start.character;
2926
+ }
2927
+ return diff;
2928
+ });
2929
+ let lastModifiedOffset = text.length;
2930
+ for (let i = sortedEdits.length - 1; i >= 0; i--) {
2931
+ let e = sortedEdits[i];
2932
+ let startOffset = document.offsetAt(e.range.start);
2933
+ let endOffset = document.offsetAt(e.range.end);
2934
+ if (endOffset <= lastModifiedOffset) {
2935
+ text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length);
2936
+ } else {
2937
+ throw new Error("Overlapping edit");
2938
+ }
2939
+ lastModifiedOffset = startOffset;
2940
+ }
2941
+ return text;
2942
+ }
2943
+ TextDocument$2.applyEdits = applyEdits;
2944
+ function mergeSort(data, compare) {
2945
+ if (data.length <= 1) {
2946
+ return data;
2947
+ }
2948
+ const p = data.length / 2 | 0;
2949
+ const left = data.slice(0, p);
2950
+ const right = data.slice(p);
2951
+ mergeSort(left, compare);
2952
+ mergeSort(right, compare);
2953
+ let leftIdx = 0;
2954
+ let rightIdx = 0;
2955
+ let i = 0;
2956
+ while (leftIdx < left.length && rightIdx < right.length) {
2957
+ let ret = compare(left[leftIdx], right[rightIdx]);
2958
+ if (ret <= 0) {
2959
+ data[i++] = left[leftIdx++];
2960
+ } else {
2961
+ data[i++] = right[rightIdx++];
2962
+ }
2963
+ }
2964
+ while (leftIdx < left.length) {
2965
+ data[i++] = left[leftIdx++];
2966
+ }
2967
+ while (rightIdx < right.length) {
2968
+ data[i++] = right[rightIdx++];
2969
+ }
2970
+ return data;
2971
+ }
2972
+ })(TextDocument$1 || (TextDocument$1 = {}));
2973
+ /**
2974
+ * @deprecated Use the text document from the new vscode-languageserver-textdocument package.
2975
+ */
2976
+ var FullTextDocument = class {
2977
+ constructor(uri, languageId, version, content) {
2978
+ this._uri = uri;
2979
+ this._languageId = languageId;
2980
+ this._version = version;
2981
+ this._content = content;
2982
+ this._lineOffsets = undefined;
2983
+ }
2984
+ get uri() {
2985
+ return this._uri;
2986
+ }
2987
+ get languageId() {
2988
+ return this._languageId;
2989
+ }
2990
+ get version() {
2991
+ return this._version;
2992
+ }
2993
+ getText(range) {
2994
+ if (range) {
2995
+ let start = this.offsetAt(range.start);
2996
+ let end = this.offsetAt(range.end);
2997
+ return this._content.substring(start, end);
2998
+ }
2999
+ return this._content;
3000
+ }
3001
+ update(event, version) {
3002
+ this._content = event.text;
3003
+ this._version = version;
3004
+ this._lineOffsets = undefined;
3005
+ }
3006
+ getLineOffsets() {
3007
+ if (this._lineOffsets === undefined) {
3008
+ let lineOffsets = [];
3009
+ let text = this._content;
3010
+ let isLineStart = true;
3011
+ for (let i = 0; i < text.length; i++) {
3012
+ if (isLineStart) {
3013
+ lineOffsets.push(i);
3014
+ isLineStart = false;
3015
+ }
3016
+ let ch = text.charAt(i);
3017
+ isLineStart = ch === "\r" || ch === "\n";
3018
+ if (ch === "\r" && i + 1 < text.length && text.charAt(i + 1) === "\n") {
3019
+ i++;
3020
+ }
3021
+ }
3022
+ if (isLineStart && text.length > 0) {
3023
+ lineOffsets.push(text.length);
3024
+ }
3025
+ this._lineOffsets = lineOffsets;
3026
+ }
3027
+ return this._lineOffsets;
3028
+ }
3029
+ positionAt(offset) {
3030
+ offset = Math.max(Math.min(offset, this._content.length), 0);
3031
+ let lineOffsets = this.getLineOffsets();
3032
+ let low = 0, high = lineOffsets.length;
3033
+ if (high === 0) {
3034
+ return Position.create(0, offset);
3035
+ }
3036
+ while (low < high) {
3037
+ let mid = Math.floor((low + high) / 2);
3038
+ if (lineOffsets[mid] > offset) {
3039
+ high = mid;
3040
+ } else {
3041
+ low = mid + 1;
3042
+ }
3043
+ }
3044
+ let line = low - 1;
3045
+ return Position.create(line, offset - lineOffsets[line]);
3046
+ }
3047
+ offsetAt(position) {
3048
+ let lineOffsets = this.getLineOffsets();
3049
+ if (position.line >= lineOffsets.length) {
3050
+ return this._content.length;
3051
+ } else if (position.line < 0) {
3052
+ return 0;
3053
+ }
3054
+ let lineOffset = lineOffsets[position.line];
3055
+ let nextLineOffset = position.line + 1 < lineOffsets.length ? lineOffsets[position.line + 1] : this._content.length;
3056
+ return Math.max(Math.min(lineOffset + position.character, nextLineOffset), lineOffset);
3057
+ }
3058
+ get lineCount() {
3059
+ return this.getLineOffsets().length;
3060
+ }
3061
+ };
3062
+ var Is;
3063
+ (function(Is$1) {
3064
+ const toString = Object.prototype.toString;
3065
+ function defined(value) {
3066
+ return typeof value !== "undefined";
3067
+ }
3068
+ Is$1.defined = defined;
3069
+ function undefined$1(value) {
3070
+ return typeof value === "undefined";
3071
+ }
3072
+ Is$1.undefined = undefined$1;
3073
+ function boolean(value) {
3074
+ return value === true || value === false;
3075
+ }
3076
+ Is$1.boolean = boolean;
3077
+ function string(value) {
3078
+ return toString.call(value) === "[object String]";
3079
+ }
3080
+ Is$1.string = string;
3081
+ function number(value) {
3082
+ return toString.call(value) === "[object Number]";
3083
+ }
3084
+ Is$1.number = number;
3085
+ function numberRange(value, min, max) {
3086
+ return toString.call(value) === "[object Number]" && min <= value && value <= max;
3087
+ }
3088
+ Is$1.numberRange = numberRange;
3089
+ function integer$1(value) {
3090
+ return toString.call(value) === "[object Number]" && -2147483648 <= value && value <= 2147483647;
3091
+ }
3092
+ Is$1.integer = integer$1;
3093
+ function uinteger$1(value) {
3094
+ return toString.call(value) === "[object Number]" && 0 <= value && value <= 2147483647;
3095
+ }
3096
+ Is$1.uinteger = uinteger$1;
3097
+ function func(value) {
3098
+ return toString.call(value) === "[object Function]";
3099
+ }
3100
+ Is$1.func = func;
3101
+ function objectLiteral(value) {
3102
+ return value !== null && typeof value === "object";
3103
+ }
3104
+ Is$1.objectLiteral = objectLiteral;
3105
+ function typedArray(value, check) {
3106
+ return Array.isArray(value) && value.every(check);
3107
+ }
3108
+ Is$1.typedArray = typedArray;
3109
+ })(Is || (Is = {}));
3110
+
3111
+ //#endregion
3112
+ //#region packages/lsp/src/handlers/code-action.ts
3113
+ /** Handle a code action request for a GraphQL template. */
3114
+ const handleCodeAction = (input) => {
3115
+ const { template, schema, tsSource, uri, selectionRange } = input;
3116
+ if (template.kind === "fragment") {
3117
+ return [];
3118
+ }
3119
+ const { preprocessed } = preprocessFragmentArgs(template.content);
3120
+ const mapper = createPositionMapper({
3121
+ tsSource,
3122
+ contentStartOffset: template.contentRange.start,
3123
+ graphqlContent: template.content
3124
+ });
3125
+ const gqlStart = mapper.tsToGraphql(selectionRange.start);
3126
+ const gqlEnd = mapper.tsToGraphql(selectionRange.end);
3127
+ if (!gqlStart || !gqlEnd) {
3128
+ return [];
3129
+ }
3130
+ const preprocessedLineOffsets = computeLineOffsets(preprocessed);
3131
+ const startOffset = positionToOffset$1(preprocessedLineOffsets, gqlStart);
3132
+ const endOffset = positionToOffset$1(preprocessedLineOffsets, gqlEnd);
3133
+ let ast;
3134
+ try {
3135
+ ast = (0, graphql.parse)(preprocessed, { noLocation: false });
3136
+ } catch {
3137
+ return [];
3138
+ }
3139
+ const typeInfo = new graphql.TypeInfo(schema);
3140
+ const extractResult = findExtractableSelections(ast, typeInfo, startOffset, endOffset);
3141
+ if (!extractResult) {
3142
+ return [];
3143
+ }
3144
+ const { selections: matchedSelections, parentTypeName } = extractResult;
3145
+ const firstSel = matchedSelections[0];
3146
+ const lastSel = matchedSelections[matchedSelections.length - 1];
3147
+ if (!firstSel?.loc || !lastSel?.loc) {
3148
+ return [];
3149
+ }
3150
+ const selectedText = template.content.slice(firstSel.loc.start, lastSel.loc.end);
3151
+ const escapedText = selectedText.replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
3152
+ const fragmentName = "ExtractedFragment";
3153
+ const fragmentDef = `fragment ${fragmentName} on ${parentTypeName} {\n ${escapedText.trim()}\n}`;
3154
+ const newGqlExpr = `export const ${fragmentName} = gql.${template.schemaName}(({ fragment }) => fragment\`\n ${fragmentDef}\n\`);\n\n`;
3155
+ const insertionOffset = findStatementStart(tsSource, template.contentRange.start);
3156
+ const tsLineOffsets = computeLineOffsets(tsSource);
3157
+ const gqlLineOffsets = computeLineOffsets(preprocessed);
3158
+ const replaceStart = mapper.graphqlToTs(offsetToPosition(gqlLineOffsets, firstSel.loc.start));
3159
+ const replaceEnd = mapper.graphqlToTs(offsetToPosition(gqlLineOffsets, lastSel.loc.end));
3160
+ const replaceEdit = {
3161
+ range: {
3162
+ start: replaceStart,
3163
+ end: replaceEnd
3164
+ },
3165
+ newText: `...${fragmentName}`
3166
+ };
3167
+ const insertPos = offsetToPosition(tsLineOffsets, insertionOffset);
3168
+ const insertEdit = {
3169
+ range: {
3170
+ start: insertPos,
3171
+ end: insertPos
3172
+ },
3173
+ newText: newGqlExpr
3174
+ };
3175
+ return [{
3176
+ title: `Extract Fragment "${fragmentName}"`,
3177
+ kind: CodeActionKind.RefactorExtract,
3178
+ edit: { changes: { [uri]: [insertEdit, replaceEdit] } }
3179
+ }];
3180
+ };
3181
+ /** Find selections within the user's range that can be extracted into a fragment. */
3182
+ const findExtractableSelections = (ast, typeInfo, startOffset, endOffset) => {
3183
+ let result = null;
3184
+ (0, graphql.visit)(ast, (0, graphql.visitWithTypeInfo)(typeInfo, { SelectionSet(node) {
3185
+ if (!node.loc || result) {
3186
+ return;
3187
+ }
3188
+ const selected = node.selections.filter((sel) => {
3189
+ if (!sel.loc) {
3190
+ return false;
3191
+ }
3192
+ return sel.loc.start >= startOffset && sel.loc.end <= endOffset;
3193
+ });
3194
+ if (selected.length > 0) {
3195
+ const typeName = typeInfo.getParentType()?.name;
3196
+ if (typeName) {
3197
+ result = {
3198
+ selections: selected,
3199
+ parentTypeName: typeName
3200
+ };
3201
+ }
3202
+ }
3203
+ } }));
3204
+ return result;
3205
+ };
3206
+ /**
3207
+ * Compute brace depth at a given offset using TypeScript scanner.
3208
+ * Correctly handles strings, comments, regex, and template literals.
3209
+ */
3210
+ const braceDepthAt = (source, offset) => {
3211
+ const scanner = typescript.default.createScanner(typescript.default.ScriptTarget.Latest, false, typescript.default.LanguageVariant.Standard, source);
3212
+ let depth = 0;
3213
+ let lastToken = typescript.default.SyntaxKind.Unknown;
3214
+ while (true) {
3215
+ let token = scanner.scan();
3216
+ if (token === typescript.default.SyntaxKind.EndOfFileToken) break;
3217
+ if (token === typescript.default.SyntaxKind.SlashToken || token === typescript.default.SyntaxKind.SlashEqualsToken) {
3218
+ if (lastToken === typescript.default.SyntaxKind.FirstAssignment || lastToken === typescript.default.SyntaxKind.EqualsEqualsToken || lastToken === typescript.default.SyntaxKind.EqualsEqualsEqualsToken || lastToken === typescript.default.SyntaxKind.ExclamationEqualsToken || lastToken === typescript.default.SyntaxKind.ExclamationEqualsEqualsToken || lastToken === typescript.default.SyntaxKind.OpenParenToken || lastToken === typescript.default.SyntaxKind.CommaToken || lastToken === typescript.default.SyntaxKind.OpenBracketToken || lastToken === typescript.default.SyntaxKind.ColonToken || lastToken === typescript.default.SyntaxKind.SemicolonToken || lastToken === typescript.default.SyntaxKind.OpenBraceToken || lastToken === typescript.default.SyntaxKind.QuestionToken || lastToken === typescript.default.SyntaxKind.BarBarToken || lastToken === typescript.default.SyntaxKind.AmpersandAmpersandToken || lastToken === typescript.default.SyntaxKind.ExclamationToken || lastToken === typescript.default.SyntaxKind.ReturnKeyword || lastToken === typescript.default.SyntaxKind.CaseKeyword || lastToken === typescript.default.SyntaxKind.NewKeyword) {
3219
+ token = scanner.reScanSlashToken();
3220
+ }
3221
+ }
3222
+ const tokenStart = scanner.getTokenStart();
3223
+ if (tokenStart >= offset) break;
3224
+ if (token === typescript.default.SyntaxKind.OpenBraceToken) {
3225
+ depth++;
3226
+ } else if (token === typescript.default.SyntaxKind.CloseBraceToken) {
3227
+ depth--;
3228
+ }
3229
+ if (token !== typescript.default.SyntaxKind.WhitespaceTrivia && token !== typescript.default.SyntaxKind.NewLineTrivia && token !== typescript.default.SyntaxKind.SingleLineCommentTrivia && token !== typescript.default.SyntaxKind.MultiLineCommentTrivia) {
3230
+ lastToken = token;
3231
+ }
3232
+ }
3233
+ return depth;
3234
+ };
3235
+ /** Find the start of the top-level statement containing the given offset. */
3236
+ const findStatementStart = (source, offset) => {
3237
+ let pos = offset;
3238
+ while (pos > 0 && source.charCodeAt(pos - 1) !== 10) {
3239
+ pos--;
3240
+ }
3241
+ while (pos > 0) {
3242
+ const lineStart = pos;
3243
+ const lineText = source.slice(lineStart, source.indexOf("\n", lineStart)).trimStart();
3244
+ const depth = braceDepthAt(source, lineStart);
3245
+ if (depth === 0 && (lineText.startsWith("export ") || lineText.startsWith("const ") || lineText.startsWith("let ") || lineText.startsWith("var ") || lineText.startsWith("function ") || lineText.startsWith("async "))) {
3246
+ return lineStart;
3247
+ }
3248
+ pos--;
3249
+ while (pos > 0 && source.charCodeAt(pos - 1) !== 10) {
3250
+ pos--;
3251
+ }
3252
+ if (depth === 0) {
3253
+ const prevLine = source.slice(pos, lineStart - 1).trim();
3254
+ if (prevLine.endsWith(";") || prevLine.endsWith("}")) {
3255
+ return lineStart;
3256
+ }
3257
+ }
3258
+ }
3259
+ return pos;
3260
+ };
3261
+
3262
+ //#endregion
3263
+ //#region packages/lsp/src/handlers/completion.ts
3264
+ /** Handle a completion request for a GraphQL template. */
3265
+ const handleCompletion = (input) => {
3266
+ const { template, schema, tsSource, tsPosition } = input;
3267
+ const reconstructed = reconstructGraphql(template);
3268
+ const headerLen = reconstructed.length - template.content.length;
3269
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
3270
+ const mapper = createPositionMapper({
3271
+ tsSource,
3272
+ contentStartOffset: template.contentRange.start,
3273
+ graphqlContent: template.content
3274
+ });
3275
+ const contentPos = mapper.tsToGraphql(tsPosition);
3276
+ if (!contentPos) {
3277
+ return [];
3278
+ }
3279
+ const contentLineOffsets = computeLineOffsets(template.content);
3280
+ const contentOffset = positionToOffset$1(contentLineOffsets, contentPos);
3281
+ const reconstructedOffset = contentOffset + headerLen;
3282
+ const reconstructedLineOffsets = computeLineOffsets(preprocessed);
3283
+ const gqlPosition = offsetToPosition(reconstructedLineOffsets, reconstructedOffset);
3284
+ const suggestions = (0, graphql_language_service.getAutocompleteSuggestions)(schema, preprocessed, toIPosition(gqlPosition), undefined, input.externalFragments);
3285
+ return suggestions;
3286
+ };
3287
+
3288
+ //#endregion
3289
+ //#region packages/lsp/src/handlers/_utils.ts
3290
+ /**
3291
+ * Find the fragment spread node at the given GraphQL offset using AST.
3292
+ * Returns the FragmentSpreadNode if cursor is on a `...FragmentName` pattern.
3293
+ */
3294
+ const findFragmentSpreadAtOffset = (preprocessed, offset) => {
3295
+ try {
3296
+ const ast = (0, graphql.parse)(preprocessed, { noLocation: false });
3297
+ let found = null;
3298
+ (0, graphql.visit)(ast, { FragmentSpread(node) {
3299
+ if (!node.loc) {
3300
+ return;
3301
+ }
3302
+ if (offset >= node.loc.start && offset < node.loc.end) {
3303
+ found = node;
3304
+ }
3305
+ } });
3306
+ return found;
3307
+ } catch {
3308
+ return findFragmentSpreadByText(preprocessed, offset);
3309
+ }
3310
+ };
3311
+ /**
3312
+ * Text-based fallback: find fragment spread name at offset.
3313
+ * Handles documents with parse errors.
3314
+ */
3315
+ const findFragmentSpreadByText = (text, offset) => {
3316
+ const spreadPattern = /\.\.\.([A-Za-z_]\w*)/g;
3317
+ let match = null;
3318
+ while ((match = spreadPattern.exec(text)) !== null) {
3319
+ const start = match.index;
3320
+ const end = start + match[0].length;
3321
+ if (offset >= start && offset < end) {
3322
+ return {
3323
+ kind: "FragmentSpread",
3324
+ name: {
3325
+ kind: "Name",
3326
+ value: match[1] ?? ""
3327
+ }
3328
+ };
3329
+ }
3330
+ }
3331
+ return null;
3332
+ };
3333
+ /**
3334
+ * Find a FragmentDefinition at a given offset.
3335
+ * Returns the name and location, or null.
3336
+ */
3337
+ const findFragmentDefinitionAtOffset = (preprocessed, offset) => {
3338
+ try {
3339
+ const ast = (0, graphql.parse)(preprocessed, { noLocation: false });
3340
+ for (const def of ast.definitions) {
3341
+ if (def.kind === "FragmentDefinition" && def.name.loc) {
3342
+ if (offset >= def.name.loc.start && offset < def.name.loc.end) {
3343
+ return {
3344
+ name: def.name.value,
3345
+ loc: {
3346
+ start: def.name.loc.start,
3347
+ end: def.name.loc.end
3348
+ }
3349
+ };
3350
+ }
3351
+ }
3352
+ }
3353
+ } catch {}
3354
+ return null;
3355
+ };
3356
+ /**
3357
+ * Resolve the fragment name at a given offset, checking both definitions and spreads.
3358
+ */
3359
+ const resolveFragmentNameAtOffset = (preprocessed, offset) => {
3360
+ const def = findFragmentDefinitionAtOffset(preprocessed, offset);
3361
+ if (def) {
3362
+ return def.name;
3363
+ }
3364
+ const spread = findFragmentSpreadAtOffset(preprocessed, offset);
3365
+ if (spread) {
3366
+ return spread.name.value;
3367
+ }
3368
+ return null;
3369
+ };
3370
+ /** Compute TS ranges for all definitions of a named fragment. */
3371
+ const computeFragmentDefinitionRanges = (fragmentName, allFragments) => {
3372
+ const ranges = [];
3373
+ for (const frag of allFragments) {
3374
+ if (frag.fragmentName !== fragmentName) {
3375
+ continue;
3376
+ }
3377
+ if (!frag.definition.name.loc) {
3378
+ continue;
3379
+ }
3380
+ const defMapper = createPositionMapper({
3381
+ tsSource: frag.tsSource,
3382
+ contentStartOffset: frag.contentRange.start,
3383
+ graphqlContent: frag.content
3384
+ });
3385
+ const defGqlLineOffsets = computeLineOffsets(frag.content);
3386
+ const nameStart = offsetToPosition(defGqlLineOffsets, frag.definition.name.loc.start);
3387
+ const nameEnd = offsetToPosition(defGqlLineOffsets, frag.definition.name.loc.end);
3388
+ ranges.push({
3389
+ uri: frag.uri,
3390
+ range: {
3391
+ start: defMapper.graphqlToTs(nameStart),
3392
+ end: defMapper.graphqlToTs(nameEnd)
3393
+ }
3394
+ });
3395
+ }
3396
+ return ranges;
3397
+ };
3398
+ /** Compute TS ranges for all fragment spread locations. */
3399
+ const computeSpreadLocationRanges = (spreadLocations) => {
3400
+ const ranges = [];
3401
+ for (const loc of spreadLocations) {
3402
+ const spreadMapper = createPositionMapper({
3403
+ tsSource: loc.tsSource,
3404
+ contentStartOffset: loc.template.contentRange.start,
3405
+ graphqlContent: loc.template.content
3406
+ });
3407
+ const spreadGqlLineOffsets = computeLineOffsets(loc.template.content);
3408
+ const spreadStart = offsetToPosition(spreadGqlLineOffsets, loc.nameOffset);
3409
+ const spreadEnd = offsetToPosition(spreadGqlLineOffsets, loc.nameOffset + loc.nameLength);
3410
+ ranges.push({
3411
+ uri: loc.uri,
3412
+ range: {
3413
+ start: spreadMapper.graphqlToTs(spreadStart),
3414
+ end: spreadMapper.graphqlToTs(spreadEnd)
3415
+ }
3416
+ });
3417
+ }
3418
+ return ranges;
3419
+ };
3420
+
3421
+ //#endregion
3422
+ //#region packages/lsp/src/handlers/definition.ts
3423
+ /**
3424
+ * Definition handler: provides go-to-definition for fragment spreads and schema fields/types.
3425
+ * @module
3426
+ */
3427
+ /** Build ObjectTypeInfo[] from schema file info for graphql-language-service definition APIs. */
3428
+ const buildObjectTypeInfos = (files) => {
3429
+ const result = [];
3430
+ for (const file of files) {
3431
+ const doc = (0, graphql.parse)(file.content);
3432
+ for (const def of doc.definitions) {
3433
+ if ((0, graphql.isTypeDefinitionNode)(def)) {
3434
+ result.push({
3435
+ filePath: (0, node_url.pathToFileURL)(file.filePath).href,
3436
+ content: file.content,
3437
+ definition: def
3438
+ });
3439
+ }
3440
+ }
3441
+ }
3442
+ return result;
3443
+ };
3444
+ /** Handle a definition request for a GraphQL template. */
3445
+ const handleDefinition = async (input) => {
3446
+ const { template, tsSource, tsPosition, externalFragments } = input;
3447
+ const reconstructed = reconstructGraphql(template);
3448
+ const headerLen = reconstructed.length - template.content.length;
3449
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
3450
+ const mapper = createPositionMapper({
3451
+ tsSource,
3452
+ contentStartOffset: template.contentRange.start,
3453
+ graphqlContent: template.content
3454
+ });
3455
+ const gqlPosition = mapper.tsToGraphql(tsPosition);
3456
+ if (!gqlPosition) {
3457
+ return [];
3458
+ }
3459
+ const contentLineOffsets = computeLineOffsets(template.content);
3460
+ const contentOffset = positionToOffset$1(contentLineOffsets, gqlPosition);
3461
+ const reconstructedOffset = contentOffset + headerLen;
3462
+ const fragmentSpread = findFragmentSpreadAtOffset(preprocessed, reconstructedOffset);
3463
+ if (fragmentSpread) {
3464
+ return resolveFragmentSpreadDefinition(preprocessed, fragmentSpread, externalFragments);
3465
+ }
3466
+ if (input.schema && input.schemaFiles && input.schemaFiles.length > 0) {
3467
+ const reconstructedLineOffsets = computeLineOffsets(preprocessed);
3468
+ const reconstructedPosition = offsetToPosition(reconstructedLineOffsets, reconstructedOffset);
3469
+ return resolveSchemaDefinition(preprocessed, reconstructedPosition, input.schema, input.schemaFiles);
3470
+ }
3471
+ return [];
3472
+ };
3473
+ /** Resolve fragment spread to its definition in an external TypeScript file. */
3474
+ const resolveFragmentSpreadDefinition = async (preprocessed, fragmentSpread, externalFragments) => {
3475
+ const fragmentInfos = externalFragments.map((f) => ({
3476
+ filePath: f.uri,
3477
+ content: f.content,
3478
+ definition: f.definition
3479
+ }));
3480
+ try {
3481
+ const result = await (0, graphql_language_service.getDefinitionQueryResultForFragmentSpread)(preprocessed, fragmentSpread, fragmentInfos);
3482
+ return result.definitions.map((def) => {
3483
+ const defPosition = toIPosition(def.position);
3484
+ const endLine = def.range?.end?.line ?? defPosition.line;
3485
+ const endChar = def.range?.end?.character ?? defPosition.character;
3486
+ const targetFragment = externalFragments.find((f) => f.uri === def.path);
3487
+ if (targetFragment) {
3488
+ const targetReconstructedLineOffsets = computeLineOffsets(targetFragment.content);
3489
+ const targetContentLineOffsets = computeLineOffsets(targetFragment.content.slice(targetFragment.headerLen));
3490
+ const toOriginalPos = (pos) => {
3491
+ const offset = positionToOffset$1(targetReconstructedLineOffsets, pos);
3492
+ const originalOffset = Math.max(0, offset - targetFragment.headerLen);
3493
+ return offsetToPosition(targetContentLineOffsets, originalOffset);
3494
+ };
3495
+ const targetMapper = createPositionMapper({
3496
+ tsSource: targetFragment.tsSource,
3497
+ contentStartOffset: targetFragment.contentRange.start,
3498
+ graphqlContent: targetFragment.content.slice(targetFragment.headerLen)
3499
+ });
3500
+ const tsStart = targetMapper.graphqlToTs(toOriginalPos({
3501
+ line: defPosition.line,
3502
+ character: defPosition.character
3503
+ }));
3504
+ const tsEnd = targetMapper.graphqlToTs(toOriginalPos({
3505
+ line: endLine,
3506
+ character: endChar
3507
+ }));
3508
+ return {
3509
+ uri: def.path,
3510
+ range: {
3511
+ start: tsStart,
3512
+ end: tsEnd
3513
+ }
3514
+ };
3515
+ }
3516
+ return {
3517
+ uri: def.path,
3518
+ range: {
3519
+ start: {
3520
+ line: defPosition.line,
3521
+ character: defPosition.character
3522
+ },
3523
+ end: {
3524
+ line: endLine,
3525
+ character: endChar
3526
+ }
3527
+ }
3528
+ };
3529
+ });
3530
+ } catch {
3531
+ return [];
3532
+ }
3533
+ };
3534
+ /** Resolve field or type name to its definition in a schema .graphql file. */
3535
+ const resolveSchemaDefinition = (preprocessed, position, schema, schemaFiles) => {
3536
+ const context = (0, graphql_language_service.getContextAtPosition)(preprocessed, toIPosition(position), schema);
3537
+ if (!context) {
3538
+ return Promise.resolve([]);
3539
+ }
3540
+ const { typeInfo } = context;
3541
+ if (typeInfo.fieldDef && typeInfo.parentType) {
3542
+ const fieldName = typeInfo.fieldDef.name;
3543
+ const namedParentType = (0, graphql.getNamedType)(typeInfo.parentType);
3544
+ if (!namedParentType) {
3545
+ return Promise.resolve([]);
3546
+ }
3547
+ const parentTypeName = namedParentType.name;
3548
+ const objectTypeInfos = buildObjectTypeInfos(schemaFiles);
3549
+ return (0, graphql_language_service.getDefinitionQueryResultForField)(fieldName, parentTypeName, objectTypeInfos).then((result) => result.definitions.map((def) => ({
3550
+ uri: def.path ?? "",
3551
+ range: {
3552
+ start: {
3553
+ line: def.position.line,
3554
+ character: def.position.character
3555
+ },
3556
+ end: {
3557
+ line: def.range?.end?.line ?? def.position.line,
3558
+ character: def.range?.end?.character ?? def.position.character
3559
+ }
3560
+ }
3561
+ })));
3562
+ }
3563
+ return Promise.resolve([]);
3564
+ };
3565
+
3566
+ //#endregion
3567
+ //#region packages/lsp/src/handlers/diagnostics.ts
3568
+ /** Compute LSP diagnostics for a single GraphQL template. */
3569
+ const computeTemplateDiagnostics = (input) => {
3570
+ const { template, schema, tsSource } = input;
3571
+ const reconstructed = reconstructGraphql(template);
3572
+ const headerLen = reconstructed.length - template.content.length;
3573
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
3574
+ const mapper = createPositionMapper({
3575
+ tsSource,
3576
+ contentStartOffset: template.contentRange.start,
3577
+ graphqlContent: template.content
3578
+ });
3579
+ const gqlDiagnostics = (0, graphql_language_service.getDiagnostics)(preprocessed, schema, undefined, undefined, input.externalFragments);
3580
+ const placeholderPattern = /__FRAG_SPREAD_\d+__/;
3581
+ const reconstructedLineOffsets = computeLineOffsets(preprocessed);
3582
+ const contentLineOffsets = computeLineOffsets(template.content);
3583
+ const toContentPosition = (pos) => {
3584
+ const offset = positionToOffset$1(reconstructedLineOffsets, pos);
3585
+ const contentOffset = Math.max(0, offset - headerLen);
3586
+ return offsetToPosition(contentLineOffsets, contentOffset);
3587
+ };
3588
+ return gqlDiagnostics.filter((diag) => {
3589
+ if (placeholderPattern.test(diag.message)) {
3590
+ return false;
3591
+ }
3592
+ const offset = positionToOffset$1(reconstructedLineOffsets, diag.range.start);
3593
+ if (offset < headerLen) {
3594
+ return false;
3595
+ }
3596
+ return true;
3597
+ }).map((diag) => {
3598
+ const startContent = toContentPosition(diag.range.start);
3599
+ const endContent = toContentPosition(diag.range.end);
3600
+ const startTs = mapper.graphqlToTs(startContent);
3601
+ const endTs = mapper.graphqlToTs(endContent);
3602
+ return {
3603
+ range: {
3604
+ start: {
3605
+ line: startTs.line,
3606
+ character: startTs.character
3607
+ },
3608
+ end: {
3609
+ line: endTs.line,
3610
+ character: endTs.character
3611
+ }
3612
+ },
3613
+ message: diag.message,
3614
+ severity: diag.severity,
3615
+ source: "soda-gql"
3616
+ };
3617
+ });
3618
+ };
3619
+
3620
+ //#endregion
3621
+ //#region packages/lsp/src/handlers/document-symbol.ts
3622
+ /**
3623
+ * Document symbol handler: provides outline view for GraphQL templates.
3624
+ * @module
3625
+ */
3626
+ const KIND_MAP = {
3627
+ OperationDefinition: SymbolKind.Function,
3628
+ FragmentDefinition: SymbolKind.Class,
3629
+ Field: SymbolKind.Field,
3630
+ FragmentSpread: SymbolKind.Constant,
3631
+ InlineFragment: SymbolKind.Struct,
3632
+ EnumValueDefinition: SymbolKind.EnumMember,
3633
+ InputValueDefinition: SymbolKind.Property,
3634
+ FieldDefinition: SymbolKind.Field,
3635
+ ObjectTypeDefinition: SymbolKind.Class,
3636
+ InputObjectTypeDefinition: SymbolKind.Class,
3637
+ InterfaceTypeDefinition: SymbolKind.Interface,
3638
+ EnumTypeDefinition: SymbolKind.Enum
3639
+ };
3640
+ const getSymbolName = (tree) => {
3641
+ if (tree.representativeName) {
3642
+ return tree.representativeName;
3643
+ }
3644
+ if (tree.tokenizedText) {
3645
+ return tree.tokenizedText.map((t) => t.value).join("");
3646
+ }
3647
+ return tree.kind;
3648
+ };
3649
+ const convertTree = (tree, toContentPos, mapper) => {
3650
+ const name = getSymbolName(tree);
3651
+ const kind = KIND_MAP[tree.kind] ?? SymbolKind.Variable;
3652
+ const startTs = mapper.graphqlToTs(toContentPos(tree.startPosition));
3653
+ const endTs = tree.endPosition ? mapper.graphqlToTs(toContentPos(tree.endPosition)) : startTs;
3654
+ const range = {
3655
+ start: {
3656
+ line: startTs.line,
3657
+ character: startTs.character
3658
+ },
3659
+ end: {
3660
+ line: endTs.line,
3661
+ character: endTs.character
3662
+ }
3663
+ };
3664
+ const children = [];
3665
+ for (const child of tree.children) {
3666
+ const converted = convertTree(child, toContentPos, mapper);
3667
+ if (converted) {
3668
+ children.push(converted);
3669
+ }
3670
+ }
3671
+ return {
3672
+ name,
3673
+ kind,
3674
+ range,
3675
+ selectionRange: range,
3676
+ children: children.length > 0 ? children : undefined
3677
+ };
3678
+ };
3679
+ /** Handle a documentSymbol request for all GraphQL templates in a document. */
3680
+ const handleDocumentSymbol = (input) => {
3681
+ const { templates, tsSource } = input;
3682
+ const symbols = [];
3683
+ for (const template of templates) {
3684
+ const reconstructed = reconstructGraphql(template);
3685
+ const headerLen = reconstructed.length - template.content.length;
3686
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
3687
+ const outline = (0, graphql_language_service.getOutline)(preprocessed);
3688
+ if (!outline) {
3689
+ continue;
3690
+ }
3691
+ const mapper = createPositionMapper({
3692
+ tsSource,
3693
+ contentStartOffset: template.contentRange.start,
3694
+ graphqlContent: template.content
3695
+ });
3696
+ const reconstructedLineOffsets = computeLineOffsets(preprocessed);
3697
+ const contentLineOffsets = computeLineOffsets(template.content);
3698
+ const toContentPos = (pos) => {
3699
+ const offset = positionToOffset$1(reconstructedLineOffsets, pos);
3700
+ const contentOffset = Math.max(0, offset - headerLen);
3701
+ return offsetToPosition(contentLineOffsets, contentOffset);
3702
+ };
3703
+ for (const tree of outline.outlineTrees) {
3704
+ const symbol = convertTree(tree, toContentPos, mapper);
3705
+ if (symbol) {
3706
+ symbols.push(symbol);
3707
+ }
3708
+ }
3709
+ }
3710
+ return symbols;
3711
+ };
3712
+
3713
+ //#endregion
3714
+ //#region packages/lsp/src/handlers/formatting.ts
3715
+ /**
3716
+ * Formatting handler: format GraphQL content within tagged templates.
3717
+ * @module
3718
+ */
3719
+ const defaultFormatGraphql = (source) => {
3720
+ const ast = (0, graphql.parse)(source, { noLocation: false });
3721
+ return (0, graphql.print)(ast);
3722
+ };
3723
+ /** Handle a document formatting request for GraphQL templates. */
3724
+ const handleFormatting = (input) => {
3725
+ const { templates, tsSource, formatGraphql } = input;
3726
+ const format = formatGraphql ?? defaultFormatGraphql;
3727
+ const tsLineOffsets = computeLineOffsets(tsSource);
3728
+ const edits = [];
3729
+ for (const template of templates) {
3730
+ let formatted;
3731
+ try {
3732
+ formatted = format(template.content);
3733
+ } catch {
3734
+ continue;
3735
+ }
3736
+ if (formatted === template.content) {
3737
+ continue;
3738
+ }
3739
+ const baseIndent = detectBaseIndent(tsSource, template.contentRange.start);
3740
+ const reindented = reindent(formatted, baseIndent, template.content);
3741
+ if (reindented === template.content) {
3742
+ continue;
3743
+ }
3744
+ const start = offsetToPosition(tsLineOffsets, template.contentRange.start);
3745
+ const end = offsetToPosition(tsLineOffsets, template.contentRange.end);
3746
+ edits.push({
3747
+ range: {
3748
+ start,
3749
+ end
3750
+ },
3751
+ newText: reindented
3752
+ });
3753
+ }
3754
+ return edits;
3755
+ };
3756
+ /**
3757
+ * Detect the base indentation for a template by looking at the line
3758
+ * containing the opening backtick.
3759
+ */
3760
+ const detectBaseIndent = (tsSource, contentStartOffset) => {
3761
+ let lineStart = contentStartOffset;
3762
+ while (lineStart > 0 && tsSource.charCodeAt(lineStart - 1) !== 10) {
3763
+ lineStart--;
3764
+ }
3765
+ let i = lineStart;
3766
+ while (i < tsSource.length && (tsSource.charCodeAt(i) === 32 || tsSource.charCodeAt(i) === 9)) {
3767
+ i++;
3768
+ }
3769
+ return tsSource.slice(lineStart, i);
3770
+ };
3771
+ /**
3772
+ * Re-indent formatted GraphQL to match the embedding context.
3773
+ *
3774
+ * The original template may start with a newline (common for multi-line templates)
3775
+ * or be inline. We match the original pattern:
3776
+ * - If original starts with newline, formatted output gets newline + indented lines
3777
+ * - If original is single-line, keep formatted as single-line if it fits
3778
+ */
3779
+ const reindent = (formatted, baseIndent, originalContent) => {
3780
+ const trimmedFormatted = formatted.trim();
3781
+ if (!originalContent.includes("\n") && !trimmedFormatted.includes("\n")) {
3782
+ return trimmedFormatted;
3783
+ }
3784
+ const indent = `${baseIndent} `;
3785
+ const lines = trimmedFormatted.split("\n");
3786
+ const indentedLines = lines.map((line) => line.trim() === "" ? "" : indent + line);
3787
+ const startsWithNewline = originalContent.startsWith("\n");
3788
+ const endsWithNewline = originalContent.endsWith("\n");
3789
+ let result = indentedLines.join("\n");
3790
+ if (startsWithNewline) {
3791
+ result = `\n${result}`;
3792
+ }
3793
+ if (endsWithNewline) {
3794
+ result = `${result}\n${baseIndent}`;
3795
+ }
3796
+ return result;
3797
+ };
3798
+
3799
+ //#endregion
3800
+ //#region packages/lsp/src/handlers/hover.ts
3801
+ /** Handle a hover request for a GraphQL template. */
3802
+ const handleHover = (input) => {
3803
+ const { template, schema, tsSource, tsPosition } = input;
3804
+ const reconstructed = reconstructGraphql(template);
3805
+ const headerLen = reconstructed.length - template.content.length;
3806
+ const { preprocessed } = preprocessFragmentArgs(reconstructed);
3807
+ const mapper = createPositionMapper({
3808
+ tsSource,
3809
+ contentStartOffset: template.contentRange.start,
3810
+ graphqlContent: template.content
3811
+ });
3812
+ const contentPos = mapper.tsToGraphql(tsPosition);
3813
+ if (!contentPos) {
3814
+ return null;
3815
+ }
3816
+ const contentLineOffsets = computeLineOffsets(template.content);
3817
+ const contentOffset = positionToOffset$1(contentLineOffsets, contentPos);
3818
+ const reconstructedOffset = contentOffset + headerLen;
3819
+ const reconstructedLineOffsets = computeLineOffsets(preprocessed);
3820
+ const gqlPosition = offsetToPosition(reconstructedLineOffsets, reconstructedOffset);
3821
+ const hoverInfo = (0, graphql_language_service.getHoverInformation)(schema, preprocessed, toIPosition(gqlPosition), undefined, { useMarkdown: true });
3822
+ if (!hoverInfo || hoverInfo === "" || Array.isArray(hoverInfo) && hoverInfo.length === 0) {
3823
+ return null;
3824
+ }
3825
+ let contents;
3826
+ if (typeof hoverInfo === "string") {
3827
+ contents = {
3828
+ kind: "markdown",
3829
+ value: hoverInfo
3830
+ };
3831
+ } else if (Array.isArray(hoverInfo)) {
3832
+ const parts = hoverInfo.map((item) => typeof item === "string" ? item : item.value);
3833
+ contents = {
3834
+ kind: "markdown",
3835
+ value: parts.join("\n\n")
3836
+ };
3837
+ } else {
3838
+ contents = hoverInfo;
3839
+ }
3840
+ return { contents };
3841
+ };
3842
+
3843
+ //#endregion
3844
+ //#region packages/lsp/src/handlers/references.ts
3845
+ /** Handle a references request for a GraphQL template. */
3846
+ const handleReferences = (input) => {
3847
+ const { template, tsSource, tsPosition, allFragments, findSpreadLocations } = input;
3848
+ const { preprocessed } = preprocessFragmentArgs(template.content);
3849
+ const mapper = createPositionMapper({
3850
+ tsSource,
3851
+ contentStartOffset: template.contentRange.start,
3852
+ graphqlContent: template.content
3853
+ });
3854
+ const gqlPosition = mapper.tsToGraphql(tsPosition);
3855
+ if (!gqlPosition) {
3856
+ return [];
3857
+ }
3858
+ const offset = positionToOffset$1(computeLineOffsets(preprocessed), gqlPosition);
3859
+ const fragmentName = resolveFragmentNameAtOffset(preprocessed, offset);
3860
+ if (!fragmentName) {
3861
+ return [];
3862
+ }
3863
+ const locations = [];
3864
+ for (const r of computeFragmentDefinitionRanges(fragmentName, allFragments)) {
3865
+ locations.push({
3866
+ uri: r.uri,
3867
+ range: r.range
3868
+ });
3869
+ }
3870
+ for (const r of computeSpreadLocationRanges(findSpreadLocations(fragmentName))) {
3871
+ locations.push({
3872
+ uri: r.uri,
3873
+ range: r.range
3874
+ });
3875
+ }
3876
+ return locations;
3877
+ };
3878
+
3879
+ //#endregion
3880
+ //#region packages/lsp/src/handlers/rename.ts
3881
+ /** Validate and return the range of the symbol to be renamed. */
3882
+ const handlePrepareRename = (input) => {
3883
+ const { template, tsSource, tsPosition } = input;
3884
+ const { preprocessed } = preprocessFragmentArgs(template.content);
3885
+ const mapper = createPositionMapper({
3886
+ tsSource,
3887
+ contentStartOffset: template.contentRange.start,
3888
+ graphqlContent: template.content
3889
+ });
3890
+ const gqlPosition = mapper.tsToGraphql(tsPosition);
3891
+ if (!gqlPosition) {
3892
+ return null;
3893
+ }
3894
+ const offset = positionToOffset$1(computeLineOffsets(preprocessed), gqlPosition);
3895
+ const defResult = findFragmentDefinitionAtOffset(preprocessed, offset);
3896
+ if (defResult) {
3897
+ const gqlLineOffsets = computeLineOffsets(preprocessed);
3898
+ const start = mapper.graphqlToTs(offsetToPosition(gqlLineOffsets, defResult.loc.start));
3899
+ const end = mapper.graphqlToTs(offsetToPosition(gqlLineOffsets, defResult.loc.end));
3900
+ return {
3901
+ range: {
3902
+ start,
3903
+ end
3904
+ },
3905
+ placeholder: defResult.name
3906
+ };
3907
+ }
3908
+ const spread = findFragmentSpreadAtOffset(preprocessed, offset);
3909
+ if (spread?.name.value && spread.name.loc) {
3910
+ const gqlLineOffsets = computeLineOffsets(preprocessed);
3911
+ const start = mapper.graphqlToTs(offsetToPosition(gqlLineOffsets, spread.name.loc.start));
3912
+ const end = mapper.graphqlToTs(offsetToPosition(gqlLineOffsets, spread.name.loc.end));
3913
+ return {
3914
+ range: {
3915
+ start,
3916
+ end
3917
+ },
3918
+ placeholder: spread.name.value
3919
+ };
3920
+ }
3921
+ return null;
3922
+ };
3923
+ /** Perform a rename across the workspace. */
3924
+ const handleRename = (input) => {
3925
+ const { template, tsSource, tsPosition, newName, allFragments, findSpreadLocations } = input;
3926
+ const { preprocessed } = preprocessFragmentArgs(template.content);
3927
+ const mapper = createPositionMapper({
3928
+ tsSource,
3929
+ contentStartOffset: template.contentRange.start,
3930
+ graphqlContent: template.content
3931
+ });
3932
+ const gqlPosition = mapper.tsToGraphql(tsPosition);
3933
+ if (!gqlPosition) {
3934
+ return null;
3935
+ }
3936
+ const offset = positionToOffset$1(computeLineOffsets(preprocessed), gqlPosition);
3937
+ const fragmentName = resolveFragmentNameAtOffset(preprocessed, offset);
3938
+ if (!fragmentName) {
3939
+ return null;
3940
+ }
3941
+ const changes = {};
3942
+ const addEdit = (uri, range, text) => {
3943
+ if (!changes[uri]) {
3944
+ changes[uri] = [];
3945
+ }
3946
+ changes[uri].push({
3947
+ range,
3948
+ newText: text
3949
+ });
3950
+ };
3951
+ for (const r of computeFragmentDefinitionRanges(fragmentName, allFragments)) {
3952
+ addEdit(r.uri, r.range, newName);
3953
+ }
3954
+ for (const r of computeSpreadLocationRanges(findSpreadLocations(fragmentName))) {
3955
+ addEdit(r.uri, r.range, newName);
3956
+ }
3957
+ if (Object.keys(changes).length === 0) {
3958
+ return null;
3959
+ }
3960
+ return { changes };
3961
+ };
3962
+
3963
+ //#endregion
3964
+ //#region packages/lsp/src/server.ts
3965
+ /**
3966
+ * LSP server: wires all components together via vscode-languageserver.
3967
+ * @module
3968
+ */
3969
+ const createLspServer = (options) => {
3970
+ const connection = options?.connection ?? (0, vscode_languageserver_node.createConnection)(vscode_languageserver_node.ProposedFeatures.all);
3971
+ const documents = new vscode_languageserver_node.TextDocuments(vscode_languageserver_textdocument.TextDocument);
3972
+ let registry;
3973
+ const swcNotification = { shown: false };
3974
+ const publishDiagnosticsForDocument = (uri) => {
3975
+ if (!registry) {
3976
+ return;
3977
+ }
3978
+ const ctx = registry.resolveForUri(uri);
3979
+ if (!ctx) {
3980
+ connection.sendDiagnostics({
3981
+ uri,
3982
+ diagnostics: []
3983
+ });
3984
+ return;
3985
+ }
3986
+ const state = ctx.documentManager.get(uri);
3987
+ if (!state) {
3988
+ connection.sendDiagnostics({
3989
+ uri,
3990
+ diagnostics: []
3991
+ });
3992
+ return;
3993
+ }
3994
+ const allDiagnostics = state.templates.flatMap((template) => {
3995
+ const entry = ctx.schemaResolver.getSchema(template.schemaName);
3996
+ if (!entry) {
3997
+ return [];
3998
+ }
3999
+ const externalFragments = ctx.documentManager.getExternalFragments(uri, template.schemaName).map((f) => f.definition);
4000
+ return [...computeTemplateDiagnostics({
4001
+ template,
4002
+ schema: entry.schema,
4003
+ tsSource: state.source,
4004
+ externalFragments
4005
+ })];
4006
+ });
4007
+ connection.sendDiagnostics({
4008
+ uri,
4009
+ diagnostics: allDiagnostics
4010
+ });
4011
+ };
4012
+ const publishDiagnosticsForAllOpen = () => {
4013
+ for (const doc of documents.all()) {
4014
+ publishDiagnosticsForDocument(doc.uri);
4015
+ }
4016
+ };
4017
+ connection.onInitialize((params) => {
4018
+ const rootUri = params.rootUri ?? params.rootPath;
4019
+ if (!rootUri) {
4020
+ connection.window.showErrorMessage("soda-gql LSP: no workspace root provided");
4021
+ return { capabilities: {} };
4022
+ }
4023
+ const rootPath = rootUri.startsWith("file://") ? (0, node_url.fileURLToPath)(rootUri) : rootUri;
4024
+ let configPaths = (0, __soda_gql_config.findAllConfigFiles)(rootPath);
4025
+ if (configPaths.length === 0) {
4026
+ const singleConfigPath = (0, __soda_gql_config.findConfigFile)(rootPath);
4027
+ if (!singleConfigPath) {
4028
+ connection.window.showErrorMessage("soda-gql LSP: no config file found");
4029
+ return { capabilities: {} };
4030
+ }
4031
+ configPaths = [singleConfigPath];
4032
+ }
4033
+ const registryResult = createConfigRegistry(configPaths);
4034
+ if (registryResult.isErr()) {
4035
+ connection.window.showErrorMessage(`soda-gql LSP: ${registryResult.error.message}`);
4036
+ return { capabilities: {} };
4037
+ }
4038
+ registry = registryResult.value;
4039
+ return { capabilities: {
4040
+ textDocumentSync: vscode_languageserver_node.TextDocumentSyncKind.Full,
4041
+ hoverProvider: true,
4042
+ documentSymbolProvider: true,
4043
+ definitionProvider: true,
4044
+ referencesProvider: true,
4045
+ renameProvider: { prepareProvider: true },
4046
+ documentFormattingProvider: true,
4047
+ completionProvider: { triggerCharacters: [
4048
+ "{",
4049
+ "(",
4050
+ ":",
4051
+ "@",
4052
+ "$",
4053
+ " ",
4054
+ "\n",
4055
+ "."
4056
+ ] },
4057
+ codeActionProvider: { codeActionKinds: ["refactor.extract"] }
4058
+ } };
4059
+ });
4060
+ connection.onInitialized(() => {
4061
+ connection.client.register(vscode_languageserver_node.DidChangeWatchedFilesNotification.type, { watchers: [{ globPattern: "**/*.graphql" }] });
4062
+ });
4063
+ documents.onDidChangeContent((change) => {
4064
+ if (!registry) {
4065
+ return;
4066
+ }
4067
+ const ctx = registry.resolveForUri(change.document.uri);
4068
+ if (!ctx) {
4069
+ return;
4070
+ }
4071
+ const state = ctx.documentManager.update(change.document.uri, change.document.version, change.document.getText());
4072
+ checkSwcUnavailable(state.swcUnavailable, swcNotification, (msg) => connection.window.showErrorMessage(msg));
4073
+ publishDiagnosticsForDocument(change.document.uri);
4074
+ });
4075
+ documents.onDidClose((change) => {
4076
+ if (!registry) {
4077
+ return;
4078
+ }
4079
+ const ctx = registry.resolveForUri(change.document.uri);
4080
+ if (ctx) {
4081
+ ctx.documentManager.remove(change.document.uri);
4082
+ }
4083
+ connection.sendDiagnostics({
4084
+ uri: change.document.uri,
4085
+ diagnostics: []
4086
+ });
4087
+ });
4088
+ connection.onCompletion((params) => {
4089
+ if (!registry) {
4090
+ return [];
4091
+ }
4092
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4093
+ if (!ctx) {
4094
+ return [];
4095
+ }
4096
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(documents.get(params.textDocument.uri)?.getText() ?? "", params.position));
4097
+ if (!template) {
4098
+ return [];
4099
+ }
4100
+ const entry = ctx.schemaResolver.getSchema(template.schemaName);
4101
+ if (!entry) {
4102
+ return [];
4103
+ }
4104
+ const doc = documents.get(params.textDocument.uri);
4105
+ if (!doc) {
4106
+ return [];
4107
+ }
4108
+ const externalFragments = ctx.documentManager.getExternalFragments(params.textDocument.uri, template.schemaName).map((f) => f.definition);
4109
+ return handleCompletion({
4110
+ template,
4111
+ schema: entry.schema,
4112
+ tsSource: doc.getText(),
4113
+ tsPosition: {
4114
+ line: params.position.line,
4115
+ character: params.position.character
4116
+ },
4117
+ externalFragments
4118
+ });
4119
+ });
4120
+ connection.onHover((params) => {
4121
+ if (!registry) {
4122
+ return null;
4123
+ }
4124
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4125
+ if (!ctx) {
4126
+ return null;
4127
+ }
4128
+ const doc = documents.get(params.textDocument.uri);
4129
+ if (!doc) {
4130
+ return null;
4131
+ }
4132
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(doc.getText(), params.position));
4133
+ if (!template) {
4134
+ return null;
4135
+ }
4136
+ const entry = ctx.schemaResolver.getSchema(template.schemaName);
4137
+ if (!entry) {
4138
+ return null;
4139
+ }
4140
+ return handleHover({
4141
+ template,
4142
+ schema: entry.schema,
4143
+ tsSource: doc.getText(),
4144
+ tsPosition: {
4145
+ line: params.position.line,
4146
+ character: params.position.character
4147
+ }
4148
+ });
4149
+ });
4150
+ connection.onDefinition(async (params) => {
4151
+ if (!registry) {
4152
+ return [];
4153
+ }
4154
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4155
+ if (!ctx) {
4156
+ return [];
4157
+ }
4158
+ const doc = documents.get(params.textDocument.uri);
4159
+ if (!doc) {
4160
+ return [];
4161
+ }
4162
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(doc.getText(), params.position));
4163
+ if (!template) {
4164
+ return [];
4165
+ }
4166
+ const externalFragments = ctx.documentManager.getExternalFragments(params.textDocument.uri, template.schemaName);
4167
+ const entry = ctx.schemaResolver.getSchema(template.schemaName);
4168
+ return handleDefinition({
4169
+ template,
4170
+ tsSource: doc.getText(),
4171
+ tsPosition: {
4172
+ line: params.position.line,
4173
+ character: params.position.character
4174
+ },
4175
+ externalFragments,
4176
+ schema: entry?.schema,
4177
+ schemaFiles: entry?.files
4178
+ });
4179
+ });
4180
+ connection.onReferences((params) => {
4181
+ if (!registry) {
4182
+ return [];
4183
+ }
4184
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4185
+ if (!ctx) {
4186
+ return [];
4187
+ }
4188
+ const doc = documents.get(params.textDocument.uri);
4189
+ if (!doc) {
4190
+ return [];
4191
+ }
4192
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(doc.getText(), params.position));
4193
+ if (!template) {
4194
+ return [];
4195
+ }
4196
+ return handleReferences({
4197
+ template,
4198
+ tsSource: doc.getText(),
4199
+ tsPosition: {
4200
+ line: params.position.line,
4201
+ character: params.position.character
4202
+ },
4203
+ allFragments: ctx.documentManager.getAllFragments(template.schemaName),
4204
+ findSpreadLocations: (name) => ctx.documentManager.findFragmentSpreadLocations(name, template.schemaName)
4205
+ });
4206
+ });
4207
+ connection.onPrepareRename((params) => {
4208
+ if (!registry) {
4209
+ return null;
4210
+ }
4211
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4212
+ if (!ctx) {
4213
+ return null;
4214
+ }
4215
+ const doc = documents.get(params.textDocument.uri);
4216
+ if (!doc) {
4217
+ return null;
4218
+ }
4219
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(doc.getText(), params.position));
4220
+ if (!template) {
4221
+ return null;
4222
+ }
4223
+ return handlePrepareRename({
4224
+ template,
4225
+ tsSource: doc.getText(),
4226
+ tsPosition: {
4227
+ line: params.position.line,
4228
+ character: params.position.character
4229
+ }
4230
+ });
4231
+ });
4232
+ connection.onRenameRequest((params) => {
4233
+ if (!registry) {
4234
+ return null;
4235
+ }
4236
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4237
+ if (!ctx) {
4238
+ return null;
4239
+ }
4240
+ const doc = documents.get(params.textDocument.uri);
4241
+ if (!doc) {
4242
+ return null;
4243
+ }
4244
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(doc.getText(), params.position));
4245
+ if (!template) {
4246
+ return null;
4247
+ }
4248
+ return handleRename({
4249
+ template,
4250
+ tsSource: doc.getText(),
4251
+ tsPosition: {
4252
+ line: params.position.line,
4253
+ character: params.position.character
4254
+ },
4255
+ newName: params.newName,
4256
+ allFragments: ctx.documentManager.getAllFragments(template.schemaName),
4257
+ findSpreadLocations: (name) => ctx.documentManager.findFragmentSpreadLocations(name, template.schemaName)
4258
+ });
4259
+ });
4260
+ connection.onDocumentSymbol((params) => {
4261
+ if (!registry) {
4262
+ return [];
4263
+ }
4264
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4265
+ if (!ctx) {
4266
+ return [];
4267
+ }
4268
+ const state = ctx.documentManager.get(params.textDocument.uri);
4269
+ if (!state) {
4270
+ return [];
4271
+ }
4272
+ return handleDocumentSymbol({
4273
+ templates: state.templates,
4274
+ tsSource: state.source
4275
+ });
4276
+ });
4277
+ connection.onDocumentFormatting((params) => {
4278
+ if (!registry) {
4279
+ return [];
4280
+ }
4281
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4282
+ if (!ctx) {
4283
+ return [];
4284
+ }
4285
+ const state = ctx.documentManager.get(params.textDocument.uri);
4286
+ if (!state) {
4287
+ return [];
4288
+ }
4289
+ return handleFormatting({
4290
+ templates: state.templates,
4291
+ tsSource: state.source
4292
+ });
4293
+ });
4294
+ connection.onCodeAction((params) => {
4295
+ if (!registry) {
4296
+ return [];
4297
+ }
4298
+ const ctx = registry.resolveForUri(params.textDocument.uri);
4299
+ if (!ctx) {
4300
+ return [];
4301
+ }
4302
+ const doc = documents.get(params.textDocument.uri);
4303
+ if (!doc) {
4304
+ return [];
4305
+ }
4306
+ const template = ctx.documentManager.findTemplateAtOffset(params.textDocument.uri, positionToOffset(doc.getText(), params.range.start));
4307
+ if (!template) {
4308
+ return [];
4309
+ }
4310
+ const entry = ctx.schemaResolver.getSchema(template.schemaName);
4311
+ if (!entry) {
4312
+ return [];
4313
+ }
4314
+ return handleCodeAction({
4315
+ template,
4316
+ schema: entry.schema,
4317
+ tsSource: doc.getText(),
4318
+ uri: params.textDocument.uri,
4319
+ selectionRange: {
4320
+ start: {
4321
+ line: params.range.start.line,
4322
+ character: params.range.start.character
4323
+ },
4324
+ end: {
4325
+ line: params.range.end.line,
4326
+ character: params.range.end.character
4327
+ }
4328
+ }
4329
+ });
4330
+ });
4331
+ connection.onDidChangeWatchedFiles((_params) => {
4332
+ if (!registry) {
4333
+ return;
4334
+ }
4335
+ const graphqlChanged = _params.changes.some((change) => change.uri.endsWith(".graphql") && (change.type === vscode_languageserver_node.FileChangeType.Changed || change.type === vscode_languageserver_node.FileChangeType.Created));
4336
+ if (graphqlChanged) {
4337
+ const result = registry.reloadAllSchemas();
4338
+ publishDiagnosticsForAllOpen();
4339
+ if (result.isErr()) {
4340
+ for (const error of result.error) {
4341
+ connection.window.showErrorMessage(`soda-gql LSP: schema reload failed: ${error.message}`);
4342
+ }
4343
+ }
4344
+ }
4345
+ });
4346
+ documents.listen(connection);
4347
+ return { start: () => {
4348
+ connection.listen();
4349
+ } };
4350
+ };
4351
+ /** Check if SWC is unavailable and show a one-time error notification. */
4352
+ const checkSwcUnavailable = (swcUnavailable, state, showError) => {
4353
+ if (swcUnavailable && !state.shown) {
4354
+ state.shown = true;
4355
+ showError(`soda-gql LSP: ${lspErrors.swcResolutionFailed().message}`);
4356
+ }
4357
+ };
4358
+ /** Convert LSP Position to byte offset in source text. */
4359
+ const positionToOffset = (source, position) => {
4360
+ let line = 0;
4361
+ let offset = 0;
4362
+ while (line < position.line && offset < source.length) {
4363
+ if (source.charCodeAt(offset) === 10) {
4364
+ line++;
4365
+ }
4366
+ offset++;
4367
+ }
4368
+ return offset + position.character;
4369
+ };
4370
+
4371
+ //#endregion
4372
+ Object.defineProperty(exports, 'createDocumentManager', {
4373
+ enumerable: true,
4374
+ get: function () {
4375
+ return createDocumentManager;
4376
+ }
4377
+ });
4378
+ Object.defineProperty(exports, 'createLspServer', {
4379
+ enumerable: true,
4380
+ get: function () {
4381
+ return createLspServer;
4382
+ }
4383
+ });
4384
+ Object.defineProperty(exports, 'createPositionMapper', {
4385
+ enumerable: true,
4386
+ get: function () {
4387
+ return createPositionMapper;
4388
+ }
4389
+ });
4390
+ Object.defineProperty(exports, 'createSchemaResolver', {
4391
+ enumerable: true,
4392
+ get: function () {
4393
+ return createSchemaResolver;
4394
+ }
4395
+ });
4396
+ Object.defineProperty(exports, 'lspErrors', {
4397
+ enumerable: true,
4398
+ get: function () {
4399
+ return lspErrors;
4400
+ }
4401
+ });
4402
+ Object.defineProperty(exports, 'preprocessFragmentArgs', {
4403
+ enumerable: true,
4404
+ get: function () {
4405
+ return preprocessFragmentArgs;
4406
+ }
4407
+ });
4408
+ //# sourceMappingURL=server-0Mbk3BXO.cjs.map