@soda-gql/cli 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +387 -253
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -1
- package/dist/index.d.cts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26,17 +26,115 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
}) : target, mod));
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
|
+
let neverthrow = require("neverthrow");
|
|
29
30
|
let node_fs_promises = require("node:fs/promises");
|
|
30
31
|
let node_path = require("node:path");
|
|
31
32
|
let __soda_gql_builder = require("@soda-gql/builder");
|
|
32
33
|
let __soda_gql_config = require("@soda-gql/config");
|
|
33
34
|
let __soda_gql_codegen = require("@soda-gql/codegen");
|
|
34
|
-
let neverthrow = require("neverthrow");
|
|
35
35
|
let zod = require("zod");
|
|
36
36
|
let fast_glob = require("fast-glob");
|
|
37
37
|
fast_glob = __toESM(fast_glob);
|
|
38
38
|
let node_fs = require("node:fs");
|
|
39
39
|
|
|
40
|
+
//#region packages/cli/src/errors.ts
|
|
41
|
+
/**
|
|
42
|
+
* Error constructor helpers for concise error creation.
|
|
43
|
+
* Each function returns a specific error type for better type inference.
|
|
44
|
+
*/
|
|
45
|
+
const cliErrors = {
|
|
46
|
+
argsInvalid: (command, message) => ({
|
|
47
|
+
category: "cli",
|
|
48
|
+
code: "CLI_ARGS_INVALID",
|
|
49
|
+
message,
|
|
50
|
+
command
|
|
51
|
+
}),
|
|
52
|
+
unknownCommand: (command) => ({
|
|
53
|
+
category: "cli",
|
|
54
|
+
code: "CLI_UNKNOWN_COMMAND",
|
|
55
|
+
message: `Unknown command: ${command}`,
|
|
56
|
+
command
|
|
57
|
+
}),
|
|
58
|
+
unknownSubcommand: (parent, subcommand) => ({
|
|
59
|
+
category: "cli",
|
|
60
|
+
code: "CLI_UNKNOWN_SUBCOMMAND",
|
|
61
|
+
message: `Unknown subcommand: ${subcommand}`,
|
|
62
|
+
parent,
|
|
63
|
+
subcommand
|
|
64
|
+
}),
|
|
65
|
+
fileExists: (filePath, message) => ({
|
|
66
|
+
category: "cli",
|
|
67
|
+
code: "CLI_FILE_EXISTS",
|
|
68
|
+
message: message ?? `File already exists: ${filePath}. Use --force to overwrite.`,
|
|
69
|
+
filePath
|
|
70
|
+
}),
|
|
71
|
+
fileNotFound: (filePath, message) => ({
|
|
72
|
+
category: "cli",
|
|
73
|
+
code: "CLI_FILE_NOT_FOUND",
|
|
74
|
+
message: message ?? `File not found: ${filePath}`,
|
|
75
|
+
filePath
|
|
76
|
+
}),
|
|
77
|
+
writeFailed: (filePath, message, cause) => ({
|
|
78
|
+
category: "cli",
|
|
79
|
+
code: "CLI_WRITE_FAILED",
|
|
80
|
+
message: message ?? `Failed to write file: ${filePath}`,
|
|
81
|
+
filePath,
|
|
82
|
+
cause
|
|
83
|
+
}),
|
|
84
|
+
readFailed: (filePath, message, cause) => ({
|
|
85
|
+
category: "cli",
|
|
86
|
+
code: "CLI_READ_FAILED",
|
|
87
|
+
message: message ?? `Failed to read file: ${filePath}`,
|
|
88
|
+
filePath,
|
|
89
|
+
cause
|
|
90
|
+
}),
|
|
91
|
+
noPatterns: (message) => ({
|
|
92
|
+
category: "cli",
|
|
93
|
+
code: "CLI_NO_PATTERNS",
|
|
94
|
+
message: message ?? "No patterns provided and config not found. Usage: soda-gql format [patterns...] [--check]"
|
|
95
|
+
}),
|
|
96
|
+
formatterNotInstalled: (message) => ({
|
|
97
|
+
category: "cli",
|
|
98
|
+
code: "CLI_FORMATTER_NOT_INSTALLED",
|
|
99
|
+
message: message ?? "@soda-gql/formatter is not installed. Run: bun add @soda-gql/formatter"
|
|
100
|
+
}),
|
|
101
|
+
parseError: (message, filePath) => ({
|
|
102
|
+
category: "cli",
|
|
103
|
+
code: "CLI_PARSE_ERROR",
|
|
104
|
+
message,
|
|
105
|
+
filePath
|
|
106
|
+
}),
|
|
107
|
+
formatError: (message, filePath) => ({
|
|
108
|
+
category: "cli",
|
|
109
|
+
code: "CLI_FORMAT_ERROR",
|
|
110
|
+
message,
|
|
111
|
+
filePath
|
|
112
|
+
}),
|
|
113
|
+
unexpected: (message, cause) => ({
|
|
114
|
+
category: "cli",
|
|
115
|
+
code: "CLI_UNEXPECTED",
|
|
116
|
+
message,
|
|
117
|
+
cause
|
|
118
|
+
}),
|
|
119
|
+
fromCodegen: (error) => ({
|
|
120
|
+
category: "codegen",
|
|
121
|
+
error
|
|
122
|
+
}),
|
|
123
|
+
fromBuilder: (error) => ({
|
|
124
|
+
category: "builder",
|
|
125
|
+
error
|
|
126
|
+
}),
|
|
127
|
+
fromArtifact: (error) => ({
|
|
128
|
+
category: "artifact",
|
|
129
|
+
error
|
|
130
|
+
}),
|
|
131
|
+
fromConfig: (error) => ({
|
|
132
|
+
category: "config",
|
|
133
|
+
error
|
|
134
|
+
})
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
//#endregion
|
|
40
138
|
//#region packages/cli/src/commands/artifact/build.ts
|
|
41
139
|
const BUILD_HELP = `Usage: soda-gql artifact build [options]
|
|
42
140
|
|
|
@@ -78,33 +176,29 @@ const parseBuildArgs = (argv) => {
|
|
|
78
176
|
}
|
|
79
177
|
return args;
|
|
80
178
|
};
|
|
179
|
+
const formatSuccess$3 = (data) => {
|
|
180
|
+
const { artifact, outputPath, dryRun } = data;
|
|
181
|
+
const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === "fragment").length;
|
|
182
|
+
const operationCount = Object.values(artifact.elements).filter((e) => e.type === "operation").length;
|
|
183
|
+
const lines = [];
|
|
184
|
+
if (dryRun) lines.push(`Validation passed: ${fragmentCount} fragments, ${operationCount} operations`);
|
|
185
|
+
else lines.push(`Build complete: ${fragmentCount} fragments, ${operationCount} operations`);
|
|
186
|
+
if (artifact.meta?.version) lines.push(` Version: ${artifact.meta.version}`);
|
|
187
|
+
if (outputPath && !dryRun) lines.push(`Artifact written to: ${outputPath}`);
|
|
188
|
+
return lines.join("\n");
|
|
189
|
+
};
|
|
81
190
|
/**
|
|
82
191
|
* Build command - builds and validates soda-gql artifacts.
|
|
83
192
|
*/
|
|
84
193
|
const buildCommand = async (argv) => {
|
|
85
194
|
const args = parseBuildArgs(argv);
|
|
86
|
-
if (args.help) {
|
|
87
|
-
process.stdout.write(BUILD_HELP);
|
|
88
|
-
return 0;
|
|
89
|
-
}
|
|
195
|
+
if (args.help) return (0, neverthrow.ok)({ message: BUILD_HELP });
|
|
90
196
|
const configResult = (0, __soda_gql_config.loadConfig)(args.configPath);
|
|
91
|
-
if (configResult.isErr())
|
|
92
|
-
const error = configResult.error;
|
|
93
|
-
process.stderr.write(`Error: Failed to load config\n`);
|
|
94
|
-
process.stderr.write(` at ${error.filePath}\n`);
|
|
95
|
-
process.stderr.write(` ${error.message}\n`);
|
|
96
|
-
return 1;
|
|
97
|
-
}
|
|
197
|
+
if (configResult.isErr()) return (0, neverthrow.err)(cliErrors.fromConfig(configResult.error));
|
|
98
198
|
const config = configResult.value;
|
|
99
199
|
const buildResult = await (0, __soda_gql_builder.createBuilderService)({ config }).buildAsync();
|
|
100
|
-
if (buildResult.isErr())
|
|
101
|
-
const formattedError = (0, __soda_gql_builder.formatBuilderErrorForCLI)(buildResult.error);
|
|
102
|
-
process.stderr.write(`${formattedError}\n`);
|
|
103
|
-
return 1;
|
|
104
|
-
}
|
|
200
|
+
if (buildResult.isErr()) return (0, neverthrow.err)(cliErrors.fromBuilder(buildResult.error));
|
|
105
201
|
const artifact = buildResult.value;
|
|
106
|
-
const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === "fragment").length;
|
|
107
|
-
const operationCount = Object.values(artifact.elements).filter((e) => e.type === "operation").length;
|
|
108
202
|
const meta = args.version ? {
|
|
109
203
|
version: args.version,
|
|
110
204
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -114,17 +208,33 @@ const buildCommand = async (argv) => {
|
|
|
114
208
|
...artifact
|
|
115
209
|
};
|
|
116
210
|
if (args.dryRun) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
211
|
+
const data$1 = {
|
|
212
|
+
artifact: artifactWithMeta,
|
|
213
|
+
dryRun: true
|
|
214
|
+
};
|
|
215
|
+
return (0, neverthrow.ok)({
|
|
216
|
+
message: formatSuccess$3(data$1),
|
|
217
|
+
data: data$1
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
const outputPath = (0, node_path.resolve)(process.cwd(), args.outputPath);
|
|
221
|
+
const outputDir = (0, node_path.dirname)(outputPath);
|
|
222
|
+
try {
|
|
223
|
+
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
122
224
|
await (0, node_fs_promises.writeFile)(outputPath, JSON.stringify(artifactWithMeta, null, 2));
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
225
|
+
} catch (error) {
|
|
226
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
227
|
+
return (0, neverthrow.err)(cliErrors.writeFailed(outputPath, `Failed to write artifact: ${message}`, error));
|
|
126
228
|
}
|
|
127
|
-
|
|
229
|
+
const data = {
|
|
230
|
+
artifact: artifactWithMeta,
|
|
231
|
+
outputPath,
|
|
232
|
+
dryRun: false
|
|
233
|
+
};
|
|
234
|
+
return (0, neverthrow.ok)({
|
|
235
|
+
message: formatSuccess$3(data),
|
|
236
|
+
data
|
|
237
|
+
});
|
|
128
238
|
};
|
|
129
239
|
|
|
130
240
|
//#endregion
|
|
@@ -155,36 +265,27 @@ const parseValidateArgs = (argv) => {
|
|
|
155
265
|
else if (!arg.startsWith("-")) args.artifactPath = arg;
|
|
156
266
|
return args;
|
|
157
267
|
};
|
|
268
|
+
const formatSuccess$2 = (artifact) => {
|
|
269
|
+
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`];
|
|
270
|
+
if (artifact.meta) {
|
|
271
|
+
lines.push(` Version: ${artifact.meta.version}`);
|
|
272
|
+
lines.push(` Created: ${artifact.meta.createdAt}`);
|
|
273
|
+
} else lines.push(` (No metadata - legacy artifact format)`);
|
|
274
|
+
return lines.join("\n");
|
|
275
|
+
};
|
|
158
276
|
/**
|
|
159
277
|
* Validate command - validates a pre-built artifact file.
|
|
160
278
|
*/
|
|
161
279
|
const validateCommand = async (argv) => {
|
|
162
280
|
const args = parseValidateArgs(argv);
|
|
163
|
-
if (args.help) {
|
|
164
|
-
|
|
165
|
-
return 0;
|
|
166
|
-
}
|
|
167
|
-
if (!args.artifactPath) {
|
|
168
|
-
process.stderr.write("Error: Missing artifact path argument\n\n");
|
|
169
|
-
process.stdout.write(VALIDATE_HELP);
|
|
170
|
-
return 1;
|
|
171
|
-
}
|
|
281
|
+
if (args.help) return (0, neverthrow.ok)({ message: VALIDATE_HELP });
|
|
282
|
+
if (!args.artifactPath) return (0, neverthrow.err)(cliErrors.argsInvalid("artifact validate", "Missing artifact path argument"));
|
|
172
283
|
const result = await (0, __soda_gql_builder.loadArtifact)((0, node_path.resolve)(process.cwd(), args.artifactPath));
|
|
173
|
-
if (result.isErr())
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
const artifact = result.value;
|
|
180
|
-
const fragmentCount = Object.values(artifact.elements).filter((e) => e.type === "fragment").length;
|
|
181
|
-
const operationCount = Object.values(artifact.elements).filter((e) => e.type === "operation").length;
|
|
182
|
-
process.stdout.write(`Artifact valid: ${fragmentCount} fragments, ${operationCount} operations\n`);
|
|
183
|
-
if (artifact.meta) {
|
|
184
|
-
process.stdout.write(` Version: ${artifact.meta.version}\n`);
|
|
185
|
-
process.stdout.write(` Created: ${artifact.meta.createdAt}\n`);
|
|
186
|
-
} else process.stdout.write(` (No metadata - legacy artifact format)\n`);
|
|
187
|
-
return 0;
|
|
284
|
+
if (result.isErr()) return (0, neverthrow.err)(cliErrors.fromArtifact(result.error));
|
|
285
|
+
return (0, neverthrow.ok)({
|
|
286
|
+
message: formatSuccess$2(result.value),
|
|
287
|
+
data: result.value
|
|
288
|
+
});
|
|
188
289
|
};
|
|
189
290
|
|
|
190
291
|
//#endregion
|
|
@@ -204,15 +305,10 @@ Run 'soda-gql artifact <subcommand> --help' for more information.
|
|
|
204
305
|
*/
|
|
205
306
|
const artifactCommand = async (argv) => {
|
|
206
307
|
const [subcommand, ...rest] = argv;
|
|
207
|
-
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
208
|
-
process.stdout.write(ARTIFACT_HELP);
|
|
209
|
-
return 0;
|
|
210
|
-
}
|
|
308
|
+
if (!subcommand || subcommand === "--help" || subcommand === "-h") return (0, neverthrow.ok)({ message: ARTIFACT_HELP });
|
|
211
309
|
if (subcommand === "build") return buildCommand(rest);
|
|
212
310
|
if (subcommand === "validate") return validateCommand(rest);
|
|
213
|
-
|
|
214
|
-
process.stderr.write(`Run 'soda-gql artifact --help' for available subcommands.\n`);
|
|
215
|
-
return 1;
|
|
311
|
+
return (0, neverthrow.err)(cliErrors.unknownSubcommand("artifact", subcommand));
|
|
216
312
|
};
|
|
217
313
|
|
|
218
314
|
//#endregion
|
|
@@ -262,28 +358,16 @@ const parseArgs = (args, schema) => {
|
|
|
262
358
|
//#region packages/cli/src/commands/codegen.ts
|
|
263
359
|
const parseCodegenArgs = (argv) => {
|
|
264
360
|
const parsed = parseArgs([...argv], CodegenArgsSchema);
|
|
265
|
-
if (!parsed.isOk()) return (0, neverthrow.err)(
|
|
266
|
-
code: "EMIT_FAILED",
|
|
267
|
-
message: parsed.error,
|
|
268
|
-
outPath: ""
|
|
269
|
-
});
|
|
361
|
+
if (!parsed.isOk()) return (0, neverthrow.err)(cliErrors.argsInvalid("codegen", parsed.error));
|
|
270
362
|
const args = parsed.value;
|
|
271
363
|
if (args["emit-inject-template"]) return (0, neverthrow.ok)({
|
|
272
364
|
kind: "emitInjectTemplate",
|
|
273
365
|
outPath: args["emit-inject-template"]
|
|
274
366
|
});
|
|
275
367
|
const configResult = (0, __soda_gql_config.loadConfig)(args.config);
|
|
276
|
-
if (configResult.isErr()) return (0, neverthrow.err)(
|
|
277
|
-
code: "EMIT_FAILED",
|
|
278
|
-
message: `Failed to load config: ${configResult.error.message}`,
|
|
279
|
-
outPath: ""
|
|
280
|
-
});
|
|
368
|
+
if (configResult.isErr()) return (0, neverthrow.err)(cliErrors.fromConfig(configResult.error));
|
|
281
369
|
const config = configResult.value;
|
|
282
|
-
if (!config.schemas || Object.keys(config.schemas).length === 0) return (0, neverthrow.err)(
|
|
283
|
-
code: "EMIT_FAILED",
|
|
284
|
-
message: "schemas configuration is required in soda-gql.config.ts",
|
|
285
|
-
outPath: ""
|
|
286
|
-
});
|
|
370
|
+
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"));
|
|
287
371
|
const schemas = {};
|
|
288
372
|
for (const [name, schemaConfig] of Object.entries(config.schemas)) schemas[name] = {
|
|
289
373
|
schema: schemaConfig.schema,
|
|
@@ -305,20 +389,6 @@ const formatSuccess$1 = (success) => {
|
|
|
305
389
|
const formatTemplateSuccess = (outPath) => {
|
|
306
390
|
return `Created inject template → ${outPath}`;
|
|
307
391
|
};
|
|
308
|
-
const errorHints = {
|
|
309
|
-
SCHEMA_NOT_FOUND: "Verify the schema path in soda-gql.config.ts",
|
|
310
|
-
SCHEMA_INVALID: "Check your GraphQL schema for syntax errors",
|
|
311
|
-
INJECT_MODULE_NOT_FOUND: "Run: soda-gql codegen --emit-inject-template <path>",
|
|
312
|
-
INJECT_MODULE_REQUIRED: "Add inject configuration to your schema in soda-gql.config.ts",
|
|
313
|
-
INJECT_TEMPLATE_EXISTS: "Delete the existing file to regenerate, or use a different path",
|
|
314
|
-
EMIT_FAILED: "Check write permissions and that the output directory exists"
|
|
315
|
-
};
|
|
316
|
-
const formatCodegenError = (error) => {
|
|
317
|
-
const message = "message" in error ? error.message : "Unknown error";
|
|
318
|
-
const hint = errorHints[error.code];
|
|
319
|
-
const hintLine = hint ? `\n Hint: ${hint}` : "";
|
|
320
|
-
return `${error.code}: ${message}${hintLine}`;
|
|
321
|
-
};
|
|
322
392
|
const CODEGEN_HELP = `Usage: soda-gql codegen [options]
|
|
323
393
|
|
|
324
394
|
Generate graphql-system runtime module from GraphQL schema.
|
|
@@ -333,58 +403,37 @@ Examples:
|
|
|
333
403
|
soda-gql codegen --emit-inject-template ./src/graphql/scalars.ts
|
|
334
404
|
`;
|
|
335
405
|
const codegenCommand = async (argv) => {
|
|
336
|
-
if (argv.includes("--help") || argv.includes("-h")) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
const command = parsed.value;
|
|
347
|
-
if (command.kind === "emitInjectTemplate") {
|
|
348
|
-
const outPath = (0, node_path.resolve)(command.outPath);
|
|
349
|
-
const result$1 = (0, __soda_gql_codegen.writeInjectTemplate)(outPath);
|
|
350
|
-
if (result$1.isErr()) {
|
|
351
|
-
process.stderr.write(`${formatCodegenError(result$1.error)}\n`);
|
|
352
|
-
return 1;
|
|
353
|
-
}
|
|
354
|
-
process.stdout.write(`${formatTemplateSuccess(outPath)}\n`);
|
|
355
|
-
return 0;
|
|
356
|
-
}
|
|
357
|
-
const resolvedSchemas = {};
|
|
358
|
-
for (const [name, schemaConfig] of Object.entries(command.schemas)) resolvedSchemas[name] = {
|
|
359
|
-
schema: (0, node_path.resolve)(schemaConfig.schema),
|
|
360
|
-
inject: {
|
|
361
|
-
scalars: (0, node_path.resolve)(schemaConfig.inject.scalars),
|
|
362
|
-
...schemaConfig.inject.adapter ? { adapter: (0, node_path.resolve)(schemaConfig.inject.adapter) } : {}
|
|
363
|
-
},
|
|
364
|
-
defaultInputDepth: schemaConfig.defaultInputDepth,
|
|
365
|
-
inputDepthOverrides: schemaConfig.inputDepthOverrides
|
|
366
|
-
};
|
|
367
|
-
const result = await (0, __soda_gql_codegen.runCodegen)({
|
|
368
|
-
schemas: resolvedSchemas,
|
|
369
|
-
outPath: (0, node_path.resolve)(command.outPath),
|
|
370
|
-
format: "human",
|
|
371
|
-
importExtension: command.importExtension
|
|
372
|
-
});
|
|
373
|
-
if (result.isErr()) {
|
|
374
|
-
process.stderr.write(`${formatCodegenError(result.error)}\n`);
|
|
375
|
-
return 1;
|
|
376
|
-
}
|
|
377
|
-
process.stdout.write(`${formatSuccess$1(result.value)}\n`);
|
|
378
|
-
return 0;
|
|
379
|
-
} catch (error) {
|
|
380
|
-
const unexpectedError = {
|
|
381
|
-
code: "EMIT_FAILED",
|
|
382
|
-
message: error instanceof Error ? error.message : String(error),
|
|
383
|
-
outPath: ""
|
|
384
|
-
};
|
|
385
|
-
process.stderr.write(`${formatCodegenError(unexpectedError)}\n`);
|
|
386
|
-
return 1;
|
|
406
|
+
if (argv.includes("--help") || argv.includes("-h")) return (0, neverthrow.ok)({ message: CODEGEN_HELP });
|
|
407
|
+
const parsed = parseCodegenArgs(argv);
|
|
408
|
+
if (parsed.isErr()) return (0, neverthrow.err)(parsed.error);
|
|
409
|
+
const command = parsed.value;
|
|
410
|
+
if (command.kind === "emitInjectTemplate") {
|
|
411
|
+
const outPath = (0, node_path.resolve)(command.outPath);
|
|
412
|
+
const result$1 = (0, __soda_gql_codegen.writeInjectTemplate)(outPath);
|
|
413
|
+
if (result$1.isErr()) return (0, neverthrow.err)(cliErrors.fromCodegen(result$1.error));
|
|
414
|
+
return (0, neverthrow.ok)({ message: formatTemplateSuccess(outPath) });
|
|
387
415
|
}
|
|
416
|
+
const resolvedSchemas = {};
|
|
417
|
+
for (const [name, schemaConfig] of Object.entries(command.schemas)) resolvedSchemas[name] = {
|
|
418
|
+
schema: (0, node_path.resolve)(schemaConfig.schema),
|
|
419
|
+
inject: {
|
|
420
|
+
scalars: (0, node_path.resolve)(schemaConfig.inject.scalars),
|
|
421
|
+
...schemaConfig.inject.adapter ? { adapter: (0, node_path.resolve)(schemaConfig.inject.adapter) } : {}
|
|
422
|
+
},
|
|
423
|
+
defaultInputDepth: schemaConfig.defaultInputDepth,
|
|
424
|
+
inputDepthOverrides: schemaConfig.inputDepthOverrides
|
|
425
|
+
};
|
|
426
|
+
const result = await (0, __soda_gql_codegen.runCodegen)({
|
|
427
|
+
schemas: resolvedSchemas,
|
|
428
|
+
outPath: (0, node_path.resolve)(command.outPath),
|
|
429
|
+
format: "human",
|
|
430
|
+
importExtension: command.importExtension
|
|
431
|
+
});
|
|
432
|
+
if (result.isErr()) return (0, neverthrow.err)(cliErrors.fromCodegen(result.error));
|
|
433
|
+
return (0, neverthrow.ok)({
|
|
434
|
+
message: formatSuccess$1(result.value),
|
|
435
|
+
data: result.value
|
|
436
|
+
});
|
|
388
437
|
};
|
|
389
438
|
|
|
390
439
|
//#endregion
|
|
@@ -396,22 +445,19 @@ const loadFormatter = async () => {
|
|
|
396
445
|
return null;
|
|
397
446
|
}
|
|
398
447
|
};
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
if (result.unformatted.length > 0) {
|
|
405
|
-
const files = result.unformatted.map((f) => ` ${f}`).join("\n");
|
|
406
|
-
return `${result.unformatted.length} file(s) need formatting:\n${files}`;
|
|
448
|
+
const formatResultMessage = (data) => {
|
|
449
|
+
if (data.mode === "check") {
|
|
450
|
+
if (data.unformatted.length > 0) {
|
|
451
|
+
const files = data.unformatted.map((f) => ` ${f}`).join("\n");
|
|
452
|
+
return `${data.unformatted.length} file(s) need formatting:\n${files}`;
|
|
407
453
|
}
|
|
408
|
-
return `All ${
|
|
454
|
+
return `All ${data.total} file(s) are properly formatted`;
|
|
409
455
|
}
|
|
410
456
|
const parts = [];
|
|
411
|
-
if (
|
|
412
|
-
if (
|
|
413
|
-
if (
|
|
414
|
-
return `${
|
|
457
|
+
if (data.modified > 0) parts.push(`${data.modified} formatted`);
|
|
458
|
+
if (data.unchanged > 0) parts.push(`${data.unchanged} unchanged`);
|
|
459
|
+
if (data.errors > 0) parts.push(`${data.errors} errors`);
|
|
460
|
+
return `${data.total} file(s) checked: ${parts.join(", ")}`;
|
|
415
461
|
};
|
|
416
462
|
const isGlobPattern = (pattern) => {
|
|
417
463
|
return /[*?[\]{}]/.test(pattern);
|
|
@@ -449,19 +495,9 @@ Examples:
|
|
|
449
495
|
soda-gql format --check # Check mode with config
|
|
450
496
|
`;
|
|
451
497
|
const formatCommand = async (argv) => {
|
|
452
|
-
if (argv.includes("--help") || argv.includes("-h")) {
|
|
453
|
-
process.stdout.write(FORMAT_HELP);
|
|
454
|
-
return 0;
|
|
455
|
-
}
|
|
498
|
+
if (argv.includes("--help") || argv.includes("-h")) return (0, neverthrow.ok)({ message: FORMAT_HELP });
|
|
456
499
|
const parsed = parseArgs([...argv], FormatArgsSchema);
|
|
457
|
-
if (!parsed.isOk())
|
|
458
|
-
const error = {
|
|
459
|
-
code: "PARSE_ERROR",
|
|
460
|
-
message: parsed.error
|
|
461
|
-
};
|
|
462
|
-
process.stderr.write(`${formatFormatError(error)}\n`);
|
|
463
|
-
return 1;
|
|
464
|
-
}
|
|
500
|
+
if (!parsed.isOk()) return (0, neverthrow.err)(cliErrors.argsInvalid("format", parsed.error));
|
|
465
501
|
const args = parsed.value;
|
|
466
502
|
const isCheckMode = args.check === true;
|
|
467
503
|
const explicitPatterns = args._ ?? [];
|
|
@@ -470,36 +506,27 @@ const formatCommand = async (argv) => {
|
|
|
470
506
|
if (explicitPatterns.length > 0) targetPatterns = explicitPatterns;
|
|
471
507
|
else {
|
|
472
508
|
const configResult = (0, __soda_gql_config.loadConfig)(args.config);
|
|
473
|
-
if (configResult.isErr())
|
|
474
|
-
process.stderr.write(`${formatFormatError({
|
|
475
|
-
code: "NO_PATTERNS",
|
|
476
|
-
message: "No patterns provided and config not found. Usage: soda-gql format [patterns...] [--check]"
|
|
477
|
-
})}\n`);
|
|
478
|
-
return 1;
|
|
479
|
-
}
|
|
509
|
+
if (configResult.isErr()) return (0, neverthrow.err)(cliErrors.noPatterns());
|
|
480
510
|
targetPatterns = configResult.value.include;
|
|
481
511
|
excludePatterns = configResult.value.exclude;
|
|
482
512
|
}
|
|
483
513
|
const formatter = await loadFormatter();
|
|
484
|
-
if (!formatter)
|
|
485
|
-
process.stderr.write(`${formatFormatError({
|
|
486
|
-
code: "FORMATTER_NOT_INSTALLED",
|
|
487
|
-
message: "@soda-gql/formatter is not installed. Run: npm install @soda-gql/formatter"
|
|
488
|
-
})}\n`);
|
|
489
|
-
return 1;
|
|
490
|
-
}
|
|
514
|
+
if (!formatter) return (0, neverthrow.err)(cliErrors.formatterNotInstalled());
|
|
491
515
|
const files = await expandGlobPatterns(targetPatterns, excludePatterns);
|
|
492
516
|
if (files.length === 0) {
|
|
493
|
-
const
|
|
517
|
+
const data$1 = {
|
|
494
518
|
mode: isCheckMode ? "check" : "format",
|
|
495
519
|
total: 0,
|
|
496
520
|
modified: 0,
|
|
497
521
|
unchanged: 0,
|
|
498
522
|
errors: 0,
|
|
499
|
-
unformatted: []
|
|
523
|
+
unformatted: [],
|
|
524
|
+
hasFormattingIssues: false
|
|
500
525
|
};
|
|
501
|
-
|
|
502
|
-
|
|
526
|
+
return (0, neverthrow.ok)({
|
|
527
|
+
message: formatResultMessage(data$1),
|
|
528
|
+
data: data$1
|
|
529
|
+
});
|
|
503
530
|
}
|
|
504
531
|
let modified = 0;
|
|
505
532
|
let unchanged = 0;
|
|
@@ -508,44 +535,46 @@ const formatCommand = async (argv) => {
|
|
|
508
535
|
for (const filePath of files) {
|
|
509
536
|
const sourceCode = await (0, node_fs_promises.readFile)(filePath, "utf-8");
|
|
510
537
|
if (isCheckMode) {
|
|
511
|
-
const result
|
|
538
|
+
const result = formatter.needsFormat({
|
|
512
539
|
sourceCode,
|
|
513
540
|
filePath
|
|
514
541
|
});
|
|
515
|
-
if (result
|
|
542
|
+
if (result.isErr()) {
|
|
516
543
|
errors++;
|
|
517
544
|
continue;
|
|
518
545
|
}
|
|
519
|
-
if (result
|
|
546
|
+
if (result.value) {
|
|
520
547
|
unformatted.push(filePath);
|
|
521
548
|
modified++;
|
|
522
549
|
} else unchanged++;
|
|
523
550
|
} else {
|
|
524
|
-
const result
|
|
551
|
+
const result = formatter.format({
|
|
525
552
|
sourceCode,
|
|
526
553
|
filePath
|
|
527
554
|
});
|
|
528
|
-
if (result
|
|
555
|
+
if (result.isErr()) {
|
|
529
556
|
errors++;
|
|
530
557
|
continue;
|
|
531
558
|
}
|
|
532
|
-
if (result
|
|
533
|
-
await (0, node_fs_promises.writeFile)(filePath, result
|
|
559
|
+
if (result.value.modified) {
|
|
560
|
+
await (0, node_fs_promises.writeFile)(filePath, result.value.sourceCode, "utf-8");
|
|
534
561
|
modified++;
|
|
535
562
|
} else unchanged++;
|
|
536
563
|
}
|
|
537
564
|
}
|
|
538
|
-
const
|
|
565
|
+
const data = {
|
|
539
566
|
mode: isCheckMode ? "check" : "format",
|
|
540
567
|
total: files.length,
|
|
541
568
|
modified,
|
|
542
569
|
unchanged,
|
|
543
570
|
errors,
|
|
544
|
-
unformatted
|
|
571
|
+
unformatted,
|
|
572
|
+
hasFormattingIssues: isCheckMode && unformatted.length > 0 || errors > 0
|
|
545
573
|
};
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
574
|
+
return (0, neverthrow.ok)({
|
|
575
|
+
message: formatResultMessage(data),
|
|
576
|
+
data
|
|
577
|
+
});
|
|
549
578
|
};
|
|
550
579
|
|
|
551
580
|
//#endregion
|
|
@@ -619,11 +648,7 @@ Generated files:
|
|
|
619
648
|
`;
|
|
620
649
|
const checkFilesExist = (files, force) => {
|
|
621
650
|
if (force) return (0, neverthrow.ok)(void 0);
|
|
622
|
-
for (const file of files) if ((0, node_fs.existsSync)(file.path)) return (0, neverthrow.err)(
|
|
623
|
-
code: "FILE_EXISTS",
|
|
624
|
-
message: `File already exists: ${file.path}. Use --force to overwrite.`,
|
|
625
|
-
filePath: file.path
|
|
626
|
-
});
|
|
651
|
+
for (const file of files) if ((0, node_fs.existsSync)(file.path)) return (0, neverthrow.err)(cliErrors.fileExists(file.path));
|
|
627
652
|
return (0, neverthrow.ok)(void 0);
|
|
628
653
|
};
|
|
629
654
|
const writeFiles = (files) => {
|
|
@@ -634,11 +659,7 @@ const writeFiles = (files) => {
|
|
|
634
659
|
createdPaths.push(file.path);
|
|
635
660
|
} catch (error) {
|
|
636
661
|
const message = error instanceof Error ? error.message : String(error);
|
|
637
|
-
return (0, neverthrow.err)({
|
|
638
|
-
code: "WRITE_FAILED",
|
|
639
|
-
message: `Failed to write ${file.description}: ${message}`,
|
|
640
|
-
filePath: file.path
|
|
641
|
-
});
|
|
662
|
+
return (0, neverthrow.err)(cliErrors.writeFailed(file.path, `Failed to write ${file.description}: ${message}`, error));
|
|
642
663
|
}
|
|
643
664
|
return (0, neverthrow.ok)({ filesCreated: createdPaths });
|
|
644
665
|
};
|
|
@@ -655,23 +676,10 @@ const formatSuccess = (result) => {
|
|
|
655
676
|
lines.push(" 3. Import gql from ./graphql-system");
|
|
656
677
|
return lines.join("\n");
|
|
657
678
|
};
|
|
658
|
-
const formatInitError = (error) => {
|
|
659
|
-
return `${error.code}: ${error.message}`;
|
|
660
|
-
};
|
|
661
679
|
const initCommand = async (argv) => {
|
|
662
|
-
if (argv.includes("--help") || argv.includes("-h")) {
|
|
663
|
-
process.stdout.write(INIT_HELP);
|
|
664
|
-
return 0;
|
|
665
|
-
}
|
|
680
|
+
if (argv.includes("--help") || argv.includes("-h")) return (0, neverthrow.ok)({ message: INIT_HELP });
|
|
666
681
|
const parsed = parseArgs([...argv], InitArgsSchema);
|
|
667
|
-
if (!parsed.isOk())
|
|
668
|
-
const error = {
|
|
669
|
-
code: "PARSE_ERROR",
|
|
670
|
-
message: parsed.error
|
|
671
|
-
};
|
|
672
|
-
process.stderr.write(`${formatInitError(error)}\n`);
|
|
673
|
-
return 1;
|
|
674
|
-
}
|
|
682
|
+
if (!parsed.isOk()) return (0, neverthrow.err)(cliErrors.argsInvalid("init", parsed.error));
|
|
675
683
|
const force = parsed.value.force === true;
|
|
676
684
|
const cwd = process.cwd();
|
|
677
685
|
const files = [
|
|
@@ -697,54 +705,180 @@ const initCommand = async (argv) => {
|
|
|
697
705
|
}
|
|
698
706
|
];
|
|
699
707
|
const existsCheck = checkFilesExist(files, force);
|
|
700
|
-
if (existsCheck.isErr())
|
|
701
|
-
process.stderr.write(`${formatInitError(existsCheck.error)}\n`);
|
|
702
|
-
return 1;
|
|
703
|
-
}
|
|
708
|
+
if (existsCheck.isErr()) return (0, neverthrow.err)(existsCheck.error);
|
|
704
709
|
const writeResult = writeFiles(files);
|
|
705
|
-
if (writeResult.isErr())
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
return 0;
|
|
710
|
+
if (writeResult.isErr()) return (0, neverthrow.err)(writeResult.error);
|
|
711
|
+
return (0, neverthrow.ok)({
|
|
712
|
+
message: formatSuccess(writeResult.value),
|
|
713
|
+
data: writeResult.value
|
|
714
|
+
});
|
|
711
715
|
};
|
|
712
716
|
|
|
713
717
|
//#endregion
|
|
714
718
|
//#region packages/cli/src/utils/format.ts
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
719
|
+
/**
|
|
720
|
+
* CLI-specific error hints to help users fix issues.
|
|
721
|
+
*/
|
|
722
|
+
const cliErrorHints = {
|
|
723
|
+
CLI_ARGS_INVALID: "Check command usage with --help",
|
|
724
|
+
CLI_UNKNOWN_COMMAND: "Run 'soda-gql --help' for available commands",
|
|
725
|
+
CLI_UNKNOWN_SUBCOMMAND: "Run the parent command with --help for available subcommands",
|
|
726
|
+
CLI_FILE_EXISTS: "Use --force flag to overwrite existing files",
|
|
727
|
+
CLI_FILE_NOT_FOUND: "Verify the file path exists",
|
|
728
|
+
CLI_WRITE_FAILED: "Check write permissions and disk space",
|
|
729
|
+
CLI_READ_FAILED: "Check file permissions and verify the file is not locked",
|
|
730
|
+
CLI_NO_PATTERNS: "Provide file patterns or create soda-gql.config.ts",
|
|
731
|
+
CLI_FORMATTER_NOT_INSTALLED: "Install with: bun add @soda-gql/formatter",
|
|
732
|
+
CLI_PARSE_ERROR: "Check the file for syntax errors",
|
|
733
|
+
CLI_FORMAT_ERROR: "Verify the file contains valid soda-gql code",
|
|
734
|
+
CLI_UNEXPECTED: "This is an unexpected error. Please report at https://github.com/soda-gql/soda-gql/issues"
|
|
735
|
+
};
|
|
736
|
+
/**
|
|
737
|
+
* Codegen-specific error hints.
|
|
738
|
+
*/
|
|
739
|
+
const codegenErrorHints = {
|
|
740
|
+
SCHEMA_NOT_FOUND: "Verify the schema path in soda-gql.config.ts",
|
|
741
|
+
SCHEMA_INVALID: "Check your GraphQL schema for syntax errors",
|
|
742
|
+
INJECT_MODULE_NOT_FOUND: "Run: soda-gql codegen --emit-inject-template <path>",
|
|
743
|
+
INJECT_MODULE_REQUIRED: "Add inject configuration to your schema in soda-gql.config.ts",
|
|
744
|
+
INJECT_TEMPLATE_EXISTS: "Delete the existing file to regenerate, or use a different path",
|
|
745
|
+
EMIT_FAILED: "Check write permissions and that the output directory exists",
|
|
746
|
+
INJECT_TEMPLATE_FAILED: "Check write permissions for the output path"
|
|
747
|
+
};
|
|
748
|
+
/**
|
|
749
|
+
* Config-specific error hints.
|
|
750
|
+
*/
|
|
751
|
+
const configErrorHints = {
|
|
752
|
+
CONFIG_NOT_FOUND: "Create a soda-gql.config.ts file in your project root",
|
|
753
|
+
CONFIG_LOAD_FAILED: "Check your configuration file for syntax errors",
|
|
754
|
+
CONFIG_VALIDATION_FAILED: "Verify your configuration matches the expected schema",
|
|
755
|
+
CONFIG_INVALID_PATH: "Verify the path in your configuration exists"
|
|
756
|
+
};
|
|
757
|
+
/**
|
|
758
|
+
* Artifact-specific error hints.
|
|
759
|
+
*/
|
|
760
|
+
const artifactErrorHints = {
|
|
761
|
+
ARTIFACT_NOT_FOUND: "Verify the artifact file path exists",
|
|
762
|
+
ARTIFACT_PARSE_ERROR: "Check that the artifact file is valid JSON",
|
|
763
|
+
ARTIFACT_VALIDATION_ERROR: "Verify the artifact was built with a compatible version of soda-gql"
|
|
764
|
+
};
|
|
765
|
+
/**
|
|
766
|
+
* Get hint for any error type.
|
|
767
|
+
*/
|
|
768
|
+
const getErrorHint = (error) => {
|
|
769
|
+
if (error.category === "cli") return cliErrorHints[error.code];
|
|
770
|
+
if (error.category === "codegen") return codegenErrorHints[error.error.code];
|
|
771
|
+
if (error.category === "config") return configErrorHints[error.error.code];
|
|
772
|
+
if (error.category === "artifact") return artifactErrorHints[error.error.code];
|
|
773
|
+
};
|
|
774
|
+
/**
|
|
775
|
+
* Format CliError to human-readable string with hints.
|
|
776
|
+
*/
|
|
777
|
+
const formatCliErrorHuman = (error) => {
|
|
778
|
+
if (error.category === "builder") return (0, __soda_gql_builder.formatBuilderErrorForCLI)(error.error);
|
|
779
|
+
const lines = [];
|
|
780
|
+
if (error.category === "codegen") {
|
|
781
|
+
const codegenError = error.error;
|
|
782
|
+
lines.push(`Error [${codegenError.code}]: ${codegenError.message}`);
|
|
783
|
+
if ("schemaPath" in codegenError) lines.push(` Schema: ${codegenError.schemaPath}`);
|
|
784
|
+
if ("outPath" in codegenError && codegenError.outPath) lines.push(` Output: ${codegenError.outPath}`);
|
|
785
|
+
if ("injectPath" in codegenError) lines.push(` Inject: ${codegenError.injectPath}`);
|
|
786
|
+
} else if (error.category === "config") {
|
|
787
|
+
const configError = error.error;
|
|
788
|
+
lines.push(`Error [${configError.code}]: ${configError.message}`);
|
|
789
|
+
if (configError.filePath) lines.push(` Config: ${configError.filePath}`);
|
|
790
|
+
} else if (error.category === "artifact") {
|
|
791
|
+
const artifactError = error.error;
|
|
792
|
+
lines.push(`Error [${artifactError.code}]: ${artifactError.message}`);
|
|
793
|
+
if (artifactError.filePath) lines.push(` Artifact: ${artifactError.filePath}`);
|
|
794
|
+
} else {
|
|
795
|
+
lines.push(`Error [${error.code}]: ${error.message}`);
|
|
796
|
+
if ("filePath" in error && error.filePath) lines.push(` File: ${error.filePath}`);
|
|
797
|
+
if ("command" in error && error.code !== "CLI_UNKNOWN_COMMAND") lines.push(` Command: ${error.command}`);
|
|
798
|
+
if ("parent" in error) lines.push(` Parent: ${error.parent}`);
|
|
799
|
+
}
|
|
800
|
+
const hint = getErrorHint(error);
|
|
801
|
+
if (hint) {
|
|
802
|
+
lines.push("");
|
|
803
|
+
lines.push(` Hint: ${hint}`);
|
|
804
|
+
}
|
|
805
|
+
return lines.join("\n");
|
|
806
|
+
};
|
|
807
|
+
/**
|
|
808
|
+
* Format CliError to JSON string.
|
|
809
|
+
*/
|
|
810
|
+
const formatCliErrorJson = (error) => {
|
|
811
|
+
if (error.category === "cli") {
|
|
812
|
+
const { category: _category, ...rest } = error;
|
|
813
|
+
return JSON.stringify({ error: rest }, null, 2);
|
|
814
|
+
}
|
|
815
|
+
return JSON.stringify({ error: error.error }, null, 2);
|
|
816
|
+
};
|
|
817
|
+
/**
|
|
818
|
+
* Format CliError with output format preference.
|
|
819
|
+
*/
|
|
820
|
+
const formatCliError = (error, format = "human") => {
|
|
821
|
+
return format === "json" ? formatCliErrorJson(error) : formatCliErrorHuman(error);
|
|
718
822
|
};
|
|
719
823
|
|
|
720
824
|
//#endregion
|
|
721
825
|
//#region packages/cli/src/index.ts
|
|
826
|
+
const MAIN_HELP = `Usage: soda-gql <command> [options]
|
|
827
|
+
|
|
828
|
+
Commands:
|
|
829
|
+
init Initialize a new soda-gql project
|
|
830
|
+
codegen Generate graphql-system runtime module
|
|
831
|
+
format Format soda-gql field selections
|
|
832
|
+
artifact Manage soda-gql artifacts
|
|
833
|
+
|
|
834
|
+
Run 'soda-gql <command> --help' for more information on a specific command.
|
|
835
|
+
`;
|
|
836
|
+
/**
|
|
837
|
+
* Parse output format from argv.
|
|
838
|
+
* Returns "json" if --format=json or --json flag is present, otherwise "human".
|
|
839
|
+
*/
|
|
840
|
+
const getOutputFormat = (argv) => {
|
|
841
|
+
for (const arg of argv) {
|
|
842
|
+
if (arg === "--format=json" || arg === "--json") return "json";
|
|
843
|
+
if (arg === "--format=human") return "human";
|
|
844
|
+
}
|
|
845
|
+
return "human";
|
|
846
|
+
};
|
|
722
847
|
const dispatch = async (argv) => {
|
|
723
848
|
const [command, ...rest] = argv;
|
|
724
|
-
if (!command || command === "--help" || command === "-h") {
|
|
725
|
-
process.stdout.write(`Usage: soda-gql <command> [options]\n`);
|
|
726
|
-
process.stdout.write(`\nCommands:\n`);
|
|
727
|
-
process.stdout.write(` init Initialize a new soda-gql project\n`);
|
|
728
|
-
process.stdout.write(` codegen Generate graphql-system runtime module\n`);
|
|
729
|
-
process.stdout.write(` format Format soda-gql field selections\n`);
|
|
730
|
-
process.stdout.write(` artifact Manage soda-gql artifacts\n`);
|
|
731
|
-
return 0;
|
|
732
|
-
}
|
|
849
|
+
if (!command || command === "--help" || command === "-h") return (0, neverthrow.ok)({ message: MAIN_HELP });
|
|
733
850
|
if (command === "init") return initCommand(rest);
|
|
734
851
|
if (command === "codegen") return codegenCommand(rest);
|
|
735
|
-
if (command === "format")
|
|
852
|
+
if (command === "format") {
|
|
853
|
+
const result = await formatCommand(rest);
|
|
854
|
+
if (result.isOk()) {
|
|
855
|
+
const exitCode = result.value.data?.hasFormattingIssues ? 1 : 0;
|
|
856
|
+
return (0, neverthrow.ok)({
|
|
857
|
+
...result.value,
|
|
858
|
+
exitCode
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
return (0, neverthrow.err)(result.error);
|
|
862
|
+
}
|
|
736
863
|
if (command === "artifact") return artifactCommand(rest);
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
}
|
|
747
|
-
|
|
864
|
+
return (0, neverthrow.err)(cliErrors.unknownCommand(command));
|
|
865
|
+
};
|
|
866
|
+
const main = async () => {
|
|
867
|
+
const argv = process.argv.slice(2);
|
|
868
|
+
const format = getOutputFormat(argv);
|
|
869
|
+
const result = await dispatch(argv);
|
|
870
|
+
if (result.isOk()) {
|
|
871
|
+
process.stdout.write(`${result.value.message}\n`);
|
|
872
|
+
process.exitCode = result.value.exitCode ?? 0;
|
|
873
|
+
} else {
|
|
874
|
+
process.stderr.write(`${formatCliError(result.error, format)}\n`);
|
|
875
|
+
process.exitCode = 1;
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
main().catch((error) => {
|
|
879
|
+
const unexpectedError = cliErrors.unexpected(error instanceof Error ? error.message : String(error), error);
|
|
880
|
+
const format = getOutputFormat(process.argv.slice(2));
|
|
881
|
+
process.stderr.write(`${formatCliError(unexpectedError, format)}\n`);
|
|
748
882
|
process.exitCode = 1;
|
|
749
883
|
});
|
|
750
884
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["args: BuildArgs","meta: BuilderArtifactMeta | undefined","artifactWithMeta: BuilderArtifact","args: ValidateArgs","z","parsed: Record<string, unknown>","positional: string[]","schemas: Record<string, CodegenSchemaConfig>","formatSuccess","errorHints: Record<string, string>","result","resolvedSchemas: Record<string, CodegenSchemaConfig>","unexpectedError: CodegenError","parts: string[]","files: string[]","error: FormatError","targetPatterns: readonly string[]","excludePatterns: readonly string[]","result: FormatResult","result","unformatted: string[]","createdPaths: string[]","error: InitError","files: FileToGenerate[]"],"sources":["../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/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/utils/format.ts","../src/index.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport type { BuilderArtifact, BuilderArtifactMeta } from \"@soda-gql/builder\";\nimport { createBuilderService, formatBuilderErrorForCLI } from \"@soda-gql/builder\";\nimport { loadConfig } from \"@soda-gql/config\";\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\n/**\n * Build command - builds and validates soda-gql artifacts.\n */\nexport const buildCommand = async (argv: readonly string[]): Promise<number> => {\n const args = parseBuildArgs(argv);\n\n if (args.help) {\n process.stdout.write(BUILD_HELP);\n return 0;\n }\n\n // Load config\n const configResult = loadConfig(args.configPath);\n if (configResult.isErr()) {\n const error = configResult.error;\n process.stderr.write(`Error: Failed to load config\\n`);\n process.stderr.write(` at ${error.filePath}\\n`);\n process.stderr.write(` ${error.message}\\n`);\n return 1;\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 const formattedError = formatBuilderErrorForCLI(buildResult.error);\n process.stderr.write(`${formattedError}\\n`);\n return 1;\n }\n\n const artifact = buildResult.value;\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 // 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 process.stdout.write(`Validation passed: ${fragmentCount} fragments, ${operationCount} operations\\n`);\n if (args.version) {\n process.stdout.write(` Version: ${args.version}\\n`);\n }\n } else {\n // Write artifact to output file\n const outputPath = resolve(process.cwd(), args.outputPath);\n const outputDir = dirname(outputPath);\n await mkdir(outputDir, { recursive: true });\n await writeFile(outputPath, JSON.stringify(artifactWithMeta, null, 2));\n\n process.stdout.write(`Build complete: ${fragmentCount} fragments, ${operationCount} operations\\n`);\n if (args.version) {\n process.stdout.write(` Version: ${args.version}\\n`);\n }\n process.stdout.write(`Artifact written to: ${outputPath}\\n`);\n }\n\n return 0;\n};\n","import { resolve } from \"node:path\";\nimport { loadArtifact } from \"@soda-gql/builder\";\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\n/**\n * Validate command - validates a pre-built artifact file.\n */\nexport const validateCommand = async (argv: readonly string[]): Promise<number> => {\n const args = parseValidateArgs(argv);\n\n if (args.help) {\n process.stdout.write(VALIDATE_HELP);\n return 0;\n }\n\n if (!args.artifactPath) {\n process.stderr.write(\"Error: Missing artifact path argument\\n\\n\");\n process.stdout.write(VALIDATE_HELP);\n return 1;\n }\n\n const artifactPath = resolve(process.cwd(), args.artifactPath);\n const result = await loadArtifact(artifactPath);\n\n if (result.isErr()) {\n const error = result.error;\n process.stderr.write(`Validation failed: ${error.message}\\n`);\n if (error.filePath) {\n process.stderr.write(` File: ${error.filePath}\\n`);\n }\n return 1;\n }\n\n const artifact = result.value;\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 process.stdout.write(`Artifact valid: ${fragmentCount} fragments, ${operationCount} operations\\n`);\n\n if (artifact.meta) {\n process.stdout.write(` Version: ${artifact.meta.version}\\n`);\n process.stdout.write(` Created: ${artifact.meta.createdAt}\\n`);\n } else {\n process.stdout.write(` (No metadata - legacy artifact format)\\n`);\n }\n\n return 0;\n};\n","import { 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\n/**\n * Dispatcher for artifact subcommands.\n */\nexport const artifactCommand = async (argv: readonly string[]): Promise<number> => {\n const [subcommand, ...rest] = argv;\n\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\") {\n process.stdout.write(ARTIFACT_HELP);\n return 0;\n }\n\n if (subcommand === \"build\") {\n return buildCommand(rest);\n }\n\n if (subcommand === \"validate\") {\n return validateCommand(rest);\n }\n\n process.stderr.write(`Unknown subcommand: ${subcommand}\\n`);\n process.stderr.write(`Run 'soda-gql artifact --help' for available subcommands.\\n`);\n return 1;\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});\n\nexport const InitArgsSchema = z.object({\n force: z.boolean().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>;\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 { CodegenError, CodegenSchemaConfig, CodegenSuccess } from \"@soda-gql/codegen\";\nimport { runCodegen, writeInjectTemplate } from \"@soda-gql/codegen\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport { CodegenArgsSchema } from \"../schemas/args\";\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[]): Result<ParsedCommand, CodegenError> => {\n const parsed = parseArgs([...argv], CodegenArgsSchema);\n\n if (!parsed.isOk()) {\n return err<ParsedCommand, CodegenError>({\n code: \"EMIT_FAILED\",\n message: parsed.error,\n outPath: \"\",\n });\n }\n\n const args = parsed.value;\n\n // Handle emit inject template\n if (args[\"emit-inject-template\"]) {\n return ok<ParsedCommand, CodegenError>({\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<ParsedCommand, CodegenError>({\n code: \"EMIT_FAILED\",\n message: `Failed to load config: ${configResult.error.message}`,\n outPath: \"\",\n });\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<ParsedCommand, CodegenError>({\n code: \"EMIT_FAILED\",\n message: \"schemas configuration is required in soda-gql.config.ts\",\n outPath: \"\",\n });\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<ParsedCommand, CodegenError>({\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 errorHints: 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};\n\nconst formatCodegenError = (error: CodegenError): string => {\n const message = \"message\" in error ? error.message : \"Unknown error\";\n const hint = errorHints[error.code];\n const hintLine = hint ? `\\n Hint: ${hint}` : \"\";\n return `${error.code}: ${message}${hintLine}`;\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 --config ./soda-gql.config.ts\n soda-gql codegen --emit-inject-template ./src/graphql/scalars.ts\n`;\n\nexport const codegenCommand = async (argv: readonly string[]): Promise<number> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n process.stdout.write(CODEGEN_HELP);\n return 0;\n }\n\n try {\n const parsed = parseCodegenArgs(argv);\n\n if (parsed.isErr()) {\n process.stderr.write(`${formatCodegenError(parsed.error)}\\n`);\n return 1;\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 process.stderr.write(`${formatCodegenError(result.error)}\\n`);\n return 1;\n }\n process.stdout.write(`${formatTemplateSuccess(outPath)}\\n`);\n return 0;\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: resolve(schemaConfig.schema),\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 process.stderr.write(`${formatCodegenError(result.error)}\\n`);\n return 1;\n }\n\n process.stdout.write(`${formatSuccess(result.value)}\\n`);\n return 0;\n } catch (error) {\n // Catch unexpected errors and convert to structured format\n const unexpectedError: CodegenError = {\n code: \"EMIT_FAILED\",\n message: error instanceof Error ? error.message : String(error),\n outPath: \"\",\n };\n process.stderr.write(`${formatCodegenError(unexpectedError)}\\n`);\n return 1;\n }\n};\n","import { access, readFile, writeFile } from \"node:fs/promises\";\nimport { loadConfig } from \"@soda-gql/config\";\nimport fg from \"fast-glob\";\nimport { FormatArgsSchema } from \"../schemas/args\";\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 FormatError = {\n code: \"PARSE_ERROR\" | \"NO_PATTERNS\" | \"FORMAT_ERROR\" | \"FORMATTER_NOT_INSTALLED\";\n message: string;\n};\n\ntype FormatResult = {\n mode: \"format\" | \"check\";\n total: number;\n modified: number;\n unchanged: number;\n errors: number;\n unformatted: string[];\n};\n\nconst formatFormatError = (error: FormatError): string => {\n return `${error.code}: ${error.message}`;\n};\n\nconst formatResult = (result: FormatResult): string => {\n if (result.mode === \"check\") {\n if (result.unformatted.length > 0) {\n const files = result.unformatted.map((f) => ` ${f}`).join(\"\\n\");\n return `${result.unformatted.length} file(s) need formatting:\\n${files}`;\n }\n return `All ${result.total} file(s) are properly formatted`;\n }\n\n const parts: string[] = [];\n if (result.modified > 0) {\n parts.push(`${result.modified} formatted`);\n }\n if (result.unchanged > 0) {\n parts.push(`${result.unchanged} unchanged`);\n }\n if (result.errors > 0) {\n parts.push(`${result.errors} errors`);\n }\n return `${result.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 --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`;\n\nexport const formatCommand = async (argv: readonly string[]): Promise<number> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n process.stdout.write(FORMAT_HELP);\n return 0;\n }\n\n const parsed = parseArgs([...argv], FormatArgsSchema);\n\n if (!parsed.isOk()) {\n const error: FormatError = {\n code: \"PARSE_ERROR\",\n message: parsed.error,\n };\n process.stderr.write(`${formatFormatError(error)}\\n`);\n return 1;\n }\n\n const args = parsed.value;\n const isCheckMode = args.check === 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 const error: FormatError = {\n code: \"NO_PATTERNS\",\n message: \"No patterns provided and config not found. Usage: soda-gql format [patterns...] [--check]\",\n };\n process.stderr.write(`${formatFormatError(error)}\\n`);\n return 1;\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 const error: FormatError = {\n code: \"FORMATTER_NOT_INSTALLED\",\n message: \"@soda-gql/formatter is not installed. Run: npm install @soda-gql/formatter\",\n };\n process.stderr.write(`${formatFormatError(error)}\\n`);\n return 1;\n }\n\n const files = await expandGlobPatterns(targetPatterns, excludePatterns);\n\n if (files.length === 0) {\n const result: FormatResult = {\n mode: isCheckMode ? \"check\" : \"format\",\n total: 0,\n modified: 0,\n unchanged: 0,\n errors: 0,\n unformatted: [],\n };\n process.stdout.write(`${formatResult(result)}\\n`);\n return 0;\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 });\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 result: FormatResult = {\n mode: isCheckMode ? \"check\" : \"format\",\n total: files.length,\n modified,\n unchanged,\n errors,\n unformatted,\n };\n\n process.stdout.write(`${formatResult(result)}\\n`);\n\n if (isCheckMode && unformatted.length > 0) {\n return 1;\n }\n\n return errors > 0 ? 1 : 0;\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 { 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 { parseArgs } from \"../utils/parse-args\";\n\ntype InitErrorCode = \"FILE_EXISTS\" | \"WRITE_FAILED\" | \"PARSE_ERROR\";\n\ntype InitError = {\n readonly code: InitErrorCode;\n readonly message: string;\n readonly filePath?: string;\n};\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, InitError> => {\n if (force) {\n return ok(undefined);\n }\n\n for (const file of files) {\n if (existsSync(file.path)) {\n return err({\n code: \"FILE_EXISTS\",\n message: `File already exists: ${file.path}. Use --force to overwrite.`,\n filePath: file.path,\n });\n }\n }\n\n return ok(undefined);\n};\n\nconst writeFiles = (files: readonly FileToGenerate[]): Result<InitSuccess, InitError> => {\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({\n code: \"WRITE_FAILED\",\n message: `Failed to write ${file.description}: ${message}`,\n filePath: file.path,\n });\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\nconst formatInitError = (error: InitError): string => {\n return `${error.code}: ${error.message}`;\n};\n\nexport const initCommand = async (argv: readonly string[]): Promise<number> => {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n process.stdout.write(INIT_HELP);\n return 0;\n }\n\n const parsed = parseArgs([...argv], InitArgsSchema);\n\n if (!parsed.isOk()) {\n const error: InitError = {\n code: \"PARSE_ERROR\",\n message: parsed.error,\n };\n process.stderr.write(`${formatInitError(error)}\\n`);\n return 1;\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 process.stderr.write(`${formatInitError(existsCheck.error)}\\n`);\n return 1;\n }\n\n const writeResult = writeFiles(files);\n if (writeResult.isErr()) {\n process.stderr.write(`${formatInitError(writeResult.error)}\\n`);\n return 1;\n }\n\n process.stdout.write(`${formatSuccess(writeResult.value)}\\n`);\n return 0;\n};\n","export 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 type OutputFormat = keyof typeof formatters;\n\nexport const formatOutput = (data: unknown, format: OutputFormat = \"human\"): string => {\n return formatters[format](data);\n};\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 { artifactCommand } from \"./commands/artifact\";\nimport { codegenCommand } from \"./commands/codegen\";\nimport { formatCommand } from \"./commands/format\";\nimport { initCommand } from \"./commands/init\";\nimport { formatError } from \"./utils/format\";\n\nconst dispatch = async (argv: readonly string[]): Promise<number> => {\n const [command, ...rest] = argv;\n\n if (!command || command === \"--help\" || command === \"-h\") {\n process.stdout.write(`Usage: soda-gql <command> [options]\\n`);\n process.stdout.write(`\\nCommands:\\n`);\n process.stdout.write(` init Initialize a new soda-gql project\\n`);\n process.stdout.write(` codegen Generate graphql-system runtime module\\n`);\n process.stdout.write(` format Format soda-gql field selections\\n`);\n process.stdout.write(` artifact Manage soda-gql artifacts\\n`);\n return 0;\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 === \"format\") {\n return formatCommand(rest);\n }\n\n if (command === \"artifact\") {\n return artifactCommand(rest);\n }\n\n process.stderr.write(`Unknown command: ${command}\\n`);\n return 1;\n};\n\n// Run CLI when executed directly\ndispatch(process.argv.slice(2))\n .then((exitCode) => {\n process.exitCode = exitCode;\n })\n .catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n const unexpectedError = {\n code: \"UNEXPECTED_ERROR\",\n message,\n };\n process.stderr.write(`${formatError(unexpectedError, \"json\")}\\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[]","schemas: Record<string, CodegenSchemaConfig>","formatSuccess","result","resolvedSchemas: Record<string, CodegenSchemaConfig>","parts: string[]","files: string[]","targetPatterns: readonly string[]","excludePatterns: readonly string[]","data: FormatData","data","unformatted: string[]","createdPaths: string[]","files: FileToGenerate[]","cliErrorHints: Partial<Record<CliErrorCode, string>>","codegenErrorHints: Record<string, string>","configErrorHints: Record<string, string>","artifactErrorHints: 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/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/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 { 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) 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 // 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\" }>;\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} 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});\n\nexport const InitArgsSchema = z.object({\n force: z.boolean().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>;\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 --config ./soda-gql.config.ts\n soda-gql codegen --emit-inject-template ./src/graphql/scalars.ts\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: resolve(schemaConfig.schema),\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","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 --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`;\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 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 });\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 { 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 * 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 // 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 {\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 { formatCommand } from \"./commands/format\";\nimport { initCommand } from \"./commands/init\";\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 format Format soda-gql field selections\n artifact Manage soda-gql artifacts\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 === \"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 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
|
@@ -1,5 +1,106 @@
|
|
|
1
|
+
import { Result } from "neverthrow";
|
|
2
|
+
import { ArtifactLoadError, BuilderError } from "@soda-gql/builder";
|
|
3
|
+
import { CodegenError } from "@soda-gql/codegen";
|
|
4
|
+
import { ConfigError } from "@soda-gql/config";
|
|
5
|
+
|
|
6
|
+
//#region packages/cli/src/errors.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Unified CLI error discriminated union.
|
|
10
|
+
* Wraps external errors (codegen, builder, config) and defines CLI-specific errors.
|
|
11
|
+
*/
|
|
12
|
+
type CliError = {
|
|
13
|
+
readonly category: "codegen";
|
|
14
|
+
readonly error: CodegenError;
|
|
15
|
+
} | {
|
|
16
|
+
readonly category: "builder";
|
|
17
|
+
readonly error: BuilderError;
|
|
18
|
+
} | {
|
|
19
|
+
readonly category: "artifact";
|
|
20
|
+
readonly error: ArtifactLoadError;
|
|
21
|
+
} | {
|
|
22
|
+
readonly category: "config";
|
|
23
|
+
readonly error: ConfigError;
|
|
24
|
+
} | {
|
|
25
|
+
readonly category: "cli";
|
|
26
|
+
readonly code: "CLI_ARGS_INVALID";
|
|
27
|
+
readonly message: string;
|
|
28
|
+
readonly command: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly category: "cli";
|
|
31
|
+
readonly code: "CLI_UNKNOWN_COMMAND";
|
|
32
|
+
readonly message: string;
|
|
33
|
+
readonly command: string;
|
|
34
|
+
} | {
|
|
35
|
+
readonly category: "cli";
|
|
36
|
+
readonly code: "CLI_UNKNOWN_SUBCOMMAND";
|
|
37
|
+
readonly message: string;
|
|
38
|
+
readonly parent: string;
|
|
39
|
+
readonly subcommand: string;
|
|
40
|
+
} | {
|
|
41
|
+
readonly category: "cli";
|
|
42
|
+
readonly code: "CLI_FILE_EXISTS";
|
|
43
|
+
readonly message: string;
|
|
44
|
+
readonly filePath: string;
|
|
45
|
+
} | {
|
|
46
|
+
readonly category: "cli";
|
|
47
|
+
readonly code: "CLI_FILE_NOT_FOUND";
|
|
48
|
+
readonly message: string;
|
|
49
|
+
readonly filePath: string;
|
|
50
|
+
} | {
|
|
51
|
+
readonly category: "cli";
|
|
52
|
+
readonly code: "CLI_WRITE_FAILED";
|
|
53
|
+
readonly message: string;
|
|
54
|
+
readonly filePath: string;
|
|
55
|
+
readonly cause?: unknown;
|
|
56
|
+
} | {
|
|
57
|
+
readonly category: "cli";
|
|
58
|
+
readonly code: "CLI_READ_FAILED";
|
|
59
|
+
readonly message: string;
|
|
60
|
+
readonly filePath: string;
|
|
61
|
+
readonly cause?: unknown;
|
|
62
|
+
} | {
|
|
63
|
+
readonly category: "cli";
|
|
64
|
+
readonly code: "CLI_NO_PATTERNS";
|
|
65
|
+
readonly message: string;
|
|
66
|
+
} | {
|
|
67
|
+
readonly category: "cli";
|
|
68
|
+
readonly code: "CLI_FORMATTER_NOT_INSTALLED";
|
|
69
|
+
readonly message: string;
|
|
70
|
+
} | {
|
|
71
|
+
readonly category: "cli";
|
|
72
|
+
readonly code: "CLI_PARSE_ERROR";
|
|
73
|
+
readonly message: string;
|
|
74
|
+
readonly filePath?: string;
|
|
75
|
+
} | {
|
|
76
|
+
readonly category: "cli";
|
|
77
|
+
readonly code: "CLI_FORMAT_ERROR";
|
|
78
|
+
readonly message: string;
|
|
79
|
+
readonly filePath?: string;
|
|
80
|
+
} | {
|
|
81
|
+
readonly category: "cli";
|
|
82
|
+
readonly code: "CLI_UNEXPECTED";
|
|
83
|
+
readonly message: string;
|
|
84
|
+
readonly cause?: unknown;
|
|
85
|
+
};
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region packages/cli/src/types.d.ts
|
|
88
|
+
/**
|
|
89
|
+
* Result type for all CLI commands.
|
|
90
|
+
*/
|
|
91
|
+
type CommandResult<T = CommandSuccess> = Result<T, CliError>;
|
|
92
|
+
/**
|
|
93
|
+
* Standard success response for commands.
|
|
94
|
+
*/
|
|
95
|
+
type CommandSuccess = {
|
|
96
|
+
readonly message: string;
|
|
97
|
+
};
|
|
98
|
+
//#endregion
|
|
1
99
|
//#region packages/cli/src/index.d.ts
|
|
2
|
-
|
|
100
|
+
type DispatchResult = CommandResult<CommandSuccess & {
|
|
101
|
+
exitCode?: number;
|
|
102
|
+
}>;
|
|
103
|
+
declare const dispatch: (argv: readonly string[]) => Promise<DispatchResult>;
|
|
3
104
|
//#endregion
|
|
4
105
|
export { dispatch };
|
|
5
106
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;ACWA,CAAA,CAAA;AAA8B,IAAA,CDwBlB,QAAA,CAAA,CAAA,CCxBkB;EAAyB,QAAA,CAAA,QAAA,CAAA,CAAA,CAAA,OAAA,CAAA;EAAG,QAAA,CAAA,KAAA,CAAA,CD0BN,YC1BM;CAAV,CAAA,CAAA,CAAA;EAAM,QAAA,CAAA,QAAA,CAAA,CAAA,CAAA,OAAA,CAAA;EAK1C,QAAA,CAAA,KAAA,CAAA,CDsBwC,YCtB1B;;;kBDuB2B;AEjCsB,CAAA,CAAA,CAAA,CA8BtE;EAEC,QAAA,CAAA,QA8BL,CAAA,CAAA,CAAA,MAAA,CA9ByD;kBFEP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AALnD,CAAA,CAAA;;;AAIqD,IAAA,CC5BzC,aD4ByC,CAAA,CAAA,CAAA,CAAA,CC5BvB,cD4BuB,CAAA,CAAA,CAAA,CC5BL,MD4BK,CC5BE,CD4BF,CAAA,CC5BK,QD4BL,CAAA;;;;KCvBzC,cAAA,CAAA,CAAA;;AALZ,CAAA;;;KCyBK,cAAA,CAAA,CAAA,CAAiB,cAAc;;;cAE9B,uCAA4C,QAAQ"}
|