@soda-gql/cli 0.11.11 → 0.11.12
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 +28 -0
- package/dist/index.cjs +266 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.cts.map +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -53,6 +53,34 @@ For first-time setup, generate inject template with scalar and adapter definitio
|
|
|
53
53
|
bun run soda-gql codegen --emit-inject-template ./src/graphql-system/default.inject.ts
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
#### Generate from .graphql Files
|
|
57
|
+
|
|
58
|
+
Convert existing `.graphql` operation files to soda-gql compat pattern:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
bun run soda-gql codegen graphql --input "src/**/*.graphql" --output src/generated
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This generates TypeScript files using the compat API pattern, allowing gradual migration from traditional `.graphql` files.
|
|
65
|
+
|
|
66
|
+
**Options:**
|
|
67
|
+
|
|
68
|
+
| Option | Description |
|
|
69
|
+
|--------|-------------|
|
|
70
|
+
| `--config <path>` | Path to config file |
|
|
71
|
+
| `--schema <name>` | Schema name (required if multiple schemas configured) |
|
|
72
|
+
| `--input <glob>` | Glob pattern for .graphql files (repeatable) |
|
|
73
|
+
| `--output <dir>` | Output directory for generated files |
|
|
74
|
+
|
|
75
|
+
**Example:**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Generate compat files from all .graphql files in src/
|
|
79
|
+
bun run soda-gql codegen graphql \
|
|
80
|
+
--input "src/**/*.graphql" \
|
|
81
|
+
--output src/generated
|
|
82
|
+
```
|
|
83
|
+
|
|
56
84
|
### CLI Options
|
|
57
85
|
|
|
58
86
|
| Option | Description |
|
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,8 @@ let node_path = require("node:path");
|
|
|
32
32
|
let __soda_gql_builder = require("@soda-gql/builder");
|
|
33
33
|
let __soda_gql_config = require("@soda-gql/config");
|
|
34
34
|
let __soda_gql_codegen = require("@soda-gql/codegen");
|
|
35
|
+
let __soda_gql_common = require("@soda-gql/common");
|
|
36
|
+
let bun = require("bun");
|
|
35
37
|
let zod = require("zod");
|
|
36
38
|
let node_fs = require("node:fs");
|
|
37
39
|
let fast_glob = require("fast-glob");
|
|
@@ -111,6 +113,21 @@ const cliErrors = {
|
|
|
111
113
|
message,
|
|
112
114
|
filePath
|
|
113
115
|
}),
|
|
116
|
+
duplicateFragment: (fragmentName, existingFile, newFile) => ({
|
|
117
|
+
category: "cli",
|
|
118
|
+
code: "CLI_DUPLICATE_FRAGMENT",
|
|
119
|
+
message: `Fragment "${fragmentName}" is defined in multiple files:\n - ${existingFile}\n - ${newFile}`,
|
|
120
|
+
fragmentName,
|
|
121
|
+
existingFile,
|
|
122
|
+
newFile
|
|
123
|
+
}),
|
|
124
|
+
fragmentNotFound: (fragmentName, referencedIn) => ({
|
|
125
|
+
category: "cli",
|
|
126
|
+
code: "CLI_FRAGMENT_NOT_FOUND",
|
|
127
|
+
message: `Fragment "${fragmentName}" is referenced but not defined in any input file`,
|
|
128
|
+
fragmentName,
|
|
129
|
+
referencedIn
|
|
130
|
+
}),
|
|
114
131
|
unexpected: (message, cause) => ({
|
|
115
132
|
category: "cli",
|
|
116
133
|
code: "CLI_UNEXPECTED",
|
|
@@ -181,7 +198,7 @@ const parseBuildArgs = (argv) => {
|
|
|
181
198
|
}
|
|
182
199
|
return args;
|
|
183
200
|
};
|
|
184
|
-
const formatSuccess$
|
|
201
|
+
const formatSuccess$5 = (data) => {
|
|
185
202
|
const { artifact, outputPath, dryRun } = data;
|
|
186
203
|
const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === "fragment").length;
|
|
187
204
|
const operationCount = Object.values(artifact.elements).filter((e) => e.type === "operation").length;
|
|
@@ -218,7 +235,7 @@ const buildCommand = async (argv) => {
|
|
|
218
235
|
dryRun: true
|
|
219
236
|
};
|
|
220
237
|
return (0, neverthrow.ok)({
|
|
221
|
-
message: formatSuccess$
|
|
238
|
+
message: formatSuccess$5(data$1),
|
|
222
239
|
data: data$1
|
|
223
240
|
});
|
|
224
241
|
}
|
|
@@ -237,7 +254,7 @@ const buildCommand = async (argv) => {
|
|
|
237
254
|
dryRun: false
|
|
238
255
|
};
|
|
239
256
|
return (0, neverthrow.ok)({
|
|
240
|
-
message: formatSuccess$
|
|
257
|
+
message: formatSuccess$5(data),
|
|
241
258
|
data
|
|
242
259
|
});
|
|
243
260
|
};
|
|
@@ -270,7 +287,7 @@ const parseValidateArgs = (argv) => {
|
|
|
270
287
|
else if (!arg.startsWith("-")) args.artifactPath = arg;
|
|
271
288
|
return args;
|
|
272
289
|
};
|
|
273
|
-
const formatSuccess$
|
|
290
|
+
const formatSuccess$4 = (artifact) => {
|
|
274
291
|
const lines = [`Artifact valid: ${Object.values(artifact.elements).filter((e) => e.type === "fragment").length} fragments, ${Object.values(artifact.elements).filter((e) => e.type === "operation").length} operations`];
|
|
275
292
|
if (artifact.meta) {
|
|
276
293
|
lines.push(` Version: ${artifact.meta.version}`);
|
|
@@ -288,7 +305,7 @@ const validateCommand = async (argv) => {
|
|
|
288
305
|
const result = await (0, __soda_gql_builder.loadArtifact)((0, node_path.resolve)(process.cwd(), args.artifactPath));
|
|
289
306
|
if (result.isErr()) return (0, neverthrow.err)(cliErrors.fromArtifact(result.error));
|
|
290
307
|
return (0, neverthrow.ok)({
|
|
291
|
-
message: formatSuccess$
|
|
308
|
+
message: formatSuccess$4(result.value),
|
|
292
309
|
data: result.value
|
|
293
310
|
});
|
|
294
311
|
};
|
|
@@ -318,7 +335,10 @@ const artifactCommand = async (argv) => {
|
|
|
318
335
|
|
|
319
336
|
//#endregion
|
|
320
337
|
//#region packages/cli/src/schemas/args.ts
|
|
321
|
-
|
|
338
|
+
/**
|
|
339
|
+
* Args for `codegen schema` subcommand.
|
|
340
|
+
*/
|
|
341
|
+
const CodegenSchemaArgsSchema = zod.z.object({
|
|
322
342
|
config: zod.z.string().optional(),
|
|
323
343
|
"emit-inject-template": zod.z.string().optional()
|
|
324
344
|
});
|
|
@@ -336,6 +356,15 @@ const FormatArgsSchema = zod.z.object({
|
|
|
336
356
|
});
|
|
337
357
|
const InitArgsSchema = zod.z.object({ force: zod.z.boolean().optional() });
|
|
338
358
|
const TypegenArgsSchema = zod.z.object({ config: zod.z.string().optional() });
|
|
359
|
+
/**
|
|
360
|
+
* Args for `codegen graphql` subcommand.
|
|
361
|
+
*/
|
|
362
|
+
const CodegenGraphqlArgsSchema = zod.z.object({
|
|
363
|
+
config: zod.z.string().optional(),
|
|
364
|
+
schema: zod.z.string().optional(),
|
|
365
|
+
input: zod.z.array(zod.z.string()).or(zod.z.string()).optional(),
|
|
366
|
+
suffix: zod.z.string().optional()
|
|
367
|
+
});
|
|
339
368
|
|
|
340
369
|
//#endregion
|
|
341
370
|
//#region packages/cli/src/utils/parse-args.ts
|
|
@@ -362,10 +391,190 @@ const parseArgs = (args, schema) => {
|
|
|
362
391
|
};
|
|
363
392
|
|
|
364
393
|
//#endregion
|
|
365
|
-
//#region packages/cli/src/commands/codegen.ts
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
394
|
+
//#region packages/cli/src/commands/codegen/graphql.ts
|
|
395
|
+
/**
|
|
396
|
+
* Codegen graphql subcommand - generates compat code from .graphql files.
|
|
397
|
+
* @module
|
|
398
|
+
*/
|
|
399
|
+
const parseGraphqlArgs = (argv) => {
|
|
400
|
+
const parsed = parseArgs([...argv], CodegenGraphqlArgsSchema);
|
|
401
|
+
if (!parsed.isOk()) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen graphql", parsed.error));
|
|
402
|
+
const args = parsed.value;
|
|
403
|
+
const configResult = (0, __soda_gql_config.loadConfig)(args.config);
|
|
404
|
+
if (configResult.isErr()) return (0, neverthrow.err)(cliErrors.fromConfig(configResult.error));
|
|
405
|
+
const config = configResult.value;
|
|
406
|
+
const schemaNames = Object.keys(config.schemas ?? {});
|
|
407
|
+
if (schemaNames.length === 0) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen graphql", "No schemas configured in soda-gql.config.ts"));
|
|
408
|
+
let schemaName = args.schema;
|
|
409
|
+
if (!schemaName) {
|
|
410
|
+
const firstSchema = schemaNames[0];
|
|
411
|
+
if (schemaNames.length > 1 || !firstSchema) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen graphql", `Multiple schemas configured. Use --schema to specify: ${schemaNames.join(", ")}`));
|
|
412
|
+
schemaName = firstSchema;
|
|
413
|
+
}
|
|
414
|
+
const schemaConfig = config.schemas?.[schemaName];
|
|
415
|
+
if (!schemaConfig) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen graphql", `Schema "${schemaName}" not found in config`));
|
|
416
|
+
let inputPatterns = [];
|
|
417
|
+
if (args.input) inputPatterns = Array.isArray(args.input) ? args.input : [args.input];
|
|
418
|
+
if (inputPatterns.length === 0) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen graphql", "No input patterns provided. Use --input to specify .graphql file patterns"));
|
|
419
|
+
const suffix = args.suffix ?? ".compat.ts";
|
|
420
|
+
return (0, neverthrow.ok)({
|
|
421
|
+
schemaName,
|
|
422
|
+
schemaFiles: schemaConfig.schema,
|
|
423
|
+
inputPatterns,
|
|
424
|
+
suffix,
|
|
425
|
+
graphqlSystemDir: (0, node_path.resolve)(config.outdir)
|
|
426
|
+
});
|
|
427
|
+
};
|
|
428
|
+
const generateCompatFiles = async (args) => {
|
|
429
|
+
const schemaResult = (0, __soda_gql_codegen.loadSchema)(args.schemaFiles.map((s) => (0, node_path.resolve)(s)));
|
|
430
|
+
if (schemaResult.isErr()) return (0, neverthrow.err)(cliErrors.fromCodegen(schemaResult.error));
|
|
431
|
+
const schemaDocument = schemaResult.value;
|
|
432
|
+
const graphqlFiles = [];
|
|
433
|
+
for (const pattern of args.inputPatterns) {
|
|
434
|
+
const glob = new bun.Glob(pattern);
|
|
435
|
+
for await (const file of glob.scan({
|
|
436
|
+
cwd: process.cwd(),
|
|
437
|
+
absolute: true
|
|
438
|
+
})) if (file.endsWith(".graphql") || file.endsWith(".gql")) graphqlFiles.push(file);
|
|
439
|
+
}
|
|
440
|
+
if (graphqlFiles.length === 0) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen graphql", `No .graphql files found matching patterns: ${args.inputPatterns.join(", ")}`));
|
|
441
|
+
const fragmentsByName = /* @__PURE__ */ new Map();
|
|
442
|
+
const parseCache = /* @__PURE__ */ new Map();
|
|
443
|
+
for (const file of graphqlFiles) {
|
|
444
|
+
const parseResult = (0, __soda_gql_codegen.parseGraphqlSource)(await (0, node_fs_promises.readFile)(file, "utf-8"), file);
|
|
445
|
+
if (parseResult.isErr()) return (0, neverthrow.err)(cliErrors.parseError(parseResult.error.message, file));
|
|
446
|
+
const parsed = parseResult.value;
|
|
447
|
+
parseCache.set(file, parsed);
|
|
448
|
+
const outputBase = (0, node_path.basename)(file).replace(/\.(graphql|gql)$/, args.suffix);
|
|
449
|
+
const outputPath = (0, node_path.join)((0, node_path.dirname)(file), outputBase);
|
|
450
|
+
for (const frag of parsed.fragments) {
|
|
451
|
+
const existing = fragmentsByName.get(frag.name);
|
|
452
|
+
if (existing && existing.file !== file) return (0, neverthrow.err)(cliErrors.duplicateFragment(frag.name, existing.file, file));
|
|
453
|
+
fragmentsByName.set(frag.name, {
|
|
454
|
+
file,
|
|
455
|
+
outputPath
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
const files = [];
|
|
460
|
+
let operationCount = 0;
|
|
461
|
+
let fragmentCount = 0;
|
|
462
|
+
for (const file of graphqlFiles) {
|
|
463
|
+
const parsed = parseCache.get(file);
|
|
464
|
+
if (!parsed) throw new Error(`Internal error: parse cache missing for ${file}`);
|
|
465
|
+
const transformResult = (0, __soda_gql_codegen.transformParsedGraphql)(parsed, { schemaDocument });
|
|
466
|
+
if (transformResult.isErr()) {
|
|
467
|
+
const error = transformResult.error;
|
|
468
|
+
return (0, neverthrow.err)(cliErrors.parseError(error.message, file));
|
|
469
|
+
}
|
|
470
|
+
const { operations, fragments } = transformResult.value;
|
|
471
|
+
const outputBase = (0, node_path.basename)(file).replace(/\.(graphql|gql)$/, args.suffix);
|
|
472
|
+
const outputPath = (0, node_path.join)((0, node_path.dirname)(file), outputBase);
|
|
473
|
+
const fragmentImports = /* @__PURE__ */ new Map();
|
|
474
|
+
const collectDeps = (deps) => {
|
|
475
|
+
for (const fragName of deps) {
|
|
476
|
+
const fragInfo = fragmentsByName.get(fragName);
|
|
477
|
+
if (!fragInfo) return (0, neverthrow.err)(cliErrors.fragmentNotFound(fragName, file));
|
|
478
|
+
if (fragInfo.outputPath !== outputPath) {
|
|
479
|
+
const relativePath = (0, __soda_gql_common.normalizePath)((0, node_path.relative)((0, node_path.dirname)(outputPath), fragInfo.outputPath)).replace(/\.ts$/, "");
|
|
480
|
+
const importPath = relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
481
|
+
fragmentImports.set(fragName, importPath);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return (0, neverthrow.ok)(void 0);
|
|
485
|
+
};
|
|
486
|
+
for (const op of operations) {
|
|
487
|
+
const result = collectDeps(op.fragmentDependencies);
|
|
488
|
+
if (result.isErr()) return (0, neverthrow.err)(result.error);
|
|
489
|
+
}
|
|
490
|
+
for (const frag of fragments) {
|
|
491
|
+
const result = collectDeps(frag.fragmentDependencies);
|
|
492
|
+
if (result.isErr()) return (0, neverthrow.err)(result.error);
|
|
493
|
+
}
|
|
494
|
+
const graphqlSystemRelative = (0, __soda_gql_common.normalizePath)((0, node_path.relative)((0, node_path.dirname)(outputPath), args.graphqlSystemDir));
|
|
495
|
+
const graphqlSystemPath = graphqlSystemRelative.startsWith(".") ? graphqlSystemRelative : `./${graphqlSystemRelative}`;
|
|
496
|
+
const emitOptions = {
|
|
497
|
+
schemaName: args.schemaName,
|
|
498
|
+
graphqlSystemPath,
|
|
499
|
+
fragmentImports,
|
|
500
|
+
schemaDocument
|
|
501
|
+
};
|
|
502
|
+
const parts = [];
|
|
503
|
+
for (const op of operations) {
|
|
504
|
+
const emitResult = (0, __soda_gql_codegen.emitOperation)(op, emitOptions);
|
|
505
|
+
if (emitResult.isErr()) return (0, neverthrow.err)(cliErrors.parseError(emitResult.error.message, file));
|
|
506
|
+
parts.push(emitResult.value);
|
|
507
|
+
operationCount++;
|
|
508
|
+
}
|
|
509
|
+
for (const frag of fragments) {
|
|
510
|
+
const emitResult = (0, __soda_gql_codegen.emitFragment)(frag, emitOptions);
|
|
511
|
+
if (emitResult.isErr()) return (0, neverthrow.err)(cliErrors.parseError(emitResult.error.message, file));
|
|
512
|
+
parts.push(emitResult.value);
|
|
513
|
+
fragmentCount++;
|
|
514
|
+
}
|
|
515
|
+
if (parts.length > 0) files.push({
|
|
516
|
+
inputPath: file,
|
|
517
|
+
outputPath,
|
|
518
|
+
content: parts.join("\n\n")
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
return (0, neverthrow.ok)({
|
|
522
|
+
files,
|
|
523
|
+
operationCount,
|
|
524
|
+
fragmentCount
|
|
525
|
+
});
|
|
526
|
+
};
|
|
527
|
+
const writeGeneratedFiles = async (files) => {
|
|
528
|
+
for (const file of files) {
|
|
529
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(file.outputPath), { recursive: true });
|
|
530
|
+
await (0, node_fs_promises.writeFile)(file.outputPath, file.content, "utf-8");
|
|
531
|
+
}
|
|
532
|
+
return (0, neverthrow.ok)(void 0);
|
|
533
|
+
};
|
|
534
|
+
const formatSuccess$3 = (result) => {
|
|
535
|
+
const lines = [`Generated ${result.operationCount} operation(s) and ${result.fragmentCount} fragment(s) from ${result.files.length} file(s):`];
|
|
536
|
+
for (const file of result.files) lines.push(` ${(0, node_path.relative)(process.cwd(), file.outputPath)}`);
|
|
537
|
+
return lines.join("\n");
|
|
538
|
+
};
|
|
539
|
+
const GRAPHQL_HELP = `Usage: soda-gql codegen graphql [options]
|
|
540
|
+
|
|
541
|
+
Generate TypeScript compat code from .graphql operation files.
|
|
542
|
+
Output files are created alongside input files.
|
|
543
|
+
|
|
544
|
+
Options:
|
|
545
|
+
--config <path> Path to soda-gql.config.ts
|
|
546
|
+
--schema <name> Schema name (required if multiple schemas configured)
|
|
547
|
+
--input <glob> Glob pattern for .graphql files (repeatable)
|
|
548
|
+
--suffix <ext> Output file suffix (default: ".compat.ts")
|
|
549
|
+
--help, -h Show this help message
|
|
550
|
+
|
|
551
|
+
Examples:
|
|
552
|
+
soda-gql codegen graphql --input "src/**/*.graphql"
|
|
553
|
+
soda-gql codegen graphql --input "queries/*.graphql" --suffix ".generated.ts"
|
|
554
|
+
`;
|
|
555
|
+
const graphqlCommand = async (argv) => {
|
|
556
|
+
if (argv.includes("--help") || argv.includes("-h")) return (0, neverthrow.ok)({ message: GRAPHQL_HELP });
|
|
557
|
+
const parsed = parseGraphqlArgs(argv);
|
|
558
|
+
if (parsed.isErr()) return (0, neverthrow.err)(parsed.error);
|
|
559
|
+
const result = await generateCompatFiles(parsed.value);
|
|
560
|
+
if (result.isErr()) return (0, neverthrow.err)(result.error);
|
|
561
|
+
const writeResult = await writeGeneratedFiles(result.value.files);
|
|
562
|
+
if (writeResult.isErr()) return (0, neverthrow.err)(writeResult.error);
|
|
563
|
+
return (0, neverthrow.ok)({
|
|
564
|
+
message: formatSuccess$3(result.value),
|
|
565
|
+
data: result.value
|
|
566
|
+
});
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region packages/cli/src/commands/codegen/schema.ts
|
|
571
|
+
/**
|
|
572
|
+
* Codegen schema subcommand - generates graphql-system runtime module.
|
|
573
|
+
* @module
|
|
574
|
+
*/
|
|
575
|
+
const parseSchemaArgs = (argv) => {
|
|
576
|
+
const parsed = parseArgs([...argv], CodegenSchemaArgsSchema);
|
|
577
|
+
if (!parsed.isOk()) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen schema", parsed.error));
|
|
369
578
|
const args = parsed.value;
|
|
370
579
|
if (args["emit-inject-template"]) return (0, neverthrow.ok)({
|
|
371
580
|
kind: "emitInjectTemplate",
|
|
@@ -374,7 +583,7 @@ const parseCodegenArgs = (argv) => {
|
|
|
374
583
|
const configResult = (0, __soda_gql_config.loadConfig)(args.config);
|
|
375
584
|
if (configResult.isErr()) return (0, neverthrow.err)(cliErrors.fromConfig(configResult.error));
|
|
376
585
|
const config = configResult.value;
|
|
377
|
-
if (!config.schemas || Object.keys(config.schemas).length === 0) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen", "schemas configuration is required in soda-gql.config.ts"));
|
|
586
|
+
if (!config.schemas || Object.keys(config.schemas).length === 0) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen schema", "schemas configuration is required in soda-gql.config.ts"));
|
|
378
587
|
const schemas = {};
|
|
379
588
|
for (const [name, schemaConfig] of Object.entries(config.schemas)) schemas[name] = {
|
|
380
589
|
schema: schemaConfig.schema,
|
|
@@ -396,7 +605,7 @@ const formatSuccess$2 = (success) => {
|
|
|
396
605
|
const formatTemplateSuccess = (outPath) => {
|
|
397
606
|
return `Created inject template → ${outPath}`;
|
|
398
607
|
};
|
|
399
|
-
const
|
|
608
|
+
const SCHEMA_HELP = `Usage: soda-gql codegen schema [options]
|
|
400
609
|
|
|
401
610
|
Generate graphql-system runtime module from GraphQL schema.
|
|
402
611
|
|
|
@@ -406,15 +615,15 @@ Options:
|
|
|
406
615
|
--help, -h Show this help message
|
|
407
616
|
|
|
408
617
|
Examples:
|
|
409
|
-
soda-gql codegen
|
|
410
|
-
soda-gql codegen --config ./soda-gql.config.ts
|
|
411
|
-
soda-gql codegen --emit-inject-template ./src/graphql/scalars.ts
|
|
618
|
+
soda-gql codegen schema
|
|
619
|
+
soda-gql codegen schema --config ./soda-gql.config.ts
|
|
620
|
+
soda-gql codegen schema --emit-inject-template ./src/graphql/scalars.ts
|
|
412
621
|
|
|
413
622
|
Note: Run 'soda-gql typegen' after codegen to generate prebuilt types.
|
|
414
623
|
`;
|
|
415
|
-
const
|
|
416
|
-
if (argv.includes("--help") || argv.includes("-h")) return (0, neverthrow.ok)({ message:
|
|
417
|
-
const parsed =
|
|
624
|
+
const schemaCommand = async (argv) => {
|
|
625
|
+
if (argv.includes("--help") || argv.includes("-h")) return (0, neverthrow.ok)({ message: SCHEMA_HELP });
|
|
626
|
+
const parsed = parseSchemaArgs(argv);
|
|
418
627
|
if (parsed.isErr()) return (0, neverthrow.err)(parsed.error);
|
|
419
628
|
const command = parsed.value;
|
|
420
629
|
if (command.kind === "emitInjectTemplate") {
|
|
@@ -446,6 +655,45 @@ const codegenCommand = async (argv) => {
|
|
|
446
655
|
});
|
|
447
656
|
};
|
|
448
657
|
|
|
658
|
+
//#endregion
|
|
659
|
+
//#region packages/cli/src/commands/codegen/index.ts
|
|
660
|
+
/**
|
|
661
|
+
* Codegen command dispatcher.
|
|
662
|
+
* @module
|
|
663
|
+
*/
|
|
664
|
+
const CODEGEN_HELP = `Usage: soda-gql codegen <subcommand> [options]
|
|
665
|
+
|
|
666
|
+
Generate code from GraphQL schemas and operations.
|
|
667
|
+
|
|
668
|
+
Subcommands:
|
|
669
|
+
schema Generate graphql-system runtime module from schema
|
|
670
|
+
graphql Generate compat code from .graphql operation files
|
|
671
|
+
|
|
672
|
+
Run 'soda-gql codegen <subcommand> --help' for more information.
|
|
673
|
+
|
|
674
|
+
Legacy usage (equivalent to 'codegen schema'):
|
|
675
|
+
soda-gql codegen [--config <path>]
|
|
676
|
+
`;
|
|
677
|
+
/**
|
|
678
|
+
* Check if argv looks like schema command args (for backwards compatibility).
|
|
679
|
+
*/
|
|
680
|
+
const isLegacySchemaArgs = (argv) => {
|
|
681
|
+
if (argv[0] === "schema" || argv[0] === "graphql") return false;
|
|
682
|
+
return argv.some((arg) => arg === "--config" || arg.startsWith("--config=") || arg === "--emit-inject-template" || arg.startsWith("--emit-inject-template="));
|
|
683
|
+
};
|
|
684
|
+
/**
|
|
685
|
+
* Dispatcher for codegen subcommands.
|
|
686
|
+
*/
|
|
687
|
+
const codegenCommand = async (argv) => {
|
|
688
|
+
const [subcommand, ...rest] = argv;
|
|
689
|
+
if (!subcommand || subcommand === "--help" || subcommand === "-h") return (0, neverthrow.ok)({ message: CODEGEN_HELP });
|
|
690
|
+
if (subcommand === "schema") return schemaCommand(rest);
|
|
691
|
+
if (subcommand === "graphql") return graphqlCommand(rest);
|
|
692
|
+
if (isLegacySchemaArgs(argv)) return schemaCommand(argv);
|
|
693
|
+
if (!subcommand.startsWith("-")) return (0, neverthrow.err)(cliErrors.unknownSubcommand("codegen", subcommand));
|
|
694
|
+
return schemaCommand(argv);
|
|
695
|
+
};
|
|
696
|
+
|
|
449
697
|
//#endregion
|
|
450
698
|
//#region packages/cli/src/commands/doctor/checks/codegen-freshness.ts
|
|
451
699
|
/**
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["args: BuildArgs","formatSuccess","lines: string[]","meta: BuilderArtifactMeta | undefined","artifactWithMeta: BuilderArtifact","data: BuildData","data","args: ValidateArgs","formatSuccess","lines: string[]","z","parsed: Record<string, unknown>","positional: string[]","schemas: Record<string, CodegenSchemaConfig>","formatSuccess","result","resolvedSchemas: Record<string, CodegenSchemaConfig>","schemaResults: CodegenFreshnessData[\"schemas\"][number][]","existingPaths: string[]","missingFiles: string[]","packages: DiscoveredPackage[]","allPackages: DiscoveredPackage[]","queue: string[]","realPath: string","duplicates: DuplicatePackageData[\"duplicates\"][number][]","STATUS_SYMBOLS: Record<CheckStatus, string>","lines: string[]","parts: string[]","checks: CheckResult[]","result: DoctorResult","parts: string[]","files: string[]","targetPatterns: readonly string[]","excludePatterns: readonly string[]","data: FormatData","data","unformatted: string[]","createdPaths: string[]","formatSuccess","files: FileToGenerate[]","lines: string[]","data: TypegenSuccessData","cliErrorHints: Partial<Record<CliErrorCode, string>>","codegenErrorHints: Record<string, string>","configErrorHints: Record<string, string>","artifactErrorHints: Record<string, string>","typegenErrorHints: Record<string, string>","lines: string[]"],"sources":["../src/errors.ts","../src/commands/artifact/build.ts","../src/commands/artifact/validate.ts","../src/commands/artifact/index.ts","../src/schemas/args.ts","../src/utils/parse-args.ts","../src/commands/codegen.ts","../src/commands/doctor/checks/codegen-freshness.ts","../src/commands/doctor/checks/config-validation.ts","../src/commands/doctor/discovery.ts","../src/commands/doctor/checks/duplicate-packages.ts","../src/commands/doctor/checks/version-consistency.ts","../src/commands/doctor/output.ts","../src/commands/doctor/index.ts","../src/commands/format.ts","../src/templates/config.template.ts","../src/templates/gitignore.template.ts","../src/templates/inject.template.ts","../src/templates/schema.template.ts","../src/commands/init.ts","../src/commands/typegen.ts","../src/utils/format.ts","../src/index.ts"],"sourcesContent":["/**\n * Unified CLI error types and constructors.\n * @module\n */\n\nimport type { ArtifactLoadError, BuilderError } from \"@soda-gql/builder\";\nimport type { CodegenError } from \"@soda-gql/codegen\";\nimport type { ConfigError } from \"@soda-gql/config\";\nimport type { TypegenError } from \"@soda-gql/typegen\";\nimport { err, type Result } from \"neverthrow\";\n\n/**\n * CLI-specific error codes.\n */\nexport type CliErrorCode =\n // Argument parsing errors\n | \"CLI_ARGS_INVALID\"\n | \"CLI_UNKNOWN_COMMAND\"\n | \"CLI_UNKNOWN_SUBCOMMAND\"\n // File operation errors\n | \"CLI_FILE_EXISTS\"\n | \"CLI_FILE_NOT_FOUND\"\n | \"CLI_WRITE_FAILED\"\n | \"CLI_READ_FAILED\"\n // Format command specific\n | \"CLI_NO_PATTERNS\"\n | \"CLI_FORMATTER_NOT_INSTALLED\"\n | \"CLI_PARSE_ERROR\"\n | \"CLI_FORMAT_ERROR\"\n // Unexpected errors\n | \"CLI_UNEXPECTED\";\n\n/**\n * Unified CLI error discriminated union.\n * Wraps external errors (codegen, builder, config, typegen) and defines CLI-specific errors.\n */\nexport type CliError =\n // Wrapped external errors (preserve original structure)\n | { readonly category: \"codegen\"; readonly error: CodegenError }\n | { readonly category: \"builder\"; readonly error: BuilderError }\n | { readonly category: \"artifact\"; readonly error: ArtifactLoadError }\n | { readonly category: \"config\"; readonly error: ConfigError }\n | { readonly category: \"typegen\"; readonly error: TypegenError }\n // CLI-specific errors\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_ARGS_INVALID\";\n readonly message: string;\n readonly command: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_UNKNOWN_COMMAND\";\n readonly message: string;\n readonly command: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_UNKNOWN_SUBCOMMAND\";\n readonly message: string;\n readonly parent: string;\n readonly subcommand: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FILE_EXISTS\";\n readonly message: string;\n readonly filePath: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FILE_NOT_FOUND\";\n readonly message: string;\n readonly filePath: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_WRITE_FAILED\";\n readonly message: string;\n readonly filePath: string;\n readonly cause?: unknown;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_READ_FAILED\";\n readonly message: string;\n readonly filePath: string;\n readonly cause?: unknown;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_NO_PATTERNS\";\n readonly message: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FORMATTER_NOT_INSTALLED\";\n readonly message: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_PARSE_ERROR\";\n readonly message: string;\n readonly filePath?: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FORMAT_ERROR\";\n readonly message: string;\n readonly filePath?: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_UNEXPECTED\";\n readonly message: string;\n readonly cause?: unknown;\n };\n\n/**\n * Result type for CLI operations.\n */\nexport type CliResult<T> = Result<T, CliError>;\n\n// Extract CLI-specific error types for type-safe constructors\ntype CliArgsInvalidError = Extract<CliError, { code: \"CLI_ARGS_INVALID\" }>;\ntype CliUnknownCommandError = Extract<CliError, { code: \"CLI_UNKNOWN_COMMAND\" }>;\ntype CliUnknownSubcommandError = Extract<CliError, { code: \"CLI_UNKNOWN_SUBCOMMAND\" }>;\ntype CliFileExistsError = Extract<CliError, { code: \"CLI_FILE_EXISTS\" }>;\ntype CliFileNotFoundError = Extract<CliError, { code: \"CLI_FILE_NOT_FOUND\" }>;\ntype CliWriteFailedError = Extract<CliError, { code: \"CLI_WRITE_FAILED\" }>;\ntype CliReadFailedError = Extract<CliError, { code: \"CLI_READ_FAILED\" }>;\ntype CliNoPatternsError = Extract<CliError, { code: \"CLI_NO_PATTERNS\" }>;\ntype CliFormatterNotInstalledError = Extract<CliError, { code: \"CLI_FORMATTER_NOT_INSTALLED\" }>;\ntype CliParseErrorError = Extract<CliError, { code: \"CLI_PARSE_ERROR\" }>;\ntype CliFormatErrorError = Extract<CliError, { code: \"CLI_FORMAT_ERROR\" }>;\ntype CliUnexpectedError = Extract<CliError, { code: \"CLI_UNEXPECTED\" }>;\ntype CliCodegenError = Extract<CliError, { category: \"codegen\" }>;\ntype CliBuilderError = Extract<CliError, { category: \"builder\" }>;\ntype CliArtifactError = Extract<CliError, { category: \"artifact\" }>;\ntype CliConfigError = Extract<CliError, { category: \"config\" }>;\ntype CliTypegenError = Extract<CliError, { category: \"typegen\" }>;\n\n/**\n * Error constructor helpers for concise error creation.\n * Each function returns a specific error type for better type inference.\n */\nexport const cliErrors = {\n argsInvalid: (command: string, message: string): CliArgsInvalidError => ({\n category: \"cli\",\n code: \"CLI_ARGS_INVALID\",\n message,\n command,\n }),\n\n unknownCommand: (command: string): CliUnknownCommandError => ({\n category: \"cli\",\n code: \"CLI_UNKNOWN_COMMAND\",\n message: `Unknown command: ${command}`,\n command,\n }),\n\n unknownSubcommand: (parent: string, subcommand: string): CliUnknownSubcommandError => ({\n category: \"cli\",\n code: \"CLI_UNKNOWN_SUBCOMMAND\",\n message: `Unknown subcommand: ${subcommand}`,\n parent,\n subcommand,\n }),\n\n fileExists: (filePath: string, message?: string): CliFileExistsError => ({\n category: \"cli\",\n code: \"CLI_FILE_EXISTS\",\n message: message ?? `File already exists: ${filePath}. Use --force to overwrite.`,\n filePath,\n }),\n\n fileNotFound: (filePath: string, message?: string): CliFileNotFoundError => ({\n category: \"cli\",\n code: \"CLI_FILE_NOT_FOUND\",\n message: message ?? `File not found: ${filePath}`,\n filePath,\n }),\n\n writeFailed: (filePath: string, message?: string, cause?: unknown): CliWriteFailedError => ({\n category: \"cli\",\n code: \"CLI_WRITE_FAILED\",\n message: message ?? `Failed to write file: ${filePath}`,\n filePath,\n cause,\n }),\n\n readFailed: (filePath: string, message?: string, cause?: unknown): CliReadFailedError => ({\n category: \"cli\",\n code: \"CLI_READ_FAILED\",\n message: message ?? `Failed to read file: ${filePath}`,\n filePath,\n cause,\n }),\n\n noPatterns: (message?: string): CliNoPatternsError => ({\n category: \"cli\",\n code: \"CLI_NO_PATTERNS\",\n message: message ?? \"No patterns provided and config not found. Usage: soda-gql format [patterns...] [--check]\",\n }),\n\n formatterNotInstalled: (message?: string): CliFormatterNotInstalledError => ({\n category: \"cli\",\n code: \"CLI_FORMATTER_NOT_INSTALLED\",\n message: message ?? \"@soda-gql/formatter is not installed. Run: bun add @soda-gql/formatter\",\n }),\n\n parseError: (message: string, filePath?: string): CliParseErrorError => ({\n category: \"cli\",\n code: \"CLI_PARSE_ERROR\",\n message,\n filePath,\n }),\n\n formatError: (message: string, filePath?: string): CliFormatErrorError => ({\n category: \"cli\",\n code: \"CLI_FORMAT_ERROR\",\n message,\n filePath,\n }),\n\n unexpected: (message: string, cause?: unknown): CliUnexpectedError => ({\n category: \"cli\",\n code: \"CLI_UNEXPECTED\",\n message,\n cause,\n }),\n\n // Wrappers for external errors\n fromCodegen: (error: CodegenError): CliCodegenError => ({\n category: \"codegen\",\n error,\n }),\n\n fromBuilder: (error: BuilderError): CliBuilderError => ({\n category: \"builder\",\n error,\n }),\n\n fromArtifact: (error: ArtifactLoadError): CliArtifactError => ({\n category: \"artifact\",\n error,\n }),\n\n fromConfig: (error: ConfigError): CliConfigError => ({\n category: \"config\",\n error,\n }),\n\n fromTypegen: (error: TypegenError): CliTypegenError => ({\n category: \"typegen\",\n error,\n }),\n} as const;\n\n/**\n * Convenience helper to create an err Result from CliError.\n */\nexport const cliErr = <T = never>(error: CliError): CliResult<T> => err(error);\n\n/**\n * Type guard to check if error is a CLI-specific error.\n */\nexport const isCliError = (error: CliError): error is CliError & { category: \"cli\" } => {\n return error.category === \"cli\";\n};\n\n/**\n * Extract error code from any CliError variant.\n */\nexport const getErrorCode = (error: CliError): string => {\n if (error.category === \"cli\") {\n return error.code;\n }\n // codegen, builder, artifact, config all have error.code\n return error.error.code;\n};\n\n/**\n * Extract error message from any CliError variant.\n */\nexport const getErrorMessage = (error: CliError): string => {\n if (error.category === \"cli\") {\n return error.message;\n }\n return error.error.message;\n};\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport type { BuilderArtifact, BuilderArtifactMeta } from \"@soda-gql/builder\";\nimport { createBuilderService } from \"@soda-gql/builder\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\n\nconst BUILD_HELP = `Usage: soda-gql artifact build [options]\n\nBuild and validate soda-gql artifacts.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --output, -o Output file path (default: ./soda-gql-artifact.json)\n --version, -v Custom version string for the artifact (default: package version)\n --dry-run Validate only, don't write output\n --help, -h Show this help message\n\nExamples:\n soda-gql artifact build\n soda-gql artifact build --output ./dist/artifact.json\n soda-gql artifact build --version \"1.0.0\"\n soda-gql artifact build --dry-run\n soda-gql artifact build --config ./soda-gql.config.ts\n`;\n\ntype BuildArgs = {\n configPath?: string;\n outputPath: string;\n version?: string;\n dryRun: boolean;\n help: boolean;\n};\n\nconst DEFAULT_OUTPUT_PATH = \"./soda-gql-artifact.json\";\n\n/**\n * Parse build command arguments.\n */\nconst parseBuildArgs = (argv: readonly string[]): BuildArgs => {\n const args: BuildArgs = {\n configPath: undefined,\n outputPath: DEFAULT_OUTPUT_PATH,\n version: undefined,\n dryRun: false,\n help: false,\n };\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--config\" || arg === \"-c\") {\n args.configPath = argv[++i];\n } else if (arg === \"--output\" || arg === \"-o\") {\n args.outputPath = argv[++i] ?? DEFAULT_OUTPUT_PATH;\n } else if (arg === \"--version\" || arg === \"-v\") {\n args.version = argv[++i];\n } else if (arg === \"--dry-run\") {\n args.dryRun = true;\n } else if (arg === \"--help\" || arg === \"-h\") {\n args.help = true;\n }\n }\n\n return args;\n};\n\ntype BuildData = {\n artifact: BuilderArtifact;\n outputPath?: string;\n dryRun: boolean;\n};\n\nconst formatSuccess = (data: BuildData): string => {\n const { artifact, outputPath, dryRun } = data;\n const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === \"fragment\").length;\n const operationCount = Object.values(artifact.elements).filter((e) => e.type === \"operation\").length;\n\n const lines: string[] = [];\n if (dryRun) {\n lines.push(`Validation passed: ${fragmentCount} fragments, ${operationCount} operations`);\n } else {\n lines.push(`Build complete: ${fragmentCount} fragments, ${operationCount} operations`);\n }\n\n if (artifact.meta?.version) {\n lines.push(` Version: ${artifact.meta.version}`);\n }\n\n if (outputPath && !dryRun) {\n lines.push(`Artifact written to: ${outputPath}`);\n }\n\n return lines.join(\"\\n\");\n};\n\ntype BuildCommandResult = CommandResult<CommandSuccess & { data?: BuildData }>;\n\n/**\n * Build command - builds and validates soda-gql artifacts.\n */\nexport const buildCommand = async (argv: readonly string[]): Promise<BuildCommandResult> => {\n const args = parseBuildArgs(argv);\n\n if (args.help) {\n return ok({ message: BUILD_HELP });\n }\n\n // Load config\n const configResult = loadConfig(args.configPath);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Create builder service and build\n const service = createBuilderService({ config });\n const buildResult = await service.buildAsync();\n\n if (buildResult.isErr()) {\n return err(cliErrors.fromBuilder(buildResult.error));\n }\n\n const artifact = buildResult.value;\n\n // Create artifact with metadata (only if version is specified)\n const meta: BuilderArtifactMeta | undefined = args.version\n ? {\n version: args.version,\n createdAt: new Date().toISOString(),\n }\n : undefined;\n const artifactWithMeta: BuilderArtifact = {\n ...(meta ? { meta } : {}),\n ...artifact,\n };\n\n if (args.dryRun) {\n const data: BuildData = { artifact: artifactWithMeta, dryRun: true };\n return ok({ message: formatSuccess(data), data });\n }\n\n // Write artifact to output file\n const outputPath = resolve(process.cwd(), args.outputPath);\n const outputDir = dirname(outputPath);\n try {\n await mkdir(outputDir, { recursive: true });\n await writeFile(outputPath, JSON.stringify(artifactWithMeta, null, 2));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return err(cliErrors.writeFailed(outputPath, `Failed to write artifact: ${message}`, error));\n }\n\n const data: BuildData = { artifact: artifactWithMeta, outputPath, dryRun: false };\n return ok({ message: formatSuccess(data), data });\n};\n","import { resolve } from \"node:path\";\nimport type { BuilderArtifact } from \"@soda-gql/builder\";\nimport { loadArtifact } from \"@soda-gql/builder\";\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\n\nconst VALIDATE_HELP = `Usage: soda-gql artifact validate [options] <path>\n\nValidate a pre-built soda-gql artifact file.\n\nArguments:\n <path> Path to artifact JSON file\n\nOptions:\n --help, -h Show this help message\n\nExamples:\n soda-gql artifact validate ./soda-gql-artifact.json\n soda-gql artifact validate ./dist/artifact.json\n`;\n\ntype ValidateArgs = {\n artifactPath?: string;\n help: boolean;\n};\n\n/**\n * Parse validate command arguments.\n */\nconst parseValidateArgs = (argv: readonly string[]): ValidateArgs => {\n const args: ValidateArgs = {\n artifactPath: undefined,\n help: false,\n };\n\n for (const arg of argv) {\n if (arg === \"--help\" || arg === \"-h\") {\n args.help = true;\n } else if (!arg.startsWith(\"-\")) {\n args.artifactPath = arg;\n }\n }\n\n return args;\n};\n\nconst formatSuccess = (artifact: BuilderArtifact): string => {\n const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === \"fragment\").length;\n const operationCount = Object.values(artifact.elements).filter((e) => e.type === \"operation\").length;\n const lines: string[] = [`Artifact valid: ${fragmentCount} fragments, ${operationCount} operations`];\n\n if (artifact.meta) {\n lines.push(` Version: ${artifact.meta.version}`);\n lines.push(` Created: ${artifact.meta.createdAt}`);\n } else {\n lines.push(` (No metadata - legacy artifact format)`);\n }\n\n return lines.join(\"\\n\");\n};\n\ntype ValidateCommandResult = CommandResult<CommandSuccess & { data?: BuilderArtifact }>;\n\n/**\n * Validate command - validates a pre-built artifact file.\n */\nexport const validateCommand = async (argv: readonly string[]): Promise<ValidateCommandResult> => {\n const args = parseValidateArgs(argv);\n\n if (args.help) {\n return ok({ message: VALIDATE_HELP });\n }\n\n if (!args.artifactPath) {\n return err(cliErrors.argsInvalid(\"artifact validate\", \"Missing artifact path argument\"));\n }\n\n const artifactPath = resolve(process.cwd(), args.artifactPath);\n const result = await loadArtifact(artifactPath);\n\n if (result.isErr()) {\n return err(cliErrors.fromArtifact(result.error));\n }\n\n return ok({ message: formatSuccess(result.value), data: result.value });\n};\n","import { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { buildCommand } from \"./build\";\nimport { validateCommand } from \"./validate\";\n\nconst ARTIFACT_HELP = `Usage: soda-gql artifact <subcommand> [options]\n\nManage soda-gql artifacts.\n\nSubcommands:\n build Build artifacts (validate definitions)\n validate Validate a pre-built artifact file\n\nRun 'soda-gql artifact <subcommand> --help' for more information.\n`;\n\ntype ArtifactCommandResult = CommandResult<CommandSuccess>;\n\n/**\n * Dispatcher for artifact subcommands.\n */\nexport const artifactCommand = async (argv: readonly string[]): Promise<ArtifactCommandResult> => {\n const [subcommand, ...rest] = argv;\n\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\") {\n return ok({ message: ARTIFACT_HELP });\n }\n\n if (subcommand === \"build\") {\n return buildCommand(rest);\n }\n\n if (subcommand === \"validate\") {\n return validateCommand(rest);\n }\n\n return err(cliErrors.unknownSubcommand(\"artifact\", subcommand));\n};\n","import { z } from \"zod\";\n\nexport const CodegenArgsSchema = z.object({\n config: z.string().optional(),\n \"emit-inject-template\": z.string().optional(),\n});\n\nexport const BuilderArgsSchema = z.object({\n mode: z.enum([\"runtime\", \"zero-runtime\"]),\n entry: z.string(),\n out: z.string(),\n format: z.enum([\"human\", \"json\"]).optional().default(\"human\"),\n});\n\nexport const FormatArgsSchema = z.object({\n _: z.array(z.string()).optional(),\n config: z.string().optional(),\n check: z.boolean().optional(),\n \"inject-fragment-keys\": z.boolean().optional(),\n});\n\nexport const InitArgsSchema = z.object({\n force: z.boolean().optional(),\n});\n\nexport const TypegenArgsSchema = z.object({\n config: z.string().optional(),\n});\n\nexport type CodegenArgs = z.infer<typeof CodegenArgsSchema>;\nexport type BuilderArgs = z.infer<typeof BuilderArgsSchema>;\nexport type FormatArgs = z.infer<typeof FormatArgsSchema>;\nexport type InitArgs = z.infer<typeof InitArgsSchema>;\nexport type TypegenArgs = z.infer<typeof TypegenArgsSchema>;\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { z } from \"zod\";\n\nexport const parseArgs = <T extends z.ZodType>(args: string[], schema: T): Result<z.infer<T>, string> => {\n const parsed: Record<string, unknown> = {};\n const positional: string[] = [];\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (!arg) continue;\n\n if (arg.startsWith(\"--\")) {\n const key = arg.slice(2);\n const nextArg = args[i + 1];\n\n if (!nextArg || nextArg.startsWith(\"--\")) {\n parsed[key] = true;\n } else {\n parsed[key] = nextArg;\n i++;\n }\n } else {\n positional.push(arg);\n }\n }\n\n if (positional.length > 0) {\n parsed._ = positional;\n }\n\n const result = schema.safeParse(parsed);\n if (!result.success) {\n return err(result.error.issues.map((e) => e.message).join(\", \"));\n }\n\n return ok(result.data);\n};\n","import { resolve } from \"node:path\";\nimport type { CodegenSchemaConfig, CodegenSuccess } from \"@soda-gql/codegen\";\nimport { runCodegen, writeInjectTemplate } from \"@soda-gql/codegen\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { type CliResult, cliErrors } from \"../errors\";\nimport { CodegenArgsSchema } from \"../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype ParsedCommand =\n | {\n kind: \"emitInjectTemplate\";\n outPath: string;\n }\n | {\n kind: \"generate\";\n schemas: Record<string, CodegenSchemaConfig>;\n outPath: string;\n importExtension: boolean;\n };\n\nconst parseCodegenArgs = (argv: readonly string[]): CliResult<ParsedCommand> => {\n const parsed = parseArgs([...argv], CodegenArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"codegen\", parsed.error));\n }\n\n const args = parsed.value;\n\n // Handle emit inject template\n if (args[\"emit-inject-template\"]) {\n return ok({\n kind: \"emitInjectTemplate\",\n outPath: args[\"emit-inject-template\"],\n });\n }\n\n // Load config from @soda-gql/config\n const configResult = loadConfig(args.config);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Check if schemas config exists\n if (!config.schemas || Object.keys(config.schemas).length === 0) {\n return err(cliErrors.argsInvalid(\"codegen\", \"schemas configuration is required in soda-gql.config.ts\"));\n }\n\n // Build schemas config with resolved paths\n const schemas: Record<string, CodegenSchemaConfig> = {};\n\n for (const [name, schemaConfig] of Object.entries(config.schemas)) {\n schemas[name] = {\n schema: schemaConfig.schema,\n inject: schemaConfig.inject,\n defaultInputDepth: schemaConfig.defaultInputDepth,\n inputDepthOverrides: schemaConfig.inputDepthOverrides,\n };\n }\n\n // Derive output path from outdir (default to index.ts)\n const outPath = resolve(config.outdir, \"index.ts\");\n\n return ok({\n kind: \"generate\",\n schemas,\n outPath,\n importExtension: config.styles.importExtension,\n });\n};\n\nconst formatSuccess = (success: CodegenSuccess): string => {\n const schemaNames = Object.keys(success.schemas).join(\", \");\n const totalObjects = Object.values(success.schemas).reduce((sum, s) => sum + s.objects, 0);\n return `Generated ${totalObjects} objects from schemas: ${schemaNames}\\n TypeScript: ${success.outPath}\\n CommonJS: ${success.cjsPath}`;\n};\n\nconst formatTemplateSuccess = (outPath: string): string => {\n return `Created inject template → ${outPath}`;\n};\n\nconst CODEGEN_HELP = `Usage: soda-gql codegen [options]\n\nGenerate graphql-system runtime module from GraphQL schema.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --emit-inject-template <path> Create inject template file\n --help, -h Show this help message\n\nExamples:\n soda-gql codegen\n soda-gql codegen --config ./soda-gql.config.ts\n soda-gql codegen --emit-inject-template ./src/graphql/scalars.ts\n\nNote: Run 'soda-gql typegen' after codegen to generate prebuilt types.\n`;\n\ntype CodegenCommandResult = CommandResult<CommandSuccess & { data?: CodegenSuccess }>;\n\nexport const codegenCommand = async (argv: readonly string[]): Promise<CodegenCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: CODEGEN_HELP });\n }\n\n const parsed = parseCodegenArgs(argv);\n\n if (parsed.isErr()) {\n return err(parsed.error);\n }\n\n const command = parsed.value;\n\n if (command.kind === \"emitInjectTemplate\") {\n const outPath = resolve(command.outPath);\n const result = writeInjectTemplate(outPath);\n if (result.isErr()) {\n return err(cliErrors.fromCodegen(result.error));\n }\n return ok({ message: formatTemplateSuccess(outPath) });\n }\n\n // Resolve all paths in schemas config\n const resolvedSchemas: Record<string, CodegenSchemaConfig> = {};\n for (const [name, schemaConfig] of Object.entries(command.schemas)) {\n resolvedSchemas[name] = {\n schema: schemaConfig.schema.map((s) => resolve(s)),\n inject: {\n scalars: resolve(schemaConfig.inject.scalars),\n ...(schemaConfig.inject.adapter ? { adapter: resolve(schemaConfig.inject.adapter) } : {}),\n },\n defaultInputDepth: schemaConfig.defaultInputDepth,\n inputDepthOverrides: schemaConfig.inputDepthOverrides,\n };\n }\n\n const result = await runCodegen({\n schemas: resolvedSchemas,\n outPath: resolve(command.outPath),\n format: \"human\",\n importExtension: command.importExtension,\n });\n\n if (result.isErr()) {\n return err(cliErrors.fromCodegen(result.error));\n }\n\n return ok({ message: formatSuccess(result.value), data: result.value });\n};\n","/**\n * Codegen freshness check.\n * @module\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findConfigFile, loadConfig } from \"@soda-gql/config\";\nimport type { CheckResult, CodegenFreshnessData } from \"../types\";\n\n/**\n * Check if generated code is newer than schema files.\n */\nexport const checkCodegenFreshness = (): CheckResult<CodegenFreshnessData> => {\n const configPath = findConfigFile();\n\n if (!configPath) {\n return {\n name: \"Codegen Freshness\",\n status: \"skip\",\n message: \"No soda-gql.config.ts found\",\n data: { schemas: [] },\n };\n }\n\n const configResult = loadConfig(configPath);\n\n if (configResult.isErr()) {\n return {\n name: \"Codegen Freshness\",\n status: \"skip\",\n message: \"Could not load config\",\n data: { schemas: [] },\n };\n }\n\n const config = configResult.value;\n const generatedPath = join(config.outdir, \"index.ts\");\n\n if (!existsSync(generatedPath)) {\n return {\n name: \"Codegen Freshness\",\n status: \"warn\",\n message: \"Generated code not found - run codegen\",\n data: { schemas: [] },\n fix: \"Run: soda-gql codegen\",\n };\n }\n\n const generatedStat = statSync(generatedPath);\n const generatedMtime = generatedStat.mtimeMs;\n\n const schemaResults: CodegenFreshnessData[\"schemas\"][number][] = [];\n let hasStale = false;\n\n for (const [name, schemaConfig] of Object.entries(config.schemas)) {\n // Get the latest mtime from all schema files\n let maxSchemaMtime = 0;\n const existingPaths: string[] = [];\n\n for (const schemaPath of schemaConfig.schema) {\n if (!existsSync(schemaPath)) {\n continue; // Handled by config validation check\n }\n existingPaths.push(schemaPath);\n const schemaStat = statSync(schemaPath);\n maxSchemaMtime = Math.max(maxSchemaMtime, schemaStat.mtimeMs);\n }\n\n // Skip if no schema files exist\n if (existingPaths.length === 0) {\n continue;\n }\n\n const isStale = maxSchemaMtime > generatedMtime;\n if (isStale) hasStale = true;\n\n schemaResults.push({\n name,\n schemaPath: existingPaths.join(\", \"),\n generatedPath,\n schemaMtime: maxSchemaMtime,\n generatedMtime,\n isStale,\n });\n }\n\n if (hasStale) {\n const staleSchemas = schemaResults.filter((s) => s.isStale);\n return {\n name: \"Codegen Freshness\",\n status: \"warn\",\n message: `Schema modified after codegen: ${staleSchemas.map((s) => s.name).join(\", \")}`,\n data: { schemas: schemaResults },\n fix: \"Run: soda-gql codegen\",\n };\n }\n\n return {\n name: \"Codegen Freshness\",\n status: \"pass\",\n message: \"Generated code is up to date\",\n data: { schemas: schemaResults },\n };\n};\n","/**\n * Config validation check.\n * @module\n */\n\nimport { existsSync } from \"node:fs\";\nimport { findConfigFile, loadConfig } from \"@soda-gql/config\";\nimport type { CheckResult, ConfigValidationData } from \"../types\";\n\n/**\n * Check that config file is valid and referenced files exist.\n */\nexport const checkConfigValidation = (): CheckResult<ConfigValidationData> => {\n const configPath = findConfigFile();\n\n if (!configPath) {\n return {\n name: \"Config Validation\",\n status: \"skip\",\n message: \"No soda-gql.config.ts found\",\n data: { configPath: null, missingFiles: [] },\n };\n }\n\n const configResult = loadConfig(configPath);\n\n if (configResult.isErr()) {\n return {\n name: \"Config Validation\",\n status: \"fail\",\n message: `Config error: ${configResult.error.message}`,\n data: { configPath, missingFiles: [] },\n fix: \"Check your soda-gql.config.ts for syntax errors\",\n };\n }\n\n const config = configResult.value;\n const missingFiles: string[] = [];\n\n // Check schema files exist\n for (const [name, schemaConfig] of Object.entries(config.schemas)) {\n for (const schemaPath of schemaConfig.schema) {\n if (!existsSync(schemaPath)) {\n missingFiles.push(`Schema '${name}': ${schemaPath}`);\n }\n }\n if (!existsSync(schemaConfig.inject.scalars)) {\n missingFiles.push(`Scalars '${name}': ${schemaConfig.inject.scalars}`);\n }\n if (schemaConfig.inject.adapter && !existsSync(schemaConfig.inject.adapter)) {\n missingFiles.push(`Adapter '${name}': ${schemaConfig.inject.adapter}`);\n }\n }\n\n if (missingFiles.length > 0) {\n return {\n name: \"Config Validation\",\n status: \"fail\",\n message: `${missingFiles.length} referenced file(s) not found`,\n data: { configPath, missingFiles },\n fix: \"Create the missing files or update paths in config\",\n };\n }\n\n return {\n name: \"Config Validation\",\n status: \"pass\",\n message: \"Config loaded successfully\",\n data: { configPath, missingFiles: [] },\n };\n};\n","/**\n * Package discovery utilities for doctor command.\n * @module\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport type { DiscoveredPackage } from \"./types\";\n\nconst SODA_GQL_SCOPE = \"@soda-gql\";\n\n/**\n * Find the nearest node_modules directory.\n */\nexport const findNodeModules = (startDir: string = process.cwd()): string | null => {\n let currentDir = startDir;\n while (currentDir !== dirname(currentDir)) {\n const nodeModulesPath = join(currentDir, \"node_modules\");\n if (existsSync(nodeModulesPath) && statSync(nodeModulesPath).isDirectory()) {\n return nodeModulesPath;\n }\n currentDir = dirname(currentDir);\n }\n return null;\n};\n\n/**\n * Read package.json from a directory.\n */\nconst readPackageJson = (dir: string): Result<{ name: string; version: string }, string> => {\n const packageJsonPath = join(dir, \"package.json\");\n try {\n const content = readFileSync(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { name?: string; version?: string };\n if (!pkg.name || !pkg.version) {\n return err(`Invalid package.json at ${packageJsonPath}`);\n }\n return ok({ name: pkg.name, version: pkg.version });\n } catch {\n return err(`Failed to read package.json at ${packageJsonPath}`);\n }\n};\n\n/**\n * Discover @soda-gql packages at a specific node_modules path.\n */\nconst discoverAtPath = (nodeModulesPath: string): DiscoveredPackage[] => {\n const scopePath = join(nodeModulesPath, SODA_GQL_SCOPE);\n if (!existsSync(scopePath)) {\n return [];\n }\n\n const packages: DiscoveredPackage[] = [];\n\n try {\n const entries = readdirSync(scopePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const packageDir = join(scopePath, entry.name);\n const result = readPackageJson(packageDir);\n\n if (result.isOk()) {\n packages.push({\n name: result.value.name,\n version: result.value.version,\n path: packageDir,\n });\n }\n }\n } catch {\n // Ignore read errors\n }\n\n return packages;\n};\n\n/**\n * Discover all @soda-gql packages including nested node_modules.\n * Uses breadth-first search to avoid deep recursion.\n */\nexport const discoverAllSodaGqlPackages = (startDir: string = process.cwd()): Result<DiscoveredPackage[], string> => {\n const rootNodeModules = findNodeModules(startDir);\n if (!rootNodeModules) {\n return err(\"No node_modules directory found\");\n }\n\n const allPackages: DiscoveredPackage[] = [];\n const visitedPaths = new Set<string>();\n const queue: string[] = [rootNodeModules];\n\n while (queue.length > 0) {\n const nodeModulesPath = queue.shift();\n if (!nodeModulesPath) continue;\n\n // Resolve to handle symlinks\n let realPath: string;\n try {\n realPath = resolve(nodeModulesPath);\n } catch {\n continue;\n }\n\n if (visitedPaths.has(realPath)) continue;\n visitedPaths.add(realPath);\n\n // Discover packages at this level\n const packages = discoverAtPath(nodeModulesPath);\n allPackages.push(...packages);\n\n // Look for nested node_modules\n try {\n const entries = readdirSync(nodeModulesPath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n // Check scoped packages\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = join(nodeModulesPath, entry.name);\n try {\n const scopeEntries = readdirSync(scopeDir, { withFileTypes: true });\n\n for (const scopeEntry of scopeEntries) {\n if (!scopeEntry.isDirectory()) continue;\n const nestedNodeModules = join(scopeDir, scopeEntry.name, \"node_modules\");\n if (existsSync(nestedNodeModules)) {\n queue.push(nestedNodeModules);\n }\n }\n } catch {\n // Ignore read errors\n }\n } else {\n // Check regular packages\n const nestedNodeModules = join(nodeModulesPath, entry.name, \"node_modules\");\n if (existsSync(nestedNodeModules)) {\n queue.push(nestedNodeModules);\n }\n }\n }\n } catch {\n // Ignore read errors\n }\n }\n\n return ok(allPackages);\n};\n\n/**\n * Get the soda-gql CLI version.\n */\nexport const getCliVersion = (): string => {\n try {\n // Navigate from this file (commands/doctor/discovery.ts) to package.json\n // Path: discovery.ts -> doctor/ -> commands/ -> src/ -> cli/package.json\n const cliPackageJsonPath = join(import.meta.dirname, \"..\", \"..\", \"..\", \"package.json\");\n const content = readFileSync(cliPackageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { version?: string };\n return pkg.version ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n};\n\n/**\n * Get TypeScript version from node_modules.\n */\nexport const getTypescriptVersion = (startDir: string = process.cwd()): string | null => {\n const nodeModulesPath = findNodeModules(startDir);\n if (!nodeModulesPath) return null;\n\n const tsPackageJson = join(nodeModulesPath, \"typescript\", \"package.json\");\n try {\n const content = readFileSync(tsPackageJson, \"utf-8\");\n const pkg = JSON.parse(content) as { version?: string };\n return pkg.version ?? null;\n } catch {\n return null;\n }\n};\n","/**\n * Duplicate packages check.\n * @module\n */\n\nimport { discoverAllSodaGqlPackages } from \"../discovery\";\nimport type { CheckResult, DuplicatePackageData } from \"../types\";\n\n/**\n * Check for duplicate @soda-gql packages installed at different paths.\n */\nexport const checkDuplicatePackages = (): CheckResult<DuplicatePackageData> => {\n const packagesResult = discoverAllSodaGqlPackages();\n\n if (packagesResult.isErr()) {\n return {\n name: \"Duplicate Packages\",\n status: \"skip\",\n message: packagesResult.error,\n data: { duplicates: [] },\n };\n }\n\n const packages = packagesResult.value;\n\n // Group by package name\n const byName = new Map<string, typeof packages>();\n for (const pkg of packages) {\n const existing = byName.get(pkg.name) ?? [];\n existing.push(pkg);\n byName.set(pkg.name, existing);\n }\n\n // Find duplicates (same name, multiple paths)\n const duplicates: DuplicatePackageData[\"duplicates\"][number][] = [];\n for (const [name, instances] of byName) {\n if (instances.length > 1) {\n duplicates.push({\n name,\n instances: instances.map((i) => ({\n path: i.path,\n version: i.version,\n })),\n });\n }\n }\n\n if (duplicates.length === 0) {\n return {\n name: \"Duplicate Packages\",\n status: \"pass\",\n message: \"No duplicate packages detected\",\n data: { duplicates: [] },\n };\n }\n\n const duplicateNames = duplicates.map((d) => d.name).join(\", \");\n return {\n name: \"Duplicate Packages\",\n status: \"warn\",\n message: `Duplicate packages found: ${duplicateNames}`,\n data: { duplicates },\n fix: \"Run: rm -rf node_modules && bun install\",\n };\n};\n","/**\n * Version consistency check.\n * @module\n */\n\nimport { discoverAllSodaGqlPackages } from \"../discovery\";\nimport type { CheckResult, VersionConsistencyData } from \"../types\";\n\n/**\n * Check that all @soda-gql packages have consistent versions.\n */\nexport const checkVersionConsistency = (): CheckResult<VersionConsistencyData> => {\n const packagesResult = discoverAllSodaGqlPackages();\n\n if (packagesResult.isErr()) {\n return {\n name: \"Version Consistency\",\n status: \"skip\",\n message: packagesResult.error,\n data: { packages: [], expectedVersion: null },\n };\n }\n\n const packages = packagesResult.value;\n\n if (packages.length === 0) {\n return {\n name: \"Version Consistency\",\n status: \"skip\",\n message: \"No @soda-gql packages found\",\n data: { packages: [], expectedVersion: null },\n };\n }\n\n // Group by package name (to handle duplicates separately)\n const byName = new Map<string, typeof packages>();\n for (const pkg of packages) {\n const existing = byName.get(pkg.name) ?? [];\n existing.push(pkg);\n byName.set(pkg.name, existing);\n }\n\n // Get unique packages (first instance of each)\n const uniquePackages = Array.from(byName.values())\n .map((instances) => instances[0])\n .filter((pkg): pkg is (typeof packages)[number] => pkg !== undefined);\n\n // Determine expected version (most common version)\n const versionCounts = new Map<string, number>();\n for (const pkg of uniquePackages) {\n versionCounts.set(pkg.version, (versionCounts.get(pkg.version) ?? 0) + 1);\n }\n\n let expectedVersion = uniquePackages[0]?.version ?? null;\n let maxCount = 0;\n for (const [version, count] of versionCounts) {\n if (count > maxCount) {\n maxCount = count;\n expectedVersion = version;\n }\n }\n\n // Find mismatches\n const packageResults = uniquePackages.map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n path: pkg.path,\n isMismatch: pkg.version !== expectedVersion,\n }));\n\n const mismatches = packageResults.filter((p) => p.isMismatch);\n\n if (mismatches.length === 0) {\n return {\n name: \"Version Consistency\",\n status: \"pass\",\n message: `All ${uniquePackages.length} packages at version ${expectedVersion}`,\n data: { packages: packageResults, expectedVersion },\n };\n }\n\n const mismatchNames = mismatches.map((p) => p.name).join(\", \");\n return {\n name: \"Version Consistency\",\n status: \"fail\",\n message: `Version mismatch: ${mismatchNames}`,\n data: { packages: packageResults, expectedVersion },\n fix: `Run: bun update ${mismatches.map((p) => p.name).join(\" \")}`,\n };\n};\n","/**\n * Doctor command output formatting.\n * @module\n */\n\nimport type { CheckResult, CheckStatus, DoctorResult, DuplicatePackageData, VersionConsistencyData } from \"./types\";\n\nconst STATUS_SYMBOLS: Record<CheckStatus, string> = {\n pass: \"\\u2713\", // checkmark\n warn: \"!\",\n fail: \"\\u2717\", // X\n skip: \"-\",\n};\n\n/**\n * Type guard to check if data is an object (not null/primitive).\n */\nconst isObject = (data: unknown): data is Record<string, unknown> => {\n return typeof data === \"object\" && data !== null;\n};\n\n/**\n * Format a single check result for human output.\n */\nconst formatCheckResult = (result: CheckResult): string[] => {\n const lines: string[] = [];\n const symbol = STATUS_SYMBOLS[result.status];\n\n lines.push(`${symbol} ${result.message}`);\n\n // Add detailed data for failures/warnings\n if (result.status === \"fail\" || result.status === \"warn\") {\n const data = result.data;\n\n // Version consistency details\n if (isObject(data) && \"packages\" in data && \"expectedVersion\" in data) {\n const versionData = data as VersionConsistencyData;\n const mismatched = versionData.packages.filter((p) => p.isMismatch);\n for (const pkg of mismatched) {\n lines.push(` ${pkg.name}: ${pkg.version} <- mismatch`);\n }\n if (versionData.expectedVersion && mismatched.length > 0) {\n lines.push(` Expected: ${versionData.expectedVersion}`);\n }\n }\n\n // Duplicate packages details\n if (isObject(data) && \"duplicates\" in data) {\n const dupData = data as DuplicatePackageData;\n for (const dup of dupData.duplicates) {\n lines.push(` ${dup.name}:`);\n for (const instance of dup.instances) {\n lines.push(` ${instance.version} at ${instance.path}`);\n }\n }\n }\n\n // Fix suggestion\n if (result.fix) {\n lines.push(\"\");\n lines.push(` Fix: ${result.fix}`);\n }\n }\n\n return lines;\n};\n\n/**\n * Format the complete doctor result for human output.\n */\nexport const formatDoctorResult = (result: DoctorResult): string => {\n const lines: string[] = [];\n\n lines.push(`soda-gql doctor v${result.version}`);\n lines.push(\"\");\n\n for (const check of result.checks) {\n lines.push(...formatCheckResult(check));\n lines.push(\"\");\n }\n\n // Summary\n const passed = result.checks.filter((c) => c.status === \"pass\").length;\n\n if (result.issueCount === 0 && result.warningCount === 0) {\n lines.push(`Summary: All ${passed} checks passed`);\n } else {\n const parts: string[] = [];\n if (result.issueCount > 0) {\n parts.push(`${result.issueCount} issue${result.issueCount > 1 ? \"s\" : \"\"}`);\n }\n if (result.warningCount > 0) {\n parts.push(`${result.warningCount} warning${result.warningCount > 1 ? \"s\" : \"\"}`);\n }\n lines.push(`Summary: ${parts.join(\", \")} found`);\n }\n\n return lines.join(\"\\n\");\n};\n","/**\n * Doctor command entry point.\n * @module\n */\n\nimport { ok } from \"neverthrow\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { checkCodegenFreshness } from \"./checks/codegen-freshness\";\nimport { checkConfigValidation } from \"./checks/config-validation\";\nimport { checkDuplicatePackages } from \"./checks/duplicate-packages\";\nimport { checkVersionConsistency } from \"./checks/version-consistency\";\nimport { getCliVersion, getTypescriptVersion } from \"./discovery\";\nimport { formatDoctorResult } from \"./output\";\nimport type { CheckResult, DoctorResult } from \"./types\";\n\nconst DOCTOR_HELP = `Usage: soda-gql doctor\n\nRun diagnostic checks on your soda-gql installation.\n\nChecks performed:\n - Version consistency across @soda-gql packages\n - Duplicate package detection\n - Config file validation\n - Codegen freshness (schema vs generated code)\n\nOptions:\n --help, -h Show this help message\n`;\n\ntype DoctorCommandResult = CommandResult<CommandSuccess & { data?: DoctorResult }>;\n\nexport const doctorCommand = (argv: readonly string[]): DoctorCommandResult => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: DOCTOR_HELP });\n }\n\n const version = getCliVersion();\n const tsVersion = getTypescriptVersion();\n\n // Run all checks\n const checks: CheckResult[] = [];\n\n // Add TypeScript version as informational\n if (tsVersion) {\n checks.push({\n name: \"TypeScript Version\",\n status: \"pass\",\n message: `TypeScript version: ${tsVersion}`,\n });\n }\n\n // Phase 1 checks\n checks.push(checkVersionConsistency());\n checks.push(checkDuplicatePackages());\n\n // Phase 2 checks\n checks.push(checkConfigValidation());\n checks.push(checkCodegenFreshness());\n\n // Calculate summary\n const issueCount = checks.filter((c) => c.status === \"fail\").length;\n const warningCount = checks.filter((c) => c.status === \"warn\").length;\n\n const result: DoctorResult = {\n version,\n checks,\n issueCount,\n warningCount,\n };\n\n const message = formatDoctorResult(result);\n\n return ok({ message, data: result });\n};\n","import { access, readFile, writeFile } from \"node:fs/promises\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport fg from \"fast-glob\";\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../errors\";\nimport { FormatArgsSchema } from \"../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype FormatterModule = typeof import(\"@soda-gql/formatter\");\n\nconst loadFormatter = async (): Promise<FormatterModule | null> => {\n try {\n return await import(\"@soda-gql/formatter\");\n } catch {\n return null;\n }\n};\n\ntype FormatData = {\n mode: \"format\" | \"check\";\n total: number;\n modified: number;\n unchanged: number;\n errors: number;\n unformatted: string[];\n hasFormattingIssues: boolean;\n};\n\nconst formatResultMessage = (data: FormatData): string => {\n if (data.mode === \"check\") {\n if (data.unformatted.length > 0) {\n const files = data.unformatted.map((f) => ` ${f}`).join(\"\\n\");\n return `${data.unformatted.length} file(s) need formatting:\\n${files}`;\n }\n return `All ${data.total} file(s) are properly formatted`;\n }\n\n const parts: string[] = [];\n if (data.modified > 0) {\n parts.push(`${data.modified} formatted`);\n }\n if (data.unchanged > 0) {\n parts.push(`${data.unchanged} unchanged`);\n }\n if (data.errors > 0) {\n parts.push(`${data.errors} errors`);\n }\n return `${data.total} file(s) checked: ${parts.join(\", \")}`;\n};\n\nconst isGlobPattern = (pattern: string): boolean => {\n return /[*?[\\]{}]/.test(pattern);\n};\n\nconst expandGlobPatterns = async (patterns: readonly string[], excludePatterns: readonly string[] = []): Promise<string[]> => {\n const files: string[] = [];\n\n for (const pattern of patterns) {\n if (!isGlobPattern(pattern)) {\n // Direct file path - check if it exists\n try {\n await access(pattern);\n files.push(pattern);\n } catch {\n // File doesn't exist, skip it\n }\n continue;\n }\n\n // Glob pattern - use fast-glob with ignore\n const matches = await fg(pattern, {\n absolute: true,\n ignore: [...excludePatterns],\n });\n files.push(...matches);\n }\n\n return [...new Set(files)];\n};\n\nconst FORMAT_HELP = `Usage: soda-gql format [patterns...] [options]\n\nFormat soda-gql field selections by inserting empty comments.\n\nOptions:\n --config <path> Path to soda-gql.config.ts (auto-detected if omitted)\n --check Check if files need formatting (exit 1 if unformatted)\n --inject-fragment-keys Inject unique keys into anonymous fragments\n --help, -h Show this help message\n\nExamples:\n soda-gql format # Use config include/exclude\n soda-gql format \"src/**/*.ts\" # Override with explicit patterns\n soda-gql format --check # Check mode with config\n soda-gql format --inject-fragment-keys # Inject fragment keys\n`;\n\ntype FormatCommandResult = CommandResult<CommandSuccess & { data?: FormatData }>;\n\nexport const formatCommand = async (argv: readonly string[]): Promise<FormatCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: FORMAT_HELP });\n }\n\n const parsed = parseArgs([...argv], FormatArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"format\", parsed.error));\n }\n\n const args = parsed.value;\n const isCheckMode = args.check === true;\n const injectFragmentKeys = args[\"inject-fragment-keys\"] === true;\n const explicitPatterns = args._ ?? [];\n\n // Determine patterns: use explicit patterns or load from config\n let targetPatterns: readonly string[];\n let excludePatterns: readonly string[] = [];\n\n if (explicitPatterns.length > 0) {\n targetPatterns = explicitPatterns;\n } else {\n // Try to load patterns from config\n const configResult = loadConfig(args.config);\n if (configResult.isErr()) {\n return err(cliErrors.noPatterns());\n }\n targetPatterns = configResult.value.include;\n excludePatterns = configResult.value.exclude;\n }\n\n // Load formatter lazily - it's an optional dependency\n const formatter = await loadFormatter();\n if (!formatter) {\n return err(cliErrors.formatterNotInstalled());\n }\n\n const files = await expandGlobPatterns(targetPatterns, excludePatterns);\n\n if (files.length === 0) {\n const data: FormatData = {\n mode: isCheckMode ? \"check\" : \"format\",\n total: 0,\n modified: 0,\n unchanged: 0,\n errors: 0,\n unformatted: [],\n hasFormattingIssues: false,\n };\n return ok({ message: formatResultMessage(data), data });\n }\n\n let modified = 0;\n let unchanged = 0;\n let errors = 0;\n const unformatted: string[] = [];\n\n for (const filePath of files) {\n const sourceCode = await readFile(filePath, \"utf-8\");\n\n if (isCheckMode) {\n const result = formatter.needsFormat({ sourceCode, filePath });\n if (result.isErr()) {\n errors++;\n continue;\n }\n if (result.value) {\n unformatted.push(filePath);\n modified++;\n } else {\n unchanged++;\n }\n } else {\n const result = formatter.format({ sourceCode, filePath, injectFragmentKeys });\n if (result.isErr()) {\n errors++;\n continue;\n }\n if (result.value.modified) {\n await writeFile(filePath, result.value.sourceCode, \"utf-8\");\n modified++;\n } else {\n unchanged++;\n }\n }\n }\n\n const data: FormatData = {\n mode: isCheckMode ? \"check\" : \"format\",\n total: files.length,\n modified,\n unchanged,\n errors,\n unformatted,\n hasFormattingIssues: (isCheckMode && unformatted.length > 0) || errors > 0,\n };\n\n return ok({ message: formatResultMessage(data), data });\n};\n","export const getConfigTemplate = (): string => `\\\nimport { defineConfig } from \"@soda-gql/config\";\n\nexport default defineConfig({\n outdir: \"./graphql-system\",\n include: [\"./src/**/*.ts\"],\n schemas: {\n default: {\n schema: \"./schema.graphql\",\n inject: \"./graphql-system/default.inject.ts\",\n },\n },\n});\n`;\n","export const getGitignoreTemplate = (): string => `\\\n/index.ts\n/index.cjs\n`;\n","export const getInjectTemplate = (): string => `\\\nimport { defineAdapter, defineScalar } from \"@soda-gql/core/adapter\";\n\nexport const scalar = {\n ...defineScalar<\"ID\", string, string>(\"ID\"),\n ...defineScalar<\"String\", string, string>(\"String\"),\n ...defineScalar<\"Int\", number, number>(\"Int\"),\n ...defineScalar<\"Float\", number, number>(\"Float\"),\n ...defineScalar<\"Boolean\", boolean, boolean>(\"Boolean\"),\n} as const;\n\nexport const adapter = defineAdapter({\n helpers: {},\n metadata: {\n aggregateFragmentMetadata: (fragments) => fragments.map((m) => m.metadata),\n },\n});\n`;\n","export const getSchemaTemplate = (): string => `\\\ntype Query {\n hello: String!\n}\n`;\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { err, ok, type Result } from \"neverthrow\";\n\nimport { type CliError, cliErrors } from \"../errors\";\nimport { InitArgsSchema } from \"../schemas/args\";\nimport { getConfigTemplate } from \"../templates/config.template\";\nimport { getGitignoreTemplate } from \"../templates/gitignore.template\";\nimport { getInjectTemplate } from \"../templates/inject.template\";\nimport { getSchemaTemplate } from \"../templates/schema.template\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype FileToGenerate = {\n readonly path: string;\n readonly content: string;\n readonly description: string;\n};\n\ntype InitSuccess = {\n readonly filesCreated: readonly string[];\n};\n\nconst INIT_HELP = `Usage: soda-gql init [options]\n\nInitialize a new soda-gql project with starter configuration.\n\nOptions:\n --force Overwrite existing files\n --help, -h Show this help message\n\nGenerated files:\n soda-gql.config.ts Configuration file\n schema.graphql Sample GraphQL schema\n graphql-system/default.inject.ts Scalars, helpers, and metadata adapter\n graphql-system/.gitignore Ignore generated files\n`;\n\nconst checkFilesExist = (files: readonly FileToGenerate[], force: boolean): Result<void, CliError> => {\n if (force) {\n return ok(undefined);\n }\n\n for (const file of files) {\n if (existsSync(file.path)) {\n return err(cliErrors.fileExists(file.path));\n }\n }\n\n return ok(undefined);\n};\n\nconst writeFiles = (files: readonly FileToGenerate[]): Result<InitSuccess, CliError> => {\n const createdPaths: string[] = [];\n\n for (const file of files) {\n try {\n const dir = dirname(file.path);\n mkdirSync(dir, { recursive: true });\n writeFileSync(file.path, file.content);\n createdPaths.push(file.path);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return err(cliErrors.writeFailed(file.path, `Failed to write ${file.description}: ${message}`, error));\n }\n }\n\n return ok({ filesCreated: createdPaths });\n};\n\nconst formatSuccess = (result: InitSuccess): string => {\n const lines = [\"soda-gql project initialized successfully!\", \"\", \"Created files:\"];\n for (const file of result.filesCreated) {\n lines.push(` ${file}`);\n }\n lines.push(\"\", \"Next steps:\");\n lines.push(\" 1. Edit schema.graphql with your GraphQL types\");\n lines.push(\" 2. Run: soda-gql codegen\");\n lines.push(\" 3. Import gql from ./graphql-system\");\n return lines.join(\"\\n\");\n};\n\ntype InitCommandResult = CommandResult<CommandSuccess & { data?: InitSuccess }>;\n\nexport const initCommand = async (argv: readonly string[]): Promise<InitCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: INIT_HELP });\n }\n\n const parsed = parseArgs([...argv], InitArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"init\", parsed.error));\n }\n\n const args = parsed.value;\n const force = args.force === true;\n const cwd = process.cwd();\n\n const files: FileToGenerate[] = [\n {\n path: resolve(cwd, \"soda-gql.config.ts\"),\n content: getConfigTemplate(),\n description: \"configuration file\",\n },\n {\n path: resolve(cwd, \"schema.graphql\"),\n content: getSchemaTemplate(),\n description: \"GraphQL schema\",\n },\n {\n path: resolve(cwd, \"graphql-system/default.inject.ts\"),\n content: getInjectTemplate(),\n description: \"inject module\",\n },\n {\n path: resolve(cwd, \"graphql-system/.gitignore\"),\n content: getGitignoreTemplate(),\n description: \"gitignore file\",\n },\n ];\n\n const existsCheck = checkFilesExist(files, force);\n if (existsCheck.isErr()) {\n return err(existsCheck.error);\n }\n\n const writeResult = writeFiles(files);\n if (writeResult.isErr()) {\n return err(writeResult.error);\n }\n\n return ok({ message: formatSuccess(writeResult.value), data: writeResult.value });\n};\n","import { loadConfig } from \"@soda-gql/config\";\nimport { runTypegen } from \"@soda-gql/typegen\";\nimport { err, ok } from \"neverthrow\";\nimport { type CliResult, cliErrors } from \"../errors\";\nimport { TypegenArgsSchema } from \"../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype ParsedCommand = {\n kind: \"generate\";\n configPath?: string;\n};\n\nconst parseTypegenArgs = (argv: readonly string[]): CliResult<ParsedCommand> => {\n const parsed = parseArgs([...argv], TypegenArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"typegen\", parsed.error));\n }\n\n return ok({\n kind: \"generate\",\n configPath: parsed.value.config,\n });\n};\n\ntype TypegenSuccessData = {\n prebuiltIndexPath: string;\n prebuiltTypesPath: string;\n fragmentCount: number;\n operationCount: number;\n warnings: readonly string[];\n};\n\nconst formatSuccess = (data: TypegenSuccessData): string => {\n const lines: string[] = [];\n lines.push(`Generated prebuilt types:`);\n lines.push(` Index: ${data.prebuiltIndexPath}`);\n lines.push(` Types: ${data.prebuiltTypesPath}`);\n lines.push(` Fragments: ${data.fragmentCount}, Operations: ${data.operationCount}`);\n\n if (data.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"Warnings:\");\n for (const warning of data.warnings) {\n lines.push(` ${warning}`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n\nconst TYPEGEN_HELP = `Usage: soda-gql typegen [options]\n\nGenerate prebuilt types from source code.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --help, -h Show this help message\n\nExamples:\n soda-gql typegen\n soda-gql typegen --config ./soda-gql.config.ts\n\nNote: Run 'soda-gql codegen' first to generate the graphql-system module.\n`;\n\ntype TypegenCommandResult = CommandResult<CommandSuccess & { data?: TypegenSuccessData }>;\n\nexport const typegenCommand = async (argv: readonly string[]): Promise<TypegenCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: TYPEGEN_HELP });\n }\n\n const parsed = parseTypegenArgs(argv);\n\n if (parsed.isErr()) {\n return err(parsed.error);\n }\n\n const command = parsed.value;\n\n // Load config from @soda-gql/config\n const configResult = loadConfig(command.configPath);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Run typegen\n const result = await runTypegen({\n config,\n });\n\n if (result.isErr()) {\n // Handle typegen-specific errors\n const error = result.error;\n if (error.code === \"TYPEGEN_CODEGEN_REQUIRED\") {\n return err(cliErrors.argsInvalid(\"typegen\", `${error.message}\\nRun 'soda-gql codegen' first.`));\n }\n return err(cliErrors.fromTypegen(error));\n }\n\n const data: TypegenSuccessData = {\n prebuiltIndexPath: result.value.prebuiltIndexPath,\n prebuiltTypesPath: result.value.prebuiltTypesPath,\n fragmentCount: result.value.fragmentCount,\n operationCount: result.value.operationCount,\n warnings: result.value.warnings,\n };\n\n return ok({ message: formatSuccess(data), data });\n};\n","import { formatBuilderErrorForCLI } from \"@soda-gql/builder\";\nimport type { CliError, CliErrorCode } from \"../errors\";\nimport type { OutputFormat } from \"../types\";\n\nexport type { OutputFormat } from \"../types\";\n\n/**\n * CLI-specific error hints to help users fix issues.\n */\nconst cliErrorHints: Partial<Record<CliErrorCode, string>> = {\n CLI_ARGS_INVALID: \"Check command usage with --help\",\n CLI_UNKNOWN_COMMAND: \"Run 'soda-gql --help' for available commands\",\n CLI_UNKNOWN_SUBCOMMAND: \"Run the parent command with --help for available subcommands\",\n CLI_FILE_EXISTS: \"Use --force flag to overwrite existing files\",\n CLI_FILE_NOT_FOUND: \"Verify the file path exists\",\n CLI_WRITE_FAILED: \"Check write permissions and disk space\",\n CLI_READ_FAILED: \"Check file permissions and verify the file is not locked\",\n CLI_NO_PATTERNS: \"Provide file patterns or create soda-gql.config.ts\",\n CLI_FORMATTER_NOT_INSTALLED: \"Install with: bun add @soda-gql/formatter\",\n CLI_PARSE_ERROR: \"Check the file for syntax errors\",\n CLI_FORMAT_ERROR: \"Verify the file contains valid soda-gql code\",\n CLI_UNEXPECTED: \"This is an unexpected error. Please report at https://github.com/soda-gql/soda-gql/issues\",\n};\n\n/**\n * Codegen-specific error hints.\n */\nconst codegenErrorHints: Record<string, string> = {\n SCHEMA_NOT_FOUND: \"Verify the schema path in soda-gql.config.ts\",\n SCHEMA_INVALID: \"Check your GraphQL schema for syntax errors\",\n INJECT_MODULE_NOT_FOUND: \"Run: soda-gql codegen --emit-inject-template <path>\",\n INJECT_MODULE_REQUIRED: \"Add inject configuration to your schema in soda-gql.config.ts\",\n INJECT_TEMPLATE_EXISTS: \"Delete the existing file to regenerate, or use a different path\",\n EMIT_FAILED: \"Check write permissions and that the output directory exists\",\n INJECT_TEMPLATE_FAILED: \"Check write permissions for the output path\",\n};\n\n/**\n * Config-specific error hints.\n */\nconst configErrorHints: Record<string, string> = {\n CONFIG_NOT_FOUND: \"Create a soda-gql.config.ts file in your project root\",\n CONFIG_LOAD_FAILED: \"Check your configuration file for syntax errors\",\n CONFIG_VALIDATION_FAILED: \"Verify your configuration matches the expected schema\",\n CONFIG_INVALID_PATH: \"Verify the path in your configuration exists\",\n};\n\n/**\n * Artifact-specific error hints.\n */\nconst artifactErrorHints: Record<string, string> = {\n ARTIFACT_NOT_FOUND: \"Verify the artifact file path exists\",\n ARTIFACT_PARSE_ERROR: \"Check that the artifact file is valid JSON\",\n ARTIFACT_VALIDATION_ERROR: \"Verify the artifact was built with a compatible version of soda-gql\",\n};\n\n/**\n * Typegen-specific error hints.\n */\nconst typegenErrorHints: Record<string, string> = {\n TYPEGEN_CODEGEN_REQUIRED: \"Run 'soda-gql codegen' before running typegen\",\n TYPEGEN_SCHEMA_LOAD_FAILED: \"Verify the generated CJS bundle is valid\",\n TYPEGEN_BUILD_FAILED: \"Check for errors in your source files\",\n TYPEGEN_EMIT_FAILED: \"Check write permissions for the output directory\",\n TYPEGEN_BUNDLE_FAILED: \"Check write permissions for the prebuilt directory\",\n};\n\n/**\n * Get hint for any error type.\n */\nconst getErrorHint = (error: CliError): string | undefined => {\n if (error.category === \"cli\") {\n return cliErrorHints[error.code];\n }\n if (error.category === \"codegen\") {\n return codegenErrorHints[error.error.code];\n }\n if (error.category === \"config\") {\n return configErrorHints[error.error.code];\n }\n if (error.category === \"artifact\") {\n return artifactErrorHints[error.error.code];\n }\n if (error.category === \"typegen\") {\n return typegenErrorHints[error.error.code];\n }\n // Builder errors use their own hints via formatBuilderErrorForCLI\n return undefined;\n};\n\n/**\n * Format CliError to human-readable string with hints.\n */\nexport const formatCliErrorHuman = (error: CliError): string => {\n // Delegate to builder's formatter for builder errors\n if (error.category === \"builder\") {\n return formatBuilderErrorForCLI(error.error);\n }\n\n const lines: string[] = [];\n\n if (error.category === \"codegen\") {\n const codegenError = error.error;\n lines.push(`Error [${codegenError.code}]: ${codegenError.message}`);\n\n // Add context based on error type\n if (\"schemaPath\" in codegenError) {\n lines.push(` Schema: ${codegenError.schemaPath}`);\n }\n if (\"outPath\" in codegenError && codegenError.outPath) {\n lines.push(` Output: ${codegenError.outPath}`);\n }\n if (\"injectPath\" in codegenError) {\n lines.push(` Inject: ${codegenError.injectPath}`);\n }\n } else if (error.category === \"config\") {\n const configError = error.error;\n lines.push(`Error [${configError.code}]: ${configError.message}`);\n if (configError.filePath) {\n lines.push(` Config: ${configError.filePath}`);\n }\n } else if (error.category === \"artifact\") {\n const artifactError = error.error;\n lines.push(`Error [${artifactError.code}]: ${artifactError.message}`);\n if (artifactError.filePath) {\n lines.push(` Artifact: ${artifactError.filePath}`);\n }\n } else if (error.category === \"typegen\") {\n const typegenError = error.error;\n lines.push(`Error [${typegenError.code}]: ${typegenError.message}`);\n } else {\n // CLI errors\n lines.push(`Error [${error.code}]: ${error.message}`);\n\n if (\"filePath\" in error && error.filePath) {\n lines.push(` File: ${error.filePath}`);\n }\n if (\"command\" in error && error.code !== \"CLI_UNKNOWN_COMMAND\") {\n lines.push(` Command: ${error.command}`);\n }\n if (\"parent\" in error) {\n lines.push(` Parent: ${error.parent}`);\n }\n }\n\n const hint = getErrorHint(error);\n if (hint) {\n lines.push(\"\");\n lines.push(` Hint: ${hint}`);\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Format CliError to JSON string.\n */\nexport const formatCliErrorJson = (error: CliError): string => {\n if (error.category === \"cli\") {\n const { category: _category, ...rest } = error;\n return JSON.stringify({ error: rest }, null, 2);\n }\n return JSON.stringify({ error: error.error }, null, 2);\n};\n\n/**\n * Format CliError with output format preference.\n */\nexport const formatCliError = (error: CliError, format: OutputFormat = \"human\"): string => {\n return format === \"json\" ? formatCliErrorJson(error) : formatCliErrorHuman(error);\n};\n\n// ---- Legacy formatters (kept for backward compatibility) ----\n\nexport const formatters = {\n json: (data: unknown) => JSON.stringify(data, null, 2),\n human: (data: unknown) => {\n if (typeof data === \"string\") return data;\n if (data instanceof Error) return data.message;\n return JSON.stringify(data, null, 2);\n },\n} as const;\n\nexport const formatOutput = (data: unknown, format: OutputFormat = \"human\"): string => {\n return formatters[format](data);\n};\n\n/**\n * @deprecated Use formatCliError instead for CliError types.\n */\nexport const formatError = (error: unknown, format: OutputFormat = \"human\"): string => {\n if (format === \"json\") {\n return JSON.stringify(\n {\n error: error,\n },\n null,\n 2,\n );\n }\n return error instanceof Error ? error.message : String(error);\n};\n","import { err, ok } from \"neverthrow\";\nimport { artifactCommand } from \"./commands/artifact\";\nimport { codegenCommand } from \"./commands/codegen\";\nimport { doctorCommand } from \"./commands/doctor\";\nimport { formatCommand } from \"./commands/format\";\nimport { initCommand } from \"./commands/init\";\nimport { typegenCommand } from \"./commands/typegen\";\nimport { cliErrors } from \"./errors\";\nimport type { CommandResult, CommandSuccess, OutputFormat } from \"./types\";\nimport { formatCliError } from \"./utils/format\";\n\nconst MAIN_HELP = `Usage: soda-gql <command> [options]\n\nCommands:\n init Initialize a new soda-gql project\n codegen Generate graphql-system runtime module\n typegen Generate prebuilt types from source code\n format Format soda-gql field selections\n artifact Manage soda-gql artifacts\n doctor Run diagnostic checks\n\nRun 'soda-gql <command> --help' for more information on a specific command.\n`;\n\n/**\n * Parse output format from argv.\n * Returns \"json\" if --format=json or --json flag is present, otherwise \"human\".\n */\nconst getOutputFormat = (argv: readonly string[]): OutputFormat => {\n for (const arg of argv) {\n if (arg === \"--format=json\" || arg === \"--json\") {\n return \"json\";\n }\n if (arg === \"--format=human\") {\n return \"human\";\n }\n }\n return \"human\";\n};\n\ntype DispatchResult = CommandResult<CommandSuccess & { exitCode?: number }>;\n\nconst dispatch = async (argv: readonly string[]): Promise<DispatchResult> => {\n const [command, ...rest] = argv;\n\n if (!command || command === \"--help\" || command === \"-h\") {\n return ok({ message: MAIN_HELP });\n }\n\n if (command === \"init\") {\n return initCommand(rest);\n }\n\n if (command === \"codegen\") {\n return codegenCommand(rest);\n }\n\n if (command === \"typegen\") {\n return typegenCommand(rest);\n }\n\n if (command === \"format\") {\n const result = await formatCommand(rest);\n if (result.isOk()) {\n // Format command uses exit 1 for unformatted files in check mode or errors\n const exitCode = result.value.data?.hasFormattingIssues ? 1 : 0;\n return ok({ ...result.value, exitCode });\n }\n return err(result.error);\n }\n\n if (command === \"artifact\") {\n return artifactCommand(rest);\n }\n\n if (command === \"doctor\") {\n const result = doctorCommand(rest);\n if (result.isOk()) {\n // Doctor uses exit 1 if issues found\n const exitCode = result.value.data?.issueCount ? 1 : 0;\n return ok({ ...result.value, exitCode });\n }\n return result;\n }\n\n return err(cliErrors.unknownCommand(command));\n};\n\n// Run CLI when executed directly\nconst main = async () => {\n const argv = process.argv.slice(2);\n const format = getOutputFormat(argv);\n\n const result = await dispatch(argv);\n\n if (result.isOk()) {\n process.stdout.write(`${result.value.message}\\n`);\n process.exitCode = result.value.exitCode ?? 0;\n } else {\n process.stderr.write(`${formatCliError(result.error, format)}\\n`);\n process.exitCode = 1;\n }\n};\n\nmain().catch((error) => {\n const unexpectedError = cliErrors.unexpected(error instanceof Error ? error.message : String(error), error);\n const format = getOutputFormat(process.argv.slice(2));\n process.stderr.write(`${formatCliError(unexpectedError, format)}\\n`);\n process.exitCode = 1;\n});\n\nexport { dispatch };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["args: BuildArgs","formatSuccess","lines: string[]","meta: BuilderArtifactMeta | undefined","artifactWithMeta: BuilderArtifact","data: BuildData","data","args: ValidateArgs","formatSuccess","lines: string[]","z","parsed: Record<string, unknown>","positional: string[]","inputPatterns: readonly string[]","graphqlFiles: string[]","Glob","files: GeneratedFile[]","parts: string[]","formatSuccess","schemas: Record<string, CodegenSchemaConfig>","formatSuccess","result","resolvedSchemas: Record<string, CodegenSchemaConfig>","schemaResults: CodegenFreshnessData[\"schemas\"][number][]","existingPaths: string[]","missingFiles: string[]","packages: DiscoveredPackage[]","allPackages: DiscoveredPackage[]","queue: string[]","realPath: string","duplicates: DuplicatePackageData[\"duplicates\"][number][]","STATUS_SYMBOLS: Record<CheckStatus, string>","lines: string[]","parts: string[]","checks: CheckResult[]","result: DoctorResult","parts: string[]","files: string[]","targetPatterns: readonly string[]","excludePatterns: readonly string[]","data: FormatData","data","unformatted: string[]","createdPaths: string[]","formatSuccess","files: FileToGenerate[]","lines: string[]","data: TypegenSuccessData","cliErrorHints: Partial<Record<CliErrorCode, string>>","codegenErrorHints: Record<string, string>","configErrorHints: Record<string, string>","artifactErrorHints: Record<string, string>","typegenErrorHints: Record<string, string>","lines: string[]"],"sources":["../src/errors.ts","../src/commands/artifact/build.ts","../src/commands/artifact/validate.ts","../src/commands/artifact/index.ts","../src/schemas/args.ts","../src/utils/parse-args.ts","../src/commands/codegen/graphql.ts","../src/commands/codegen/schema.ts","../src/commands/codegen/index.ts","../src/commands/doctor/checks/codegen-freshness.ts","../src/commands/doctor/checks/config-validation.ts","../src/commands/doctor/discovery.ts","../src/commands/doctor/checks/duplicate-packages.ts","../src/commands/doctor/checks/version-consistency.ts","../src/commands/doctor/output.ts","../src/commands/doctor/index.ts","../src/commands/format.ts","../src/templates/config.template.ts","../src/templates/gitignore.template.ts","../src/templates/inject.template.ts","../src/templates/schema.template.ts","../src/commands/init.ts","../src/commands/typegen.ts","../src/utils/format.ts","../src/index.ts"],"sourcesContent":["/**\n * Unified CLI error types and constructors.\n * @module\n */\n\nimport type { ArtifactLoadError, BuilderError } from \"@soda-gql/builder\";\nimport type { CodegenError } from \"@soda-gql/codegen\";\nimport type { ConfigError } from \"@soda-gql/config\";\nimport type { TypegenError } from \"@soda-gql/typegen\";\nimport { err, type Result } from \"neverthrow\";\n\n/**\n * CLI-specific error codes.\n */\nexport type CliErrorCode =\n // Argument parsing errors\n | \"CLI_ARGS_INVALID\"\n | \"CLI_UNKNOWN_COMMAND\"\n | \"CLI_UNKNOWN_SUBCOMMAND\"\n // File operation errors\n | \"CLI_FILE_EXISTS\"\n | \"CLI_FILE_NOT_FOUND\"\n | \"CLI_WRITE_FAILED\"\n | \"CLI_READ_FAILED\"\n // Format command specific\n | \"CLI_NO_PATTERNS\"\n | \"CLI_FORMATTER_NOT_INSTALLED\"\n | \"CLI_PARSE_ERROR\"\n | \"CLI_FORMAT_ERROR\"\n | \"CLI_DUPLICATE_FRAGMENT\"\n | \"CLI_FRAGMENT_NOT_FOUND\"\n // Unexpected errors\n | \"CLI_UNEXPECTED\";\n\n/**\n * Unified CLI error discriminated union.\n * Wraps external errors (codegen, builder, config, typegen) and defines CLI-specific errors.\n */\nexport type CliError =\n // Wrapped external errors (preserve original structure)\n | { readonly category: \"codegen\"; readonly error: CodegenError }\n | { readonly category: \"builder\"; readonly error: BuilderError }\n | { readonly category: \"artifact\"; readonly error: ArtifactLoadError }\n | { readonly category: \"config\"; readonly error: ConfigError }\n | { readonly category: \"typegen\"; readonly error: TypegenError }\n // CLI-specific errors\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_ARGS_INVALID\";\n readonly message: string;\n readonly command: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_UNKNOWN_COMMAND\";\n readonly message: string;\n readonly command: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_UNKNOWN_SUBCOMMAND\";\n readonly message: string;\n readonly parent: string;\n readonly subcommand: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FILE_EXISTS\";\n readonly message: string;\n readonly filePath: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FILE_NOT_FOUND\";\n readonly message: string;\n readonly filePath: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_WRITE_FAILED\";\n readonly message: string;\n readonly filePath: string;\n readonly cause?: unknown;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_READ_FAILED\";\n readonly message: string;\n readonly filePath: string;\n readonly cause?: unknown;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_NO_PATTERNS\";\n readonly message: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FORMATTER_NOT_INSTALLED\";\n readonly message: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_PARSE_ERROR\";\n readonly message: string;\n readonly filePath?: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FORMAT_ERROR\";\n readonly message: string;\n readonly filePath?: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_DUPLICATE_FRAGMENT\";\n readonly message: string;\n readonly fragmentName: string;\n readonly existingFile: string;\n readonly newFile: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_FRAGMENT_NOT_FOUND\";\n readonly message: string;\n readonly fragmentName: string;\n readonly referencedIn: string;\n }\n | {\n readonly category: \"cli\";\n readonly code: \"CLI_UNEXPECTED\";\n readonly message: string;\n readonly cause?: unknown;\n };\n\n/**\n * Result type for CLI operations.\n */\nexport type CliResult<T> = Result<T, CliError>;\n\n// Extract CLI-specific error types for type-safe constructors\ntype CliArgsInvalidError = Extract<CliError, { code: \"CLI_ARGS_INVALID\" }>;\ntype CliUnknownCommandError = Extract<CliError, { code: \"CLI_UNKNOWN_COMMAND\" }>;\ntype CliUnknownSubcommandError = Extract<CliError, { code: \"CLI_UNKNOWN_SUBCOMMAND\" }>;\ntype CliFileExistsError = Extract<CliError, { code: \"CLI_FILE_EXISTS\" }>;\ntype CliFileNotFoundError = Extract<CliError, { code: \"CLI_FILE_NOT_FOUND\" }>;\ntype CliWriteFailedError = Extract<CliError, { code: \"CLI_WRITE_FAILED\" }>;\ntype CliReadFailedError = Extract<CliError, { code: \"CLI_READ_FAILED\" }>;\ntype CliNoPatternsError = Extract<CliError, { code: \"CLI_NO_PATTERNS\" }>;\ntype CliFormatterNotInstalledError = Extract<CliError, { code: \"CLI_FORMATTER_NOT_INSTALLED\" }>;\ntype CliParseErrorError = Extract<CliError, { code: \"CLI_PARSE_ERROR\" }>;\ntype CliFormatErrorError = Extract<CliError, { code: \"CLI_FORMAT_ERROR\" }>;\ntype CliDuplicateFragmentError = Extract<CliError, { code: \"CLI_DUPLICATE_FRAGMENT\" }>;\ntype CliFragmentNotFoundError = Extract<CliError, { code: \"CLI_FRAGMENT_NOT_FOUND\" }>;\ntype CliUnexpectedError = Extract<CliError, { code: \"CLI_UNEXPECTED\" }>;\ntype CliCodegenError = Extract<CliError, { category: \"codegen\" }>;\ntype CliBuilderError = Extract<CliError, { category: \"builder\" }>;\ntype CliArtifactError = Extract<CliError, { category: \"artifact\" }>;\ntype CliConfigError = Extract<CliError, { category: \"config\" }>;\ntype CliTypegenError = Extract<CliError, { category: \"typegen\" }>;\n\n/**\n * Error constructor helpers for concise error creation.\n * Each function returns a specific error type for better type inference.\n */\nexport const cliErrors = {\n argsInvalid: (command: string, message: string): CliArgsInvalidError => ({\n category: \"cli\",\n code: \"CLI_ARGS_INVALID\",\n message,\n command,\n }),\n\n unknownCommand: (command: string): CliUnknownCommandError => ({\n category: \"cli\",\n code: \"CLI_UNKNOWN_COMMAND\",\n message: `Unknown command: ${command}`,\n command,\n }),\n\n unknownSubcommand: (parent: string, subcommand: string): CliUnknownSubcommandError => ({\n category: \"cli\",\n code: \"CLI_UNKNOWN_SUBCOMMAND\",\n message: `Unknown subcommand: ${subcommand}`,\n parent,\n subcommand,\n }),\n\n fileExists: (filePath: string, message?: string): CliFileExistsError => ({\n category: \"cli\",\n code: \"CLI_FILE_EXISTS\",\n message: message ?? `File already exists: ${filePath}. Use --force to overwrite.`,\n filePath,\n }),\n\n fileNotFound: (filePath: string, message?: string): CliFileNotFoundError => ({\n category: \"cli\",\n code: \"CLI_FILE_NOT_FOUND\",\n message: message ?? `File not found: ${filePath}`,\n filePath,\n }),\n\n writeFailed: (filePath: string, message?: string, cause?: unknown): CliWriteFailedError => ({\n category: \"cli\",\n code: \"CLI_WRITE_FAILED\",\n message: message ?? `Failed to write file: ${filePath}`,\n filePath,\n cause,\n }),\n\n readFailed: (filePath: string, message?: string, cause?: unknown): CliReadFailedError => ({\n category: \"cli\",\n code: \"CLI_READ_FAILED\",\n message: message ?? `Failed to read file: ${filePath}`,\n filePath,\n cause,\n }),\n\n noPatterns: (message?: string): CliNoPatternsError => ({\n category: \"cli\",\n code: \"CLI_NO_PATTERNS\",\n message: message ?? \"No patterns provided and config not found. Usage: soda-gql format [patterns...] [--check]\",\n }),\n\n formatterNotInstalled: (message?: string): CliFormatterNotInstalledError => ({\n category: \"cli\",\n code: \"CLI_FORMATTER_NOT_INSTALLED\",\n message: message ?? \"@soda-gql/formatter is not installed. Run: bun add @soda-gql/formatter\",\n }),\n\n parseError: (message: string, filePath?: string): CliParseErrorError => ({\n category: \"cli\",\n code: \"CLI_PARSE_ERROR\",\n message,\n filePath,\n }),\n\n formatError: (message: string, filePath?: string): CliFormatErrorError => ({\n category: \"cli\",\n code: \"CLI_FORMAT_ERROR\",\n message,\n filePath,\n }),\n\n duplicateFragment: (fragmentName: string, existingFile: string, newFile: string): CliDuplicateFragmentError => ({\n category: \"cli\",\n code: \"CLI_DUPLICATE_FRAGMENT\",\n message: `Fragment \"${fragmentName}\" is defined in multiple files:\\n - ${existingFile}\\n - ${newFile}`,\n fragmentName,\n existingFile,\n newFile,\n }),\n\n fragmentNotFound: (fragmentName: string, referencedIn: string): CliFragmentNotFoundError => ({\n category: \"cli\",\n code: \"CLI_FRAGMENT_NOT_FOUND\",\n message: `Fragment \"${fragmentName}\" is referenced but not defined in any input file`,\n fragmentName,\n referencedIn,\n }),\n\n unexpected: (message: string, cause?: unknown): CliUnexpectedError => ({\n category: \"cli\",\n code: \"CLI_UNEXPECTED\",\n message,\n cause,\n }),\n\n // Wrappers for external errors\n fromCodegen: (error: CodegenError): CliCodegenError => ({\n category: \"codegen\",\n error,\n }),\n\n fromBuilder: (error: BuilderError): CliBuilderError => ({\n category: \"builder\",\n error,\n }),\n\n fromArtifact: (error: ArtifactLoadError): CliArtifactError => ({\n category: \"artifact\",\n error,\n }),\n\n fromConfig: (error: ConfigError): CliConfigError => ({\n category: \"config\",\n error,\n }),\n\n fromTypegen: (error: TypegenError): CliTypegenError => ({\n category: \"typegen\",\n error,\n }),\n} as const;\n\n/**\n * Convenience helper to create an err Result from CliError.\n */\nexport const cliErr = <T = never>(error: CliError): CliResult<T> => err(error);\n\n/**\n * Type guard to check if error is a CLI-specific error.\n */\nexport const isCliError = (error: CliError): error is CliError & { category: \"cli\" } => {\n return error.category === \"cli\";\n};\n\n/**\n * Extract error code from any CliError variant.\n */\nexport const getErrorCode = (error: CliError): string => {\n if (error.category === \"cli\") {\n return error.code;\n }\n // codegen, builder, artifact, config all have error.code\n return error.error.code;\n};\n\n/**\n * Extract error message from any CliError variant.\n */\nexport const getErrorMessage = (error: CliError): string => {\n if (error.category === \"cli\") {\n return error.message;\n }\n return error.error.message;\n};\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport type { BuilderArtifact, BuilderArtifactMeta } from \"@soda-gql/builder\";\nimport { createBuilderService } from \"@soda-gql/builder\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\n\nconst BUILD_HELP = `Usage: soda-gql artifact build [options]\n\nBuild and validate soda-gql artifacts.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --output, -o Output file path (default: ./soda-gql-artifact.json)\n --version, -v Custom version string for the artifact (default: package version)\n --dry-run Validate only, don't write output\n --help, -h Show this help message\n\nExamples:\n soda-gql artifact build\n soda-gql artifact build --output ./dist/artifact.json\n soda-gql artifact build --version \"1.0.0\"\n soda-gql artifact build --dry-run\n soda-gql artifact build --config ./soda-gql.config.ts\n`;\n\ntype BuildArgs = {\n configPath?: string;\n outputPath: string;\n version?: string;\n dryRun: boolean;\n help: boolean;\n};\n\nconst DEFAULT_OUTPUT_PATH = \"./soda-gql-artifact.json\";\n\n/**\n * Parse build command arguments.\n */\nconst parseBuildArgs = (argv: readonly string[]): BuildArgs => {\n const args: BuildArgs = {\n configPath: undefined,\n outputPath: DEFAULT_OUTPUT_PATH,\n version: undefined,\n dryRun: false,\n help: false,\n };\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--config\" || arg === \"-c\") {\n args.configPath = argv[++i];\n } else if (arg === \"--output\" || arg === \"-o\") {\n args.outputPath = argv[++i] ?? DEFAULT_OUTPUT_PATH;\n } else if (arg === \"--version\" || arg === \"-v\") {\n args.version = argv[++i];\n } else if (arg === \"--dry-run\") {\n args.dryRun = true;\n } else if (arg === \"--help\" || arg === \"-h\") {\n args.help = true;\n }\n }\n\n return args;\n};\n\ntype BuildData = {\n artifact: BuilderArtifact;\n outputPath?: string;\n dryRun: boolean;\n};\n\nconst formatSuccess = (data: BuildData): string => {\n const { artifact, outputPath, dryRun } = data;\n const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === \"fragment\").length;\n const operationCount = Object.values(artifact.elements).filter((e) => e.type === \"operation\").length;\n\n const lines: string[] = [];\n if (dryRun) {\n lines.push(`Validation passed: ${fragmentCount} fragments, ${operationCount} operations`);\n } else {\n lines.push(`Build complete: ${fragmentCount} fragments, ${operationCount} operations`);\n }\n\n if (artifact.meta?.version) {\n lines.push(` Version: ${artifact.meta.version}`);\n }\n\n if (outputPath && !dryRun) {\n lines.push(`Artifact written to: ${outputPath}`);\n }\n\n return lines.join(\"\\n\");\n};\n\ntype BuildCommandResult = CommandResult<CommandSuccess & { data?: BuildData }>;\n\n/**\n * Build command - builds and validates soda-gql artifacts.\n */\nexport const buildCommand = async (argv: readonly string[]): Promise<BuildCommandResult> => {\n const args = parseBuildArgs(argv);\n\n if (args.help) {\n return ok({ message: BUILD_HELP });\n }\n\n // Load config\n const configResult = loadConfig(args.configPath);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Create builder service and build\n const service = createBuilderService({ config });\n const buildResult = await service.buildAsync();\n\n if (buildResult.isErr()) {\n return err(cliErrors.fromBuilder(buildResult.error));\n }\n\n const artifact = buildResult.value;\n\n // Create artifact with metadata (only if version is specified)\n const meta: BuilderArtifactMeta | undefined = args.version\n ? {\n version: args.version,\n createdAt: new Date().toISOString(),\n }\n : undefined;\n const artifactWithMeta: BuilderArtifact = {\n ...(meta ? { meta } : {}),\n ...artifact,\n };\n\n if (args.dryRun) {\n const data: BuildData = { artifact: artifactWithMeta, dryRun: true };\n return ok({ message: formatSuccess(data), data });\n }\n\n // Write artifact to output file\n const outputPath = resolve(process.cwd(), args.outputPath);\n const outputDir = dirname(outputPath);\n try {\n await mkdir(outputDir, { recursive: true });\n await writeFile(outputPath, JSON.stringify(artifactWithMeta, null, 2));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return err(cliErrors.writeFailed(outputPath, `Failed to write artifact: ${message}`, error));\n }\n\n const data: BuildData = { artifact: artifactWithMeta, outputPath, dryRun: false };\n return ok({ message: formatSuccess(data), data });\n};\n","import { resolve } from \"node:path\";\nimport type { BuilderArtifact } from \"@soda-gql/builder\";\nimport { loadArtifact } from \"@soda-gql/builder\";\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\n\nconst VALIDATE_HELP = `Usage: soda-gql artifact validate [options] <path>\n\nValidate a pre-built soda-gql artifact file.\n\nArguments:\n <path> Path to artifact JSON file\n\nOptions:\n --help, -h Show this help message\n\nExamples:\n soda-gql artifact validate ./soda-gql-artifact.json\n soda-gql artifact validate ./dist/artifact.json\n`;\n\ntype ValidateArgs = {\n artifactPath?: string;\n help: boolean;\n};\n\n/**\n * Parse validate command arguments.\n */\nconst parseValidateArgs = (argv: readonly string[]): ValidateArgs => {\n const args: ValidateArgs = {\n artifactPath: undefined,\n help: false,\n };\n\n for (const arg of argv) {\n if (arg === \"--help\" || arg === \"-h\") {\n args.help = true;\n } else if (!arg.startsWith(\"-\")) {\n args.artifactPath = arg;\n }\n }\n\n return args;\n};\n\nconst formatSuccess = (artifact: BuilderArtifact): string => {\n const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === \"fragment\").length;\n const operationCount = Object.values(artifact.elements).filter((e) => e.type === \"operation\").length;\n const lines: string[] = [`Artifact valid: ${fragmentCount} fragments, ${operationCount} operations`];\n\n if (artifact.meta) {\n lines.push(` Version: ${artifact.meta.version}`);\n lines.push(` Created: ${artifact.meta.createdAt}`);\n } else {\n lines.push(` (No metadata - legacy artifact format)`);\n }\n\n return lines.join(\"\\n\");\n};\n\ntype ValidateCommandResult = CommandResult<CommandSuccess & { data?: BuilderArtifact }>;\n\n/**\n * Validate command - validates a pre-built artifact file.\n */\nexport const validateCommand = async (argv: readonly string[]): Promise<ValidateCommandResult> => {\n const args = parseValidateArgs(argv);\n\n if (args.help) {\n return ok({ message: VALIDATE_HELP });\n }\n\n if (!args.artifactPath) {\n return err(cliErrors.argsInvalid(\"artifact validate\", \"Missing artifact path argument\"));\n }\n\n const artifactPath = resolve(process.cwd(), args.artifactPath);\n const result = await loadArtifact(artifactPath);\n\n if (result.isErr()) {\n return err(cliErrors.fromArtifact(result.error));\n }\n\n return ok({ message: formatSuccess(result.value), data: result.value });\n};\n","import { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { buildCommand } from \"./build\";\nimport { validateCommand } from \"./validate\";\n\nconst ARTIFACT_HELP = `Usage: soda-gql artifact <subcommand> [options]\n\nManage soda-gql artifacts.\n\nSubcommands:\n build Build artifacts (validate definitions)\n validate Validate a pre-built artifact file\n\nRun 'soda-gql artifact <subcommand> --help' for more information.\n`;\n\ntype ArtifactCommandResult = CommandResult<CommandSuccess>;\n\n/**\n * Dispatcher for artifact subcommands.\n */\nexport const artifactCommand = async (argv: readonly string[]): Promise<ArtifactCommandResult> => {\n const [subcommand, ...rest] = argv;\n\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\") {\n return ok({ message: ARTIFACT_HELP });\n }\n\n if (subcommand === \"build\") {\n return buildCommand(rest);\n }\n\n if (subcommand === \"validate\") {\n return validateCommand(rest);\n }\n\n return err(cliErrors.unknownSubcommand(\"artifact\", subcommand));\n};\n","import { z } from \"zod\";\n\n/**\n * Args for `codegen schema` subcommand.\n */\nexport const CodegenSchemaArgsSchema = z.object({\n config: z.string().optional(),\n \"emit-inject-template\": z.string().optional(),\n});\n\n/**\n * Legacy alias for backwards compatibility.\n * @deprecated Use CodegenSchemaArgsSchema instead.\n */\nexport const CodegenArgsSchema = CodegenSchemaArgsSchema;\n\nexport const BuilderArgsSchema = z.object({\n mode: z.enum([\"runtime\", \"zero-runtime\"]),\n entry: z.string(),\n out: z.string(),\n format: z.enum([\"human\", \"json\"]).optional().default(\"human\"),\n});\n\nexport const FormatArgsSchema = z.object({\n _: z.array(z.string()).optional(),\n config: z.string().optional(),\n check: z.boolean().optional(),\n \"inject-fragment-keys\": z.boolean().optional(),\n});\n\nexport const InitArgsSchema = z.object({\n force: z.boolean().optional(),\n});\n\nexport const TypegenArgsSchema = z.object({\n config: z.string().optional(),\n});\n\n/**\n * Args for `codegen graphql` subcommand.\n */\nexport const CodegenGraphqlArgsSchema = z.object({\n config: z.string().optional(),\n schema: z.string().optional(),\n input: z.array(z.string()).or(z.string()).optional(),\n suffix: z.string().optional(),\n});\n\nexport type CodegenSchemaArgs = z.infer<typeof CodegenSchemaArgsSchema>;\nexport type CodegenGraphqlArgs = z.infer<typeof CodegenGraphqlArgsSchema>;\n/** @deprecated Use CodegenSchemaArgs instead. */\nexport type CodegenArgs = CodegenSchemaArgs;\nexport type BuilderArgs = z.infer<typeof BuilderArgsSchema>;\nexport type FormatArgs = z.infer<typeof FormatArgsSchema>;\nexport type InitArgs = z.infer<typeof InitArgsSchema>;\nexport type TypegenArgs = z.infer<typeof TypegenArgsSchema>;\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { z } from \"zod\";\n\nexport const parseArgs = <T extends z.ZodType>(args: string[], schema: T): Result<z.infer<T>, string> => {\n const parsed: Record<string, unknown> = {};\n const positional: string[] = [];\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (!arg) continue;\n\n if (arg.startsWith(\"--\")) {\n const key = arg.slice(2);\n const nextArg = args[i + 1];\n\n if (!nextArg || nextArg.startsWith(\"--\")) {\n parsed[key] = true;\n } else {\n parsed[key] = nextArg;\n i++;\n }\n } else {\n positional.push(arg);\n }\n }\n\n if (positional.length > 0) {\n parsed._ = positional;\n }\n\n const result = schema.safeParse(parsed);\n if (!result.success) {\n return err(result.error.issues.map((e) => e.message).join(\", \"));\n }\n\n return ok(result.data);\n};\n","/**\n * Codegen graphql subcommand - generates compat code from .graphql files.\n * @module\n */\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, relative, resolve } from \"node:path\";\nimport type { EnrichedFragment, EnrichedOperation, ParseResult } from \"@soda-gql/codegen\";\nimport { emitFragment, emitOperation, loadSchema, parseGraphqlSource, transformParsedGraphql } from \"@soda-gql/codegen\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport { Glob } from \"bun\";\nimport { err, ok } from \"neverthrow\";\nimport { type CliResult, cliErrors } from \"../../errors\";\nimport { CodegenGraphqlArgsSchema } from \"../../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { parseArgs } from \"../../utils/parse-args\";\n\ntype ParsedGraphqlArgs = {\n schemaName: string;\n schemaFiles: readonly string[];\n inputPatterns: readonly string[];\n /** Output file suffix (e.g., \".compat.ts\", \".generated.ts\") */\n suffix: string;\n /** Resolved absolute path to graphql-system directory (config.outdir) */\n graphqlSystemDir: string;\n};\n\nconst parseGraphqlArgs = (argv: readonly string[]): CliResult<ParsedGraphqlArgs> => {\n const parsed = parseArgs([...argv], CodegenGraphqlArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"codegen graphql\", parsed.error));\n }\n\n const args = parsed.value;\n\n // Load config from @soda-gql/config\n const configResult = loadConfig(args.config);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Get schema name (required if multiple schemas, or use the only one)\n const schemaNames = Object.keys(config.schemas ?? {});\n if (schemaNames.length === 0) {\n return err(cliErrors.argsInvalid(\"codegen graphql\", \"No schemas configured in soda-gql.config.ts\"));\n }\n\n let schemaName = args.schema;\n if (!schemaName) {\n const firstSchema = schemaNames[0];\n if (schemaNames.length > 1 || !firstSchema) {\n return err(\n cliErrors.argsInvalid(\n \"codegen graphql\",\n `Multiple schemas configured. Use --schema to specify: ${schemaNames.join(\", \")}`,\n ),\n );\n }\n schemaName = firstSchema;\n }\n\n const schemaConfig = config.schemas?.[schemaName];\n if (!schemaConfig) {\n return err(cliErrors.argsInvalid(\"codegen graphql\", `Schema \"${schemaName}\" not found in config`));\n }\n\n // Get input patterns from args\n let inputPatterns: readonly string[] = [];\n if (args.input) {\n inputPatterns = Array.isArray(args.input) ? args.input : [args.input];\n }\n\n if (inputPatterns.length === 0) {\n return err(\n cliErrors.argsInvalid(\"codegen graphql\", \"No input patterns provided. Use --input to specify .graphql file patterns\"),\n );\n }\n\n // Get suffix from CLI args or use default\n const suffix = args.suffix ?? \".compat.ts\";\n\n return ok({\n schemaName,\n schemaFiles: schemaConfig.schema,\n inputPatterns,\n suffix,\n graphqlSystemDir: resolve(config.outdir),\n });\n};\n\ntype GeneratedFile = {\n inputPath: string;\n outputPath: string;\n content: string;\n};\n\ntype GraphqlGenerationResult = {\n files: GeneratedFile[];\n operationCount: number;\n fragmentCount: number;\n};\n\nconst generateCompatFiles = async (args: ParsedGraphqlArgs): Promise<CliResult<GraphqlGenerationResult>> => {\n // Load schema\n const schemaResult = loadSchema(args.schemaFiles.map((s) => resolve(s)));\n if (schemaResult.isErr()) {\n return err(cliErrors.fromCodegen(schemaResult.error));\n }\n const schemaDocument = schemaResult.value;\n\n // Find all .graphql files matching input patterns\n const graphqlFiles: string[] = [];\n for (const pattern of args.inputPatterns) {\n const glob = new Glob(pattern);\n for await (const file of glob.scan({ cwd: process.cwd(), absolute: true })) {\n if (file.endsWith(\".graphql\") || file.endsWith(\".gql\")) {\n graphqlFiles.push(file);\n }\n }\n }\n\n if (graphqlFiles.length === 0) {\n return err(\n cliErrors.argsInvalid(\"codegen graphql\", `No .graphql files found matching patterns: ${args.inputPatterns.join(\", \")}`),\n );\n }\n\n // Track all fragments for cross-file imports\n const fragmentsByName = new Map<string, { file: string; outputPath: string }>();\n // Cache parsed results to avoid re-reading and re-parsing files\n const parseCache = new Map<string, ParseResult>();\n\n // First pass: collect all fragments and cache parse results\n for (const file of graphqlFiles) {\n const source = await readFile(file, \"utf-8\");\n const parseResult = parseGraphqlSource(source, file);\n if (parseResult.isErr()) {\n return err(cliErrors.parseError(parseResult.error.message, file));\n }\n\n const parsed = parseResult.value;\n parseCache.set(file, parsed);\n\n const outputBase = basename(file).replace(/\\.(graphql|gql)$/, args.suffix);\n const outputPath = join(dirname(file), outputBase);\n\n for (const frag of parsed.fragments) {\n const existing = fragmentsByName.get(frag.name);\n if (existing && existing.file !== file) {\n return err(cliErrors.duplicateFragment(frag.name, existing.file, file));\n }\n fragmentsByName.set(frag.name, { file, outputPath });\n }\n }\n\n // Second pass: generate code (using cached parse results)\n const files: GeneratedFile[] = [];\n let operationCount = 0;\n let fragmentCount = 0;\n\n for (const file of graphqlFiles) {\n // Use cached parse result instead of re-reading file\n const parsed = parseCache.get(file);\n if (!parsed) {\n throw new Error(`Internal error: parse cache missing for ${file}`);\n }\n\n const transformResult = transformParsedGraphql(parsed, { schemaDocument });\n if (transformResult.isErr()) {\n const error = transformResult.error;\n return err(cliErrors.parseError(error.message, file));\n }\n\n const { operations, fragments } = transformResult.value;\n\n const outputBase = basename(file).replace(/\\.(graphql|gql)$/, args.suffix);\n const outputPath = join(dirname(file), outputBase);\n\n // Build fragment imports map for this file\n const fragmentImports = new Map<string, string>();\n const collectDeps = (deps: readonly string[]): CliResult<void> => {\n for (const fragName of deps) {\n const fragInfo = fragmentsByName.get(fragName);\n if (!fragInfo) {\n return err(cliErrors.fragmentNotFound(fragName, file));\n }\n if (fragInfo.outputPath !== outputPath) {\n // Calculate relative import path (normalize for cross-platform compatibility)\n const relativePath = normalizePath(relative(dirname(outputPath), fragInfo.outputPath)).replace(/\\.ts$/, \"\");\n const importPath = relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n fragmentImports.set(fragName, importPath);\n }\n }\n return ok(undefined);\n };\n\n // Collect dependencies from operations and fragments\n for (const op of operations) {\n const result = collectDeps(op.fragmentDependencies);\n if (result.isErr()) {\n return err(result.error);\n }\n }\n for (const frag of fragments) {\n const result = collectDeps(frag.fragmentDependencies);\n if (result.isErr()) {\n return err(result.error);\n }\n }\n\n // Calculate graphqlSystemPath as relative path from output file (normalize for cross-platform compatibility)\n const graphqlSystemRelative = normalizePath(relative(dirname(outputPath), args.graphqlSystemDir));\n const graphqlSystemPath = graphqlSystemRelative.startsWith(\".\") ? graphqlSystemRelative : `./${graphqlSystemRelative}`;\n\n // Generate code\n const emitOptions = {\n schemaName: args.schemaName,\n graphqlSystemPath,\n fragmentImports,\n schemaDocument,\n };\n\n const parts: string[] = [];\n\n for (const op of operations) {\n const emitResult = emitOperation(op as EnrichedOperation, emitOptions);\n if (emitResult.isErr()) {\n return err(cliErrors.parseError(emitResult.error.message, file));\n }\n parts.push(emitResult.value);\n operationCount++;\n }\n\n for (const frag of fragments) {\n const emitResult = emitFragment(frag as EnrichedFragment, emitOptions);\n if (emitResult.isErr()) {\n return err(cliErrors.parseError(emitResult.error.message, file));\n }\n parts.push(emitResult.value);\n fragmentCount++;\n }\n\n if (parts.length > 0) {\n files.push({\n inputPath: file,\n outputPath,\n content: parts.join(\"\\n\\n\"),\n });\n }\n }\n\n return ok({ files, operationCount, fragmentCount });\n};\n\nconst writeGeneratedFiles = async (files: GeneratedFile[]): Promise<CliResult<void>> => {\n for (const file of files) {\n // Ensure directory exists\n const dir = dirname(file.outputPath);\n await mkdir(dir, { recursive: true });\n\n // Write file\n await writeFile(file.outputPath, file.content, \"utf-8\");\n }\n return ok(undefined);\n};\n\nconst formatSuccess = (result: GraphqlGenerationResult): string => {\n const lines = [\n `Generated ${result.operationCount} operation(s) and ${result.fragmentCount} fragment(s) from ${result.files.length} file(s):`,\n ];\n for (const file of result.files) {\n lines.push(` ${relative(process.cwd(), file.outputPath)}`);\n }\n return lines.join(\"\\n\");\n};\n\nexport const GRAPHQL_HELP = `Usage: soda-gql codegen graphql [options]\n\nGenerate TypeScript compat code from .graphql operation files.\nOutput files are created alongside input files.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --schema <name> Schema name (required if multiple schemas configured)\n --input <glob> Glob pattern for .graphql files (repeatable)\n --suffix <ext> Output file suffix (default: \".compat.ts\")\n --help, -h Show this help message\n\nExamples:\n soda-gql codegen graphql --input \"src/**/*.graphql\"\n soda-gql codegen graphql --input \"queries/*.graphql\" --suffix \".generated.ts\"\n`;\n\ntype GraphqlCommandResult = CommandResult<CommandSuccess & { data?: GraphqlGenerationResult }>;\n\nexport const graphqlCommand = async (argv: readonly string[]): Promise<GraphqlCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: GRAPHQL_HELP });\n }\n\n const parsed = parseGraphqlArgs(argv);\n if (parsed.isErr()) {\n return err(parsed.error);\n }\n\n const result = await generateCompatFiles(parsed.value);\n if (result.isErr()) {\n return err(result.error);\n }\n\n const writeResult = await writeGeneratedFiles(result.value.files);\n if (writeResult.isErr()) {\n return err(writeResult.error);\n }\n\n return ok({ message: formatSuccess(result.value), data: result.value });\n};\n","/**\n * Codegen schema subcommand - generates graphql-system runtime module.\n * @module\n */\n\nimport { resolve } from \"node:path\";\nimport type { CodegenSchemaConfig, CodegenSuccess } from \"@soda-gql/codegen\";\nimport { runCodegen, writeInjectTemplate } from \"@soda-gql/codegen\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport { err, ok } from \"neverthrow\";\nimport { type CliResult, cliErrors } from \"../../errors\";\nimport { CodegenSchemaArgsSchema } from \"../../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { parseArgs } from \"../../utils/parse-args\";\n\ntype ParsedCommand =\n | {\n kind: \"emitInjectTemplate\";\n outPath: string;\n }\n | {\n kind: \"generate\";\n schemas: Record<string, CodegenSchemaConfig>;\n outPath: string;\n importExtension: boolean;\n };\n\nconst parseSchemaArgs = (argv: readonly string[]): CliResult<ParsedCommand> => {\n const parsed = parseArgs([...argv], CodegenSchemaArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"codegen schema\", parsed.error));\n }\n\n const args = parsed.value;\n\n // Handle emit inject template\n if (args[\"emit-inject-template\"]) {\n return ok({\n kind: \"emitInjectTemplate\",\n outPath: args[\"emit-inject-template\"],\n });\n }\n\n // Load config from @soda-gql/config\n const configResult = loadConfig(args.config);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Check if schemas config exists\n if (!config.schemas || Object.keys(config.schemas).length === 0) {\n return err(cliErrors.argsInvalid(\"codegen schema\", \"schemas configuration is required in soda-gql.config.ts\"));\n }\n\n // Build schemas config with resolved paths\n const schemas: Record<string, CodegenSchemaConfig> = {};\n\n for (const [name, schemaConfig] of Object.entries(config.schemas)) {\n schemas[name] = {\n schema: schemaConfig.schema,\n inject: schemaConfig.inject,\n defaultInputDepth: schemaConfig.defaultInputDepth,\n inputDepthOverrides: schemaConfig.inputDepthOverrides,\n };\n }\n\n // Derive output path from outdir (default to index.ts)\n const outPath = resolve(config.outdir, \"index.ts\");\n\n return ok({\n kind: \"generate\",\n schemas,\n outPath,\n importExtension: config.styles.importExtension,\n });\n};\n\nconst formatSuccess = (success: CodegenSuccess): string => {\n const schemaNames = Object.keys(success.schemas).join(\", \");\n const totalObjects = Object.values(success.schemas).reduce((sum, s) => sum + s.objects, 0);\n return `Generated ${totalObjects} objects from schemas: ${schemaNames}\\n TypeScript: ${success.outPath}\\n CommonJS: ${success.cjsPath}`;\n};\n\nconst formatTemplateSuccess = (outPath: string): string => {\n return `Created inject template → ${outPath}`;\n};\n\nexport const SCHEMA_HELP = `Usage: soda-gql codegen schema [options]\n\nGenerate graphql-system runtime module from GraphQL schema.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --emit-inject-template <path> Create inject template file\n --help, -h Show this help message\n\nExamples:\n soda-gql codegen schema\n soda-gql codegen schema --config ./soda-gql.config.ts\n soda-gql codegen schema --emit-inject-template ./src/graphql/scalars.ts\n\nNote: Run 'soda-gql typegen' after codegen to generate prebuilt types.\n`;\n\ntype SchemaCommandResult = CommandResult<CommandSuccess & { data?: CodegenSuccess }>;\n\nexport const schemaCommand = async (argv: readonly string[]): Promise<SchemaCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: SCHEMA_HELP });\n }\n\n const parsed = parseSchemaArgs(argv);\n\n if (parsed.isErr()) {\n return err(parsed.error);\n }\n\n const command = parsed.value;\n\n if (command.kind === \"emitInjectTemplate\") {\n const outPath = resolve(command.outPath);\n const result = writeInjectTemplate(outPath);\n if (result.isErr()) {\n return err(cliErrors.fromCodegen(result.error));\n }\n return ok({ message: formatTemplateSuccess(outPath) });\n }\n\n // Resolve all paths in schemas config\n const resolvedSchemas: Record<string, CodegenSchemaConfig> = {};\n for (const [name, schemaConfig] of Object.entries(command.schemas)) {\n resolvedSchemas[name] = {\n schema: schemaConfig.schema.map((s) => resolve(s)),\n inject: {\n scalars: resolve(schemaConfig.inject.scalars),\n ...(schemaConfig.inject.adapter ? { adapter: resolve(schemaConfig.inject.adapter) } : {}),\n },\n defaultInputDepth: schemaConfig.defaultInputDepth,\n inputDepthOverrides: schemaConfig.inputDepthOverrides,\n };\n }\n\n const result = await runCodegen({\n schemas: resolvedSchemas,\n outPath: resolve(command.outPath),\n format: \"human\",\n importExtension: command.importExtension,\n });\n\n if (result.isErr()) {\n return err(cliErrors.fromCodegen(result.error));\n }\n\n return ok({ message: formatSuccess(result.value), data: result.value });\n};\n","/**\n * Codegen command dispatcher.\n * @module\n */\n\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../../errors\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { graphqlCommand } from \"./graphql\";\nimport { schemaCommand } from \"./schema\";\n\nconst CODEGEN_HELP = `Usage: soda-gql codegen <subcommand> [options]\n\nGenerate code from GraphQL schemas and operations.\n\nSubcommands:\n schema Generate graphql-system runtime module from schema\n graphql Generate compat code from .graphql operation files\n\nRun 'soda-gql codegen <subcommand> --help' for more information.\n\nLegacy usage (equivalent to 'codegen schema'):\n soda-gql codegen [--config <path>]\n`;\n\ntype CodegenCommandResult = CommandResult<CommandSuccess>;\n\n/**\n * Check if argv looks like schema command args (for backwards compatibility).\n */\nconst isLegacySchemaArgs = (argv: readonly string[]): boolean => {\n // If first arg is a known subcommand, not legacy\n if (argv[0] === \"schema\" || argv[0] === \"graphql\") {\n return false;\n }\n\n // If any arg looks like a schema flag, it's legacy\n return argv.some(\n (arg) =>\n arg === \"--config\" ||\n arg.startsWith(\"--config=\") ||\n arg === \"--emit-inject-template\" ||\n arg.startsWith(\"--emit-inject-template=\"),\n );\n};\n\n/**\n * Dispatcher for codegen subcommands.\n */\nexport const codegenCommand = async (argv: readonly string[]): Promise<CodegenCommandResult> => {\n const [subcommand, ...rest] = argv;\n\n // No args - show help\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\") {\n return ok({ message: CODEGEN_HELP });\n }\n\n // Explicit schema subcommand\n if (subcommand === \"schema\") {\n return schemaCommand(rest);\n }\n\n // Explicit graphql subcommand\n if (subcommand === \"graphql\") {\n return graphqlCommand(rest);\n }\n\n // Legacy support: if args look like schema args, route to schema\n if (isLegacySchemaArgs(argv)) {\n // Pass all args to schema command (not rest, because first arg is a flag)\n return schemaCommand(argv);\n }\n\n // If no subcommand provided and no legacy args, show schema help\n // This handles the case of `soda-gql codegen` with no args\n if (!subcommand.startsWith(\"-\")) {\n return err(cliErrors.unknownSubcommand(\"codegen\", subcommand));\n }\n\n // Default to schema for any other flags (maintains backwards compatibility)\n return schemaCommand(argv);\n};\n","/**\n * Codegen freshness check.\n * @module\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { findConfigFile, loadConfig } from \"@soda-gql/config\";\nimport type { CheckResult, CodegenFreshnessData } from \"../types\";\n\n/**\n * Check if generated code is newer than schema files.\n */\nexport const checkCodegenFreshness = (): CheckResult<CodegenFreshnessData> => {\n const configPath = findConfigFile();\n\n if (!configPath) {\n return {\n name: \"Codegen Freshness\",\n status: \"skip\",\n message: \"No soda-gql.config.ts found\",\n data: { schemas: [] },\n };\n }\n\n const configResult = loadConfig(configPath);\n\n if (configResult.isErr()) {\n return {\n name: \"Codegen Freshness\",\n status: \"skip\",\n message: \"Could not load config\",\n data: { schemas: [] },\n };\n }\n\n const config = configResult.value;\n const generatedPath = join(config.outdir, \"index.ts\");\n\n if (!existsSync(generatedPath)) {\n return {\n name: \"Codegen Freshness\",\n status: \"warn\",\n message: \"Generated code not found - run codegen\",\n data: { schemas: [] },\n fix: \"Run: soda-gql codegen\",\n };\n }\n\n const generatedStat = statSync(generatedPath);\n const generatedMtime = generatedStat.mtimeMs;\n\n const schemaResults: CodegenFreshnessData[\"schemas\"][number][] = [];\n let hasStale = false;\n\n for (const [name, schemaConfig] of Object.entries(config.schemas)) {\n // Get the latest mtime from all schema files\n let maxSchemaMtime = 0;\n const existingPaths: string[] = [];\n\n for (const schemaPath of schemaConfig.schema) {\n if (!existsSync(schemaPath)) {\n continue; // Handled by config validation check\n }\n existingPaths.push(schemaPath);\n const schemaStat = statSync(schemaPath);\n maxSchemaMtime = Math.max(maxSchemaMtime, schemaStat.mtimeMs);\n }\n\n // Skip if no schema files exist\n if (existingPaths.length === 0) {\n continue;\n }\n\n const isStale = maxSchemaMtime > generatedMtime;\n if (isStale) hasStale = true;\n\n schemaResults.push({\n name,\n schemaPath: existingPaths.join(\", \"),\n generatedPath,\n schemaMtime: maxSchemaMtime,\n generatedMtime,\n isStale,\n });\n }\n\n if (hasStale) {\n const staleSchemas = schemaResults.filter((s) => s.isStale);\n return {\n name: \"Codegen Freshness\",\n status: \"warn\",\n message: `Schema modified after codegen: ${staleSchemas.map((s) => s.name).join(\", \")}`,\n data: { schemas: schemaResults },\n fix: \"Run: soda-gql codegen\",\n };\n }\n\n return {\n name: \"Codegen Freshness\",\n status: \"pass\",\n message: \"Generated code is up to date\",\n data: { schemas: schemaResults },\n };\n};\n","/**\n * Config validation check.\n * @module\n */\n\nimport { existsSync } from \"node:fs\";\nimport { findConfigFile, loadConfig } from \"@soda-gql/config\";\nimport type { CheckResult, ConfigValidationData } from \"../types\";\n\n/**\n * Check that config file is valid and referenced files exist.\n */\nexport const checkConfigValidation = (): CheckResult<ConfigValidationData> => {\n const configPath = findConfigFile();\n\n if (!configPath) {\n return {\n name: \"Config Validation\",\n status: \"skip\",\n message: \"No soda-gql.config.ts found\",\n data: { configPath: null, missingFiles: [] },\n };\n }\n\n const configResult = loadConfig(configPath);\n\n if (configResult.isErr()) {\n return {\n name: \"Config Validation\",\n status: \"fail\",\n message: `Config error: ${configResult.error.message}`,\n data: { configPath, missingFiles: [] },\n fix: \"Check your soda-gql.config.ts for syntax errors\",\n };\n }\n\n const config = configResult.value;\n const missingFiles: string[] = [];\n\n // Check schema files exist\n for (const [name, schemaConfig] of Object.entries(config.schemas)) {\n for (const schemaPath of schemaConfig.schema) {\n if (!existsSync(schemaPath)) {\n missingFiles.push(`Schema '${name}': ${schemaPath}`);\n }\n }\n if (!existsSync(schemaConfig.inject.scalars)) {\n missingFiles.push(`Scalars '${name}': ${schemaConfig.inject.scalars}`);\n }\n if (schemaConfig.inject.adapter && !existsSync(schemaConfig.inject.adapter)) {\n missingFiles.push(`Adapter '${name}': ${schemaConfig.inject.adapter}`);\n }\n }\n\n if (missingFiles.length > 0) {\n return {\n name: \"Config Validation\",\n status: \"fail\",\n message: `${missingFiles.length} referenced file(s) not found`,\n data: { configPath, missingFiles },\n fix: \"Create the missing files or update paths in config\",\n };\n }\n\n return {\n name: \"Config Validation\",\n status: \"pass\",\n message: \"Config loaded successfully\",\n data: { configPath, missingFiles: [] },\n };\n};\n","/**\n * Package discovery utilities for doctor command.\n * @module\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport type { DiscoveredPackage } from \"./types\";\n\nconst SODA_GQL_SCOPE = \"@soda-gql\";\n\n/**\n * Find the nearest node_modules directory.\n */\nexport const findNodeModules = (startDir: string = process.cwd()): string | null => {\n let currentDir = startDir;\n while (currentDir !== dirname(currentDir)) {\n const nodeModulesPath = join(currentDir, \"node_modules\");\n if (existsSync(nodeModulesPath) && statSync(nodeModulesPath).isDirectory()) {\n return nodeModulesPath;\n }\n currentDir = dirname(currentDir);\n }\n return null;\n};\n\n/**\n * Read package.json from a directory.\n */\nconst readPackageJson = (dir: string): Result<{ name: string; version: string }, string> => {\n const packageJsonPath = join(dir, \"package.json\");\n try {\n const content = readFileSync(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { name?: string; version?: string };\n if (!pkg.name || !pkg.version) {\n return err(`Invalid package.json at ${packageJsonPath}`);\n }\n return ok({ name: pkg.name, version: pkg.version });\n } catch {\n return err(`Failed to read package.json at ${packageJsonPath}`);\n }\n};\n\n/**\n * Discover @soda-gql packages at a specific node_modules path.\n */\nconst discoverAtPath = (nodeModulesPath: string): DiscoveredPackage[] => {\n const scopePath = join(nodeModulesPath, SODA_GQL_SCOPE);\n if (!existsSync(scopePath)) {\n return [];\n }\n\n const packages: DiscoveredPackage[] = [];\n\n try {\n const entries = readdirSync(scopePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const packageDir = join(scopePath, entry.name);\n const result = readPackageJson(packageDir);\n\n if (result.isOk()) {\n packages.push({\n name: result.value.name,\n version: result.value.version,\n path: packageDir,\n });\n }\n }\n } catch {\n // Ignore read errors\n }\n\n return packages;\n};\n\n/**\n * Discover all @soda-gql packages including nested node_modules.\n * Uses breadth-first search to avoid deep recursion.\n */\nexport const discoverAllSodaGqlPackages = (startDir: string = process.cwd()): Result<DiscoveredPackage[], string> => {\n const rootNodeModules = findNodeModules(startDir);\n if (!rootNodeModules) {\n return err(\"No node_modules directory found\");\n }\n\n const allPackages: DiscoveredPackage[] = [];\n const visitedPaths = new Set<string>();\n const queue: string[] = [rootNodeModules];\n\n while (queue.length > 0) {\n const nodeModulesPath = queue.shift();\n if (!nodeModulesPath) continue;\n\n // Resolve to handle symlinks\n let realPath: string;\n try {\n realPath = resolve(nodeModulesPath);\n } catch {\n continue;\n }\n\n if (visitedPaths.has(realPath)) continue;\n visitedPaths.add(realPath);\n\n // Discover packages at this level\n const packages = discoverAtPath(nodeModulesPath);\n allPackages.push(...packages);\n\n // Look for nested node_modules\n try {\n const entries = readdirSync(nodeModulesPath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n // Check scoped packages\n if (entry.name.startsWith(\"@\")) {\n const scopeDir = join(nodeModulesPath, entry.name);\n try {\n const scopeEntries = readdirSync(scopeDir, { withFileTypes: true });\n\n for (const scopeEntry of scopeEntries) {\n if (!scopeEntry.isDirectory()) continue;\n const nestedNodeModules = join(scopeDir, scopeEntry.name, \"node_modules\");\n if (existsSync(nestedNodeModules)) {\n queue.push(nestedNodeModules);\n }\n }\n } catch {\n // Ignore read errors\n }\n } else {\n // Check regular packages\n const nestedNodeModules = join(nodeModulesPath, entry.name, \"node_modules\");\n if (existsSync(nestedNodeModules)) {\n queue.push(nestedNodeModules);\n }\n }\n }\n } catch {\n // Ignore read errors\n }\n }\n\n return ok(allPackages);\n};\n\n/**\n * Get the soda-gql CLI version.\n */\nexport const getCliVersion = (): string => {\n try {\n // Navigate from this file (commands/doctor/discovery.ts) to package.json\n // Path: discovery.ts -> doctor/ -> commands/ -> src/ -> cli/package.json\n const cliPackageJsonPath = join(import.meta.dirname, \"..\", \"..\", \"..\", \"package.json\");\n const content = readFileSync(cliPackageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { version?: string };\n return pkg.version ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n};\n\n/**\n * Get TypeScript version from node_modules.\n */\nexport const getTypescriptVersion = (startDir: string = process.cwd()): string | null => {\n const nodeModulesPath = findNodeModules(startDir);\n if (!nodeModulesPath) return null;\n\n const tsPackageJson = join(nodeModulesPath, \"typescript\", \"package.json\");\n try {\n const content = readFileSync(tsPackageJson, \"utf-8\");\n const pkg = JSON.parse(content) as { version?: string };\n return pkg.version ?? null;\n } catch {\n return null;\n }\n};\n","/**\n * Duplicate packages check.\n * @module\n */\n\nimport { discoverAllSodaGqlPackages } from \"../discovery\";\nimport type { CheckResult, DuplicatePackageData } from \"../types\";\n\n/**\n * Check for duplicate @soda-gql packages installed at different paths.\n */\nexport const checkDuplicatePackages = (): CheckResult<DuplicatePackageData> => {\n const packagesResult = discoverAllSodaGqlPackages();\n\n if (packagesResult.isErr()) {\n return {\n name: \"Duplicate Packages\",\n status: \"skip\",\n message: packagesResult.error,\n data: { duplicates: [] },\n };\n }\n\n const packages = packagesResult.value;\n\n // Group by package name\n const byName = new Map<string, typeof packages>();\n for (const pkg of packages) {\n const existing = byName.get(pkg.name) ?? [];\n existing.push(pkg);\n byName.set(pkg.name, existing);\n }\n\n // Find duplicates (same name, multiple paths)\n const duplicates: DuplicatePackageData[\"duplicates\"][number][] = [];\n for (const [name, instances] of byName) {\n if (instances.length > 1) {\n duplicates.push({\n name,\n instances: instances.map((i) => ({\n path: i.path,\n version: i.version,\n })),\n });\n }\n }\n\n if (duplicates.length === 0) {\n return {\n name: \"Duplicate Packages\",\n status: \"pass\",\n message: \"No duplicate packages detected\",\n data: { duplicates: [] },\n };\n }\n\n const duplicateNames = duplicates.map((d) => d.name).join(\", \");\n return {\n name: \"Duplicate Packages\",\n status: \"warn\",\n message: `Duplicate packages found: ${duplicateNames}`,\n data: { duplicates },\n fix: \"Run: rm -rf node_modules && bun install\",\n };\n};\n","/**\n * Version consistency check.\n * @module\n */\n\nimport { discoverAllSodaGqlPackages } from \"../discovery\";\nimport type { CheckResult, VersionConsistencyData } from \"../types\";\n\n/**\n * Check that all @soda-gql packages have consistent versions.\n */\nexport const checkVersionConsistency = (): CheckResult<VersionConsistencyData> => {\n const packagesResult = discoverAllSodaGqlPackages();\n\n if (packagesResult.isErr()) {\n return {\n name: \"Version Consistency\",\n status: \"skip\",\n message: packagesResult.error,\n data: { packages: [], expectedVersion: null },\n };\n }\n\n const packages = packagesResult.value;\n\n if (packages.length === 0) {\n return {\n name: \"Version Consistency\",\n status: \"skip\",\n message: \"No @soda-gql packages found\",\n data: { packages: [], expectedVersion: null },\n };\n }\n\n // Group by package name (to handle duplicates separately)\n const byName = new Map<string, typeof packages>();\n for (const pkg of packages) {\n const existing = byName.get(pkg.name) ?? [];\n existing.push(pkg);\n byName.set(pkg.name, existing);\n }\n\n // Get unique packages (first instance of each)\n const uniquePackages = Array.from(byName.values())\n .map((instances) => instances[0])\n .filter((pkg): pkg is (typeof packages)[number] => pkg !== undefined);\n\n // Determine expected version (most common version)\n const versionCounts = new Map<string, number>();\n for (const pkg of uniquePackages) {\n versionCounts.set(pkg.version, (versionCounts.get(pkg.version) ?? 0) + 1);\n }\n\n let expectedVersion = uniquePackages[0]?.version ?? null;\n let maxCount = 0;\n for (const [version, count] of versionCounts) {\n if (count > maxCount) {\n maxCount = count;\n expectedVersion = version;\n }\n }\n\n // Find mismatches\n const packageResults = uniquePackages.map((pkg) => ({\n name: pkg.name,\n version: pkg.version,\n path: pkg.path,\n isMismatch: pkg.version !== expectedVersion,\n }));\n\n const mismatches = packageResults.filter((p) => p.isMismatch);\n\n if (mismatches.length === 0) {\n return {\n name: \"Version Consistency\",\n status: \"pass\",\n message: `All ${uniquePackages.length} packages at version ${expectedVersion}`,\n data: { packages: packageResults, expectedVersion },\n };\n }\n\n const mismatchNames = mismatches.map((p) => p.name).join(\", \");\n return {\n name: \"Version Consistency\",\n status: \"fail\",\n message: `Version mismatch: ${mismatchNames}`,\n data: { packages: packageResults, expectedVersion },\n fix: `Run: bun update ${mismatches.map((p) => p.name).join(\" \")}`,\n };\n};\n","/**\n * Doctor command output formatting.\n * @module\n */\n\nimport type { CheckResult, CheckStatus, DoctorResult, DuplicatePackageData, VersionConsistencyData } from \"./types\";\n\nconst STATUS_SYMBOLS: Record<CheckStatus, string> = {\n pass: \"\\u2713\", // checkmark\n warn: \"!\",\n fail: \"\\u2717\", // X\n skip: \"-\",\n};\n\n/**\n * Type guard to check if data is an object (not null/primitive).\n */\nconst isObject = (data: unknown): data is Record<string, unknown> => {\n return typeof data === \"object\" && data !== null;\n};\n\n/**\n * Format a single check result for human output.\n */\nconst formatCheckResult = (result: CheckResult): string[] => {\n const lines: string[] = [];\n const symbol = STATUS_SYMBOLS[result.status];\n\n lines.push(`${symbol} ${result.message}`);\n\n // Add detailed data for failures/warnings\n if (result.status === \"fail\" || result.status === \"warn\") {\n const data = result.data;\n\n // Version consistency details\n if (isObject(data) && \"packages\" in data && \"expectedVersion\" in data) {\n const versionData = data as VersionConsistencyData;\n const mismatched = versionData.packages.filter((p) => p.isMismatch);\n for (const pkg of mismatched) {\n lines.push(` ${pkg.name}: ${pkg.version} <- mismatch`);\n }\n if (versionData.expectedVersion && mismatched.length > 0) {\n lines.push(` Expected: ${versionData.expectedVersion}`);\n }\n }\n\n // Duplicate packages details\n if (isObject(data) && \"duplicates\" in data) {\n const dupData = data as DuplicatePackageData;\n for (const dup of dupData.duplicates) {\n lines.push(` ${dup.name}:`);\n for (const instance of dup.instances) {\n lines.push(` ${instance.version} at ${instance.path}`);\n }\n }\n }\n\n // Fix suggestion\n if (result.fix) {\n lines.push(\"\");\n lines.push(` Fix: ${result.fix}`);\n }\n }\n\n return lines;\n};\n\n/**\n * Format the complete doctor result for human output.\n */\nexport const formatDoctorResult = (result: DoctorResult): string => {\n const lines: string[] = [];\n\n lines.push(`soda-gql doctor v${result.version}`);\n lines.push(\"\");\n\n for (const check of result.checks) {\n lines.push(...formatCheckResult(check));\n lines.push(\"\");\n }\n\n // Summary\n const passed = result.checks.filter((c) => c.status === \"pass\").length;\n\n if (result.issueCount === 0 && result.warningCount === 0) {\n lines.push(`Summary: All ${passed} checks passed`);\n } else {\n const parts: string[] = [];\n if (result.issueCount > 0) {\n parts.push(`${result.issueCount} issue${result.issueCount > 1 ? \"s\" : \"\"}`);\n }\n if (result.warningCount > 0) {\n parts.push(`${result.warningCount} warning${result.warningCount > 1 ? \"s\" : \"\"}`);\n }\n lines.push(`Summary: ${parts.join(\", \")} found`);\n }\n\n return lines.join(\"\\n\");\n};\n","/**\n * Doctor command entry point.\n * @module\n */\n\nimport { ok } from \"neverthrow\";\nimport type { CommandResult, CommandSuccess } from \"../../types\";\nimport { checkCodegenFreshness } from \"./checks/codegen-freshness\";\nimport { checkConfigValidation } from \"./checks/config-validation\";\nimport { checkDuplicatePackages } from \"./checks/duplicate-packages\";\nimport { checkVersionConsistency } from \"./checks/version-consistency\";\nimport { getCliVersion, getTypescriptVersion } from \"./discovery\";\nimport { formatDoctorResult } from \"./output\";\nimport type { CheckResult, DoctorResult } from \"./types\";\n\nconst DOCTOR_HELP = `Usage: soda-gql doctor\n\nRun diagnostic checks on your soda-gql installation.\n\nChecks performed:\n - Version consistency across @soda-gql packages\n - Duplicate package detection\n - Config file validation\n - Codegen freshness (schema vs generated code)\n\nOptions:\n --help, -h Show this help message\n`;\n\ntype DoctorCommandResult = CommandResult<CommandSuccess & { data?: DoctorResult }>;\n\nexport const doctorCommand = (argv: readonly string[]): DoctorCommandResult => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: DOCTOR_HELP });\n }\n\n const version = getCliVersion();\n const tsVersion = getTypescriptVersion();\n\n // Run all checks\n const checks: CheckResult[] = [];\n\n // Add TypeScript version as informational\n if (tsVersion) {\n checks.push({\n name: \"TypeScript Version\",\n status: \"pass\",\n message: `TypeScript version: ${tsVersion}`,\n });\n }\n\n // Phase 1 checks\n checks.push(checkVersionConsistency());\n checks.push(checkDuplicatePackages());\n\n // Phase 2 checks\n checks.push(checkConfigValidation());\n checks.push(checkCodegenFreshness());\n\n // Calculate summary\n const issueCount = checks.filter((c) => c.status === \"fail\").length;\n const warningCount = checks.filter((c) => c.status === \"warn\").length;\n\n const result: DoctorResult = {\n version,\n checks,\n issueCount,\n warningCount,\n };\n\n const message = formatDoctorResult(result);\n\n return ok({ message, data: result });\n};\n","import { access, readFile, writeFile } from \"node:fs/promises\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport fg from \"fast-glob\";\nimport { err, ok } from \"neverthrow\";\nimport { cliErrors } from \"../errors\";\nimport { FormatArgsSchema } from \"../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype FormatterModule = typeof import(\"@soda-gql/formatter\");\n\nconst loadFormatter = async (): Promise<FormatterModule | null> => {\n try {\n return await import(\"@soda-gql/formatter\");\n } catch {\n return null;\n }\n};\n\ntype FormatData = {\n mode: \"format\" | \"check\";\n total: number;\n modified: number;\n unchanged: number;\n errors: number;\n unformatted: string[];\n hasFormattingIssues: boolean;\n};\n\nconst formatResultMessage = (data: FormatData): string => {\n if (data.mode === \"check\") {\n if (data.unformatted.length > 0) {\n const files = data.unformatted.map((f) => ` ${f}`).join(\"\\n\");\n return `${data.unformatted.length} file(s) need formatting:\\n${files}`;\n }\n return `All ${data.total} file(s) are properly formatted`;\n }\n\n const parts: string[] = [];\n if (data.modified > 0) {\n parts.push(`${data.modified} formatted`);\n }\n if (data.unchanged > 0) {\n parts.push(`${data.unchanged} unchanged`);\n }\n if (data.errors > 0) {\n parts.push(`${data.errors} errors`);\n }\n return `${data.total} file(s) checked: ${parts.join(\", \")}`;\n};\n\nconst isGlobPattern = (pattern: string): boolean => {\n return /[*?[\\]{}]/.test(pattern);\n};\n\nconst expandGlobPatterns = async (patterns: readonly string[], excludePatterns: readonly string[] = []): Promise<string[]> => {\n const files: string[] = [];\n\n for (const pattern of patterns) {\n if (!isGlobPattern(pattern)) {\n // Direct file path - check if it exists\n try {\n await access(pattern);\n files.push(pattern);\n } catch {\n // File doesn't exist, skip it\n }\n continue;\n }\n\n // Glob pattern - use fast-glob with ignore\n const matches = await fg(pattern, {\n absolute: true,\n ignore: [...excludePatterns],\n });\n files.push(...matches);\n }\n\n return [...new Set(files)];\n};\n\nconst FORMAT_HELP = `Usage: soda-gql format [patterns...] [options]\n\nFormat soda-gql field selections by inserting empty comments.\n\nOptions:\n --config <path> Path to soda-gql.config.ts (auto-detected if omitted)\n --check Check if files need formatting (exit 1 if unformatted)\n --inject-fragment-keys Inject unique keys into anonymous fragments\n --help, -h Show this help message\n\nExamples:\n soda-gql format # Use config include/exclude\n soda-gql format \"src/**/*.ts\" # Override with explicit patterns\n soda-gql format --check # Check mode with config\n soda-gql format --inject-fragment-keys # Inject fragment keys\n`;\n\ntype FormatCommandResult = CommandResult<CommandSuccess & { data?: FormatData }>;\n\nexport const formatCommand = async (argv: readonly string[]): Promise<FormatCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: FORMAT_HELP });\n }\n\n const parsed = parseArgs([...argv], FormatArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"format\", parsed.error));\n }\n\n const args = parsed.value;\n const isCheckMode = args.check === true;\n const injectFragmentKeys = args[\"inject-fragment-keys\"] === true;\n const explicitPatterns = args._ ?? [];\n\n // Determine patterns: use explicit patterns or load from config\n let targetPatterns: readonly string[];\n let excludePatterns: readonly string[] = [];\n\n if (explicitPatterns.length > 0) {\n targetPatterns = explicitPatterns;\n } else {\n // Try to load patterns from config\n const configResult = loadConfig(args.config);\n if (configResult.isErr()) {\n return err(cliErrors.noPatterns());\n }\n targetPatterns = configResult.value.include;\n excludePatterns = configResult.value.exclude;\n }\n\n // Load formatter lazily - it's an optional dependency\n const formatter = await loadFormatter();\n if (!formatter) {\n return err(cliErrors.formatterNotInstalled());\n }\n\n const files = await expandGlobPatterns(targetPatterns, excludePatterns);\n\n if (files.length === 0) {\n const data: FormatData = {\n mode: isCheckMode ? \"check\" : \"format\",\n total: 0,\n modified: 0,\n unchanged: 0,\n errors: 0,\n unformatted: [],\n hasFormattingIssues: false,\n };\n return ok({ message: formatResultMessage(data), data });\n }\n\n let modified = 0;\n let unchanged = 0;\n let errors = 0;\n const unformatted: string[] = [];\n\n for (const filePath of files) {\n const sourceCode = await readFile(filePath, \"utf-8\");\n\n if (isCheckMode) {\n const result = formatter.needsFormat({ sourceCode, filePath });\n if (result.isErr()) {\n errors++;\n continue;\n }\n if (result.value) {\n unformatted.push(filePath);\n modified++;\n } else {\n unchanged++;\n }\n } else {\n const result = formatter.format({ sourceCode, filePath, injectFragmentKeys });\n if (result.isErr()) {\n errors++;\n continue;\n }\n if (result.value.modified) {\n await writeFile(filePath, result.value.sourceCode, \"utf-8\");\n modified++;\n } else {\n unchanged++;\n }\n }\n }\n\n const data: FormatData = {\n mode: isCheckMode ? \"check\" : \"format\",\n total: files.length,\n modified,\n unchanged,\n errors,\n unformatted,\n hasFormattingIssues: (isCheckMode && unformatted.length > 0) || errors > 0,\n };\n\n return ok({ message: formatResultMessage(data), data });\n};\n","export const getConfigTemplate = (): string => `\\\nimport { defineConfig } from \"@soda-gql/config\";\n\nexport default defineConfig({\n outdir: \"./graphql-system\",\n include: [\"./src/**/*.ts\"],\n schemas: {\n default: {\n schema: \"./schema.graphql\",\n inject: \"./graphql-system/default.inject.ts\",\n },\n },\n});\n`;\n","export const getGitignoreTemplate = (): string => `\\\n/index.ts\n/index.cjs\n`;\n","export const getInjectTemplate = (): string => `\\\nimport { defineAdapter, defineScalar } from \"@soda-gql/core/adapter\";\n\nexport const scalar = {\n ...defineScalar<\"ID\", string, string>(\"ID\"),\n ...defineScalar<\"String\", string, string>(\"String\"),\n ...defineScalar<\"Int\", number, number>(\"Int\"),\n ...defineScalar<\"Float\", number, number>(\"Float\"),\n ...defineScalar<\"Boolean\", boolean, boolean>(\"Boolean\"),\n} as const;\n\nexport const adapter = defineAdapter({\n helpers: {},\n metadata: {\n aggregateFragmentMetadata: (fragments) => fragments.map((m) => m.metadata),\n },\n});\n`;\n","export const getSchemaTemplate = (): string => `\\\ntype Query {\n hello: String!\n}\n`;\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { err, ok, type Result } from \"neverthrow\";\n\nimport { type CliError, cliErrors } from \"../errors\";\nimport { InitArgsSchema } from \"../schemas/args\";\nimport { getConfigTemplate } from \"../templates/config.template\";\nimport { getGitignoreTemplate } from \"../templates/gitignore.template\";\nimport { getInjectTemplate } from \"../templates/inject.template\";\nimport { getSchemaTemplate } from \"../templates/schema.template\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype FileToGenerate = {\n readonly path: string;\n readonly content: string;\n readonly description: string;\n};\n\ntype InitSuccess = {\n readonly filesCreated: readonly string[];\n};\n\nconst INIT_HELP = `Usage: soda-gql init [options]\n\nInitialize a new soda-gql project with starter configuration.\n\nOptions:\n --force Overwrite existing files\n --help, -h Show this help message\n\nGenerated files:\n soda-gql.config.ts Configuration file\n schema.graphql Sample GraphQL schema\n graphql-system/default.inject.ts Scalars, helpers, and metadata adapter\n graphql-system/.gitignore Ignore generated files\n`;\n\nconst checkFilesExist = (files: readonly FileToGenerate[], force: boolean): Result<void, CliError> => {\n if (force) {\n return ok(undefined);\n }\n\n for (const file of files) {\n if (existsSync(file.path)) {\n return err(cliErrors.fileExists(file.path));\n }\n }\n\n return ok(undefined);\n};\n\nconst writeFiles = (files: readonly FileToGenerate[]): Result<InitSuccess, CliError> => {\n const createdPaths: string[] = [];\n\n for (const file of files) {\n try {\n const dir = dirname(file.path);\n mkdirSync(dir, { recursive: true });\n writeFileSync(file.path, file.content);\n createdPaths.push(file.path);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return err(cliErrors.writeFailed(file.path, `Failed to write ${file.description}: ${message}`, error));\n }\n }\n\n return ok({ filesCreated: createdPaths });\n};\n\nconst formatSuccess = (result: InitSuccess): string => {\n const lines = [\"soda-gql project initialized successfully!\", \"\", \"Created files:\"];\n for (const file of result.filesCreated) {\n lines.push(` ${file}`);\n }\n lines.push(\"\", \"Next steps:\");\n lines.push(\" 1. Edit schema.graphql with your GraphQL types\");\n lines.push(\" 2. Run: soda-gql codegen\");\n lines.push(\" 3. Import gql from ./graphql-system\");\n return lines.join(\"\\n\");\n};\n\ntype InitCommandResult = CommandResult<CommandSuccess & { data?: InitSuccess }>;\n\nexport const initCommand = async (argv: readonly string[]): Promise<InitCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: INIT_HELP });\n }\n\n const parsed = parseArgs([...argv], InitArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"init\", parsed.error));\n }\n\n const args = parsed.value;\n const force = args.force === true;\n const cwd = process.cwd();\n\n const files: FileToGenerate[] = [\n {\n path: resolve(cwd, \"soda-gql.config.ts\"),\n content: getConfigTemplate(),\n description: \"configuration file\",\n },\n {\n path: resolve(cwd, \"schema.graphql\"),\n content: getSchemaTemplate(),\n description: \"GraphQL schema\",\n },\n {\n path: resolve(cwd, \"graphql-system/default.inject.ts\"),\n content: getInjectTemplate(),\n description: \"inject module\",\n },\n {\n path: resolve(cwd, \"graphql-system/.gitignore\"),\n content: getGitignoreTemplate(),\n description: \"gitignore file\",\n },\n ];\n\n const existsCheck = checkFilesExist(files, force);\n if (existsCheck.isErr()) {\n return err(existsCheck.error);\n }\n\n const writeResult = writeFiles(files);\n if (writeResult.isErr()) {\n return err(writeResult.error);\n }\n\n return ok({ message: formatSuccess(writeResult.value), data: writeResult.value });\n};\n","import { loadConfig } from \"@soda-gql/config\";\nimport { runTypegen } from \"@soda-gql/typegen\";\nimport { err, ok } from \"neverthrow\";\nimport { type CliResult, cliErrors } from \"../errors\";\nimport { TypegenArgsSchema } from \"../schemas/args\";\nimport type { CommandResult, CommandSuccess } from \"../types\";\nimport { parseArgs } from \"../utils/parse-args\";\n\ntype ParsedCommand = {\n kind: \"generate\";\n configPath?: string;\n};\n\nconst parseTypegenArgs = (argv: readonly string[]): CliResult<ParsedCommand> => {\n const parsed = parseArgs([...argv], TypegenArgsSchema);\n\n if (!parsed.isOk()) {\n return err(cliErrors.argsInvalid(\"typegen\", parsed.error));\n }\n\n return ok({\n kind: \"generate\",\n configPath: parsed.value.config,\n });\n};\n\ntype TypegenSuccessData = {\n prebuiltIndexPath: string;\n prebuiltTypesPath: string;\n fragmentCount: number;\n operationCount: number;\n warnings: readonly string[];\n};\n\nconst formatSuccess = (data: TypegenSuccessData): string => {\n const lines: string[] = [];\n lines.push(`Generated prebuilt types:`);\n lines.push(` Index: ${data.prebuiltIndexPath}`);\n lines.push(` Types: ${data.prebuiltTypesPath}`);\n lines.push(` Fragments: ${data.fragmentCount}, Operations: ${data.operationCount}`);\n\n if (data.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"Warnings:\");\n for (const warning of data.warnings) {\n lines.push(` ${warning}`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n\nconst TYPEGEN_HELP = `Usage: soda-gql typegen [options]\n\nGenerate prebuilt types from source code.\n\nOptions:\n --config <path> Path to soda-gql.config.ts\n --help, -h Show this help message\n\nExamples:\n soda-gql typegen\n soda-gql typegen --config ./soda-gql.config.ts\n\nNote: Run 'soda-gql codegen' first to generate the graphql-system module.\n`;\n\ntype TypegenCommandResult = CommandResult<CommandSuccess & { data?: TypegenSuccessData }>;\n\nexport const typegenCommand = async (argv: readonly string[]): Promise<TypegenCommandResult> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n return ok({ message: TYPEGEN_HELP });\n }\n\n const parsed = parseTypegenArgs(argv);\n\n if (parsed.isErr()) {\n return err(parsed.error);\n }\n\n const command = parsed.value;\n\n // Load config from @soda-gql/config\n const configResult = loadConfig(command.configPath);\n if (configResult.isErr()) {\n return err(cliErrors.fromConfig(configResult.error));\n }\n\n const config = configResult.value;\n\n // Run typegen\n const result = await runTypegen({\n config,\n });\n\n if (result.isErr()) {\n // Handle typegen-specific errors\n const error = result.error;\n if (error.code === \"TYPEGEN_CODEGEN_REQUIRED\") {\n return err(cliErrors.argsInvalid(\"typegen\", `${error.message}\\nRun 'soda-gql codegen' first.`));\n }\n return err(cliErrors.fromTypegen(error));\n }\n\n const data: TypegenSuccessData = {\n prebuiltIndexPath: result.value.prebuiltIndexPath,\n prebuiltTypesPath: result.value.prebuiltTypesPath,\n fragmentCount: result.value.fragmentCount,\n operationCount: result.value.operationCount,\n warnings: result.value.warnings,\n };\n\n return ok({ message: formatSuccess(data), data });\n};\n","import { formatBuilderErrorForCLI } from \"@soda-gql/builder\";\nimport type { CliError, CliErrorCode } from \"../errors\";\nimport type { OutputFormat } from \"../types\";\n\nexport type { OutputFormat } from \"../types\";\n\n/**\n * CLI-specific error hints to help users fix issues.\n */\nconst cliErrorHints: Partial<Record<CliErrorCode, string>> = {\n CLI_ARGS_INVALID: \"Check command usage with --help\",\n CLI_UNKNOWN_COMMAND: \"Run 'soda-gql --help' for available commands\",\n CLI_UNKNOWN_SUBCOMMAND: \"Run the parent command with --help for available subcommands\",\n CLI_FILE_EXISTS: \"Use --force flag to overwrite existing files\",\n CLI_FILE_NOT_FOUND: \"Verify the file path exists\",\n CLI_WRITE_FAILED: \"Check write permissions and disk space\",\n CLI_READ_FAILED: \"Check file permissions and verify the file is not locked\",\n CLI_NO_PATTERNS: \"Provide file patterns or create soda-gql.config.ts\",\n CLI_FORMATTER_NOT_INSTALLED: \"Install with: bun add @soda-gql/formatter\",\n CLI_PARSE_ERROR: \"Check the file for syntax errors\",\n CLI_FORMAT_ERROR: \"Verify the file contains valid soda-gql code\",\n CLI_UNEXPECTED: \"This is an unexpected error. Please report at https://github.com/soda-gql/soda-gql/issues\",\n};\n\n/**\n * Codegen-specific error hints.\n */\nconst codegenErrorHints: Record<string, string> = {\n SCHEMA_NOT_FOUND: \"Verify the schema path in soda-gql.config.ts\",\n SCHEMA_INVALID: \"Check your GraphQL schema for syntax errors\",\n INJECT_MODULE_NOT_FOUND: \"Run: soda-gql codegen --emit-inject-template <path>\",\n INJECT_MODULE_REQUIRED: \"Add inject configuration to your schema in soda-gql.config.ts\",\n INJECT_TEMPLATE_EXISTS: \"Delete the existing file to regenerate, or use a different path\",\n EMIT_FAILED: \"Check write permissions and that the output directory exists\",\n INJECT_TEMPLATE_FAILED: \"Check write permissions for the output path\",\n};\n\n/**\n * Config-specific error hints.\n */\nconst configErrorHints: Record<string, string> = {\n CONFIG_NOT_FOUND: \"Create a soda-gql.config.ts file in your project root\",\n CONFIG_LOAD_FAILED: \"Check your configuration file for syntax errors\",\n CONFIG_VALIDATION_FAILED: \"Verify your configuration matches the expected schema\",\n CONFIG_INVALID_PATH: \"Verify the path in your configuration exists\",\n};\n\n/**\n * Artifact-specific error hints.\n */\nconst artifactErrorHints: Record<string, string> = {\n ARTIFACT_NOT_FOUND: \"Verify the artifact file path exists\",\n ARTIFACT_PARSE_ERROR: \"Check that the artifact file is valid JSON\",\n ARTIFACT_VALIDATION_ERROR: \"Verify the artifact was built with a compatible version of soda-gql\",\n};\n\n/**\n * Typegen-specific error hints.\n */\nconst typegenErrorHints: Record<string, string> = {\n TYPEGEN_CODEGEN_REQUIRED: \"Run 'soda-gql codegen' before running typegen\",\n TYPEGEN_SCHEMA_LOAD_FAILED: \"Verify the generated CJS bundle is valid\",\n TYPEGEN_BUILD_FAILED: \"Check for errors in your source files\",\n TYPEGEN_EMIT_FAILED: \"Check write permissions for the output directory\",\n TYPEGEN_BUNDLE_FAILED: \"Check write permissions for the prebuilt directory\",\n};\n\n/**\n * Get hint for any error type.\n */\nconst getErrorHint = (error: CliError): string | undefined => {\n if (error.category === \"cli\") {\n return cliErrorHints[error.code];\n }\n if (error.category === \"codegen\") {\n return codegenErrorHints[error.error.code];\n }\n if (error.category === \"config\") {\n return configErrorHints[error.error.code];\n }\n if (error.category === \"artifact\") {\n return artifactErrorHints[error.error.code];\n }\n if (error.category === \"typegen\") {\n return typegenErrorHints[error.error.code];\n }\n // Builder errors use their own hints via formatBuilderErrorForCLI\n return undefined;\n};\n\n/**\n * Format CliError to human-readable string with hints.\n */\nexport const formatCliErrorHuman = (error: CliError): string => {\n // Delegate to builder's formatter for builder errors\n if (error.category === \"builder\") {\n return formatBuilderErrorForCLI(error.error);\n }\n\n const lines: string[] = [];\n\n if (error.category === \"codegen\") {\n const codegenError = error.error;\n lines.push(`Error [${codegenError.code}]: ${codegenError.message}`);\n\n // Add context based on error type\n if (\"schemaPath\" in codegenError) {\n lines.push(` Schema: ${codegenError.schemaPath}`);\n }\n if (\"outPath\" in codegenError && codegenError.outPath) {\n lines.push(` Output: ${codegenError.outPath}`);\n }\n if (\"injectPath\" in codegenError) {\n lines.push(` Inject: ${codegenError.injectPath}`);\n }\n } else if (error.category === \"config\") {\n const configError = error.error;\n lines.push(`Error [${configError.code}]: ${configError.message}`);\n if (configError.filePath) {\n lines.push(` Config: ${configError.filePath}`);\n }\n } else if (error.category === \"artifact\") {\n const artifactError = error.error;\n lines.push(`Error [${artifactError.code}]: ${artifactError.message}`);\n if (artifactError.filePath) {\n lines.push(` Artifact: ${artifactError.filePath}`);\n }\n } else if (error.category === \"typegen\") {\n const typegenError = error.error;\n lines.push(`Error [${typegenError.code}]: ${typegenError.message}`);\n } else {\n // CLI errors\n lines.push(`Error [${error.code}]: ${error.message}`);\n\n if (\"filePath\" in error && error.filePath) {\n lines.push(` File: ${error.filePath}`);\n }\n if (\"command\" in error && error.code !== \"CLI_UNKNOWN_COMMAND\") {\n lines.push(` Command: ${error.command}`);\n }\n if (\"parent\" in error) {\n lines.push(` Parent: ${error.parent}`);\n }\n }\n\n const hint = getErrorHint(error);\n if (hint) {\n lines.push(\"\");\n lines.push(` Hint: ${hint}`);\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Format CliError to JSON string.\n */\nexport const formatCliErrorJson = (error: CliError): string => {\n if (error.category === \"cli\") {\n const { category: _category, ...rest } = error;\n return JSON.stringify({ error: rest }, null, 2);\n }\n return JSON.stringify({ error: error.error }, null, 2);\n};\n\n/**\n * Format CliError with output format preference.\n */\nexport const formatCliError = (error: CliError, format: OutputFormat = \"human\"): string => {\n return format === \"json\" ? formatCliErrorJson(error) : formatCliErrorHuman(error);\n};\n\n// ---- Legacy formatters (kept for backward compatibility) ----\n\nexport const formatters = {\n json: (data: unknown) => JSON.stringify(data, null, 2),\n human: (data: unknown) => {\n if (typeof data === \"string\") return data;\n if (data instanceof Error) return data.message;\n return JSON.stringify(data, null, 2);\n },\n} as const;\n\nexport const formatOutput = (data: unknown, format: OutputFormat = \"human\"): string => {\n return formatters[format](data);\n};\n\n/**\n * @deprecated Use formatCliError instead for CliError types.\n */\nexport const formatError = (error: unknown, format: OutputFormat = \"human\"): string => {\n if (format === \"json\") {\n return JSON.stringify(\n {\n error: error,\n },\n null,\n 2,\n );\n }\n return error instanceof Error ? error.message : String(error);\n};\n","import { err, ok } from \"neverthrow\";\nimport { artifactCommand } from \"./commands/artifact\";\nimport { codegenCommand } from \"./commands/codegen/index\";\nimport { doctorCommand } from \"./commands/doctor\";\nimport { formatCommand } from \"./commands/format\";\nimport { initCommand } from \"./commands/init\";\nimport { typegenCommand } from \"./commands/typegen\";\nimport { cliErrors } from \"./errors\";\nimport type { CommandResult, CommandSuccess, OutputFormat } from \"./types\";\nimport { formatCliError } from \"./utils/format\";\n\nconst MAIN_HELP = `Usage: soda-gql <command> [options]\n\nCommands:\n init Initialize a new soda-gql project\n codegen Generate graphql-system runtime module\n typegen Generate prebuilt types from source code\n format Format soda-gql field selections\n artifact Manage soda-gql artifacts\n doctor Run diagnostic checks\n\nRun 'soda-gql <command> --help' for more information on a specific command.\n`;\n\n/**\n * Parse output format from argv.\n * Returns \"json\" if --format=json or --json flag is present, otherwise \"human\".\n */\nconst getOutputFormat = (argv: readonly string[]): OutputFormat => {\n for (const arg of argv) {\n if (arg === \"--format=json\" || arg === \"--json\") {\n return \"json\";\n }\n if (arg === \"--format=human\") {\n return \"human\";\n }\n }\n return \"human\";\n};\n\ntype DispatchResult = CommandResult<CommandSuccess & { exitCode?: number }>;\n\nconst dispatch = async (argv: readonly string[]): Promise<DispatchResult> => {\n const [command, ...rest] = argv;\n\n if (!command || command === \"--help\" || command === \"-h\") {\n return ok({ message: MAIN_HELP });\n }\n\n if (command === \"init\") {\n return initCommand(rest);\n }\n\n if (command === \"codegen\") {\n return codegenCommand(rest);\n }\n\n if (command === \"typegen\") {\n return typegenCommand(rest);\n }\n\n if (command === \"format\") {\n const result = await formatCommand(rest);\n if (result.isOk()) {\n // Format command uses exit 1 for unformatted files in check mode or errors\n const exitCode = result.value.data?.hasFormattingIssues ? 1 : 0;\n return ok({ ...result.value, exitCode });\n }\n return err(result.error);\n }\n\n if (command === \"artifact\") {\n return artifactCommand(rest);\n }\n\n if (command === \"doctor\") {\n const result = doctorCommand(rest);\n if (result.isOk()) {\n // Doctor uses exit 1 if issues found\n const exitCode = result.value.data?.issueCount ? 1 : 0;\n return ok({ ...result.value, exitCode });\n }\n return result;\n }\n\n return err(cliErrors.unknownCommand(command));\n};\n\n// Run CLI when executed directly\nconst main = async () => {\n const argv = process.argv.slice(2);\n const format = getOutputFormat(argv);\n\n const result = await dispatch(argv);\n\n if (result.isOk()) {\n process.stdout.write(`${result.value.message}\\n`);\n process.exitCode = result.value.exitCode ?? 0;\n } else {\n process.stderr.write(`${formatCliError(result.error, format)}\\n`);\n process.exitCode = 1;\n }\n};\n\nmain().catch((error) => {\n const unexpectedError = cliErrors.unexpected(error instanceof Error ? error.message : String(error), error);\n const format = getOutputFormat(process.argv.slice(2));\n process.stderr.write(`${formatCliError(unexpectedError, format)}\\n`);\n process.exitCode = 1;\n});\n\nexport { dispatch };\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -81,6 +81,19 @@ type CliError = {
|
|
|
81
81
|
readonly code: "CLI_FORMAT_ERROR";
|
|
82
82
|
readonly message: string;
|
|
83
83
|
readonly filePath?: string;
|
|
84
|
+
} | {
|
|
85
|
+
readonly category: "cli";
|
|
86
|
+
readonly code: "CLI_DUPLICATE_FRAGMENT";
|
|
87
|
+
readonly message: string;
|
|
88
|
+
readonly fragmentName: string;
|
|
89
|
+
readonly existingFile: string;
|
|
90
|
+
readonly newFile: string;
|
|
91
|
+
} | {
|
|
92
|
+
readonly category: "cli";
|
|
93
|
+
readonly code: "CLI_FRAGMENT_NOT_FOUND";
|
|
94
|
+
readonly message: string;
|
|
95
|
+
readonly fragmentName: string;
|
|
96
|
+
readonly referencedIn: string;
|
|
84
97
|
} | {
|
|
85
98
|
readonly category: "cli";
|
|
86
99
|
readonly code: "CLI_UNEXPECTED";
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;ACWY,IAAA,
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;ACWY,IAAA,CD2BA,QAAA,CAAA,CAAA,CC3Ba;EAAK,QAAA,CAAA,QAAA,CAAA,CAAA,CAAA,OAAA,CAAA;EAAyB,QAAA,CAAA,KAAA,CAAA,CD6BH,YC7BG;CAAG,CAAA,CAAA,CAAA;EAAV,QAAA,CAAA,QAAA,CAAA,CAAA,CAAA,OAAA,CAAA;EAAM,QAAA,CAAA,KAAA,CAAA,CD8BF,YC9BE;AAKtD,CAAA,CAAA,CAAA,CAAY;;kBD0ByC;;EEFhD,QAAA,CAAA,QAAc,CAAA,CAAA,CAAA,MAAA,CAAA;EAEb,QAAA,CAAA,KA4CL,CAAA,CF3CkD,WEDO;;;kBFEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AANpD,CAAA,CAAA,CAAA,MAAA,CAAA,IAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,QAAA;;AAGoD,IAAA,CC9BxC,aD8BwC,CAAA,CAAA,CAAA,CAAA,CC9BtB,cD8BsB,CAAA,CAAA,CAAA,CC9BJ,MD8BI,CC9BG,CD8BH,CAAA,CC9BM,QD8BN,CAAA;;;;AAGY,IAAA,CC5BpD,cAAA,CAAA,CAAA,CD4BoD;;;;;KEJ3D,cAAA,CAAA,CAAA,CAAiB,cAAc;;;cAE9B,uCAA4C,QAAQ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soda-gql/cli",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.12",
|
|
4
4
|
"description": "Command-line interface for soda-gql",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -50,10 +50,11 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@soda-gql/
|
|
54
|
-
"@soda-gql/
|
|
55
|
-
"@soda-gql/
|
|
56
|
-
"@soda-gql/
|
|
53
|
+
"@soda-gql/common": "0.11.12",
|
|
54
|
+
"@soda-gql/codegen": "0.11.12",
|
|
55
|
+
"@soda-gql/builder": "0.11.12",
|
|
56
|
+
"@soda-gql/config": "0.11.12",
|
|
57
|
+
"@soda-gql/typegen": "0.11.12",
|
|
57
58
|
"fast-glob": "^3.3.3",
|
|
58
59
|
"neverthrow": "^8.1.1",
|
|
59
60
|
"zod": "^4.1.11"
|
|
@@ -61,6 +62,6 @@
|
|
|
61
62
|
"devDependencies": {},
|
|
62
63
|
"peerDependencies": {},
|
|
63
64
|
"optionalDependencies": {
|
|
64
|
-
"@soda-gql/formatter": "0.11.
|
|
65
|
+
"@soda-gql/formatter": "0.11.12"
|
|
65
66
|
}
|
|
66
67
|
}
|