@soda-gql/cli 0.0.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @soda-gql/cli
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@soda-gql/cli.svg)](https://www.npmjs.com/package/@soda-gql/cli)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Command-line interface for soda-gql zero-runtime GraphQL code generation.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ bun add -D @soda-gql/cli @soda-gql/config
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ### Configuration
17
+
18
+ Create a `soda-gql.config.ts` file in your project root:
19
+
20
+ ```typescript
21
+ import { defineConfig } from "@soda-gql/config";
22
+
23
+ export default defineConfig({
24
+ outdir: "./src/graphql-system",
25
+ include: ["./src/**/*.ts"],
26
+ schemas: {
27
+ default: {
28
+ schema: "./schema.graphql",
29
+ runtimeAdapter: "./src/graphql-system/runtime-adapter.ts",
30
+ scalars: "./src/graphql-system/scalars.ts",
31
+ },
32
+ },
33
+ });
34
+ ```
35
+
36
+ ### Commands
37
+
38
+ #### Generate GraphQL System
39
+
40
+ ```bash
41
+ bun run soda-gql codegen
42
+ ```
43
+
44
+ This command:
45
+ 1. Reads your GraphQL schema
46
+ 2. Generates type-safe GraphQL system module
47
+ 3. Outputs to the directory specified in `outdir`
48
+
49
+ #### Scaffold Templates
50
+
51
+ For first-time setup, generate scalar and runtime adapter templates:
52
+
53
+ ```bash
54
+ bun run soda-gql codegen --emit-inject-template ./src/graphql-system/inject.ts
55
+ ```
56
+
57
+ ### CLI Options
58
+
59
+ | Option | Description |
60
+ |--------|-------------|
61
+ | `--config <path>` | Path to config file (auto-discovered if not specified) |
62
+ | `--emit-inject-template <path>` | Generate scaffold templates for scalars and runtime adapter |
63
+ | `--format <type>` | Output format: `human` (default) or `json` |
64
+
65
+ ### Config File Discovery
66
+
67
+ The CLI automatically searches for configuration files in the following order:
68
+ 1. `soda-gql.config.ts`
69
+ 2. `soda-gql.config.mts`
70
+ 3. `soda-gql.config.js`
71
+ 4. `soda-gql.config.mjs`
72
+
73
+ ## Example Workflow
74
+
75
+ ```bash
76
+ # 1. Install dependencies
77
+ bun add @soda-gql/core @soda-gql/runtime
78
+ bun add -D @soda-gql/cli @soda-gql/config
79
+
80
+ # 2. Create config file
81
+ cat > soda-gql.config.ts << 'EOF'
82
+ import { defineConfig } from "@soda-gql/config";
83
+
84
+ export default defineConfig({
85
+ outdir: "./src/graphql-system",
86
+ include: ["./src/**/*.ts"],
87
+ schemas: {
88
+ default: {
89
+ schema: "./schema.graphql",
90
+ runtimeAdapter: "./src/graphql-system/runtime-adapter.ts",
91
+ scalars: "./src/graphql-system/scalars.ts",
92
+ },
93
+ },
94
+ });
95
+ EOF
96
+
97
+ # 3. Generate templates (first-time only)
98
+ bun run soda-gql codegen --emit-inject-template ./src/graphql-system/inject.ts
99
+
100
+ # 4. Generate GraphQL system
101
+ bun run soda-gql codegen
102
+ ```
103
+
104
+ ## Related Packages
105
+
106
+ - [@soda-gql/config](../config) - Configuration management
107
+ - [@soda-gql/codegen](../codegen) - Code generation engine
108
+ - [@soda-gql/core](../core) - Core types and utilities
109
+
110
+ ## License
111
+
112
+ MIT
package/dist/index.cjs CHANGED
@@ -1,14 +1,44 @@
1
1
  #!/usr/bin/env node
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) {
14
+ __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ }
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
+ value: mod,
25
+ enumerable: true
26
+ }) : target, mod));
27
+
28
+ //#endregion
2
29
  let node_path = require("node:path");
3
30
  let __soda_gql_codegen = require("@soda-gql/codegen");
4
31
  let __soda_gql_config = require("@soda-gql/config");
5
32
  let neverthrow = require("neverthrow");
6
33
  let zod = require("zod");
34
+ let node_fs_promises = require("node:fs/promises");
35
+ let fast_glob = require("fast-glob");
36
+ fast_glob = __toESM(fast_glob);
37
+ let node_fs = require("node:fs");
7
38
 
8
39
  //#region packages/cli/src/schemas/args.ts
9
40
  const CodegenArgsSchema = zod.z.object({
10
41
  config: zod.z.string().optional(),
11
- format: zod.z.enum(["human", "json"]).optional(),
12
42
  "emit-inject-template": zod.z.string().optional()
13
43
  });
14
44
  const BuilderArgsSchema = zod.z.object({
@@ -17,24 +47,12 @@ const BuilderArgsSchema = zod.z.object({
17
47
  out: zod.z.string(),
18
48
  format: zod.z.enum(["human", "json"]).optional().default("human")
19
49
  });
20
-
21
- //#endregion
22
- //#region packages/cli/src/utils/format.ts
23
- const formatters = {
24
- json: (data) => JSON.stringify(data, null, 2),
25
- human: (data) => {
26
- if (typeof data === "string") return data;
27
- if (data instanceof Error) return data.message;
28
- return JSON.stringify(data, null, 2);
29
- }
30
- };
31
- const formatOutput = (data, format = "human") => {
32
- return formatters[format](data);
33
- };
34
- const formatError = (error, format = "human") => {
35
- if (format === "json") return JSON.stringify({ error }, null, 2);
36
- return error instanceof Error ? error.message : String(error);
37
- };
50
+ const FormatArgsSchema = zod.z.object({
51
+ _: zod.z.array(zod.z.string()).optional(),
52
+ config: zod.z.string().optional(),
53
+ check: zod.z.boolean().optional()
54
+ });
55
+ const InitArgsSchema = zod.z.object({ force: zod.z.boolean().optional() });
38
56
 
39
57
  //#endregion
40
58
  //#region packages/cli/src/utils/parse-args.ts
@@ -72,8 +90,7 @@ const parseCodegenArgs = (argv) => {
72
90
  const args = parsed.value;
73
91
  if (args["emit-inject-template"]) return (0, neverthrow.ok)({
74
92
  kind: "emitInjectTemplate",
75
- outPath: args["emit-inject-template"],
76
- format: args.format ?? "human"
93
+ outPath: args["emit-inject-template"]
77
94
  });
78
95
  const configResult = (0, __soda_gql_config.loadConfig)(args.config);
79
96
  if (configResult.isErr()) return (0, neverthrow.err)({
@@ -88,43 +105,49 @@ const parseCodegenArgs = (argv) => {
88
105
  outPath: ""
89
106
  });
90
107
  const schemas = {};
91
- const runtimeAdapters = {};
92
- const scalars = {};
93
- for (const [name, schemaConfig] of Object.entries(config.schemas)) {
94
- schemas[name] = schemaConfig.schema;
95
- runtimeAdapters[name] = schemaConfig.runtimeAdapter;
96
- scalars[name] = schemaConfig.scalars;
97
- }
108
+ for (const [name, schemaConfig] of Object.entries(config.schemas)) schemas[name] = {
109
+ schema: schemaConfig.schema,
110
+ inject: schemaConfig.inject
111
+ };
98
112
  return (0, neverthrow.ok)({
99
- kind: "multi",
113
+ kind: "generate",
100
114
  schemas,
101
115
  outPath: (0, node_path.resolve)(config.outdir, "index.ts"),
102
- format: args.format ?? "human",
103
- runtimeAdapters,
104
- scalars,
105
116
  importExtension: config.styles.importExtension
106
117
  });
107
118
  };
108
- const formatMultiSchemaSuccess = (format, success) => {
109
- if (format === "json") return formatOutput(success, "json");
119
+ const formatSuccess$1 = (success) => {
110
120
  const schemaNames = Object.keys(success.schemas).join(", ");
111
- return `Generated ${Object.values(success.schemas).reduce((sum, s) => {
112
- return sum + s.objects;
113
- }, 0)} objects from schemas: ${schemaNames}\n TypeScript: ${success.outPath}\n CommonJS: ${success.cjsPath}`;
121
+ return `Generated ${Object.values(success.schemas).reduce((sum, s) => sum + s.objects, 0)} objects from schemas: ${schemaNames}\n TypeScript: ${success.outPath}\n CommonJS: ${success.cjsPath}`;
114
122
  };
115
- const formatTemplateSuccess = (format, outPath) => {
116
- if (format === "json") return formatOutput({ outPath }, "json");
123
+ const formatTemplateSuccess = (outPath) => {
117
124
  return `Created inject template → ${outPath}`;
118
125
  };
119
- const formatCodegenError = (format, error) => {
120
- if (format === "json") return formatError(error, "json");
126
+ const formatCodegenError = (error) => {
121
127
  return `${error.code}: ${"message" in error ? error.message : "Unknown error"}`;
122
128
  };
129
+ const CODEGEN_HELP = `Usage: soda-gql codegen [options]
130
+
131
+ Generate graphql-system runtime module from GraphQL schema.
132
+
133
+ Options:
134
+ --config <path> Path to soda-gql.config.ts
135
+ --emit-inject-template <path> Create inject template file
136
+ --help, -h Show this help message
137
+
138
+ Examples:
139
+ soda-gql codegen --config ./soda-gql.config.ts
140
+ soda-gql codegen --emit-inject-template ./src/graphql/scalars.ts
141
+ `;
123
142
  const codegenCommand = async (argv) => {
143
+ if (argv.includes("--help") || argv.includes("-h")) {
144
+ process.stdout.write(CODEGEN_HELP);
145
+ return 0;
146
+ }
124
147
  try {
125
148
  const parsed = parseCodegenArgs(argv);
126
149
  if (parsed.isErr()) {
127
- process.stderr.write(`${formatCodegenError("json", parsed.error)}\n`);
150
+ process.stderr.write(`${formatCodegenError(parsed.error)}\n`);
128
151
  return 1;
129
152
  }
130
153
  const command = parsed.value;
@@ -132,25 +155,31 @@ const codegenCommand = async (argv) => {
132
155
  const outPath = (0, node_path.resolve)(command.outPath);
133
156
  const result$1 = (0, __soda_gql_codegen.writeInjectTemplate)(outPath);
134
157
  if (result$1.isErr()) {
135
- process.stderr.write(`${formatCodegenError(command.format, result$1.error)}\n`);
158
+ process.stderr.write(`${formatCodegenError(result$1.error)}\n`);
136
159
  return 1;
137
160
  }
138
- process.stdout.write(`${formatTemplateSuccess(command.format, outPath)}\n`);
161
+ process.stdout.write(`${formatTemplateSuccess(outPath)}\n`);
139
162
  return 0;
140
163
  }
141
- const result = await (0, __soda_gql_codegen.runMultiSchemaCodegen)({
142
- schemas: Object.fromEntries(Object.entries(command.schemas).map(([name, path]) => [name, (0, node_path.resolve)(path)])),
164
+ const resolvedSchemas = {};
165
+ for (const [name, schemaConfig] of Object.entries(command.schemas)) resolvedSchemas[name] = {
166
+ schema: (0, node_path.resolve)(schemaConfig.schema),
167
+ inject: {
168
+ scalars: (0, node_path.resolve)(schemaConfig.inject.scalars),
169
+ ...schemaConfig.inject.adapter ? { adapter: (0, node_path.resolve)(schemaConfig.inject.adapter) } : {}
170
+ }
171
+ };
172
+ const result = await (0, __soda_gql_codegen.runCodegen)({
173
+ schemas: resolvedSchemas,
143
174
  outPath: (0, node_path.resolve)(command.outPath),
144
- format: command.format,
145
- runtimeAdapters: Object.fromEntries(Object.entries(command.runtimeAdapters).map(([name, path]) => [name, (0, node_path.resolve)(path)])),
146
- scalars: Object.fromEntries(Object.entries(command.scalars).map(([name, path]) => [name, (0, node_path.resolve)(path)])),
175
+ format: "human",
147
176
  importExtension: command.importExtension
148
177
  });
149
178
  if (result.isErr()) {
150
- process.stderr.write(`${formatCodegenError(command.format, result.error)}\n`);
179
+ process.stderr.write(`${formatCodegenError(result.error)}\n`);
151
180
  return 1;
152
181
  }
153
- process.stdout.write(`${formatMultiSchemaSuccess(command.format, result.value)}\n`);
182
+ process.stdout.write(`${formatSuccess$1(result.value)}\n`);
154
183
  return 0;
155
184
  } catch (error) {
156
185
  const unexpectedError = {
@@ -158,9 +187,339 @@ const codegenCommand = async (argv) => {
158
187
  message: error instanceof Error ? error.message : String(error),
159
188
  outPath: ""
160
189
  };
161
- process.stderr.write(`${formatCodegenError("json", unexpectedError)}\n`);
190
+ process.stderr.write(`${formatCodegenError(unexpectedError)}\n`);
191
+ return 1;
192
+ }
193
+ };
194
+
195
+ //#endregion
196
+ //#region packages/cli/src/commands/format.ts
197
+ const loadFormatter = async () => {
198
+ try {
199
+ return await import("@soda-gql/formatter");
200
+ } catch {
201
+ return null;
202
+ }
203
+ };
204
+ const formatFormatError = (error) => {
205
+ return `${error.code}: ${error.message}`;
206
+ };
207
+ const formatResult = (result) => {
208
+ if (result.mode === "check") {
209
+ if (result.unformatted.length > 0) {
210
+ const files = result.unformatted.map((f) => ` ${f}`).join("\n");
211
+ return `${result.unformatted.length} file(s) need formatting:\n${files}`;
212
+ }
213
+ return `All ${result.total} file(s) are properly formatted`;
214
+ }
215
+ const parts = [];
216
+ if (result.modified > 0) parts.push(`${result.modified} formatted`);
217
+ if (result.unchanged > 0) parts.push(`${result.unchanged} unchanged`);
218
+ if (result.errors > 0) parts.push(`${result.errors} errors`);
219
+ return `${result.total} file(s) checked: ${parts.join(", ")}`;
220
+ };
221
+ const isGlobPattern = (pattern) => {
222
+ return /[*?[\]{}]/.test(pattern);
223
+ };
224
+ const expandGlobPatterns = async (patterns, excludePatterns = []) => {
225
+ const files = [];
226
+ for (const pattern of patterns) {
227
+ if (!isGlobPattern(pattern)) {
228
+ try {
229
+ await (0, node_fs_promises.access)(pattern);
230
+ files.push(pattern);
231
+ } catch {}
232
+ continue;
233
+ }
234
+ const matches = await (0, fast_glob.default)(pattern, {
235
+ absolute: true,
236
+ ignore: [...excludePatterns]
237
+ });
238
+ files.push(...matches);
239
+ }
240
+ return [...new Set(files)];
241
+ };
242
+ const FORMAT_HELP = `Usage: soda-gql format [patterns...] [options]
243
+
244
+ Format soda-gql field selections by inserting empty comments.
245
+
246
+ Options:
247
+ --config <path> Path to soda-gql.config.ts (auto-detected if omitted)
248
+ --check Check if files need formatting (exit 1 if unformatted)
249
+ --help, -h Show this help message
250
+
251
+ Examples:
252
+ soda-gql format # Use config include/exclude
253
+ soda-gql format "src/**/*.ts" # Override with explicit patterns
254
+ soda-gql format --check # Check mode with config
255
+ `;
256
+ const formatCommand = async (argv) => {
257
+ if (argv.includes("--help") || argv.includes("-h")) {
258
+ process.stdout.write(FORMAT_HELP);
259
+ return 0;
260
+ }
261
+ const parsed = parseArgs([...argv], FormatArgsSchema);
262
+ if (!parsed.isOk()) {
263
+ const error = {
264
+ code: "PARSE_ERROR",
265
+ message: parsed.error
266
+ };
267
+ process.stderr.write(`${formatFormatError(error)}\n`);
268
+ return 1;
269
+ }
270
+ const args = parsed.value;
271
+ const isCheckMode = args.check === true;
272
+ const explicitPatterns = args._ ?? [];
273
+ let targetPatterns;
274
+ let excludePatterns = [];
275
+ if (explicitPatterns.length > 0) targetPatterns = explicitPatterns;
276
+ else {
277
+ const configResult = (0, __soda_gql_config.loadConfig)(args.config);
278
+ if (configResult.isErr()) {
279
+ process.stderr.write(`${formatFormatError({
280
+ code: "NO_PATTERNS",
281
+ message: "No patterns provided and config not found. Usage: soda-gql format [patterns...] [--check]"
282
+ })}\n`);
283
+ return 1;
284
+ }
285
+ targetPatterns = configResult.value.include;
286
+ excludePatterns = configResult.value.exclude;
287
+ }
288
+ const formatter = await loadFormatter();
289
+ if (!formatter) {
290
+ process.stderr.write(`${formatFormatError({
291
+ code: "FORMATTER_NOT_INSTALLED",
292
+ message: "@soda-gql/formatter is not installed. Run: npm install @soda-gql/formatter"
293
+ })}\n`);
294
+ return 1;
295
+ }
296
+ const files = await expandGlobPatterns(targetPatterns, excludePatterns);
297
+ if (files.length === 0) {
298
+ const result$1 = {
299
+ mode: isCheckMode ? "check" : "format",
300
+ total: 0,
301
+ modified: 0,
302
+ unchanged: 0,
303
+ errors: 0,
304
+ unformatted: []
305
+ };
306
+ process.stdout.write(`${formatResult(result$1)}\n`);
307
+ return 0;
308
+ }
309
+ let modified = 0;
310
+ let unchanged = 0;
311
+ let errors = 0;
312
+ const unformatted = [];
313
+ for (const filePath of files) {
314
+ const sourceCode = await (0, node_fs_promises.readFile)(filePath, "utf-8");
315
+ if (isCheckMode) {
316
+ const result$1 = formatter.needsFormat({
317
+ sourceCode,
318
+ filePath
319
+ });
320
+ if (result$1.isErr()) {
321
+ errors++;
322
+ continue;
323
+ }
324
+ if (result$1.value) {
325
+ unformatted.push(filePath);
326
+ modified++;
327
+ } else unchanged++;
328
+ } else {
329
+ const result$1 = formatter.format({
330
+ sourceCode,
331
+ filePath
332
+ });
333
+ if (result$1.isErr()) {
334
+ errors++;
335
+ continue;
336
+ }
337
+ if (result$1.value.modified) {
338
+ await (0, node_fs_promises.writeFile)(filePath, result$1.value.sourceCode, "utf-8");
339
+ modified++;
340
+ } else unchanged++;
341
+ }
342
+ }
343
+ const result = {
344
+ mode: isCheckMode ? "check" : "format",
345
+ total: files.length,
346
+ modified,
347
+ unchanged,
348
+ errors,
349
+ unformatted
350
+ };
351
+ process.stdout.write(`${formatResult(result)}\n`);
352
+ if (isCheckMode && unformatted.length > 0) return 1;
353
+ return errors > 0 ? 1 : 0;
354
+ };
355
+
356
+ //#endregion
357
+ //#region packages/cli/src/templates/config.template.ts
358
+ const getConfigTemplate = () => `\
359
+ import { defineConfig } from "@soda-gql/config";
360
+
361
+ export default defineConfig({
362
+ outdir: "./graphql-system",
363
+ include: ["./src/**/*.ts"],
364
+ schemas: {
365
+ default: {
366
+ schema: "./schema.graphql",
367
+ inject: "./graphql-system/default.inject.ts",
368
+ },
369
+ },
370
+ });
371
+ `;
372
+
373
+ //#endregion
374
+ //#region packages/cli/src/templates/gitignore.template.ts
375
+ const getGitignoreTemplate = () => `\
376
+ /index.ts
377
+ /index.cjs
378
+ `;
379
+
380
+ //#endregion
381
+ //#region packages/cli/src/templates/inject.template.ts
382
+ const getInjectTemplate = () => `\
383
+ import { defineAdapter, defineScalar } from "@soda-gql/core/adapter";
384
+
385
+ export const scalar = {
386
+ ...defineScalar<"ID", string, string>("ID"),
387
+ ...defineScalar<"String", string, string>("String"),
388
+ ...defineScalar<"Int", number, number>("Int"),
389
+ ...defineScalar<"Float", number, number>("Float"),
390
+ ...defineScalar<"Boolean", boolean, boolean>("Boolean"),
391
+ } as const;
392
+
393
+ export const adapter = defineAdapter({
394
+ helpers: {},
395
+ metadata: {
396
+ aggregateFragmentMetadata: (fragments) => fragments.map((m) => m.metadata),
397
+ },
398
+ });
399
+ `;
400
+
401
+ //#endregion
402
+ //#region packages/cli/src/templates/schema.template.ts
403
+ const getSchemaTemplate = () => `\
404
+ type Query {
405
+ hello: String!
406
+ }
407
+ `;
408
+
409
+ //#endregion
410
+ //#region packages/cli/src/commands/init.ts
411
+ const INIT_HELP = `Usage: soda-gql init [options]
412
+
413
+ Initialize a new soda-gql project with starter configuration.
414
+
415
+ Options:
416
+ --force Overwrite existing files
417
+ --help, -h Show this help message
418
+
419
+ Generated files:
420
+ soda-gql.config.ts Configuration file
421
+ schema.graphql Sample GraphQL schema
422
+ graphql-system/default.inject.ts Scalars, helpers, and metadata adapter
423
+ graphql-system/.gitignore Ignore generated files
424
+ `;
425
+ const checkFilesExist = (files, force) => {
426
+ if (force) return (0, neverthrow.ok)(void 0);
427
+ for (const file of files) if ((0, node_fs.existsSync)(file.path)) return (0, neverthrow.err)({
428
+ code: "FILE_EXISTS",
429
+ message: `File already exists: ${file.path}. Use --force to overwrite.`,
430
+ filePath: file.path
431
+ });
432
+ return (0, neverthrow.ok)(void 0);
433
+ };
434
+ const writeFiles = (files) => {
435
+ const createdPaths = [];
436
+ for (const file of files) try {
437
+ (0, node_fs.mkdirSync)((0, node_path.dirname)(file.path), { recursive: true });
438
+ (0, node_fs.writeFileSync)(file.path, file.content);
439
+ createdPaths.push(file.path);
440
+ } catch (error) {
441
+ const message = error instanceof Error ? error.message : String(error);
442
+ return (0, neverthrow.err)({
443
+ code: "WRITE_FAILED",
444
+ message: `Failed to write ${file.description}: ${message}`,
445
+ filePath: file.path
446
+ });
447
+ }
448
+ return (0, neverthrow.ok)({ filesCreated: createdPaths });
449
+ };
450
+ const formatSuccess = (result) => {
451
+ const lines = [
452
+ "soda-gql project initialized successfully!",
453
+ "",
454
+ "Created files:"
455
+ ];
456
+ for (const file of result.filesCreated) lines.push(` ${file}`);
457
+ lines.push("", "Next steps:");
458
+ lines.push(" 1. Edit schema.graphql with your GraphQL types");
459
+ lines.push(" 2. Run: soda-gql codegen");
460
+ lines.push(" 3. Import gql from ./graphql-system");
461
+ return lines.join("\n");
462
+ };
463
+ const formatInitError = (error) => {
464
+ return `${error.code}: ${error.message}`;
465
+ };
466
+ const initCommand = async (argv) => {
467
+ if (argv.includes("--help") || argv.includes("-h")) {
468
+ process.stdout.write(INIT_HELP);
469
+ return 0;
470
+ }
471
+ const parsed = parseArgs([...argv], InitArgsSchema);
472
+ if (!parsed.isOk()) {
473
+ const error = {
474
+ code: "PARSE_ERROR",
475
+ message: parsed.error
476
+ };
477
+ process.stderr.write(`${formatInitError(error)}\n`);
478
+ return 1;
479
+ }
480
+ const force = parsed.value.force === true;
481
+ const cwd = process.cwd();
482
+ const files = [
483
+ {
484
+ path: (0, node_path.resolve)(cwd, "soda-gql.config.ts"),
485
+ content: getConfigTemplate(),
486
+ description: "configuration file"
487
+ },
488
+ {
489
+ path: (0, node_path.resolve)(cwd, "schema.graphql"),
490
+ content: getSchemaTemplate(),
491
+ description: "GraphQL schema"
492
+ },
493
+ {
494
+ path: (0, node_path.resolve)(cwd, "graphql-system/default.inject.ts"),
495
+ content: getInjectTemplate(),
496
+ description: "inject module"
497
+ },
498
+ {
499
+ path: (0, node_path.resolve)(cwd, "graphql-system/.gitignore"),
500
+ content: getGitignoreTemplate(),
501
+ description: "gitignore file"
502
+ }
503
+ ];
504
+ const existsCheck = checkFilesExist(files, force);
505
+ if (existsCheck.isErr()) {
506
+ process.stderr.write(`${formatInitError(existsCheck.error)}\n`);
162
507
  return 1;
163
508
  }
509
+ const writeResult = writeFiles(files);
510
+ if (writeResult.isErr()) {
511
+ process.stderr.write(`${formatInitError(writeResult.error)}\n`);
512
+ return 1;
513
+ }
514
+ process.stdout.write(`${formatSuccess(writeResult.value)}\n`);
515
+ return 0;
516
+ };
517
+
518
+ //#endregion
519
+ //#region packages/cli/src/utils/format.ts
520
+ const formatError = (error, format = "human") => {
521
+ if (format === "json") return JSON.stringify({ error }, null, 2);
522
+ return error instanceof Error ? error.message : String(error);
164
523
  };
165
524
 
166
525
  //#endregion
@@ -170,10 +529,14 @@ const dispatch = async (argv) => {
170
529
  if (!command || command === "--help" || command === "-h") {
171
530
  process.stdout.write(`Usage: soda-gql <command> [options]\n`);
172
531
  process.stdout.write(`\nCommands:\n`);
532
+ process.stdout.write(` init Initialize a new soda-gql project\n`);
173
533
  process.stdout.write(` codegen Generate graphql-system runtime module\n`);
534
+ process.stdout.write(` format Format soda-gql field selections\n`);
174
535
  return 0;
175
536
  }
537
+ if (command === "init") return initCommand(rest);
176
538
  if (command === "codegen") return codegenCommand(rest);
539
+ if (command === "format") return formatCommand(rest);
177
540
  process.stderr.write(`Unknown command: ${command}\n`);
178
541
  return 1;
179
542
  };
@@ -189,4 +552,5 @@ dispatch(process.argv.slice(2)).then((exitCode) => {
189
552
  });
190
553
 
191
554
  //#endregion
192
- exports.dispatch = dispatch;
555
+ exports.dispatch = dispatch;
556
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["z","parsed: Record<string, unknown>","positional: string[]","schemas: Record<string, CodegenSchemaConfig>","formatSuccess","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/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 { 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 };\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 formatCodegenError = (error: CodegenError): string => {\n return `${error.code}: ${\"message\" in error ? error.message : \"Unknown error\"}`;\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 };\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 { 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 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 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 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";cAGM,uCAA4C"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";cAKM,uCAA4C"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@soda-gql/cli",
3
- "version": "0.0.9",
3
+ "version": "0.2.0",
4
+ "description": "Command-line interface for soda-gql",
4
5
  "type": "module",
5
6
  "private": false,
6
7
  "license": "MIT",
@@ -15,12 +16,31 @@
15
16
  "email": "shota.hatada@whatasoda.me",
16
17
  "url": "https://github.com/whatasoda"
17
18
  },
19
+ "keywords": [
20
+ "graphql",
21
+ "codegen",
22
+ "zero-runtime",
23
+ "typescript",
24
+ "cli"
25
+ ],
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/whatasoda/soda-gql.git",
29
+ "directory": "packages/cli"
30
+ },
31
+ "homepage": "https://github.com/whatasoda/soda-gql#readme",
32
+ "bugs": {
33
+ "url": "https://github.com/whatasoda/soda-gql/issues"
34
+ },
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
18
38
  "main": "./dist/index.cjs",
19
39
  "module": "./dist/index.cjs",
20
40
  "types": "./dist/index.d.cts",
21
41
  "exports": {
22
42
  ".": {
23
- "@soda-gql": "./src/index.ts",
43
+ "@soda-gql": "./@x-index.ts",
24
44
  "types": "./dist/index.d.cts",
25
45
  "require": "./dist/index.cjs",
26
46
  "default": "./dist/index.cjs"
@@ -28,11 +48,15 @@
28
48
  "./package.json": "./package.json"
29
49
  },
30
50
  "dependencies": {
31
- "@soda-gql/codegen": "0.0.9",
32
- "@soda-gql/builder": "0.0.9",
51
+ "@soda-gql/codegen": "0.2.0",
52
+ "@soda-gql/builder": "0.2.0",
53
+ "fast-glob": "^3.3.3",
33
54
  "neverthrow": "^8.1.1",
34
55
  "zod": "^4.1.11"
35
56
  },
36
57
  "devDependencies": {},
37
- "peerDependencies": {}
58
+ "peerDependencies": {},
59
+ "optionalDependencies": {
60
+ "@soda-gql/formatter": "workspace:*"
61
+ }
38
62
  }