@soda-gql/lsp 0.14.1 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/bin.cjs +1 -1
- package/dist/bin.mjs +1 -1
- package/dist/index.cjs +298 -2
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +42 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +44 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +297 -2
- package/dist/index.mjs.map +1 -0
- package/dist/{server-DsJ1bZ7i.cjs → server-C1MSX490.cjs} +1101 -410
- package/dist/server-C1MSX490.cjs.map +1 -0
- package/dist/{server-CqOUHwDk.mjs → server-wPCHK04O.mjs} +1087 -414
- package/dist/server-wPCHK04O.mjs.map +1 -0
- package/package.json +6 -6
- package/dist/server-CqOUHwDk.mjs.map +0 -1
- package/dist/server-DsJ1bZ7i.cjs.map +0 -1
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/document-manager.ts","../src/errors.ts","../src/fragment-args-preprocessor.ts","../src/position-mapping.ts","../src/schema-resolver.ts","../src/server.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/cli.ts","../src/types.ts","../src/document-manager.ts","../src/errors.ts","../src/fragment-args-preprocessor.ts","../src/position-mapping.ts","../src/schema-resolver.ts","../src/server.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,298 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as collectRawDiagnostics, c as preprocessFragmentArgs, i as lspErrors, n as createConfigRegistry, o as createPositionMapper, r as createSchemaResolver, s as createDocumentManager, t as createLspServer } from "./server-wPCHK04O.mjs";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { resolveEntryPaths } from "@soda-gql/builder";
|
|
5
|
+
import { findAllConfigFiles } from "@soda-gql/config";
|
|
6
|
+
import { isEnumType, isInputObjectType, isInterfaceType, isObjectType, isScalarType, isUnionType } from "graphql";
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
//#region packages/lsp/src/cli-utils.ts
|
|
9
|
+
/**
|
|
10
|
+
* Shared utility functions for CLI.
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
/** Extract variable declaration from template content (e.g., "($id: ID!)"). */
|
|
14
|
+
const extractVariablesFromContent = (content) => {
|
|
15
|
+
const match = content.match(/^\s*\(([^)]+)\)/);
|
|
16
|
+
return match ? `(${match[1]})` : undefined;
|
|
17
|
+
};
|
|
18
|
+
/** Compute 1-based line number from a byte offset in source. */
|
|
19
|
+
const computeLineFromOffset = (source, offset) => {
|
|
20
|
+
let line = 1;
|
|
21
|
+
for (let i = 0; i < offset && i < source.length; i++) {
|
|
22
|
+
if (source[i] === "\n") line++;
|
|
23
|
+
}
|
|
24
|
+
return line;
|
|
25
|
+
};
|
|
26
|
+
const collectDiagnostics = (state, ctx) => {
|
|
27
|
+
const diagnostics = collectRawDiagnostics(state, ctx);
|
|
28
|
+
return [...diagnostics].map((d) => ({
|
|
29
|
+
message: d.message,
|
|
30
|
+
line: d.range.start.line + 1,
|
|
31
|
+
column: d.range.start.character + 1,
|
|
32
|
+
severity: diagnosticSeverityToString(d.severity)
|
|
33
|
+
}));
|
|
34
|
+
};
|
|
35
|
+
const diagnosticSeverityToString = (severity) => {
|
|
36
|
+
switch (severity) {
|
|
37
|
+
case 1: return "Error";
|
|
38
|
+
case 2: return "Warning";
|
|
39
|
+
case 3: return "Information";
|
|
40
|
+
case 4: return "Hint";
|
|
41
|
+
default: return "Error";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/** Introspect a single GraphQL type (depth-1). */
|
|
45
|
+
const introspectType = (schema, typeName) => {
|
|
46
|
+
const type = schema.getType(typeName);
|
|
47
|
+
if (!type) return undefined;
|
|
48
|
+
if (isObjectType(type) || isInterfaceType(type)) {
|
|
49
|
+
const fields = Object.values(type.getFields()).map((f) => ({
|
|
50
|
+
name: f.name,
|
|
51
|
+
type: f.type.toString(),
|
|
52
|
+
args: f.args.map((a) => ({
|
|
53
|
+
name: a.name,
|
|
54
|
+
type: a.type.toString()
|
|
55
|
+
}))
|
|
56
|
+
}));
|
|
57
|
+
return {
|
|
58
|
+
name: type.name,
|
|
59
|
+
kind: isObjectType(type) ? "OBJECT" : "INTERFACE",
|
|
60
|
+
fields
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (isUnionType(type)) {
|
|
64
|
+
return {
|
|
65
|
+
name: type.name,
|
|
66
|
+
kind: "UNION",
|
|
67
|
+
members: type.getTypes().map((t) => ({ name: t.name }))
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (isEnumType(type)) {
|
|
71
|
+
return {
|
|
72
|
+
name: type.name,
|
|
73
|
+
kind: "ENUM",
|
|
74
|
+
values: type.getValues().map((v) => ({ name: v.name }))
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (isInputObjectType(type)) {
|
|
78
|
+
const fields = Object.values(type.getFields()).map((f) => ({
|
|
79
|
+
name: f.name,
|
|
80
|
+
type: f.type.toString()
|
|
81
|
+
}));
|
|
82
|
+
return {
|
|
83
|
+
name: type.name,
|
|
84
|
+
kind: "INPUT_OBJECT",
|
|
85
|
+
fields
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (isScalarType(type)) {
|
|
89
|
+
return {
|
|
90
|
+
name: type.name,
|
|
91
|
+
kind: "SCALAR"
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
};
|
|
96
|
+
/** List all user-defined types in a schema. */
|
|
97
|
+
const listTypes = (schema) => {
|
|
98
|
+
const typeMap = schema.getTypeMap();
|
|
99
|
+
const types = Object.values(typeMap).filter((t) => !t.name.startsWith("__")).map((t) => ({
|
|
100
|
+
name: t.name,
|
|
101
|
+
kind: getTypeKind(t)
|
|
102
|
+
}));
|
|
103
|
+
return { types };
|
|
104
|
+
};
|
|
105
|
+
const getTypeKind = (type) => {
|
|
106
|
+
if (isObjectType(type)) return "OBJECT";
|
|
107
|
+
if (isInterfaceType(type)) return "INTERFACE";
|
|
108
|
+
if (isUnionType(type)) return "UNION";
|
|
109
|
+
if (isEnumType(type)) return "ENUM";
|
|
110
|
+
if (isInputObjectType(type)) return "INPUT_OBJECT";
|
|
111
|
+
if (isScalarType(type)) return "SCALAR";
|
|
112
|
+
return "UNKNOWN";
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region packages/lsp/src/cli.ts
|
|
117
|
+
/**
|
|
118
|
+
* One-shot CLI runner: exposes soda-gql GraphQL intelligence as CLI subcommands.
|
|
119
|
+
* Provides a stable, daemon-free interface for Claude Code skills.
|
|
120
|
+
* @module
|
|
121
|
+
*/
|
|
122
|
+
const USAGE = `Usage: soda-gql-lsp-cli <subcommand> [options]
|
|
123
|
+
|
|
124
|
+
Subcommands:
|
|
125
|
+
diagnostics <file> Validate GraphQL templates against the schema
|
|
126
|
+
schema [typeName] Introspect schema types (omit typeName for full list)
|
|
127
|
+
symbols <file> List fragments and operations in a file
|
|
128
|
+
|
|
129
|
+
Options:
|
|
130
|
+
--workspace Index all workspace files (for cross-file fragment resolution)
|
|
131
|
+
--schema <name> Target schema name (multi-schema projects)
|
|
132
|
+
--config <path> Config context file path (multi-config projects)
|
|
133
|
+
--help Show this help message`;
|
|
134
|
+
const parseCliArgs = (args) => {
|
|
135
|
+
const subcommand = args[0];
|
|
136
|
+
if (!subcommand || subcommand === "--help" || ![
|
|
137
|
+
"diagnostics",
|
|
138
|
+
"schema",
|
|
139
|
+
"symbols"
|
|
140
|
+
].includes(subcommand)) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
let filePath;
|
|
144
|
+
let typeName;
|
|
145
|
+
let workspace = false;
|
|
146
|
+
let schemaName;
|
|
147
|
+
let configPath;
|
|
148
|
+
let i = 1;
|
|
149
|
+
const firstArg = args[i];
|
|
150
|
+
if (firstArg !== undefined && !firstArg.startsWith("--")) {
|
|
151
|
+
if (subcommand === "schema") {
|
|
152
|
+
typeName = firstArg;
|
|
153
|
+
} else {
|
|
154
|
+
filePath = resolve(firstArg);
|
|
155
|
+
}
|
|
156
|
+
i++;
|
|
157
|
+
}
|
|
158
|
+
for (; i < args.length; i++) {
|
|
159
|
+
const arg = args[i];
|
|
160
|
+
if (arg === undefined) continue;
|
|
161
|
+
if (arg === "--workspace") {
|
|
162
|
+
workspace = true;
|
|
163
|
+
} else if (arg === "--schema" && i + 1 < args.length) {
|
|
164
|
+
schemaName = args[++i];
|
|
165
|
+
} else if (arg === "--config" && i + 1 < args.length) {
|
|
166
|
+
const nextArg = args[++i];
|
|
167
|
+
if (nextArg !== undefined) configPath = resolve(nextArg);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
subcommand,
|
|
172
|
+
filePath,
|
|
173
|
+
typeName,
|
|
174
|
+
workspace,
|
|
175
|
+
schemaName,
|
|
176
|
+
configPath
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
const output = (data) => {
|
|
180
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}\n`);
|
|
181
|
+
};
|
|
182
|
+
var CliError = class extends Error {};
|
|
183
|
+
const cliError = (message) => {
|
|
184
|
+
process.stderr.write(`${JSON.stringify({ error: message })}\n`);
|
|
185
|
+
return new CliError(message);
|
|
186
|
+
};
|
|
187
|
+
const initRegistry = () => {
|
|
188
|
+
const cwd = process.cwd();
|
|
189
|
+
const configPaths = findAllConfigFiles(cwd);
|
|
190
|
+
if (configPaths.length === 0) {
|
|
191
|
+
throw cliError(`No soda-gql config found in ${cwd}`);
|
|
192
|
+
}
|
|
193
|
+
const result = createConfigRegistry(configPaths);
|
|
194
|
+
if (result.isErr()) {
|
|
195
|
+
throw cliError(result.error.message);
|
|
196
|
+
}
|
|
197
|
+
return result.value;
|
|
198
|
+
};
|
|
199
|
+
const indexWorkspace = (registry) => {
|
|
200
|
+
for (const ctx of registry.getAllContexts()) {
|
|
201
|
+
const filesResult = resolveEntryPaths(ctx.config.include, ctx.config.exclude);
|
|
202
|
+
if (filesResult.isErr()) continue;
|
|
203
|
+
for (const fp of filesResult.value) {
|
|
204
|
+
if (ctx.documentManager.get(fp)) continue;
|
|
205
|
+
try {
|
|
206
|
+
const source = readFileSync(fp, "utf-8");
|
|
207
|
+
ctx.documentManager.update(fp, 1, source);
|
|
208
|
+
} catch {}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
const resolveContext = (registry, filePath) => {
|
|
213
|
+
const ctx = filePath ? registry.resolveForUri(filePath) : registry.getAllContexts()[0];
|
|
214
|
+
if (!ctx) {
|
|
215
|
+
throw cliError(filePath ? `No soda-gql config covers ${filePath}` : "No soda-gql config context found");
|
|
216
|
+
}
|
|
217
|
+
return ctx;
|
|
218
|
+
};
|
|
219
|
+
const readSource = (filePath) => {
|
|
220
|
+
try {
|
|
221
|
+
return readFileSync(filePath, "utf-8");
|
|
222
|
+
} catch (e) {
|
|
223
|
+
throw cliError(`Failed to read file: ${e instanceof Error ? e.message : String(e)}`);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
const requireFilePath = (args, subcommand) => {
|
|
227
|
+
const { filePath } = args;
|
|
228
|
+
if (!filePath) throw cliError(`${subcommand} requires a file path argument`);
|
|
229
|
+
return filePath;
|
|
230
|
+
};
|
|
231
|
+
const handleDiagnostics = (registry, args) => {
|
|
232
|
+
const filePath = requireFilePath(args, "diagnostics");
|
|
233
|
+
const ctx = resolveContext(registry, filePath);
|
|
234
|
+
const source = readSource(filePath);
|
|
235
|
+
const state = ctx.documentManager.update(filePath, 1, source);
|
|
236
|
+
output(collectDiagnostics(state, ctx));
|
|
237
|
+
};
|
|
238
|
+
const handleSchema = (registry, args) => {
|
|
239
|
+
const ctx = resolveContext(registry, args.configPath);
|
|
240
|
+
const targetSchemaName = args.schemaName ?? ctx.schemaResolver.getSchemaNames()[0];
|
|
241
|
+
if (!targetSchemaName) throw cliError("No schema available");
|
|
242
|
+
const entry = ctx.schemaResolver.getSchema(targetSchemaName);
|
|
243
|
+
if (!entry) throw cliError(`Schema '${targetSchemaName}' not found`);
|
|
244
|
+
if (args.typeName) {
|
|
245
|
+
const result = introspectType(entry.schema, args.typeName);
|
|
246
|
+
if (!result) throw cliError(`Type '${args.typeName}' not found in schema`);
|
|
247
|
+
output(result);
|
|
248
|
+
} else {
|
|
249
|
+
output(listTypes(entry.schema));
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
const handleSymbols = (registry, args) => {
|
|
253
|
+
const filePath = requireFilePath(args, "symbols");
|
|
254
|
+
const ctx = resolveContext(registry, filePath);
|
|
255
|
+
const source = readSource(filePath);
|
|
256
|
+
const state = ctx.documentManager.update(filePath, 1, source);
|
|
257
|
+
const symbols = state.templates.filter((t) => t.elementName !== undefined).map((t) => ({
|
|
258
|
+
name: t.elementName,
|
|
259
|
+
kind: t.kind,
|
|
260
|
+
typeName: t.typeName,
|
|
261
|
+
schemaName: t.schemaName,
|
|
262
|
+
variables: extractVariablesFromContent(t.content),
|
|
263
|
+
line: computeLineFromOffset(source, t.contentRange.start)
|
|
264
|
+
}));
|
|
265
|
+
output(symbols);
|
|
266
|
+
};
|
|
267
|
+
/** Run the soda-gql LSP CLI with the given arguments. */
|
|
268
|
+
const runLspCli = async (args) => {
|
|
269
|
+
const parsed = parseCliArgs(args);
|
|
270
|
+
if (!parsed) {
|
|
271
|
+
process.stderr.write(`${USAGE}\n`);
|
|
272
|
+
process.exit(args.includes("--help") ? 0 : 1);
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
const registry = initRegistry();
|
|
276
|
+
if (parsed.workspace) {
|
|
277
|
+
indexWorkspace(registry);
|
|
278
|
+
}
|
|
279
|
+
switch (parsed.subcommand) {
|
|
280
|
+
case "diagnostics":
|
|
281
|
+
handleDiagnostics(registry, parsed);
|
|
282
|
+
break;
|
|
283
|
+
case "schema":
|
|
284
|
+
handleSchema(registry, parsed);
|
|
285
|
+
break;
|
|
286
|
+
case "symbols":
|
|
287
|
+
handleSymbols(registry, parsed);
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
} catch (e) {
|
|
291
|
+
if (e instanceof CliError) process.exit(1);
|
|
292
|
+
throw e;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
//#endregion
|
|
297
|
+
export { createDocumentManager, createLspServer, createPositionMapper, createSchemaResolver, lspErrors, preprocessFragmentArgs, runLspCli };
|
|
298
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["filePath: string | undefined","typeName: string | undefined","schemaName: string | undefined","configPath: string | undefined"],"sources":["../src/cli-utils.ts","../src/cli.ts"],"sourcesContent":["/**\n * Shared utility functions for CLI.\n * @module\n */\n\nimport {\n type GraphQLNamedType,\n type GraphQLSchema,\n isEnumType,\n isInputObjectType,\n isInterfaceType,\n isObjectType,\n isScalarType,\n isUnionType,\n} from \"graphql\";\nimport type { ConfigContext } from \"./config-registry\";\nimport { collectRawDiagnostics } from \"./diagnostics-collector\";\nimport type { DocumentState } from \"./types\";\n\n/** Extract variable declaration from template content (e.g., \"($id: ID!)\"). */\nexport const extractVariablesFromContent = (content: string): string | undefined => {\n const match = content.match(/^\\s*\\(([^)]+)\\)/);\n return match ? `(${match[1]})` : undefined;\n};\n\n/** Compute 1-based line number from a byte offset in source. */\nexport const computeLineFromOffset = (source: string, offset: number): number => {\n let line = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === \"\\n\") line++;\n }\n return line;\n};\n\n/** Collect diagnostics and map to JSON-serializable format. */\nexport type DiagnosticResult = { message: string; line: number; column: number; severity: string };\n\nexport const collectDiagnostics = (state: DocumentState, ctx: ConfigContext): DiagnosticResult[] => {\n const diagnostics = collectRawDiagnostics(state, ctx);\n return [...diagnostics].map((d) => ({\n message: d.message,\n line: d.range.start.line + 1,\n column: d.range.start.character + 1,\n severity: diagnosticSeverityToString(d.severity),\n }));\n};\n\nexport const diagnosticSeverityToString = (severity: number | undefined): string => {\n switch (severity) {\n case 1:\n return \"Error\";\n case 2:\n return \"Warning\";\n case 3:\n return \"Information\";\n case 4:\n return \"Hint\";\n default:\n return \"Error\";\n }\n};\n\n/** Introspect a single GraphQL type (depth-1). */\nexport const introspectType = (schema: GraphQLSchema, typeName: string) => {\n const type = schema.getType(typeName);\n if (!type) return undefined;\n\n if (isObjectType(type) || isInterfaceType(type)) {\n const fields = Object.values(type.getFields()).map((f) => ({\n name: f.name,\n type: f.type.toString(),\n args: f.args.map((a) => ({ name: a.name, type: a.type.toString() })),\n }));\n return { name: type.name, kind: isObjectType(type) ? \"OBJECT\" : \"INTERFACE\", fields };\n }\n if (isUnionType(type)) {\n return { name: type.name, kind: \"UNION\", members: type.getTypes().map((t) => ({ name: t.name })) };\n }\n if (isEnumType(type)) {\n return { name: type.name, kind: \"ENUM\", values: type.getValues().map((v) => ({ name: v.name })) };\n }\n if (isInputObjectType(type)) {\n const fields = Object.values(type.getFields()).map((f) => ({\n name: f.name,\n type: f.type.toString(),\n }));\n return { name: type.name, kind: \"INPUT_OBJECT\", fields };\n }\n if (isScalarType(type)) {\n return { name: type.name, kind: \"SCALAR\" };\n }\n return undefined;\n};\n\n/** List all user-defined types in a schema. */\nexport const listTypes = (schema: GraphQLSchema) => {\n const typeMap = schema.getTypeMap();\n const types = Object.values(typeMap)\n .filter((t) => !t.name.startsWith(\"__\"))\n .map((t) => ({ name: t.name, kind: getTypeKind(t) }));\n return { types };\n};\n\nconst getTypeKind = (type: GraphQLNamedType): string => {\n if (isObjectType(type)) return \"OBJECT\";\n if (isInterfaceType(type)) return \"INTERFACE\";\n if (isUnionType(type)) return \"UNION\";\n if (isEnumType(type)) return \"ENUM\";\n if (isInputObjectType(type)) return \"INPUT_OBJECT\";\n if (isScalarType(type)) return \"SCALAR\";\n return \"UNKNOWN\";\n};\n","/**\n * One-shot CLI runner: exposes soda-gql GraphQL intelligence as CLI subcommands.\n * Provides a stable, daemon-free interface for Claude Code skills.\n * @module\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { resolveEntryPaths } from \"@soda-gql/builder\";\nimport { findAllConfigFiles } from \"@soda-gql/config\";\nimport { collectDiagnostics, computeLineFromOffset, extractVariablesFromContent, introspectType, listTypes } from \"./cli-utils\";\nimport type { ConfigContext, ConfigRegistry } from \"./config-registry\";\nimport { createConfigRegistry } from \"./config-registry\";\n\ninterface CliArgs {\n readonly subcommand: \"diagnostics\" | \"schema\" | \"symbols\";\n readonly filePath?: string;\n readonly typeName?: string;\n readonly workspace: boolean;\n readonly schemaName?: string;\n readonly configPath?: string;\n}\n\nconst USAGE = `Usage: soda-gql-lsp-cli <subcommand> [options]\n\nSubcommands:\n diagnostics <file> Validate GraphQL templates against the schema\n schema [typeName] Introspect schema types (omit typeName for full list)\n symbols <file> List fragments and operations in a file\n\nOptions:\n --workspace Index all workspace files (for cross-file fragment resolution)\n --schema <name> Target schema name (multi-schema projects)\n --config <path> Config context file path (multi-config projects)\n --help Show this help message`;\n\nexport const parseCliArgs = (args: readonly string[]): CliArgs | undefined => {\n const subcommand = args[0];\n if (!subcommand || subcommand === \"--help\" || ![\"diagnostics\", \"schema\", \"symbols\"].includes(subcommand)) {\n return undefined;\n }\n\n let filePath: string | undefined;\n let typeName: string | undefined;\n let workspace = false;\n let schemaName: string | undefined;\n let configPath: string | undefined;\n\n let i = 1;\n // Collect positional arg first (before any flags)\n const firstArg = args[i];\n if (firstArg !== undefined && !firstArg.startsWith(\"--\")) {\n if (subcommand === \"schema\") {\n typeName = firstArg;\n } else {\n filePath = resolve(firstArg);\n }\n i++;\n }\n\n // Collect flags\n for (; i < args.length; i++) {\n const arg = args[i];\n if (arg === undefined) continue;\n if (arg === \"--workspace\") {\n workspace = true;\n } else if (arg === \"--schema\" && i + 1 < args.length) {\n schemaName = args[++i];\n } else if (arg === \"--config\" && i + 1 < args.length) {\n const nextArg = args[++i];\n if (nextArg !== undefined) configPath = resolve(nextArg);\n }\n }\n\n return { subcommand: subcommand as CliArgs[\"subcommand\"], filePath, typeName, workspace, schemaName, configPath };\n};\n\nconst output = (data: unknown): void => {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n};\n\nclass CliError extends Error {}\n\nconst cliError = (message: string): CliError => {\n process.stderr.write(`${JSON.stringify({ error: message })}\\n`);\n return new CliError(message);\n};\n\nconst initRegistry = (): ConfigRegistry => {\n const cwd = process.cwd();\n const configPaths = findAllConfigFiles(cwd);\n if (configPaths.length === 0) {\n throw cliError(`No soda-gql config found in ${cwd}`);\n }\n const result = createConfigRegistry(configPaths);\n if (result.isErr()) {\n throw cliError(result.error.message);\n }\n return result.value;\n};\n\nconst indexWorkspace = (registry: ConfigRegistry): void => {\n for (const ctx of registry.getAllContexts()) {\n const filesResult = resolveEntryPaths(ctx.config.include, ctx.config.exclude);\n if (filesResult.isErr()) continue;\n for (const fp of filesResult.value) {\n if (ctx.documentManager.get(fp)) continue;\n try {\n const source = readFileSync(fp, \"utf-8\");\n ctx.documentManager.update(fp, 1, source);\n } catch {\n /* skip unreadable files */\n }\n }\n }\n};\n\nconst resolveContext = (registry: ConfigRegistry, filePath?: string): ConfigContext => {\n const ctx = filePath ? registry.resolveForUri(filePath) : registry.getAllContexts()[0];\n if (!ctx) {\n throw cliError(filePath ? `No soda-gql config covers ${filePath}` : \"No soda-gql config context found\");\n }\n return ctx;\n};\n\nconst readSource = (filePath: string): string => {\n try {\n return readFileSync(filePath, \"utf-8\");\n } catch (e) {\n throw cliError(`Failed to read file: ${e instanceof Error ? e.message : String(e)}`);\n }\n};\n\nconst requireFilePath = (args: CliArgs, subcommand: string): string => {\n const { filePath } = args;\n if (!filePath) throw cliError(`${subcommand} requires a file path argument`);\n return filePath;\n};\n\nconst handleDiagnostics = (registry: ConfigRegistry, args: CliArgs): void => {\n const filePath = requireFilePath(args, \"diagnostics\");\n const ctx = resolveContext(registry, filePath);\n const source = readSource(filePath);\n const state = ctx.documentManager.update(filePath, 1, source);\n output(collectDiagnostics(state, ctx));\n};\n\nconst handleSchema = (registry: ConfigRegistry, args: CliArgs): void => {\n const ctx = resolveContext(registry, args.configPath);\n const targetSchemaName = args.schemaName ?? ctx.schemaResolver.getSchemaNames()[0];\n if (!targetSchemaName) throw cliError(\"No schema available\");\n\n const entry = ctx.schemaResolver.getSchema(targetSchemaName);\n if (!entry) throw cliError(`Schema '${targetSchemaName}' not found`);\n\n if (args.typeName) {\n const result = introspectType(entry.schema, args.typeName);\n if (!result) throw cliError(`Type '${args.typeName}' not found in schema`);\n output(result);\n } else {\n output(listTypes(entry.schema));\n }\n};\n\nconst handleSymbols = (registry: ConfigRegistry, args: CliArgs): void => {\n const filePath = requireFilePath(args, \"symbols\");\n const ctx = resolveContext(registry, filePath);\n const source = readSource(filePath);\n const state = ctx.documentManager.update(filePath, 1, source);\n const symbols = state.templates\n .filter((t): t is typeof t & { elementName: string } => t.elementName !== undefined)\n .map((t) => ({\n name: t.elementName,\n kind: t.kind,\n typeName: t.typeName,\n schemaName: t.schemaName,\n variables: extractVariablesFromContent(t.content),\n line: computeLineFromOffset(source, t.contentRange.start),\n }));\n output(symbols);\n};\n\n/** Run the soda-gql LSP CLI with the given arguments. */\nexport const runLspCli = async (args: readonly string[]): Promise<void> => {\n const parsed = parseCliArgs(args);\n if (!parsed) {\n process.stderr.write(`${USAGE}\\n`);\n process.exit(args.includes(\"--help\") ? 0 : 1);\n }\n\n try {\n const registry = initRegistry();\n if (parsed.workspace) {\n indexWorkspace(registry);\n }\n\n switch (parsed.subcommand) {\n case \"diagnostics\":\n handleDiagnostics(registry, parsed);\n break;\n case \"schema\":\n handleSchema(registry, parsed);\n break;\n case \"symbols\":\n handleSymbols(registry, parsed);\n break;\n }\n } catch (e) {\n if (e instanceof CliError) process.exit(1);\n throw e;\n }\n};\n"],"mappings":"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"}
|