@01.software/cli 0.2.0-dev.260310.cf511cb → 0.3.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/dist/index.js CHANGED
@@ -5,11 +5,24 @@ import { createRequire } from "module";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/lib/client.ts
8
- import { CollectionClient, OrderApi, CartApi, ProductApi, parseApiKey } from "@01.software/sdk";
8
+ import {
9
+ CollectionClient,
10
+ OrderApi,
11
+ CartApi,
12
+ ProductApi,
13
+ parseApiKey
14
+ } from "@01.software/sdk";
9
15
  import pc from "picocolors";
10
16
 
11
17
  // src/lib/credentials.ts
12
- import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, appendFileSync } from "fs";
18
+ import {
19
+ existsSync,
20
+ mkdirSync,
21
+ readFileSync,
22
+ writeFileSync,
23
+ unlinkSync,
24
+ appendFileSync
25
+ } from "fs";
13
26
  import { join } from "path";
14
27
  import { homedir } from "os";
15
28
  var DIR_NAME = ".01software";
@@ -27,8 +40,14 @@ function saveCredentials(creds) {
27
40
  mkdirSync(dir, { recursive: true, mode: 448 });
28
41
  }
29
42
  const filePath = getCredentialsPath();
30
- const data = { ...creds, storedAt: (/* @__PURE__ */ new Date()).toISOString() };
31
- writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
43
+ const data = {
44
+ ...creds,
45
+ storedAt: (/* @__PURE__ */ new Date()).toISOString()
46
+ };
47
+ writeFileSync(filePath, JSON.stringify(data, null, 2), {
48
+ encoding: "utf-8",
49
+ mode: 384
50
+ });
32
51
  }
33
52
  function deleteCredentials() {
34
53
  const filePath = getCredentialsPath();
@@ -48,8 +67,14 @@ function saveLocalCredentials(creds) {
48
67
  mkdirSync(dir, { recursive: true, mode: 448 });
49
68
  }
50
69
  const filePath = getLocalCredentialsPath();
51
- const data = { ...creds, storedAt: (/* @__PURE__ */ new Date()).toISOString() };
52
- writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
70
+ const data = {
71
+ ...creds,
72
+ storedAt: (/* @__PURE__ */ new Date()).toISOString()
73
+ };
74
+ writeFileSync(filePath, JSON.stringify(data, null, 2), {
75
+ encoding: "utf-8",
76
+ mode: 384
77
+ });
53
78
  ensureGitignore();
54
79
  }
55
80
  function saveTenantList(tenants) {
@@ -58,7 +83,10 @@ function saveTenantList(tenants) {
58
83
  mkdirSync(dir, { recursive: true, mode: 448 });
59
84
  }
60
85
  const filePath = join(homedir(), DIR_NAME, TENANTS_FILE);
61
- writeFileSync(filePath, JSON.stringify(tenants, null, 2), { encoding: "utf-8", mode: 384 });
86
+ writeFileSync(filePath, JSON.stringify(tenants, null, 2), {
87
+ encoding: "utf-8",
88
+ mode: 384
89
+ });
62
90
  }
63
91
  function loadTenantList() {
64
92
  const filePath = join(homedir(), DIR_NAME, TENANTS_FILE);
@@ -111,8 +139,12 @@ function resolveClient(apiKeyFlag) {
111
139
  clientKey = parsed.clientKey;
112
140
  secretKey = parsed.secretKey;
113
141
  } catch {
114
- console.error(pc.red('Invalid --api-key value. Expected Base64-encoded "clientKey:secretKey".'));
115
- process.exit(1);
142
+ console.error(
143
+ pc.red(
144
+ 'Invalid --api-key value. Expected Base64-encoded "clientKey:secretKey".'
145
+ )
146
+ );
147
+ process.exit(2);
116
148
  }
117
149
  } else {
118
150
  clientKey = process.env.SOFTWARE_CLIENT_KEY;
@@ -139,14 +171,16 @@ function resolveClient(apiKeyFlag) {
139
171
  'Run "01 login" to authenticate via browser,\nor set SOFTWARE_CLIENT_KEY and SOFTWARE_SECRET_KEY environment variables,\nor use the --api-key <base64> flag.'
140
172
  )
141
173
  );
142
- process.exit(1);
174
+ process.exit(2);
143
175
  }
144
176
  const apiOpts = { clientKey, secretKey };
145
177
  return {
146
178
  collections: new CollectionClient(clientKey, secretKey),
147
179
  api: new OrderApi(apiOpts),
148
180
  cart: new CartApi(apiOpts),
149
- product: new ProductApi(apiOpts)
181
+ product: new ProductApi(apiOpts),
182
+ clientKey,
183
+ secretKey
150
184
  };
151
185
  }
152
186
 
@@ -163,13 +197,22 @@ function printTable(data) {
163
197
  }
164
198
  const keys = Object.keys(data[0]);
165
199
  const widths = keys.map(
166
- (k) => Math.max(k.length, ...data.map((row) => String(row[k] ?? "").length))
200
+ (k) => Math.max(
201
+ k.length,
202
+ ...data.map(
203
+ (row) => String(row[k] ?? "").length
204
+ )
205
+ )
167
206
  );
168
207
  console.log(keys.map((k, i) => k.padEnd(widths[i])).join(" "));
169
208
  console.log(keys.map((_, i) => "-".repeat(widths[i])).join(" "));
170
209
  for (const row of data) {
171
210
  console.log(
172
- keys.map((k, i) => String(row[k] ?? "").padEnd(widths[i])).join(" ")
211
+ keys.map(
212
+ (k, i) => String(row[k] ?? "").padEnd(
213
+ widths[i]
214
+ )
215
+ ).join(" ")
173
216
  );
174
217
  }
175
218
  } else if (data && typeof data === "object") {
@@ -183,13 +226,31 @@ function printTable(data) {
183
226
  console.log(String(data));
184
227
  }
185
228
  }
229
+ function printNdjson(data) {
230
+ if (Array.isArray(data)) {
231
+ data.forEach((item) => console.log(JSON.stringify(item)));
232
+ } else if (data && typeof data === "object" && "docs" in data) {
233
+ const { docs, ...meta } = data;
234
+ docs.forEach((doc) => console.log(JSON.stringify(doc)));
235
+ if (Object.keys(meta).length > 0)
236
+ console.log(JSON.stringify({ _meta: meta }));
237
+ } else {
238
+ console.log(JSON.stringify(data));
239
+ }
240
+ }
186
241
  function printResult(data, format) {
187
- if (format === "table") {
242
+ if (format === "ndjson") {
243
+ printNdjson(data);
244
+ } else if (format === "table") {
188
245
  if (data && typeof data === "object" && "docs" in data) {
189
246
  const resp = data;
190
247
  printTable(resp.docs);
191
- console.log(pc2.dim(`
192
- ${resp.totalDocs} total | page ${resp.page}/${resp.totalPages}`));
248
+ console.log(
249
+ pc2.dim(
250
+ `
251
+ ${resp.totalDocs} total | page ${resp.page}/${resp.totalPages}`
252
+ )
253
+ );
193
254
  return;
194
255
  }
195
256
  printTable(data);
@@ -197,6 +258,26 @@ ${resp.totalDocs} total | page ${resp.page}/${resp.totalPages}`));
197
258
  printJson(data);
198
259
  }
199
260
  }
261
+ function getExitCode(error) {
262
+ if (!error || typeof error !== "object") return 1;
263
+ const err = error;
264
+ if (err.name === "ConfigError") return 2;
265
+ if (err.name === "ValidationError") return 3;
266
+ if (err.name === "NetworkError" || err.name === "TimeoutError") return 4;
267
+ if (err.name === "GoneError") return 5;
268
+ if (err.name === "UsageLimitError") return 6;
269
+ const s = err.status;
270
+ if (s === 401) return 2;
271
+ if (s === 400 || s === 422) return 3;
272
+ if (s === 408 || s === 503) return 4;
273
+ if (s === 404) return 5;
274
+ if (s === 429) return 6;
275
+ return 1;
276
+ }
277
+ function exitWithError(error) {
278
+ printError(error);
279
+ process.exit(getExitCode(error));
280
+ }
200
281
  function printError(error) {
201
282
  if (error && typeof error === "object" && "message" in error) {
202
283
  const err = error;
@@ -221,12 +302,12 @@ function parseJson(value, label) {
221
302
  const parsed = JSON.parse(value);
222
303
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
223
304
  console.error(pc3.red(`--${label} must be a JSON object.`));
224
- process.exit(1);
305
+ process.exit(3);
225
306
  }
226
307
  return parsed;
227
308
  } catch {
228
309
  console.error(pc3.red(`Invalid JSON for --${label}: ${value}`));
229
- process.exit(1);
310
+ process.exit(3);
230
311
  }
231
312
  }
232
313
  function parseJsonArray(value, label) {
@@ -234,12 +315,12 @@ function parseJsonArray(value, label) {
234
315
  const parsed = JSON.parse(value);
235
316
  if (!Array.isArray(parsed)) {
236
317
  console.error(pc3.red(`--${label} must be a JSON array.`));
237
- process.exit(1);
318
+ process.exit(3);
238
319
  }
239
320
  return parsed;
240
321
  } catch {
241
322
  console.error(pc3.red(`Invalid JSON for --${label}: ${value}`));
242
- process.exit(1);
323
+ process.exit(3);
243
324
  }
244
325
  }
245
326
 
@@ -264,7 +345,11 @@ function parseSelect(input) {
264
345
  return Object.fromEntries(input.split(",").map((f) => [f.trim(), true]));
265
346
  }
266
347
  function registerCrudCommands(program2, getClient2, getFormat2) {
267
- program2.command("query <collection>").description("Query documents from a collection").option("--where <json>", "Filter conditions (JSON)").option("--limit <n>", "Max results", (v) => parseInt(v, 10)).option("--page <n>", "Page number", (v) => parseInt(v, 10)).option("--sort <field>", "Sort field (prefix with - for descending)").option("--depth <n>", "Relationship depth (0 = no population)", (v) => parseInt(v, 10)).option("--select <fields>", "Comma-separated fields to select").action(async (collection, opts) => {
348
+ program2.command("query <collection>").description("Query documents from a collection").option("--where <json>", "Filter conditions (JSON)").option("--limit <n>", "Max results", (v) => parseInt(v, 10)).option("--page <n>", "Page number", (v) => parseInt(v, 10)).option("--sort <field>", "Sort field (prefix with - for descending)").option(
349
+ "--depth <n>",
350
+ "Relationship depth (0 = no population)",
351
+ (v) => parseInt(v, 10)
352
+ ).option("--select <fields>", "Comma-separated fields to select").action(async (collection, opts) => {
268
353
  try {
269
354
  const col = validateCollection(collection);
270
355
  const client = getClient2();
@@ -278,11 +363,14 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
278
363
  const result = await client.collections.from(col).find(options);
279
364
  printResult(result, getFormat2());
280
365
  } catch (e) {
281
- printError(e);
282
- process.exit(1);
366
+ exitWithError(e);
283
367
  }
284
368
  });
285
- program2.command("get <collection> <id>").description("Get a document by ID").option("--depth <n>", "Relationship depth (0 = no population)", (v) => parseInt(v, 10)).option("--select <fields>", "Comma-separated fields to select").action(async (collection, id, opts) => {
369
+ program2.command("get <collection> <id>").description("Get a document by ID").option(
370
+ "--depth <n>",
371
+ "Relationship depth (0 = no population)",
372
+ (v) => parseInt(v, 10)
373
+ ).option("--select <fields>", "Comma-separated fields to select").action(async (collection, id, opts) => {
286
374
  try {
287
375
  const col = validateCollection(collection);
288
376
  const client = getClient2();
@@ -292,15 +380,27 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
292
380
  const result = await client.collections.from(col).findById(id, options);
293
381
  printResult(result, getFormat2());
294
382
  } catch (e) {
295
- printError(e);
296
- process.exit(1);
383
+ exitWithError(e);
297
384
  }
298
385
  });
299
- program2.command("create <collection>").description("Create a new document").requiredOption("--data <json>", "Document data (JSON)").option("--file <path>", "File to upload (for upload collections)").action(async (collection, opts) => {
386
+ program2.command("create <collection>").description("Create a new document").requiredOption("--data <json>", "Document data (JSON)").option("--file <path>", "File to upload (for upload collections)").option("--dry-run", "Validate inputs without executing").action(async (collection, opts) => {
300
387
  try {
301
388
  const col = validateCollection(collection);
302
- const client = getClient2();
303
389
  const data = parseJson(opts.data, "data");
390
+ if (opts.dryRun) {
391
+ printResult(
392
+ {
393
+ dryRun: true,
394
+ valid: true,
395
+ action: "create",
396
+ collection: col,
397
+ data
398
+ },
399
+ getFormat2()
400
+ );
401
+ return;
402
+ }
403
+ const client = getClient2();
304
404
  let fileOpts;
305
405
  if (opts.file) {
306
406
  const { blob, filename } = readFileAsBlob(opts.file);
@@ -309,15 +409,28 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
309
409
  const result = await client.collections.from(col).create(data, fileOpts);
310
410
  printResult(result, getFormat2());
311
411
  } catch (e) {
312
- printError(e);
313
- process.exit(1);
412
+ exitWithError(e);
314
413
  }
315
414
  });
316
- program2.command("update <collection> <id>").description("Update a document by ID").requiredOption("--data <json>", "Document data (JSON)").option("--file <path>", "File to upload (for upload collections)").action(async (collection, id, opts) => {
415
+ program2.command("update <collection> <id>").description("Update a document by ID").requiredOption("--data <json>", "Document data (JSON)").option("--file <path>", "File to upload (for upload collections)").option("--dry-run", "Validate inputs without executing").action(async (collection, id, opts) => {
317
416
  try {
318
417
  const col = validateCollection(collection);
319
- const client = getClient2();
320
418
  const data = parseJson(opts.data, "data");
419
+ if (opts.dryRun) {
420
+ printResult(
421
+ {
422
+ dryRun: true,
423
+ valid: true,
424
+ action: "update",
425
+ collection: col,
426
+ id,
427
+ data
428
+ },
429
+ getFormat2()
430
+ );
431
+ return;
432
+ }
433
+ const client = getClient2();
321
434
  let fileOpts;
322
435
  if (opts.file) {
323
436
  const { blob, filename } = readFileAsBlob(opts.file);
@@ -326,44 +439,80 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
326
439
  const result = await client.collections.from(col).update(id, data, fileOpts);
327
440
  printResult(result, getFormat2());
328
441
  } catch (e) {
329
- printError(e);
330
- process.exit(1);
442
+ exitWithError(e);
331
443
  }
332
444
  });
333
- program2.command("delete <collection> <id>").description("Delete a document by ID").action(async (collection, id) => {
445
+ program2.command("delete <collection> <id>").description("Delete a document by ID").option("--dry-run", "Validate inputs without executing").action(async (collection, id, opts) => {
334
446
  try {
335
447
  const col = validateCollection(collection);
448
+ if (opts.dryRun) {
449
+ printResult(
450
+ {
451
+ dryRun: true,
452
+ valid: true,
453
+ action: "delete",
454
+ collection: col,
455
+ id
456
+ },
457
+ getFormat2()
458
+ );
459
+ return;
460
+ }
336
461
  const client = getClient2();
337
462
  const result = await client.collections.from(col).remove(id);
338
463
  printResult(result, getFormat2());
339
464
  } catch (e) {
340
- printError(e);
341
- process.exit(1);
465
+ exitWithError(e);
342
466
  }
343
467
  });
344
- program2.command("update-many <collection>").description("Update multiple documents matching a filter").requiredOption("--where <json>", "Filter conditions (JSON)").requiredOption("--data <json>", "Update data (JSON)").action(async (collection, opts) => {
468
+ program2.command("update-many <collection>").description("Update multiple documents matching a filter").requiredOption("--where <json>", "Filter conditions (JSON)").requiredOption("--data <json>", "Update data (JSON)").option("--dry-run", "Validate inputs without executing").action(async (collection, opts) => {
345
469
  try {
346
470
  const col = validateCollection(collection);
347
- const client = getClient2();
348
471
  const where = parseJson(opts.where, "where");
349
472
  const data = parseJson(opts.data, "data");
473
+ if (opts.dryRun) {
474
+ printResult(
475
+ {
476
+ dryRun: true,
477
+ valid: true,
478
+ action: "update-many",
479
+ collection: col,
480
+ where,
481
+ data
482
+ },
483
+ getFormat2()
484
+ );
485
+ return;
486
+ }
487
+ const client = getClient2();
350
488
  const result = await client.collections.from(col).updateMany(where, data);
351
489
  printResult(result, getFormat2());
352
490
  } catch (e) {
353
- printError(e);
354
- process.exit(1);
491
+ exitWithError(e);
355
492
  }
356
493
  });
357
- program2.command("delete-many <collection>").description("Delete multiple documents matching a filter").requiredOption("--where <json>", "Filter conditions (JSON)").action(async (collection, opts) => {
494
+ program2.command("delete-many <collection>").description("Delete multiple documents matching a filter").requiredOption("--where <json>", "Filter conditions (JSON)").option("--dry-run", "Validate inputs without executing").action(async (collection, opts) => {
358
495
  try {
359
496
  const col = validateCollection(collection);
360
- const client = getClient2();
361
497
  const where = parseJson(opts.where, "where");
498
+ if (opts.dryRun) {
499
+ printResult(
500
+ {
501
+ dryRun: true,
502
+ valid: true,
503
+ action: "delete-many",
504
+ collection: col,
505
+ where
506
+ },
507
+ getFormat2()
508
+ );
509
+ return;
510
+ }
511
+ const client = getClient2();
362
512
  const result = await client.collections.from(col).removeMany(where);
363
513
  printResult(result, getFormat2());
364
514
  } catch (e) {
365
- printError(e);
366
- process.exit(1);
515
+ exitWithError(e);
367
516
  }
368
517
  });
369
518
  }
@@ -371,10 +520,14 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
371
520
  // src/commands/order.ts
372
521
  function registerOrderCommands(program2, getClient2, getFormat2) {
373
522
  const order = program2.command("order").description("Order management");
374
- order.command("create").description("Create a new order").option("--payment-id <id>", "Payment ID").requiredOption("--order-number <num>", "Order number").requiredOption("--email <email>", "Customer email").option("--customer <id>", "Customer ID").option("--name <name>", "Customer name").option("--phone <phone>", "Customer phone").requiredOption("--shipping-address <json>", "Shipping address (JSON)").requiredOption("--products <json>", "Order products array (JSON)").requiredOption("--total-amount <n>", "Total amount", parseFloat).action(async (opts) => {
523
+ order.command("create").description("Create a new order").option("--payment-id <id>", "Payment ID").requiredOption("--order-number <num>", "Order number").requiredOption("--email <email>", "Customer email").option("--customer <id>", "Customer ID").option("--name <name>", "Customer name").option("--phone <phone>", "Customer phone").requiredOption("--shipping-address <json>", "Shipping address (JSON)").requiredOption("--products <json>", "Order products array (JSON)").requiredOption("--total-amount <n>", "Total amount", parseFloat).option("--dry-run", "Validate inputs without executing").action(async (opts) => {
375
524
  try {
376
- const client = getClient2();
377
- const result = await client.api.createOrder({
525
+ const shippingAddress = parseJson(
526
+ opts.shippingAddress,
527
+ "shipping-address"
528
+ );
529
+ const orderProducts = parseJsonArray(opts.products, "products");
530
+ const data = {
378
531
  paymentId: opts.paymentId,
379
532
  orderNumber: opts.orderNumber,
380
533
  customerSnapshot: {
@@ -383,14 +536,25 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
383
536
  phone: opts.phone
384
537
  },
385
538
  customer: opts.customer,
386
- shippingAddress: parseJson(opts.shippingAddress, "shipping-address"),
387
- orderProducts: parseJsonArray(opts.products, "products"),
539
+ shippingAddress,
540
+ orderProducts,
388
541
  totalAmount: opts.totalAmount
542
+ };
543
+ if (opts.dryRun) {
544
+ printResult(
545
+ { dryRun: true, valid: true, action: "order create", data },
546
+ getFormat2()
547
+ );
548
+ return;
549
+ }
550
+ const client = getClient2();
551
+ const result = await client.api.createOrder({
552
+ ...data,
553
+ orderProducts
389
554
  });
390
555
  printResult(result, getFormat2());
391
556
  } catch (e) {
392
- printError(e);
393
- process.exit(1);
557
+ exitWithError(e);
394
558
  }
395
559
  });
396
560
  order.command("get <orderNumber>").description("Get an order by order number").action(async (orderNumber) => {
@@ -399,51 +563,76 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
399
563
  const result = await client.api.getOrder({ orderNumber });
400
564
  printResult(result, getFormat2());
401
565
  } catch (e) {
402
- printError(e);
403
- process.exit(1);
566
+ exitWithError(e);
404
567
  }
405
568
  });
406
- order.command("update <orderNumber>").description("Update order status").requiredOption("--status <status>", "New status").action(async (orderNumber, opts) => {
569
+ order.command("update <orderNumber>").description("Update order status").requiredOption("--status <status>", "New status").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
407
570
  try {
571
+ const data = { orderNumber, status: opts.status };
572
+ if (opts.dryRun) {
573
+ printResult(
574
+ { dryRun: true, valid: true, action: "order update", data },
575
+ getFormat2()
576
+ );
577
+ return;
578
+ }
408
579
  const client = getClient2();
409
- const result = await client.api.updateOrder({
410
- orderNumber,
411
- status: opts.status
412
- });
580
+ const result = await client.api.updateOrder(data);
413
581
  printResult(result, getFormat2());
414
582
  } catch (e) {
415
- printError(e);
416
- process.exit(1);
583
+ exitWithError(e);
417
584
  }
418
585
  });
419
- order.command("checkout").description("Convert a cart to an order").requiredOption("--cart-id <id>", "Cart ID").requiredOption("--payment-id <id>", "Payment ID").requiredOption("--order-number <num>", "Order number").requiredOption("--customer <json>", "Customer snapshot (JSON)").action(async (opts) => {
586
+ order.command("checkout").description("Convert a cart to an order").requiredOption("--cart-id <id>", "Cart ID").option("--payment-id <id>", "Payment ID (optional for free orders)").requiredOption("--order-number <num>", "Order number").requiredOption("--customer <json>", "Customer snapshot (JSON)").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
420
587
  try {
421
- const client = getClient2();
422
- const result = await client.api.checkout({
588
+ const customerSnapshot = parseJson(opts.customer, "customer");
589
+ const data = {
423
590
  cartId: opts.cartId,
424
591
  paymentId: opts.paymentId,
425
592
  orderNumber: opts.orderNumber,
426
- customerSnapshot: parseJson(opts.customer, "customer")
593
+ customerSnapshot
594
+ };
595
+ if (opts.dryRun) {
596
+ printResult(
597
+ { dryRun: true, valid: true, action: "order checkout", data },
598
+ getFormat2()
599
+ );
600
+ return;
601
+ }
602
+ const client = getClient2();
603
+ const result = await client.api.checkout({
604
+ ...data,
605
+ customerSnapshot
427
606
  });
428
607
  printResult(result, getFormat2());
429
608
  } catch (e) {
430
- printError(e);
431
- process.exit(1);
609
+ exitWithError(e);
432
610
  }
433
611
  });
434
- order.command("fulfill <orderNumber>").description("Create a fulfillment for an order").requiredOption("--items <json>", "Fulfillment items array (JSON)").option("--carrier <name>", "Shipping carrier").option("--tracking-number <num>", "Tracking number").action(async (orderNumber, opts) => {
612
+ order.command("fulfill <orderNumber>").description("Create a fulfillment for an order").requiredOption("--items <json>", "Fulfillment items array (JSON)").option("--carrier <name>", "Shipping carrier").option("--tracking-number <num>", "Tracking number").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
435
613
  try {
436
- const client = getClient2();
437
- const result = await client.api.createFulfillment({
614
+ const items = parseJsonArray(opts.items, "items");
615
+ const data = {
438
616
  orderNumber,
439
- items: parseJsonArray(opts.items, "items"),
617
+ items,
440
618
  carrier: opts.carrier,
441
619
  trackingNumber: opts.trackingNumber
620
+ };
621
+ if (opts.dryRun) {
622
+ printResult(
623
+ { dryRun: true, valid: true, action: "order fulfill", data },
624
+ getFormat2()
625
+ );
626
+ return;
627
+ }
628
+ const client = getClient2();
629
+ const result = await client.api.createFulfillment({
630
+ ...data,
631
+ items
442
632
  });
443
633
  printResult(result, getFormat2());
444
634
  } catch (e) {
445
- printError(e);
446
- process.exit(1);
635
+ exitWithError(e);
447
636
  }
448
637
  });
449
638
  }
@@ -451,51 +640,83 @@ function registerOrderCommands(program2, getClient2, getFormat2) {
451
640
  // src/commands/return.ts
452
641
  function registerReturnCommands(program2, getClient2, getFormat2) {
453
642
  const ret = program2.command("return").description("Return management");
454
- ret.command("create <orderNumber>").description("Create a return request").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).option("--reason <reason>", "Return reason (change_of_mind, defective, wrong_delivery, damaged, other)").option("--reason-detail <text>", "Detailed reason").action(async (orderNumber, opts) => {
643
+ ret.command("create <orderNumber>").description("Create a return request").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).option(
644
+ "--reason <reason>",
645
+ "Return reason (change_of_mind, defective, wrong_delivery, damaged, other)"
646
+ ).option("--reason-detail <text>", "Detailed reason").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
455
647
  try {
456
- const client = getClient2();
457
- const result = await client.api.createReturn({
648
+ const returnProducts = parseJsonArray(opts.products, "products");
649
+ const data = {
458
650
  orderNumber,
459
- returnProducts: parseJsonArray(opts.products, "products"),
651
+ returnProducts,
460
652
  refundAmount: opts.refundAmount,
461
653
  reason: opts.reason,
462
654
  reasonDetail: opts.reasonDetail
655
+ };
656
+ if (opts.dryRun) {
657
+ printResult(
658
+ { dryRun: true, valid: true, action: "return create", data },
659
+ getFormat2()
660
+ );
661
+ return;
662
+ }
663
+ const client = getClient2();
664
+ const result = await client.api.createReturn({
665
+ ...data,
666
+ returnProducts
463
667
  });
464
668
  printResult(result, getFormat2());
465
669
  } catch (e) {
466
- printError(e);
467
- process.exit(1);
670
+ exitWithError(e);
468
671
  }
469
672
  });
470
- ret.command("update <returnId>").description("Update return status").requiredOption("--status <status>", "New status (processing, approved, rejected, completed)").action(async (returnId, opts) => {
673
+ ret.command("update <returnId>").description("Update return status").requiredOption(
674
+ "--status <status>",
675
+ "New status (processing, approved, rejected, completed)"
676
+ ).option("--dry-run", "Validate inputs without executing").action(async (returnId, opts) => {
471
677
  try {
678
+ const data = { returnId, status: opts.status };
679
+ if (opts.dryRun) {
680
+ printResult(
681
+ { dryRun: true, valid: true, action: "return update", data },
682
+ getFormat2()
683
+ );
684
+ return;
685
+ }
472
686
  const client = getClient2();
473
- const result = await client.api.updateReturn({
474
- returnId,
475
- status: opts.status
476
- });
687
+ const result = await client.api.updateReturn(data);
477
688
  printResult(result, getFormat2());
478
689
  } catch (e) {
479
- printError(e);
480
- process.exit(1);
690
+ exitWithError(e);
481
691
  }
482
692
  });
483
- ret.command("refund <orderNumber>").description("Return with refund").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).requiredOption("--payment-id <id>", "Payment ID").option("--reason <reason>", "Return reason").option("--reason-detail <text>", "Detailed reason").option("--refund-receipt-url <url>", "Refund receipt URL").action(async (orderNumber, opts) => {
693
+ ret.command("refund <orderNumber>").description("Return with refund").requiredOption("--products <json>", "Return products array (JSON)").requiredOption("--refund-amount <n>", "Refund amount", parseFloat).requiredOption("--payment-id <id>", "Payment ID").option("--reason <reason>", "Return reason").option("--reason-detail <text>", "Detailed reason").option("--refund-receipt-url <url>", "Refund receipt URL").option("--dry-run", "Validate inputs without executing").action(async (orderNumber, opts) => {
484
694
  try {
485
- const client = getClient2();
486
- const result = await client.api.returnWithRefund({
695
+ const returnProducts = parseJsonArray(opts.products, "products");
696
+ const data = {
487
697
  orderNumber,
488
- returnProducts: parseJsonArray(opts.products, "products"),
698
+ returnProducts,
489
699
  refundAmount: opts.refundAmount,
490
700
  paymentId: opts.paymentId,
491
701
  reason: opts.reason,
492
702
  reasonDetail: opts.reasonDetail,
493
703
  refundReceiptUrl: opts.refundReceiptUrl
704
+ };
705
+ if (opts.dryRun) {
706
+ printResult(
707
+ { dryRun: true, valid: true, action: "return refund", data },
708
+ getFormat2()
709
+ );
710
+ return;
711
+ }
712
+ const client = getClient2();
713
+ const result = await client.api.returnWithRefund({
714
+ ...data,
715
+ returnProducts
494
716
  });
495
717
  printResult(result, getFormat2());
496
718
  } catch (e) {
497
- printError(e);
498
- process.exit(1);
719
+ exitWithError(e);
499
720
  }
500
721
  });
501
722
  }
@@ -503,43 +724,73 @@ function registerReturnCommands(program2, getClient2, getFormat2) {
503
724
  // src/commands/cart.ts
504
725
  function registerCartCommands(program2, getClient2, getFormat2) {
505
726
  const cart = program2.command("cart").description("Cart management");
506
- cart.command("add <cartId>").description("Add an item to cart").requiredOption("--product <id>", "Product ID").requiredOption("--variant <id>", "Variant ID").requiredOption("--option <id>", "Option ID").requiredOption("--quantity <n>", "Quantity", (v) => parseInt(v, 10)).action(async (cartId, opts) => {
727
+ cart.command("add <cartId>").description("Add an item to cart").requiredOption("--product <id>", "Product ID").requiredOption("--variant <id>", "Variant ID").requiredOption("--option <id>", "Option ID").requiredOption(
728
+ "--quantity <n>",
729
+ "Quantity",
730
+ (v) => parseInt(v, 10)
731
+ ).option("--dry-run", "Validate inputs without executing").action(async (cartId, opts) => {
507
732
  try {
508
- const client = getClient2();
509
- const result = await client.cart.addItem({
733
+ const data = {
510
734
  cartId,
511
735
  product: opts.product,
512
736
  variant: opts.variant,
513
737
  option: opts.option,
514
738
  quantity: opts.quantity
515
- });
739
+ };
740
+ if (opts.dryRun) {
741
+ printResult(
742
+ { dryRun: true, valid: true, action: "cart add", data },
743
+ getFormat2()
744
+ );
745
+ return;
746
+ }
747
+ const client = getClient2();
748
+ const result = await client.cart.addItem(data);
516
749
  printResult(result, getFormat2());
517
750
  } catch (e) {
518
- printError(e);
519
- process.exit(1);
751
+ exitWithError(e);
520
752
  }
521
753
  });
522
- cart.command("update <cartItemId>").description("Update cart item quantity").requiredOption("--quantity <n>", "New quantity", (v) => parseInt(v, 10)).action(async (cartItemId, opts) => {
754
+ cart.command("update <cartItemId>").description("Update cart item quantity").requiredOption(
755
+ "--quantity <n>",
756
+ "New quantity",
757
+ (v) => parseInt(v, 10)
758
+ ).option("--dry-run", "Validate inputs without executing").action(async (cartItemId, opts) => {
523
759
  try {
760
+ const data = { cartItemId, quantity: opts.quantity };
761
+ if (opts.dryRun) {
762
+ printResult(
763
+ { dryRun: true, valid: true, action: "cart update", data },
764
+ getFormat2()
765
+ );
766
+ return;
767
+ }
524
768
  const client = getClient2();
525
- const result = await client.cart.updateItem({
526
- cartItemId,
527
- quantity: opts.quantity
528
- });
769
+ const result = await client.cart.updateItem(data);
529
770
  printResult(result, getFormat2());
530
771
  } catch (e) {
531
- printError(e);
532
- process.exit(1);
772
+ exitWithError(e);
533
773
  }
534
774
  });
535
- cart.command("remove <cartItemId>").description("Remove an item from cart").action(async (cartItemId) => {
775
+ cart.command("remove <cartItemId>").description("Remove an item from cart").option("--dry-run", "Validate inputs without executing").action(async (cartItemId, opts) => {
536
776
  try {
777
+ if (opts.dryRun) {
778
+ printResult(
779
+ {
780
+ dryRun: true,
781
+ valid: true,
782
+ action: "cart remove",
783
+ data: { cartItemId }
784
+ },
785
+ getFormat2()
786
+ );
787
+ return;
788
+ }
537
789
  const client = getClient2();
538
790
  const result = await client.cart.removeItem({ cartItemId });
539
791
  printResult(result, getFormat2());
540
792
  } catch (e) {
541
- printError(e);
542
- process.exit(1);
793
+ exitWithError(e);
543
794
  }
544
795
  });
545
796
  }
@@ -547,15 +798,17 @@ function registerCartCommands(program2, getClient2, getFormat2) {
547
798
  // src/commands/stock.ts
548
799
  function registerStockCommands(program2, getClient2, getFormat2) {
549
800
  const stock = program2.command("stock").description("Stock management");
550
- stock.command("check").description("Check stock availability").requiredOption("--items <json>", "Items to check (JSON array of { optionId, quantity })").action(async (opts) => {
801
+ stock.command("check").description("Check stock availability").requiredOption(
802
+ "--items <json>",
803
+ "Items to check (JSON array of { optionId, quantity })"
804
+ ).action(async (opts) => {
551
805
  try {
552
806
  const client = getClient2();
553
807
  const items = parseJsonArray(opts.items, "items");
554
808
  const result = await client.product.stockCheck({ items });
555
809
  printResult(result, getFormat2());
556
810
  } catch (e) {
557
- printError(e);
558
- process.exit(1);
811
+ exitWithError(e);
559
812
  }
560
813
  });
561
814
  }
@@ -563,19 +816,29 @@ function registerStockCommands(program2, getClient2, getFormat2) {
563
816
  // src/commands/transaction.ts
564
817
  function registerTransactionCommands(program2, getClient2, getFormat2) {
565
818
  const tx = program2.command("transaction").description("Transaction management");
566
- tx.command("update").description("Update transaction status").requiredOption("--payment-id <id>", "Payment ID").requiredOption("--status <status>", "New status (pending, paid, failed, canceled)").requiredOption("--payment-method <method>", "Payment method").requiredOption("--receipt-url <url>", "Receipt URL").action(async (opts) => {
819
+ tx.command("update").description("Update transaction status").requiredOption("--payment-id <id>", "Payment ID").requiredOption(
820
+ "--status <status>",
821
+ "New status (pending, paid, failed, canceled)"
822
+ ).requiredOption("--payment-method <method>", "Payment method").requiredOption("--receipt-url <url>", "Receipt URL").option("--dry-run", "Validate inputs without executing").action(async (opts) => {
567
823
  try {
568
- const client = getClient2();
569
- const result = await client.api.updateTransaction({
824
+ const data = {
570
825
  paymentId: opts.paymentId,
571
826
  status: opts.status,
572
827
  paymentMethod: opts.paymentMethod,
573
828
  receiptUrl: opts.receiptUrl
574
- });
829
+ };
830
+ if (opts.dryRun) {
831
+ printResult(
832
+ { dryRun: true, valid: true, action: "transaction update", data },
833
+ getFormat2()
834
+ );
835
+ return;
836
+ }
837
+ const client = getClient2();
838
+ const result = await client.api.updateTransaction(data);
575
839
  printResult(result, getFormat2());
576
840
  } catch (e) {
577
- printError(e);
578
- process.exit(1);
841
+ exitWithError(e);
579
842
  }
580
843
  });
581
844
  }
@@ -595,8 +858,12 @@ function escapeHtml(s) {
595
858
  function openBrowser(url) {
596
859
  const os = platform();
597
860
  const onError = () => {
598
- console.log(pc4.yellow(`Could not open browser automatically. Open this URL manually:
599
- ${url}`));
861
+ console.log(
862
+ pc4.yellow(
863
+ `Could not open browser automatically. Open this URL manually:
864
+ ${url}`
865
+ )
866
+ );
600
867
  };
601
868
  if (os === "win32") {
602
869
  exec(`start "" "${url}"`, (err) => {
@@ -628,7 +895,7 @@ var ERROR_HTML = (msg) => `<!DOCTYPE html>
628
895
  <style>${PAGE_STYLE}</style>
629
896
  </head><body><div class="card"><div class="icon err">!</div><h1>Authentication failed</h1><p>${escapeHtml(msg)}</p></div></body></html>`;
630
897
  function startAuthServer(options) {
631
- return new Promise((resolve, reject) => {
898
+ return new Promise((resolve2, reject) => {
632
899
  const server = createServer((req, res) => {
633
900
  if (!req.url) {
634
901
  res.writeHead(400).end();
@@ -649,19 +916,19 @@ function startAuthServer(options) {
649
916
  if (error) {
650
917
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }).end(ERROR_HTML(error));
651
918
  console.error(pc4.red(`Login failed: ${error}`));
652
- cleanup(1);
919
+ cleanup(2);
653
920
  return;
654
921
  }
655
922
  if (receivedState !== options.state) {
656
923
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }).end(ERROR_HTML("State mismatch \u2014 possible CSRF attack."));
657
924
  console.error(pc4.red("Login failed: state mismatch."));
658
- cleanup(1);
925
+ cleanup(2);
659
926
  return;
660
927
  }
661
928
  if (!clientKey || !secretKey || !tenant) {
662
929
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }).end(ERROR_HTML("Missing credentials in callback."));
663
930
  console.error(pc4.red("Login failed: missing credentials."));
664
- cleanup(1);
931
+ cleanup(2);
665
932
  return;
666
933
  }
667
934
  options.saveFn({
@@ -703,10 +970,12 @@ Logged in successfully!`));
703
970
  return;
704
971
  }
705
972
  timeout = setTimeout(() => {
706
- console.error(pc4.red("\nLogin timed out (3 minutes). Please try again."));
707
- cleanup(1);
973
+ console.error(
974
+ pc4.red("\nLogin timed out (3 minutes). Please try again.")
975
+ );
976
+ cleanup(4);
708
977
  }, TIMEOUT_MS);
709
- resolve({ port: addr.port, cleanup });
978
+ resolve2({ port: addr.port, cleanup });
710
979
  });
711
980
  server.on("error", (err) => {
712
981
  reject(err);
@@ -731,8 +1000,12 @@ function registerAuthCommands(program2) {
731
1000
  ${loginUrl}`));
732
1001
  openBrowser(loginUrl);
733
1002
  } catch (err) {
734
- console.error(pc4.red(`Server error: ${err instanceof Error ? err.message : String(err)}`));
735
- process.exit(1);
1003
+ console.error(
1004
+ pc4.red(
1005
+ `Server error: ${err instanceof Error ? err.message : String(err)}`
1006
+ )
1007
+ );
1008
+ process.exit(4);
736
1009
  }
737
1010
  });
738
1011
  program2.command("logout").description("Remove stored credentials").action(() => {
@@ -757,7 +1030,9 @@ ${loginUrl}`));
757
1030
  console.log(`Tenant: ${pc4.bold(creds.tenantName)}${scope}`);
758
1031
  console.log(`Client Key: ${pc4.dim(masked)}`);
759
1032
  console.log(`Stored at: ${pc4.dim(creds.storedAt)}`);
760
- console.log(`File: ${pc4.dim(isLocal ? getLocalCredentialsPath() : getCredentialsPath())}`);
1033
+ console.log(
1034
+ `File: ${pc4.dim(isLocal ? getLocalCredentialsPath() : getCredentialsPath())}`
1035
+ );
761
1036
  });
762
1037
  const tenant = program2.command("tenant").description("Manage tenant switching");
763
1038
  tenant.command("list").description("Show cached tenant list").action(() => {
@@ -786,13 +1061,17 @@ ${loginUrl}`));
786
1061
  const tenants = loadTenantList();
787
1062
  if (!tenants || tenants.length === 0) {
788
1063
  console.error(pc4.red('No cached tenants. Run "01 login" first.'));
789
- process.exit(1);
1064
+ process.exit(2);
790
1065
  }
791
- const match = tenants.find((t) => t.name.toLowerCase() === name.toLowerCase());
1066
+ const match = tenants.find(
1067
+ (t) => t.name.toLowerCase() === name.toLowerCase()
1068
+ );
792
1069
  if (!match) {
793
1070
  console.error(pc4.red(`Tenant "${name}" not found in cache.`));
794
- console.error(pc4.dim(`Available: ${tenants.map((t) => t.name).join(", ")}`));
795
- process.exit(1);
1071
+ console.error(
1072
+ pc4.dim(`Available: ${tenants.map((t) => t.name).join(", ")}`)
1073
+ );
1074
+ process.exit(3);
796
1075
  }
797
1076
  const state = randomBytes(32).toString("hex");
798
1077
  const isLocal = !!opts.local;
@@ -802,10 +1081,14 @@ ${loginUrl}`));
802
1081
  saveFn: (creds) => {
803
1082
  if (isLocal) {
804
1083
  saveLocalCredentials(creds);
805
- console.log(pc4.dim(`Credentials saved to ${getLocalCredentialsPath()}`));
1084
+ console.log(
1085
+ pc4.dim(`Credentials saved to ${getLocalCredentialsPath()}`)
1086
+ );
806
1087
  } else {
807
1088
  saveCredentials(creds);
808
- console.log(pc4.dim(`Credentials saved to ${getCredentialsPath()}`));
1089
+ console.log(
1090
+ pc4.dim(`Credentials saved to ${getCredentialsPath()}`)
1091
+ );
809
1092
  }
810
1093
  }
811
1094
  });
@@ -820,22 +1103,117 @@ ${loginUrl}`));
820
1103
  ${loginUrl}`));
821
1104
  openBrowser(loginUrl);
822
1105
  } catch (err) {
823
- console.error(pc4.red(`Server error: ${err instanceof Error ? err.message : String(err)}`));
824
- process.exit(1);
1106
+ console.error(
1107
+ pc4.red(
1108
+ `Server error: ${err instanceof Error ? err.message : String(err)}`
1109
+ )
1110
+ );
1111
+ process.exit(4);
1112
+ }
1113
+ });
1114
+ }
1115
+
1116
+ // src/commands/schema.ts
1117
+ import { COLLECTIONS as COLLECTIONS2 } from "@01.software/sdk";
1118
+ function getApiUrl() {
1119
+ return (process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL || "https://api.01.software").replace(/\/$/, "");
1120
+ }
1121
+ function registerSchemaCommands(program2, getClient2, getFormat2) {
1122
+ const schema = program2.command("schema").description("Collection schema introspection");
1123
+ schema.command("list").description("List available collections").action(() => {
1124
+ printResult(COLLECTIONS2, getFormat2());
1125
+ });
1126
+ schema.command("show <collection>").description("Show collection field schema").action(async (collection) => {
1127
+ try {
1128
+ if (!COLLECTIONS2.includes(collection)) {
1129
+ const normalized = collection.replace(/-/g, "").toLowerCase();
1130
+ const suggestions = COLLECTIONS2.filter((c) => {
1131
+ const cn = c.replace(/-/g, "").toLowerCase();
1132
+ return cn.startsWith(normalized) || normalized.startsWith(cn) || normalized.length >= 3 && cn.includes(normalized);
1133
+ }).slice(0, 5);
1134
+ const hint = suggestions.length > 0 ? `Did you mean: ${suggestions.join(", ")}?` : 'Run "01 schema list" for available collections.';
1135
+ throw new Error(`Unknown collection "${collection}". ${hint}`);
1136
+ }
1137
+ const client = getClient2();
1138
+ const { createServerToken } = await import("@01.software/sdk/auth");
1139
+ const token = await createServerToken(
1140
+ client.clientKey,
1141
+ client.secretKey
1142
+ );
1143
+ const baseUrl = getApiUrl();
1144
+ const url = `${baseUrl}/api/tenants/schema/${encodeURIComponent(collection)}`;
1145
+ const response = await fetch(url, {
1146
+ headers: {
1147
+ "X-Client-Key": client.clientKey,
1148
+ Authorization: `Bearer ${token}`
1149
+ }
1150
+ });
1151
+ if (!response.ok) {
1152
+ const body = await response.json().catch(() => ({ error: response.statusText }));
1153
+ const err = new Error(
1154
+ body.error || `HTTP ${response.status}`
1155
+ );
1156
+ Object.assign(err, { status: response.status });
1157
+ throw err;
1158
+ }
1159
+ const result = await response.json();
1160
+ printResult(result, getFormat2());
1161
+ } catch (e) {
1162
+ exitWithError(e);
825
1163
  }
826
1164
  });
827
1165
  }
828
1166
 
1167
+ // src/commands/mcp.ts
1168
+ import { resolve, dirname } from "path";
1169
+ import { existsSync as existsSync2 } from "fs";
1170
+ import { spawn } from "child_process";
1171
+ import { fileURLToPath } from "url";
1172
+ var __dirname = dirname(fileURLToPath(import.meta.url));
1173
+ function findStdioEntry() {
1174
+ for (const depth of ["../../../..", "../../.."]) {
1175
+ const candidate = resolve(__dirname, depth, "apps/mcp/.xmcp/stdio.js");
1176
+ if (existsSync2(candidate)) return candidate;
1177
+ }
1178
+ return null;
1179
+ }
1180
+ function registerMcpCommands(program2) {
1181
+ program2.command("mcp").description("Start MCP server over stdio").action(() => {
1182
+ const client = resolveClient(program2.opts().apiKey);
1183
+ const stdioEntry = findStdioEntry();
1184
+ if (!stdioEntry) {
1185
+ exitWithError(
1186
+ new Error(
1187
+ "MCP server not found. Ensure apps/mcp is built (pnpm --filter mcp build)."
1188
+ )
1189
+ );
1190
+ }
1191
+ const child = spawn(process.execPath, [stdioEntry], {
1192
+ env: {
1193
+ ...process.env,
1194
+ SOFTWARE_CLIENT_KEY: client.clientKey,
1195
+ SOFTWARE_SECRET_KEY: client.secretKey
1196
+ },
1197
+ stdio: ["inherit", "inherit", "inherit"]
1198
+ });
1199
+ child.on("error", (err) => {
1200
+ exitWithError(new Error(`Failed to start MCP server: ${err.message}`));
1201
+ });
1202
+ child.on("exit", (code) => {
1203
+ process.exit(code ?? 0);
1204
+ });
1205
+ });
1206
+ }
1207
+
829
1208
  // src/index.ts
830
1209
  var require2 = createRequire(import.meta.url);
831
1210
  var { version } = require2("../package.json");
832
1211
  process.on("unhandledRejection", (err) => {
833
- printError(err);
834
- process.exit(1);
1212
+ exitWithError(err);
835
1213
  });
836
1214
  var program = new Command();
837
- program.name("01").description("CLI for the 01.software platform").version(version).option("--api-key <base64>", "Base64-encoded API key (clientKey:secretKey)").option("--format <format>", "Output format: json (default) or table", "json");
838
- var getFormat = () => program.opts().format;
1215
+ program.name("01").description("CLI for the 01.software platform").version(version).option("--api-key <base64>", "Base64-encoded API key (clientKey:secretKey)").option("--format <format>", "Output format: json, table, or ndjson");
1216
+ var getFormat = () => program.opts().format ?? process.env.OUTPUT_FORMAT ?? "json";
839
1217
  var getClient = () => resolveClient(program.opts().apiKey);
840
1218
  registerCrudCommands(program, getClient, getFormat);
841
1219
  registerOrderCommands(program, getClient, getFormat);
@@ -843,6 +1221,8 @@ registerReturnCommands(program, getClient, getFormat);
843
1221
  registerCartCommands(program, getClient, getFormat);
844
1222
  registerStockCommands(program, getClient, getFormat);
845
1223
  registerTransactionCommands(program, getClient, getFormat);
1224
+ registerSchemaCommands(program, getClient, getFormat);
1225
+ registerMcpCommands(program);
846
1226
  registerAuthCommands(program);
847
1227
  program.parse();
848
1228
  //# sourceMappingURL=index.js.map