@01.software/cli 0.1.1 → 0.2.0-dev.260306.4e16dd4

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
@@ -9,25 +9,17 @@ import { CollectionClient, OrderApi, CartApi, ProductApi, parseApiKey } from "@0
9
9
  import pc from "picocolors";
10
10
 
11
11
  // src/lib/credentials.ts
12
- import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
12
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, appendFileSync } from "fs";
13
13
  import { join } from "path";
14
14
  import { homedir } from "os";
15
15
  var DIR_NAME = ".01software";
16
16
  var FILE_NAME = "credentials.json";
17
+ var TENANTS_FILE = "tenants.json";
17
18
  function getCredentialsPath() {
18
19
  return join(homedir(), DIR_NAME, FILE_NAME);
19
20
  }
20
21
  function loadCredentials() {
21
- const filePath = getCredentialsPath();
22
- if (!existsSync(filePath)) return null;
23
- try {
24
- const raw = readFileSync(filePath, "utf-8");
25
- const data = JSON.parse(raw);
26
- if (!data.clientKey || !data.secretKey) return null;
27
- return data;
28
- } catch {
29
- return null;
30
- }
22
+ return loadCredentialsFrom(getCredentialsPath());
31
23
  }
32
24
  function saveCredentials(creds) {
33
25
  const dir = join(homedir(), DIR_NAME);
@@ -44,6 +36,70 @@ function deleteCredentials() {
44
36
  unlinkSync(filePath);
45
37
  return true;
46
38
  }
39
+ function getLocalCredentialsPath() {
40
+ return join(process.cwd(), DIR_NAME, FILE_NAME);
41
+ }
42
+ function loadLocalCredentials() {
43
+ return loadCredentialsFrom(getLocalCredentialsPath());
44
+ }
45
+ function saveLocalCredentials(creds) {
46
+ const dir = join(process.cwd(), DIR_NAME);
47
+ if (!existsSync(dir)) {
48
+ mkdirSync(dir, { recursive: true, mode: 448 });
49
+ }
50
+ 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 });
53
+ ensureGitignore();
54
+ }
55
+ function saveTenantList(tenants) {
56
+ const dir = join(homedir(), DIR_NAME);
57
+ if (!existsSync(dir)) {
58
+ mkdirSync(dir, { recursive: true, mode: 448 });
59
+ }
60
+ const filePath = join(homedir(), DIR_NAME, TENANTS_FILE);
61
+ writeFileSync(filePath, JSON.stringify(tenants, null, 2), { encoding: "utf-8", mode: 384 });
62
+ }
63
+ function loadTenantList() {
64
+ const filePath = join(homedir(), DIR_NAME, TENANTS_FILE);
65
+ if (!existsSync(filePath)) return null;
66
+ try {
67
+ const raw = readFileSync(filePath, "utf-8");
68
+ const data = JSON.parse(raw);
69
+ if (!Array.isArray(data)) return null;
70
+ const valid = data.filter(
71
+ (t) => typeof t?.id === "string" && typeof t?.name === "string"
72
+ );
73
+ return valid.length > 0 ? valid : null;
74
+ } catch {
75
+ return null;
76
+ }
77
+ }
78
+ function loadCredentialsFrom(filePath) {
79
+ if (!existsSync(filePath)) return null;
80
+ try {
81
+ const raw = readFileSync(filePath, "utf-8");
82
+ const data = JSON.parse(raw);
83
+ if (!data.clientKey || !data.secretKey) return null;
84
+ return data;
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+ function ensureGitignore() {
90
+ const gitignorePath = join(process.cwd(), ".gitignore");
91
+ const entry = ".01software/";
92
+ if (existsSync(gitignorePath)) {
93
+ const content = readFileSync(gitignorePath, "utf-8");
94
+ if (content.includes(entry)) return;
95
+ appendFileSync(gitignorePath, `
96
+ ${entry}
97
+ `, "utf-8");
98
+ } else {
99
+ writeFileSync(gitignorePath, `${entry}
100
+ `, "utf-8");
101
+ }
102
+ }
47
103
 
48
104
  // src/lib/client.ts
49
105
  function resolveClient(apiKeyFlag) {
@@ -62,6 +118,13 @@ function resolveClient(apiKeyFlag) {
62
118
  clientKey = process.env.SOFTWARE_CLIENT_KEY;
63
119
  secretKey = process.env.SOFTWARE_SECRET_KEY;
64
120
  }
121
+ if (!clientKey || !secretKey) {
122
+ const local = loadLocalCredentials();
123
+ if (local) {
124
+ clientKey = local.clientKey;
125
+ secretKey = local.secretKey;
126
+ }
127
+ }
65
128
  if (!clientKey || !secretKey) {
66
129
  const stored = loadCredentials();
67
130
  if (stored) {
@@ -147,6 +210,8 @@ function printError(error) {
147
210
  }
148
211
 
149
212
  // src/commands/crud.ts
213
+ import { readFileSync as readFileSync2 } from "fs";
214
+ import { basename } from "path";
150
215
  import { COLLECTIONS } from "@01.software/sdk";
151
216
 
152
217
  // src/lib/parse.ts
@@ -179,15 +244,27 @@ function parseJsonArray(value, label) {
179
244
  }
180
245
 
181
246
  // src/commands/crud.ts
182
- var collectionList = COLLECTIONS.join(", ");
247
+ function readFileAsBlob(filePath) {
248
+ const buffer = readFileSync2(filePath);
249
+ return { blob: new Blob([buffer]), filename: basename(filePath) };
250
+ }
183
251
  function validateCollection(name) {
184
252
  if (!COLLECTIONS.includes(name)) {
185
- throw new Error(`Unknown collection "${name}". Available: ${collectionList}`);
253
+ const normalized = name.replace(/-/g, "").toLowerCase();
254
+ const suggestions = COLLECTIONS.filter((c) => {
255
+ const cn = c.replace(/-/g, "").toLowerCase();
256
+ return cn.startsWith(normalized) || normalized.startsWith(cn) || normalized.length >= 3 && cn.includes(normalized);
257
+ }).slice(0, 5);
258
+ const hint = suggestions.length > 0 ? `Did you mean: ${suggestions.join(", ")}?` : 'Run "01 --help" for available collections.';
259
+ throw new Error(`Unknown collection "${name}". ${hint}`);
186
260
  }
187
261
  return name;
188
262
  }
263
+ function parseSelect(input) {
264
+ return Object.fromEntries(input.split(",").map((f) => [f.trim(), true]));
265
+ }
189
266
  function registerCrudCommands(program2, getClient2, getFormat2) {
190
- 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)").action(async (collection, opts) => {
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) => {
191
268
  try {
192
269
  const col = validateCollection(collection);
193
270
  const client = getClient2();
@@ -196,6 +273,8 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
196
273
  if (opts.limit) options.limit = opts.limit;
197
274
  if (opts.page) options.page = opts.page;
198
275
  if (opts.sort) options.sort = opts.sort;
276
+ if (opts.depth != null) options.depth = opts.depth;
277
+ if (opts.select) options.select = parseSelect(opts.select);
199
278
  const result = await client.collections.from(col).find(options);
200
279
  printResult(result, getFormat2());
201
280
  } catch (e) {
@@ -203,35 +282,48 @@ function registerCrudCommands(program2, getClient2, getFormat2) {
203
282
  process.exit(1);
204
283
  }
205
284
  });
206
- program2.command("get <collection> <id>").description("Get a document by ID").action(async (collection, id) => {
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) => {
207
286
  try {
208
287
  const col = validateCollection(collection);
209
288
  const client = getClient2();
210
- const result = await client.collections.from(col).findById(id);
289
+ const options = {};
290
+ if (opts.depth != null) options.depth = opts.depth;
291
+ if (opts.select) options.select = parseSelect(opts.select);
292
+ const result = await client.collections.from(col).findById(id, options);
211
293
  printResult(result, getFormat2());
212
294
  } catch (e) {
213
295
  printError(e);
214
296
  process.exit(1);
215
297
  }
216
298
  });
217
- program2.command("create <collection>").description("Create a new document").requiredOption("--data <json>", "Document data (JSON)").action(async (collection, opts) => {
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) => {
218
300
  try {
219
301
  const col = validateCollection(collection);
220
302
  const client = getClient2();
221
303
  const data = parseJson(opts.data, "data");
222
- const result = await client.collections.from(col).create(data);
304
+ let fileOpts;
305
+ if (opts.file) {
306
+ const { blob, filename } = readFileAsBlob(opts.file);
307
+ fileOpts = { file: blob, filename };
308
+ }
309
+ const result = await client.collections.from(col).create(data, fileOpts);
223
310
  printResult(result, getFormat2());
224
311
  } catch (e) {
225
312
  printError(e);
226
313
  process.exit(1);
227
314
  }
228
315
  });
229
- program2.command("update <collection> <id>").description("Update a document by ID").requiredOption("--data <json>", "Document data (JSON)").action(async (collection, id, opts) => {
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) => {
230
317
  try {
231
318
  const col = validateCollection(collection);
232
319
  const client = getClient2();
233
320
  const data = parseJson(opts.data, "data");
234
- const result = await client.collections.from(col).update(id, data);
321
+ let fileOpts;
322
+ if (opts.file) {
323
+ const { blob, filename } = readFileAsBlob(opts.file);
324
+ fileOpts = { file: blob, filename };
325
+ }
326
+ const result = await client.collections.from(col).update(id, data, fileOpts);
235
327
  printResult(result, getFormat2());
236
328
  } catch (e) {
237
329
  printError(e);
@@ -530,9 +622,8 @@ var ERROR_HTML = (msg) => `<!DOCTYPE html>
530
622
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>CLI Login Error</title>
531
623
  <style>${PAGE_STYLE}</style>
532
624
  </head><body><div class="card"><div class="icon err">!</div><h1>Authentication failed</h1><p>${escapeHtml(msg)}</p></div></body></html>`;
533
- function registerAuthCommands(program2) {
534
- program2.command("login").description("Login via browser and store credentials").action(async () => {
535
- const state = randomBytes(32).toString("hex");
625
+ function startAuthServer(options) {
626
+ return new Promise((resolve, reject) => {
536
627
  const server = createServer((req, res) => {
537
628
  if (!req.url) {
538
629
  res.writeHead(400).end();
@@ -547,6 +638,8 @@ function registerAuthCommands(program2) {
547
638
  const clientKey = url.searchParams.get("clientKey");
548
639
  const secretKey = url.searchParams.get("secretKey");
549
640
  const tenant = url.searchParams.get("tenant");
641
+ const tenantIdParam = url.searchParams.get("tenantId");
642
+ const tenantsParam = url.searchParams.get("tenants");
550
643
  const error = url.searchParams.get("error");
551
644
  if (error) {
552
645
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }).end(ERROR_HTML(error));
@@ -554,7 +647,7 @@ function registerAuthCommands(program2) {
554
647
  cleanup(1);
555
648
  return;
556
649
  }
557
- if (receivedState !== state) {
650
+ if (receivedState !== options.state) {
558
651
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }).end(ERROR_HTML("State mismatch \u2014 possible CSRF attack."));
559
652
  console.error(pc4.red("Login failed: state mismatch."));
560
653
  cleanup(1);
@@ -566,12 +659,28 @@ function registerAuthCommands(program2) {
566
659
  cleanup(1);
567
660
  return;
568
661
  }
569
- saveCredentials({ clientKey, secretKey, tenantName: tenant });
662
+ options.saveFn({
663
+ clientKey,
664
+ secretKey,
665
+ ...tenantIdParam ? { tenantId: tenantIdParam } : {},
666
+ tenantName: tenant
667
+ });
668
+ if (tenantsParam) {
669
+ try {
670
+ const parsed = JSON.parse(tenantsParam);
671
+ if (Array.isArray(parsed)) {
672
+ const valid = parsed.filter(
673
+ (t) => typeof t?.id === "string" && typeof t?.name === "string"
674
+ );
675
+ if (valid.length > 0) saveTenantList(valid);
676
+ }
677
+ } catch {
678
+ }
679
+ }
570
680
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }).end(SUCCESS_HTML);
571
681
  console.log(pc4.green(`
572
682
  Logged in successfully!`));
573
683
  console.log(pc4.dim(`Tenant: ${tenant}`));
574
- console.log(pc4.dim(`Credentials saved to ${getCredentialsPath()}`));
575
684
  cleanup(0);
576
685
  });
577
686
  let timeout;
@@ -585,26 +694,42 @@ Logged in successfully!`));
585
694
  server.listen(0, "127.0.0.1", () => {
586
695
  const addr = server.address();
587
696
  if (!addr || typeof addr === "string") {
588
- console.error(pc4.red("Failed to start local server."));
589
- process.exit(1);
697
+ reject(new Error("Failed to start local server."));
698
+ return;
590
699
  }
591
- const port = addr.port;
592
- const params = new URLSearchParams({ port: String(port), state });
593
- const loginUrl = `${WEB_URL}/cli-auth?${params.toString()}`;
594
- console.log(pc4.dim("Opening browser for login..."));
595
- console.log(pc4.dim(`If the browser does not open, visit:
596
- ${loginUrl}`));
597
- openBrowser(loginUrl);
598
700
  timeout = setTimeout(() => {
599
701
  console.error(pc4.red("\nLogin timed out (3 minutes). Please try again."));
600
702
  cleanup(1);
601
703
  }, TIMEOUT_MS);
704
+ resolve({ port: addr.port, cleanup });
602
705
  });
603
706
  server.on("error", (err) => {
604
- console.error(pc4.red(`Server error: ${err.message}`));
605
- process.exit(1);
707
+ reject(err);
606
708
  });
607
709
  });
710
+ }
711
+ function registerAuthCommands(program2) {
712
+ program2.command("login").description("Login via browser and store credentials").action(async () => {
713
+ const state = randomBytes(32).toString("hex");
714
+ try {
715
+ const { port } = await startAuthServer({
716
+ state,
717
+ saveFn: (creds) => {
718
+ saveCredentials(creds);
719
+ console.log(pc4.dim(`Credentials saved to ${getCredentialsPath()}`));
720
+ }
721
+ });
722
+ const params = new URLSearchParams({ port: String(port), state });
723
+ const loginUrl = `${WEB_URL}/cli-auth?${params.toString()}`;
724
+ console.log(pc4.dim("Opening browser for login..."));
725
+ console.log(pc4.dim(`If the browser does not open, visit:
726
+ ${loginUrl}`));
727
+ openBrowser(loginUrl);
728
+ } catch (err) {
729
+ console.error(pc4.red(`Server error: ${err instanceof Error ? err.message : String(err)}`));
730
+ process.exit(1);
731
+ }
732
+ });
608
733
  program2.command("logout").description("Remove stored credentials").action(() => {
609
734
  const deleted = deleteCredentials();
610
735
  if (deleted) {
@@ -614,16 +739,85 @@ ${loginUrl}`));
614
739
  }
615
740
  });
616
741
  program2.command("whoami").description("Show current authentication status").action(() => {
617
- const creds = loadCredentials();
742
+ const localCreds = loadLocalCredentials();
743
+ const globalCreds = loadCredentials();
744
+ const creds = localCreds || globalCreds;
745
+ const isLocal = !!localCreds;
618
746
  if (!creds) {
619
747
  console.log(pc4.dim('Not logged in. Run "01 login" to authenticate.'));
620
748
  return;
621
749
  }
622
750
  const masked = creds.clientKey.length > 8 ? creds.clientKey.slice(0, 4) + "..." + creds.clientKey.slice(-4) : "****";
623
- console.log(`Tenant: ${pc4.bold(creds.tenantName)}`);
751
+ const scope = isLocal ? pc4.cyan(" (local)") : "";
752
+ console.log(`Tenant: ${pc4.bold(creds.tenantName)}${scope}`);
624
753
  console.log(`Client Key: ${pc4.dim(masked)}`);
625
754
  console.log(`Stored at: ${pc4.dim(creds.storedAt)}`);
626
- console.log(`File: ${pc4.dim(getCredentialsPath())}`);
755
+ console.log(`File: ${pc4.dim(isLocal ? getLocalCredentialsPath() : getCredentialsPath())}`);
756
+ });
757
+ const tenant = program2.command("tenant").description("Manage tenant switching");
758
+ tenant.command("list").description("Show cached tenant list").action(() => {
759
+ const tenants = loadTenantList();
760
+ if (!tenants || tenants.length === 0) {
761
+ console.log(pc4.dim('No cached tenants. Run "01 login" first.'));
762
+ return;
763
+ }
764
+ const localCreds = loadLocalCredentials();
765
+ const globalCreds = loadCredentials();
766
+ const activeCreds = localCreds || globalCreds;
767
+ const activeId = activeCreds?.tenantId;
768
+ const activeName = activeCreds?.tenantName;
769
+ console.log(pc4.bold("Cached tenants:\n"));
770
+ for (const t of tenants) {
771
+ const active = (activeId ? t.id === activeId : t.name === activeName) ? pc4.green(" *") : "";
772
+ console.log(` ${t.name}${active}`);
773
+ }
774
+ console.log();
775
+ if (activeName) {
776
+ const scope = localCreds ? "(local)" : "(global)";
777
+ console.log(pc4.dim(`* active ${scope}`));
778
+ }
779
+ });
780
+ tenant.command("use <name>").description("Switch to a different tenant via browser").option("--local", "Save credentials locally in the current project").action(async (name, opts) => {
781
+ const tenants = loadTenantList();
782
+ if (!tenants || tenants.length === 0) {
783
+ console.error(pc4.red('No cached tenants. Run "01 login" first.'));
784
+ process.exit(1);
785
+ }
786
+ const match = tenants.find((t) => t.name.toLowerCase() === name.toLowerCase());
787
+ if (!match) {
788
+ console.error(pc4.red(`Tenant "${name}" not found in cache.`));
789
+ console.error(pc4.dim(`Available: ${tenants.map((t) => t.name).join(", ")}`));
790
+ process.exit(1);
791
+ }
792
+ const state = randomBytes(32).toString("hex");
793
+ const isLocal = !!opts.local;
794
+ try {
795
+ const { port } = await startAuthServer({
796
+ state,
797
+ saveFn: (creds) => {
798
+ if (isLocal) {
799
+ saveLocalCredentials(creds);
800
+ console.log(pc4.dim(`Credentials saved to ${getLocalCredentialsPath()}`));
801
+ } else {
802
+ saveCredentials(creds);
803
+ console.log(pc4.dim(`Credentials saved to ${getCredentialsPath()}`));
804
+ }
805
+ }
806
+ });
807
+ const params = new URLSearchParams({
808
+ port: String(port),
809
+ state,
810
+ tenantId: match.id
811
+ });
812
+ const loginUrl = `${WEB_URL}/cli-auth?${params.toString()}`;
813
+ console.log(pc4.dim(`Switching to tenant "${match.name}"...`));
814
+ console.log(pc4.dim(`If the browser does not open, visit:
815
+ ${loginUrl}`));
816
+ openBrowser(loginUrl);
817
+ } catch (err) {
818
+ console.error(pc4.red(`Server error: ${err instanceof Error ? err.message : String(err)}`));
819
+ process.exit(1);
820
+ }
627
821
  });
628
822
  }
629
823
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/client.ts","../src/lib/credentials.ts","../src/lib/output.ts","../src/commands/crud.ts","../src/lib/parse.ts","../src/commands/order.ts","../src/commands/return.ts","../src/commands/cart.ts","../src/commands/stock.ts","../src/commands/transaction.ts","../src/commands/auth.ts"],"sourcesContent":["import { createRequire } from 'node:module'\nimport { Command } from 'commander'\nimport { resolveClient } from './lib/client.js'\nimport { printError } from './lib/output.js'\nimport { registerCrudCommands } from './commands/crud.js'\nimport { registerOrderCommands } from './commands/order.js'\nimport { registerReturnCommands } from './commands/return.js'\nimport { registerCartCommands } from './commands/cart.js'\nimport { registerStockCommands } from './commands/stock.js'\nimport { registerTransactionCommands } from './commands/transaction.js'\nimport { registerAuthCommands } from './commands/auth.js'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nprocess.on('unhandledRejection', (err) => {\n printError(err)\n process.exit(1)\n})\n\nconst program = new Command()\n\nprogram\n .name('01')\n .description('CLI for the 01.software platform')\n .version(version)\n .option('--api-key <base64>', 'Base64-encoded API key (clientKey:secretKey)')\n .option('--format <format>', 'Output format: json (default) or table', 'json')\n\nconst getFormat = () => program.opts().format as string\nconst getClient = () => resolveClient(program.opts().apiKey as string | undefined)\n\nregisterCrudCommands(program, getClient, getFormat)\nregisterOrderCommands(program, getClient, getFormat)\nregisterReturnCommands(program, getClient, getFormat)\nregisterCartCommands(program, getClient, getFormat)\nregisterStockCommands(program, getClient, getFormat)\nregisterTransactionCommands(program, getClient, getFormat)\nregisterAuthCommands(program)\n\nprogram.parse()\n","import { CollectionClient, OrderApi, CartApi, ProductApi, parseApiKey } from '@01.software/sdk'\nimport pc from 'picocolors'\nimport { loadCredentials } from './credentials.js'\n\nexport interface ResolvedClient {\n collections: CollectionClient\n api: OrderApi\n cart: CartApi\n product: ProductApi\n}\n\nexport function resolveClient(apiKeyFlag?: string): ResolvedClient {\n let clientKey: string | undefined\n let secretKey: string | undefined\n\n if (apiKeyFlag) {\n try {\n const parsed = parseApiKey(apiKeyFlag)\n clientKey = parsed.clientKey\n secretKey = parsed.secretKey\n } catch {\n console.error(pc.red('Invalid --api-key value. Expected Base64-encoded \"clientKey:secretKey\".'))\n process.exit(1)\n }\n } else {\n clientKey = process.env.SOFTWARE_CLIENT_KEY\n secretKey = process.env.SOFTWARE_SECRET_KEY\n }\n\n // Fallback to stored credentials from \"01 login\"\n if (!clientKey || !secretKey) {\n const stored = loadCredentials()\n if (stored) {\n clientKey = stored.clientKey\n secretKey = stored.secretKey\n }\n }\n\n if (!clientKey || !secretKey) {\n console.error(pc.red('Authentication required.'))\n console.error(\n pc.dim(\n 'Run \"01 login\" to authenticate via browser,\\n' +\n 'or set SOFTWARE_CLIENT_KEY and SOFTWARE_SECRET_KEY environment variables,\\n' +\n 'or use the --api-key <base64> flag.',\n ),\n )\n process.exit(1)\n }\n\n const apiOpts = { clientKey, secretKey }\n\n return {\n collections: new CollectionClient(clientKey, secretKey),\n api: new OrderApi(apiOpts),\n cart: new CartApi(apiOpts),\n product: new ProductApi(apiOpts),\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nexport interface StoredCredentials {\n clientKey: string\n secretKey: string\n tenantName: string\n storedAt: string\n}\n\nconst DIR_NAME = '.01software'\nconst FILE_NAME = 'credentials.json'\n\nexport function getCredentialsPath(): string {\n return join(homedir(), DIR_NAME, FILE_NAME)\n}\n\nexport function loadCredentials(): StoredCredentials | null {\n const filePath = getCredentialsPath()\n if (!existsSync(filePath)) return null\n\n try {\n const raw = readFileSync(filePath, 'utf-8')\n const data = JSON.parse(raw) as StoredCredentials\n if (!data.clientKey || !data.secretKey) return null\n return data\n } catch {\n return null\n }\n}\n\nexport function saveCredentials(creds: Omit<StoredCredentials, 'storedAt'>): void {\n const dir = join(homedir(), DIR_NAME)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 })\n }\n\n const filePath = getCredentialsPath()\n const data: StoredCredentials = { ...creds, storedAt: new Date().toISOString() }\n writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 })\n}\n\nexport function deleteCredentials(): boolean {\n const filePath = getCredentialsPath()\n if (!existsSync(filePath)) return false\n\n unlinkSync(filePath)\n return true\n}\n","import pc from 'picocolors'\n\nexport function printJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2))\n}\n\nexport function printTable(data: unknown): void {\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log(pc.dim('(empty)'))\n return\n }\n const keys = Object.keys(data[0] as Record<string, unknown>)\n const widths = keys.map((k) =>\n Math.max(k.length, ...data.map((row) => String((row as Record<string, unknown>)[k] ?? '').length)),\n )\n\n // Header\n console.log(keys.map((k, i) => k.padEnd(widths[i]!)).join(' '))\n console.log(keys.map((_, i) => '-'.repeat(widths[i]!)).join(' '))\n\n // Rows\n for (const row of data) {\n console.log(\n keys.map((k, i) => String((row as Record<string, unknown>)[k] ?? '').padEnd(widths[i]!)).join(' '),\n )\n }\n } else if (data && typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>)\n const maxKey = Math.max(...entries.map(([k]) => k.length))\n for (const [key, value] of entries) {\n const display = typeof value === 'object' ? JSON.stringify(value) : String(value)\n console.log(`${pc.bold(key.padEnd(maxKey))} ${display}`)\n }\n } else {\n console.log(String(data))\n }\n}\n\nexport function printResult(data: unknown, format: string): void {\n if (format === 'table') {\n // For find responses with docs array, print the docs as table\n if (data && typeof data === 'object' && 'docs' in (data as Record<string, unknown>)) {\n const resp = data as { docs: unknown[]; totalDocs: number; page: number; totalPages: number }\n printTable(resp.docs)\n console.log(pc.dim(`\\n${resp.totalDocs} total | page ${resp.page}/${resp.totalPages}`))\n return\n }\n printTable(data)\n } else {\n printJson(data)\n }\n}\n\nexport function printError(error: unknown): void {\n if (error && typeof error === 'object' && 'message' in error) {\n const err = error as { message: string; code?: string; status?: number; suggestion?: string }\n console.error(pc.red(`Error: ${err.message}`))\n if (err.code) console.error(pc.dim(`Code: ${err.code}`))\n if (err.status) console.error(pc.dim(`Status: ${err.status}`))\n if (err.suggestion) console.error(pc.yellow(err.suggestion))\n } else {\n console.error(pc.red(String(error)))\n }\n}\n","import { Command } from 'commander'\nimport { COLLECTIONS } from '@01.software/sdk'\nimport type { ApiQueryOptions } from '@01.software/sdk'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJson } from '../lib/parse.js'\n\nconst collectionList = COLLECTIONS.join(', ')\n\nfunction validateCollection(name: string): string {\n if (!(COLLECTIONS as readonly string[]).includes(name)) {\n throw new Error(`Unknown collection \"${name}\". Available: ${collectionList}`)\n }\n return name\n}\n\nexport function registerCrudCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n program\n .command('query <collection>')\n .description('Query documents from a collection')\n .option('--where <json>', 'Filter conditions (JSON)')\n .option('--limit <n>', 'Max results', (v: string) => parseInt(v, 10))\n .option('--page <n>', 'Page number', (v: string) => parseInt(v, 10))\n .option('--sort <field>', 'Sort field (prefix with - for descending)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const options: Record<string, unknown> = {}\n if (opts.where) options.where = parseJson(opts.where, 'where')\n if (opts.limit) options.limit = opts.limit\n if (opts.page) options.page = opts.page\n if (opts.sort) options.sort = opts.sort\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).find(options)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('get <collection> <id>')\n .description('Get a document by ID')\n .action(async (collection: string, id: string) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).findById(id)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('create <collection>')\n .description('Create a new document')\n .requiredOption('--data <json>', 'Document data (JSON)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const data = parseJson(opts.data, 'data')\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).create(data)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('update <collection> <id>')\n .description('Update a document by ID')\n .requiredOption('--data <json>', 'Document data (JSON)')\n .action(async (collection: string, id: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const data = parseJson(opts.data, 'data')\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).update(id, data)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('delete <collection> <id>')\n .description('Delete a document by ID')\n .action(async (collection: string, id: string) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).remove(id)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('update-many <collection>')\n .description('Update multiple documents matching a filter')\n .requiredOption('--where <json>', 'Filter conditions (JSON)')\n .requiredOption('--data <json>', 'Update data (JSON)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const where = parseJson(opts.where, 'where') as ApiQueryOptions['where']\n const data = parseJson(opts.data, 'data')\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).updateMany(where, data)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('delete-many <collection>')\n .description('Delete multiple documents matching a filter')\n .requiredOption('--where <json>', 'Filter conditions (JSON)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const where = parseJson(opts.where, 'where') as ApiQueryOptions['where']\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).removeMany(where)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import pc from 'picocolors'\n\nexport function parseJson(value: string, label: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(value)\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n console.error(pc.red(`--${label} must be a JSON object.`))\n process.exit(1)\n }\n return parsed as Record<string, unknown>\n } catch {\n console.error(pc.red(`Invalid JSON for --${label}: ${value}`))\n process.exit(1)\n }\n}\n\nexport function parseJsonArray(value: string, label: string): unknown[] {\n try {\n const parsed = JSON.parse(value)\n if (!Array.isArray(parsed)) {\n console.error(pc.red(`--${label} must be a JSON array.`))\n process.exit(1)\n }\n return parsed\n } catch {\n console.error(pc.red(`Invalid JSON for --${label}: ${value}`))\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJson, parseJsonArray } from '../lib/parse.js'\n\nexport function registerOrderCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const order = program.command('order').description('Order management')\n\n order\n .command('create')\n .description('Create a new order')\n .requiredOption('--payment-id <id>', 'Payment ID')\n .requiredOption('--order-number <num>', 'Order number')\n .requiredOption('--email <email>', 'Customer email')\n .requiredOption('--shipping-address <json>', 'Shipping address (JSON)')\n .requiredOption('--products <json>', 'Order products array (JSON)')\n .requiredOption('--total-amount <n>', 'Total amount', parseFloat)\n .action(async (opts) => {\n try {\n const client = getClient()\n const result = await client.api.createOrder({\n paymentId: opts.paymentId,\n orderNumber: opts.orderNumber,\n email: opts.email,\n shippingAddress: parseJson(opts.shippingAddress, 'shipping-address'),\n orderProducts: parseJsonArray(opts.products, 'products') as Parameters<typeof client.api.createOrder>[0]['orderProducts'],\n totalAmount: opts.totalAmount,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('get <orderNumber>')\n .description('Get an order by order number')\n .action(async (orderNumber: string) => {\n try {\n const client = getClient()\n const result = await client.api.getOrder({ orderNumber })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('update <orderNumber>')\n .description('Update order status')\n .requiredOption('--status <status>', 'New status')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.updateOrder({\n orderNumber,\n status: opts.status,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('checkout')\n .description('Convert a cart to an order')\n .requiredOption('--cart-id <id>', 'Cart ID')\n .requiredOption('--payment-id <id>', 'Payment ID')\n .requiredOption('--order-number <num>', 'Order number')\n .requiredOption('--customer <json>', 'Customer snapshot (JSON)')\n .action(async (opts) => {\n try {\n const client = getClient()\n const result = await client.api.checkout({\n cartId: opts.cartId,\n paymentId: opts.paymentId,\n orderNumber: opts.orderNumber,\n customerSnapshot: parseJson(opts.customer, 'customer') as Parameters<typeof client.api.checkout>[0]['customerSnapshot'],\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('fulfill <orderNumber>')\n .description('Create a fulfillment for an order')\n .requiredOption('--items <json>', 'Fulfillment items array (JSON)')\n .option('--carrier <name>', 'Shipping carrier')\n .option('--tracking-number <num>', 'Tracking number')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.createFulfillment({\n orderNumber,\n items: parseJsonArray(opts.items, 'items') as Parameters<typeof client.api.createFulfillment>[0]['items'],\n carrier: opts.carrier,\n trackingNumber: opts.trackingNumber,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJsonArray } from '../lib/parse.js'\n\nexport function registerReturnCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const ret = program.command('return').description('Return management')\n\n ret\n .command('create <orderNumber>')\n .description('Create a return request')\n .requiredOption('--products <json>', 'Return products array (JSON)')\n .requiredOption('--refund-amount <n>', 'Refund amount', parseFloat)\n .option('--reason <reason>', 'Return reason (change_of_mind, defective, wrong_delivery, damaged, other)')\n .option('--reason-detail <text>', 'Detailed reason')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.createReturn({\n orderNumber,\n returnProducts: parseJsonArray(opts.products, 'products') as Parameters<typeof client.api.createReturn>[0]['returnProducts'],\n refundAmount: opts.refundAmount,\n reason: opts.reason,\n reasonDetail: opts.reasonDetail,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n ret\n .command('update <returnId>')\n .description('Update return status')\n .requiredOption('--status <status>', 'New status (processing, approved, rejected, completed)')\n .action(async (returnId: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.updateReturn({\n returnId,\n status: opts.status,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n ret\n .command('refund <orderNumber>')\n .description('Return with refund')\n .requiredOption('--products <json>', 'Return products array (JSON)')\n .requiredOption('--refund-amount <n>', 'Refund amount', parseFloat)\n .requiredOption('--payment-id <id>', 'Payment ID')\n .option('--reason <reason>', 'Return reason')\n .option('--reason-detail <text>', 'Detailed reason')\n .option('--refund-receipt-url <url>', 'Refund receipt URL')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.returnWithRefund({\n orderNumber,\n returnProducts: parseJsonArray(opts.products, 'products') as Parameters<typeof client.api.returnWithRefund>[0]['returnProducts'],\n refundAmount: opts.refundAmount,\n paymentId: opts.paymentId,\n reason: opts.reason,\n reasonDetail: opts.reasonDetail,\n refundReceiptUrl: opts.refundReceiptUrl,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\n\nexport function registerCartCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const cart = program.command('cart').description('Cart management')\n\n cart\n .command('add <cartId>')\n .description('Add an item to cart')\n .requiredOption('--product <id>', 'Product ID')\n .requiredOption('--variant <id>', 'Variant ID')\n .requiredOption('--option <id>', 'Option ID')\n .requiredOption('--quantity <n>', 'Quantity', (v: string) => parseInt(v, 10))\n .action(async (cartId: string, opts) => {\n try {\n const client = getClient()\n const result = await client.cart.addItem({\n cartId,\n product: opts.product,\n variant: opts.variant,\n option: opts.option,\n quantity: opts.quantity,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n cart\n .command('update <cartItemId>')\n .description('Update cart item quantity')\n .requiredOption('--quantity <n>', 'New quantity', (v: string) => parseInt(v, 10))\n .action(async (cartItemId: string, opts) => {\n try {\n const client = getClient()\n const result = await client.cart.updateItem({\n cartItemId,\n quantity: opts.quantity,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n cart\n .command('remove <cartItemId>')\n .description('Remove an item from cart')\n .action(async (cartItemId: string) => {\n try {\n const client = getClient()\n const result = await client.cart.removeItem({ cartItemId })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJsonArray } from '../lib/parse.js'\n\nexport function registerStockCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const stock = program.command('stock').description('Stock management')\n\n stock\n .command('check')\n .description('Check stock availability')\n .requiredOption('--items <json>', 'Items to check (JSON array of { optionId, quantity })')\n .action(async (opts) => {\n try {\n const client = getClient()\n const items = parseJsonArray(opts.items, 'items') as Parameters<typeof client.product.stockCheck>[0]['items']\n const result = await client.product.stockCheck({ items })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\n\nexport function registerTransactionCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const tx = program.command('transaction').description('Transaction management')\n\n tx\n .command('update')\n .description('Update transaction status')\n .requiredOption('--payment-id <id>', 'Payment ID')\n .requiredOption('--status <status>', 'New status (pending, paid, failed, canceled)')\n .requiredOption('--payment-method <method>', 'Payment method')\n .requiredOption('--receipt-url <url>', 'Receipt URL')\n .action(async (opts) => {\n try {\n const client = getClient()\n const result = await client.api.updateTransaction({\n paymentId: opts.paymentId,\n status: opts.status,\n paymentMethod: opts.paymentMethod,\n receiptUrl: opts.receiptUrl,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { randomBytes } from 'node:crypto'\nimport { createServer } from 'node:http'\nimport { execFile, exec } from 'node:child_process'\nimport { platform } from 'node:os'\nimport { URL } from 'node:url'\nimport type { Command } from 'commander'\nimport pc from 'picocolors'\nimport { loadCredentials, saveCredentials, deleteCredentials, getCredentialsPath } from '../lib/credentials.js'\n\nconst WEB_URL = process.env.SOFTWARE_WEB_URL || 'https://01.software'\nconst TIMEOUT_MS = 3 * 60 * 1000 // 3 minutes\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n\nfunction openBrowser(url: string): void {\n const os = platform()\n\n const onError = () => {\n console.log(pc.yellow(`Could not open browser automatically. Open this URL manually:\\n${url}`))\n }\n\n if (os === 'win32') {\n exec(`start \"\" \"${url}\"`, (err) => { if (err) onError() })\n } else {\n const cmd = os === 'darwin' ? 'open' : 'xdg-open'\n execFile(cmd, [url], (err) => { if (err) onError() })\n }\n}\n\nconst PAGE_STYLE = `*{margin:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;display:flex;justify-content:center;align-items:center;min-height:100vh;background:#fff;color:#252525}\n@media(prefers-color-scheme:dark){body{background:#252525;color:#f5f5f5}}\n.card{text-align:center;padding:2rem 2.5rem;border-radius:10px;max-width:380px;width:100%}\n.icon{width:40px;height:40px;margin:0 auto 1rem;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.25rem}\n.icon.ok{background:rgba(0,0,0,.05);color:#252525}\n.icon.err{background:rgba(220,38,38,.08);color:#dc2626}\n@media(prefers-color-scheme:dark){.icon.ok{background:rgba(255,255,255,.08);color:#f5f5f5}}\nh1{font-size:.875rem;font-weight:600;margin-bottom:.375rem}\np{font-size:.75rem;color:#737373;line-height:1.5}`\n\nconst SUCCESS_HTML = `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><title>CLI Login</title>\n<style>${PAGE_STYLE}</style>\n</head><body><div class=\"card\"><div class=\"icon ok\">\\u2713</div><h1>Authenticated</h1><p>You can close this tab and return to the terminal.</p></div></body></html>`\n\nconst ERROR_HTML = (msg: string) => `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><title>CLI Login Error</title>\n<style>${PAGE_STYLE}</style>\n</head><body><div class=\"card\"><div class=\"icon err\">!</div><h1>Authentication failed</h1><p>${escapeHtml(msg)}</p></div></body></html>`\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command('login')\n .description('Login via browser and store credentials')\n .action(async () => {\n const state = randomBytes(32).toString('hex')\n\n const server = createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400).end()\n return\n }\n\n const url = new URL(req.url, `http://localhost`)\n\n if (url.pathname !== '/callback') {\n res.writeHead(404).end()\n return\n }\n\n const receivedState = url.searchParams.get('state')\n const clientKey = url.searchParams.get('clientKey')\n const secretKey = url.searchParams.get('secretKey')\n const tenant = url.searchParams.get('tenant')\n const error = url.searchParams.get('error')\n\n if (error) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(ERROR_HTML(error))\n console.error(pc.red(`Login failed: ${error}`))\n cleanup(1)\n return\n }\n\n if (receivedState !== state) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(ERROR_HTML('State mismatch — possible CSRF attack.'))\n console.error(pc.red('Login failed: state mismatch.'))\n cleanup(1)\n return\n }\n\n if (!clientKey || !secretKey || !tenant) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(ERROR_HTML('Missing credentials in callback.'))\n console.error(pc.red('Login failed: missing credentials.'))\n cleanup(1)\n return\n }\n\n saveCredentials({ clientKey, secretKey, tenantName: tenant })\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(SUCCESS_HTML)\n\n console.log(pc.green(`\\nLogged in successfully!`))\n console.log(pc.dim(`Tenant: ${tenant}`))\n console.log(pc.dim(`Credentials saved to ${getCredentialsPath()}`))\n cleanup(0)\n })\n\n let timeout: ReturnType<typeof setTimeout>\n let completed = false\n\n function cleanup(exitCode = 0) {\n if (completed) return\n completed = true\n clearTimeout(timeout)\n server.close(() => process.exit(exitCode))\n }\n\n server.listen(0, '127.0.0.1', () => {\n const addr = server.address()\n if (!addr || typeof addr === 'string') {\n console.error(pc.red('Failed to start local server.'))\n process.exit(1)\n }\n\n const port = addr.port\n const params = new URLSearchParams({ port: String(port), state })\n const loginUrl = `${WEB_URL}/cli-auth?${params.toString()}`\n\n console.log(pc.dim('Opening browser for login...'))\n console.log(pc.dim(`If the browser does not open, visit:\\n${loginUrl}`))\n openBrowser(loginUrl)\n\n timeout = setTimeout(() => {\n console.error(pc.red('\\nLogin timed out (3 minutes). Please try again.'))\n cleanup(1)\n }, TIMEOUT_MS)\n })\n\n server.on('error', (err) => {\n console.error(pc.red(`Server error: ${err.message}`))\n process.exit(1)\n })\n })\n\n program\n .command('logout')\n .description('Remove stored credentials')\n .action(() => {\n const deleted = deleteCredentials()\n if (deleted) {\n console.log(pc.green('Logged out. Credentials removed.'))\n } else {\n console.log(pc.dim('No stored credentials found.'))\n }\n })\n\n program\n .command('whoami')\n .description('Show current authentication status')\n .action(() => {\n const creds = loadCredentials()\n if (!creds) {\n console.log(pc.dim('Not logged in. Run \"01 login\" to authenticate.'))\n return\n }\n\n const masked = creds.clientKey.length > 8\n ? creds.clientKey.slice(0, 4) + '...' + creds.clientKey.slice(-4)\n : '****'\n\n console.log(`Tenant: ${pc.bold(creds.tenantName)}`)\n console.log(`Client Key: ${pc.dim(masked)}`)\n console.log(`Stored at: ${pc.dim(creds.storedAt)}`)\n console.log(`File: ${pc.dim(getCredentialsPath())}`)\n })\n}\n"],"mappings":"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","names":["pc","pc","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","pc","pc","program","require"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/client.ts","../src/lib/credentials.ts","../src/lib/output.ts","../src/commands/crud.ts","../src/lib/parse.ts","../src/commands/order.ts","../src/commands/return.ts","../src/commands/cart.ts","../src/commands/stock.ts","../src/commands/transaction.ts","../src/commands/auth.ts"],"sourcesContent":["import { createRequire } from 'node:module'\nimport { Command } from 'commander'\nimport { resolveClient } from './lib/client.js'\nimport { printError } from './lib/output.js'\nimport { registerCrudCommands } from './commands/crud.js'\nimport { registerOrderCommands } from './commands/order.js'\nimport { registerReturnCommands } from './commands/return.js'\nimport { registerCartCommands } from './commands/cart.js'\nimport { registerStockCommands } from './commands/stock.js'\nimport { registerTransactionCommands } from './commands/transaction.js'\nimport { registerAuthCommands } from './commands/auth.js'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nprocess.on('unhandledRejection', (err) => {\n printError(err)\n process.exit(1)\n})\n\nconst program = new Command()\n\nprogram\n .name('01')\n .description('CLI for the 01.software platform')\n .version(version)\n .option('--api-key <base64>', 'Base64-encoded API key (clientKey:secretKey)')\n .option('--format <format>', 'Output format: json (default) or table', 'json')\n\nconst getFormat = () => program.opts().format as string\nconst getClient = () => resolveClient(program.opts().apiKey as string | undefined)\n\nregisterCrudCommands(program, getClient, getFormat)\nregisterOrderCommands(program, getClient, getFormat)\nregisterReturnCommands(program, getClient, getFormat)\nregisterCartCommands(program, getClient, getFormat)\nregisterStockCommands(program, getClient, getFormat)\nregisterTransactionCommands(program, getClient, getFormat)\nregisterAuthCommands(program)\n\nprogram.parse()\n","import { CollectionClient, OrderApi, CartApi, ProductApi, parseApiKey } from '@01.software/sdk'\nimport pc from 'picocolors'\nimport { loadCredentials, loadLocalCredentials } from './credentials.js'\n\nexport interface ResolvedClient {\n collections: CollectionClient\n api: OrderApi\n cart: CartApi\n product: ProductApi\n}\n\nexport function resolveClient(apiKeyFlag?: string): ResolvedClient {\n let clientKey: string | undefined\n let secretKey: string | undefined\n\n if (apiKeyFlag) {\n try {\n const parsed = parseApiKey(apiKeyFlag)\n clientKey = parsed.clientKey\n secretKey = parsed.secretKey\n } catch {\n console.error(pc.red('Invalid --api-key value. Expected Base64-encoded \"clientKey:secretKey\".'))\n process.exit(1)\n }\n } else {\n clientKey = process.env.SOFTWARE_CLIENT_KEY\n secretKey = process.env.SOFTWARE_SECRET_KEY\n }\n\n // Fallback: local credentials (./01software/credentials.json)\n if (!clientKey || !secretKey) {\n const local = loadLocalCredentials()\n if (local) {\n clientKey = local.clientKey\n secretKey = local.secretKey\n }\n }\n\n // Fallback: global credentials (~/.01software/credentials.json)\n if (!clientKey || !secretKey) {\n const stored = loadCredentials()\n if (stored) {\n clientKey = stored.clientKey\n secretKey = stored.secretKey\n }\n }\n\n if (!clientKey || !secretKey) {\n console.error(pc.red('Authentication required.'))\n console.error(\n pc.dim(\n 'Run \"01 login\" to authenticate via browser,\\n' +\n 'or set SOFTWARE_CLIENT_KEY and SOFTWARE_SECRET_KEY environment variables,\\n' +\n 'or use the --api-key <base64> flag.',\n ),\n )\n process.exit(1)\n }\n\n const apiOpts = { clientKey, secretKey }\n\n return {\n collections: new CollectionClient(clientKey, secretKey),\n api: new OrderApi(apiOpts),\n cart: new CartApi(apiOpts),\n product: new ProductApi(apiOpts),\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, appendFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nexport interface StoredCredentials {\n clientKey: string\n secretKey: string\n tenantId?: string\n tenantName: string\n storedAt: string\n}\n\nexport interface TenantInfo {\n id: string\n name: string\n}\n\nconst DIR_NAME = '.01software'\nconst FILE_NAME = 'credentials.json'\nconst TENANTS_FILE = 'tenants.json'\n\n// ---------------------------------------------------------------------------\n// Global credentials (~/.01software/credentials.json)\n// ---------------------------------------------------------------------------\n\nexport function getCredentialsPath(): string {\n return join(homedir(), DIR_NAME, FILE_NAME)\n}\n\nexport function loadCredentials(): StoredCredentials | null {\n return loadCredentialsFrom(getCredentialsPath())\n}\n\nexport function saveCredentials(creds: Omit<StoredCredentials, 'storedAt'>): void {\n const dir = join(homedir(), DIR_NAME)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 })\n }\n\n const filePath = getCredentialsPath()\n const data: StoredCredentials = { ...creds, storedAt: new Date().toISOString() }\n writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 })\n}\n\nexport function deleteCredentials(): boolean {\n const filePath = getCredentialsPath()\n if (!existsSync(filePath)) return false\n\n unlinkSync(filePath)\n return true\n}\n\n// ---------------------------------------------------------------------------\n// Local credentials (./01software/credentials.json)\n// ---------------------------------------------------------------------------\n\nexport function getLocalCredentialsPath(): string {\n return join(process.cwd(), DIR_NAME, FILE_NAME)\n}\n\nexport function loadLocalCredentials(): StoredCredentials | null {\n return loadCredentialsFrom(getLocalCredentialsPath())\n}\n\nexport function saveLocalCredentials(creds: Omit<StoredCredentials, 'storedAt'>): void {\n const dir = join(process.cwd(), DIR_NAME)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 })\n }\n\n const filePath = getLocalCredentialsPath()\n const data: StoredCredentials = { ...creds, storedAt: new Date().toISOString() }\n writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 })\n\n // Ensure .01software/ is in .gitignore\n ensureGitignore()\n}\n\n// ---------------------------------------------------------------------------\n// Tenant list cache (~/.01software/tenants.json)\n// ---------------------------------------------------------------------------\n\nexport function saveTenantList(tenants: TenantInfo[]): void {\n const dir = join(homedir(), DIR_NAME)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 })\n }\n\n const filePath = join(homedir(), DIR_NAME, TENANTS_FILE)\n writeFileSync(filePath, JSON.stringify(tenants, null, 2), { encoding: 'utf-8', mode: 0o600 })\n}\n\nexport function loadTenantList(): TenantInfo[] | null {\n const filePath = join(homedir(), DIR_NAME, TENANTS_FILE)\n if (!existsSync(filePath)) return null\n\n try {\n const raw = readFileSync(filePath, 'utf-8')\n const data = JSON.parse(raw)\n if (!Array.isArray(data)) return null\n const valid = data.filter(\n (t): t is TenantInfo => typeof t?.id === 'string' && typeof t?.name === 'string',\n )\n return valid.length > 0 ? valid : null\n } catch {\n return null\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction loadCredentialsFrom(filePath: string): StoredCredentials | null {\n if (!existsSync(filePath)) return null\n\n try {\n const raw = readFileSync(filePath, 'utf-8')\n const data = JSON.parse(raw) as StoredCredentials\n if (!data.clientKey || !data.secretKey) return null\n return data\n } catch {\n return null\n }\n}\n\nfunction ensureGitignore(): void {\n const gitignorePath = join(process.cwd(), '.gitignore')\n const entry = '.01software/'\n\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8')\n if (content.includes(entry)) return\n appendFileSync(gitignorePath, `\\n${entry}\\n`, 'utf-8')\n } else {\n writeFileSync(gitignorePath, `${entry}\\n`, 'utf-8')\n }\n}\n","import pc from 'picocolors'\n\nexport function printJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2))\n}\n\nexport function printTable(data: unknown): void {\n if (Array.isArray(data)) {\n if (data.length === 0) {\n console.log(pc.dim('(empty)'))\n return\n }\n const keys = Object.keys(data[0] as Record<string, unknown>)\n const widths = keys.map((k) =>\n Math.max(k.length, ...data.map((row) => String((row as Record<string, unknown>)[k] ?? '').length)),\n )\n\n // Header\n console.log(keys.map((k, i) => k.padEnd(widths[i]!)).join(' '))\n console.log(keys.map((_, i) => '-'.repeat(widths[i]!)).join(' '))\n\n // Rows\n for (const row of data) {\n console.log(\n keys.map((k, i) => String((row as Record<string, unknown>)[k] ?? '').padEnd(widths[i]!)).join(' '),\n )\n }\n } else if (data && typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>)\n const maxKey = Math.max(...entries.map(([k]) => k.length))\n for (const [key, value] of entries) {\n const display = typeof value === 'object' ? JSON.stringify(value) : String(value)\n console.log(`${pc.bold(key.padEnd(maxKey))} ${display}`)\n }\n } else {\n console.log(String(data))\n }\n}\n\nexport function printResult(data: unknown, format: string): void {\n if (format === 'table') {\n // For find responses with docs array, print the docs as table\n if (data && typeof data === 'object' && 'docs' in (data as Record<string, unknown>)) {\n const resp = data as { docs: unknown[]; totalDocs: number; page: number; totalPages: number }\n printTable(resp.docs)\n console.log(pc.dim(`\\n${resp.totalDocs} total | page ${resp.page}/${resp.totalPages}`))\n return\n }\n printTable(data)\n } else {\n printJson(data)\n }\n}\n\nexport function printError(error: unknown): void {\n if (error && typeof error === 'object' && 'message' in error) {\n const err = error as { message: string; code?: string; status?: number; suggestion?: string }\n console.error(pc.red(`Error: ${err.message}`))\n if (err.code) console.error(pc.dim(`Code: ${err.code}`))\n if (err.status) console.error(pc.dim(`Status: ${err.status}`))\n if (err.suggestion) console.error(pc.yellow(err.suggestion))\n } else {\n console.error(pc.red(String(error)))\n }\n}\n","import { readFileSync } from 'node:fs'\nimport { basename } from 'node:path'\nimport { Command } from 'commander'\nimport { COLLECTIONS } from '@01.software/sdk'\nimport type { ApiQueryOptions } from '@01.software/sdk'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJson } from '../lib/parse.js'\n\nfunction readFileAsBlob(filePath: string): { blob: Blob; filename: string } {\n const buffer = readFileSync(filePath)\n return { blob: new Blob([buffer]), filename: basename(filePath) }\n}\n\nfunction validateCollection(name: string): string {\n if (!(COLLECTIONS as readonly string[]).includes(name)) {\n const normalized = name.replace(/-/g, '').toLowerCase()\n const suggestions = COLLECTIONS.filter((c) => {\n const cn = c.replace(/-/g, '').toLowerCase()\n return cn.startsWith(normalized) || normalized.startsWith(cn) || (normalized.length >= 3 && cn.includes(normalized))\n }).slice(0, 5)\n const hint = suggestions.length > 0\n ? `Did you mean: ${suggestions.join(', ')}?`\n : 'Run \"01 --help\" for available collections.'\n throw new Error(`Unknown collection \"${name}\". ${hint}`)\n }\n return name\n}\n\nfunction parseSelect(input: string): Record<string, boolean> {\n return Object.fromEntries(input.split(',').map((f) => [f.trim(), true]))\n}\n\nexport function registerCrudCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n program\n .command('query <collection>')\n .description('Query documents from a collection')\n .option('--where <json>', 'Filter conditions (JSON)')\n .option('--limit <n>', 'Max results', (v: string) => parseInt(v, 10))\n .option('--page <n>', 'Page number', (v: string) => parseInt(v, 10))\n .option('--sort <field>', 'Sort field (prefix with - for descending)')\n .option('--depth <n>', 'Relationship depth (0 = no population)', (v: string) => parseInt(v, 10))\n .option('--select <fields>', 'Comma-separated fields to select')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const options: Record<string, unknown> = {}\n if (opts.where) options.where = parseJson(opts.where, 'where')\n if (opts.limit) options.limit = opts.limit\n if (opts.page) options.page = opts.page\n if (opts.sort) options.sort = opts.sort\n if (opts.depth != null) options.depth = opts.depth\n if (opts.select) options.select = parseSelect(opts.select)\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).find(options)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('get <collection> <id>')\n .description('Get a document by ID')\n .option('--depth <n>', 'Relationship depth (0 = no population)', (v: string) => parseInt(v, 10))\n .option('--select <fields>', 'Comma-separated fields to select')\n .action(async (collection: string, id: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const options: Record<string, unknown> = {}\n if (opts.depth != null) options.depth = opts.depth\n if (opts.select) options.select = parseSelect(opts.select)\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).findById(id, options)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('create <collection>')\n .description('Create a new document')\n .requiredOption('--data <json>', 'Document data (JSON)')\n .option('--file <path>', 'File to upload (for upload collections)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const data = parseJson(opts.data, 'data')\n let fileOpts: { file: Blob; filename: string } | undefined\n if (opts.file) {\n const { blob, filename } = readFileAsBlob(opts.file)\n fileOpts = { file: blob, filename }\n }\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).create(data, fileOpts)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('update <collection> <id>')\n .description('Update a document by ID')\n .requiredOption('--data <json>', 'Document data (JSON)')\n .option('--file <path>', 'File to upload (for upload collections)')\n .action(async (collection: string, id: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const data = parseJson(opts.data, 'data')\n let fileOpts: { file: Blob; filename: string } | undefined\n if (opts.file) {\n const { blob, filename } = readFileAsBlob(opts.file)\n fileOpts = { file: blob, filename }\n }\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).update(id, data, fileOpts)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('delete <collection> <id>')\n .description('Delete a document by ID')\n .action(async (collection: string, id: string) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).remove(id)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('update-many <collection>')\n .description('Update multiple documents matching a filter')\n .requiredOption('--where <json>', 'Filter conditions (JSON)')\n .requiredOption('--data <json>', 'Update data (JSON)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const where = parseJson(opts.where, 'where') as ApiQueryOptions['where']\n const data = parseJson(opts.data, 'data')\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).updateMany(where, data)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n program\n .command('delete-many <collection>')\n .description('Delete multiple documents matching a filter')\n .requiredOption('--where <json>', 'Filter conditions (JSON)')\n .action(async (collection: string, opts) => {\n try {\n const col = validateCollection(collection)\n const client = getClient()\n const where = parseJson(opts.where, 'where') as ApiQueryOptions['where']\n const result = await client.collections.from(col as typeof COLLECTIONS[number]).removeMany(where)\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import pc from 'picocolors'\n\nexport function parseJson(value: string, label: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(value)\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n console.error(pc.red(`--${label} must be a JSON object.`))\n process.exit(1)\n }\n return parsed as Record<string, unknown>\n } catch {\n console.error(pc.red(`Invalid JSON for --${label}: ${value}`))\n process.exit(1)\n }\n}\n\nexport function parseJsonArray(value: string, label: string): unknown[] {\n try {\n const parsed = JSON.parse(value)\n if (!Array.isArray(parsed)) {\n console.error(pc.red(`--${label} must be a JSON array.`))\n process.exit(1)\n }\n return parsed\n } catch {\n console.error(pc.red(`Invalid JSON for --${label}: ${value}`))\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJson, parseJsonArray } from '../lib/parse.js'\n\nexport function registerOrderCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const order = program.command('order').description('Order management')\n\n order\n .command('create')\n .description('Create a new order')\n .requiredOption('--payment-id <id>', 'Payment ID')\n .requiredOption('--order-number <num>', 'Order number')\n .requiredOption('--email <email>', 'Customer email')\n .requiredOption('--shipping-address <json>', 'Shipping address (JSON)')\n .requiredOption('--products <json>', 'Order products array (JSON)')\n .requiredOption('--total-amount <n>', 'Total amount', parseFloat)\n .action(async (opts) => {\n try {\n const client = getClient()\n const result = await client.api.createOrder({\n paymentId: opts.paymentId,\n orderNumber: opts.orderNumber,\n email: opts.email,\n shippingAddress: parseJson(opts.shippingAddress, 'shipping-address'),\n orderProducts: parseJsonArray(opts.products, 'products') as Parameters<typeof client.api.createOrder>[0]['orderProducts'],\n totalAmount: opts.totalAmount,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('get <orderNumber>')\n .description('Get an order by order number')\n .action(async (orderNumber: string) => {\n try {\n const client = getClient()\n const result = await client.api.getOrder({ orderNumber })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('update <orderNumber>')\n .description('Update order status')\n .requiredOption('--status <status>', 'New status')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.updateOrder({\n orderNumber,\n status: opts.status,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('checkout')\n .description('Convert a cart to an order')\n .requiredOption('--cart-id <id>', 'Cart ID')\n .requiredOption('--payment-id <id>', 'Payment ID')\n .requiredOption('--order-number <num>', 'Order number')\n .requiredOption('--customer <json>', 'Customer snapshot (JSON)')\n .action(async (opts) => {\n try {\n const client = getClient()\n const result = await client.api.checkout({\n cartId: opts.cartId,\n paymentId: opts.paymentId,\n orderNumber: opts.orderNumber,\n customerSnapshot: parseJson(opts.customer, 'customer') as Parameters<typeof client.api.checkout>[0]['customerSnapshot'],\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n order\n .command('fulfill <orderNumber>')\n .description('Create a fulfillment for an order')\n .requiredOption('--items <json>', 'Fulfillment items array (JSON)')\n .option('--carrier <name>', 'Shipping carrier')\n .option('--tracking-number <num>', 'Tracking number')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.createFulfillment({\n orderNumber,\n items: parseJsonArray(opts.items, 'items') as Parameters<typeof client.api.createFulfillment>[0]['items'],\n carrier: opts.carrier,\n trackingNumber: opts.trackingNumber,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJsonArray } from '../lib/parse.js'\n\nexport function registerReturnCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const ret = program.command('return').description('Return management')\n\n ret\n .command('create <orderNumber>')\n .description('Create a return request')\n .requiredOption('--products <json>', 'Return products array (JSON)')\n .requiredOption('--refund-amount <n>', 'Refund amount', parseFloat)\n .option('--reason <reason>', 'Return reason (change_of_mind, defective, wrong_delivery, damaged, other)')\n .option('--reason-detail <text>', 'Detailed reason')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.createReturn({\n orderNumber,\n returnProducts: parseJsonArray(opts.products, 'products') as Parameters<typeof client.api.createReturn>[0]['returnProducts'],\n refundAmount: opts.refundAmount,\n reason: opts.reason,\n reasonDetail: opts.reasonDetail,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n ret\n .command('update <returnId>')\n .description('Update return status')\n .requiredOption('--status <status>', 'New status (processing, approved, rejected, completed)')\n .action(async (returnId: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.updateReturn({\n returnId,\n status: opts.status,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n ret\n .command('refund <orderNumber>')\n .description('Return with refund')\n .requiredOption('--products <json>', 'Return products array (JSON)')\n .requiredOption('--refund-amount <n>', 'Refund amount', parseFloat)\n .requiredOption('--payment-id <id>', 'Payment ID')\n .option('--reason <reason>', 'Return reason')\n .option('--reason-detail <text>', 'Detailed reason')\n .option('--refund-receipt-url <url>', 'Refund receipt URL')\n .action(async (orderNumber: string, opts) => {\n try {\n const client = getClient()\n const result = await client.api.returnWithRefund({\n orderNumber,\n returnProducts: parseJsonArray(opts.products, 'products') as Parameters<typeof client.api.returnWithRefund>[0]['returnProducts'],\n refundAmount: opts.refundAmount,\n paymentId: opts.paymentId,\n reason: opts.reason,\n reasonDetail: opts.reasonDetail,\n refundReceiptUrl: opts.refundReceiptUrl,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\n\nexport function registerCartCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const cart = program.command('cart').description('Cart management')\n\n cart\n .command('add <cartId>')\n .description('Add an item to cart')\n .requiredOption('--product <id>', 'Product ID')\n .requiredOption('--variant <id>', 'Variant ID')\n .requiredOption('--option <id>', 'Option ID')\n .requiredOption('--quantity <n>', 'Quantity', (v: string) => parseInt(v, 10))\n .action(async (cartId: string, opts) => {\n try {\n const client = getClient()\n const result = await client.cart.addItem({\n cartId,\n product: opts.product,\n variant: opts.variant,\n option: opts.option,\n quantity: opts.quantity,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n cart\n .command('update <cartItemId>')\n .description('Update cart item quantity')\n .requiredOption('--quantity <n>', 'New quantity', (v: string) => parseInt(v, 10))\n .action(async (cartItemId: string, opts) => {\n try {\n const client = getClient()\n const result = await client.cart.updateItem({\n cartItemId,\n quantity: opts.quantity,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n\n cart\n .command('remove <cartItemId>')\n .description('Remove an item from cart')\n .action(async (cartItemId: string) => {\n try {\n const client = getClient()\n const result = await client.cart.removeItem({ cartItemId })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\nimport { parseJsonArray } from '../lib/parse.js'\n\nexport function registerStockCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const stock = program.command('stock').description('Stock management')\n\n stock\n .command('check')\n .description('Check stock availability')\n .requiredOption('--items <json>', 'Items to check (JSON array of { optionId, quantity })')\n .action(async (opts) => {\n try {\n const client = getClient()\n const items = parseJsonArray(opts.items, 'items') as Parameters<typeof client.product.stockCheck>[0]['items']\n const result = await client.product.stockCheck({ items })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { Command } from 'commander'\nimport type { ResolvedClient } from '../lib/client.js'\nimport { printResult, printError } from '../lib/output.js'\n\nexport function registerTransactionCommands(program: Command, getClient: () => ResolvedClient, getFormat: () => string) {\n const tx = program.command('transaction').description('Transaction management')\n\n tx\n .command('update')\n .description('Update transaction status')\n .requiredOption('--payment-id <id>', 'Payment ID')\n .requiredOption('--status <status>', 'New status (pending, paid, failed, canceled)')\n .requiredOption('--payment-method <method>', 'Payment method')\n .requiredOption('--receipt-url <url>', 'Receipt URL')\n .action(async (opts) => {\n try {\n const client = getClient()\n const result = await client.api.updateTransaction({\n paymentId: opts.paymentId,\n status: opts.status,\n paymentMethod: opts.paymentMethod,\n receiptUrl: opts.receiptUrl,\n })\n printResult(result, getFormat())\n } catch (e) {\n printError(e)\n process.exit(1)\n }\n })\n}\n","import { randomBytes } from 'node:crypto'\nimport { createServer } from 'node:http'\nimport { execFile, exec } from 'node:child_process'\nimport { platform } from 'node:os'\nimport { URL } from 'node:url'\nimport type { Command } from 'commander'\nimport pc from 'picocolors'\nimport {\n loadCredentials,\n saveCredentials,\n deleteCredentials,\n getCredentialsPath,\n loadLocalCredentials,\n saveLocalCredentials,\n getLocalCredentialsPath,\n loadTenantList,\n saveTenantList,\n type TenantInfo,\n} from '../lib/credentials.js'\n\nconst WEB_URL = process.env.SOFTWARE_WEB_URL || 'https://01.software'\nconst TIMEOUT_MS = 3 * 60 * 1000 // 3 minutes\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n\nfunction openBrowser(url: string): void {\n const os = platform()\n\n const onError = () => {\n console.log(pc.yellow(`Could not open browser automatically. Open this URL manually:\\n${url}`))\n }\n\n if (os === 'win32') {\n exec(`start \"\" \"${url}\"`, (err) => { if (err) onError() })\n } else {\n const cmd = os === 'darwin' ? 'open' : 'xdg-open'\n execFile(cmd, [url], (err) => { if (err) onError() })\n }\n}\n\nconst PAGE_STYLE = `*{margin:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;display:flex;justify-content:center;align-items:center;min-height:100vh;background:#fff;color:#252525}\n@media(prefers-color-scheme:dark){body{background:#252525;color:#f5f5f5}}\n.card{text-align:center;padding:2rem 2.5rem;border-radius:10px;max-width:380px;width:100%}\n.icon{width:40px;height:40px;margin:0 auto 1rem;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.25rem}\n.icon.ok{background:rgba(0,0,0,.05);color:#252525}\n.icon.err{background:rgba(220,38,38,.08);color:#dc2626}\n@media(prefers-color-scheme:dark){.icon.ok{background:rgba(255,255,255,.08);color:#f5f5f5}}\nh1{font-size:.875rem;font-weight:600;margin-bottom:.375rem}\np{font-size:.75rem;color:#737373;line-height:1.5}`\n\nconst SUCCESS_HTML = `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><title>CLI Login</title>\n<style>${PAGE_STYLE}</style>\n</head><body><div class=\"card\"><div class=\"icon ok\">\\u2713</div><h1>Authenticated</h1><p>You can close this tab and return to the terminal.</p></div></body></html>`\n\nconst ERROR_HTML = (msg: string) => `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width\"><title>CLI Login Error</title>\n<style>${PAGE_STYLE}</style>\n</head><body><div class=\"card\"><div class=\"icon err\">!</div><h1>Authentication failed</h1><p>${escapeHtml(msg)}</p></div></body></html>`\n\n/**\n * Start a local HTTP server that receives the OAuth-like callback from the browser.\n * Returns a promise that resolves with the received credentials, or rejects on error/timeout.\n */\nfunction startAuthServer(options: {\n state: string\n saveFn: (creds: { clientKey: string; secretKey: string; tenantId?: string; tenantName: string }) => void\n}): Promise<{ port: number; cleanup: (exitCode?: number) => void }> {\n return new Promise((resolve, reject) => {\n const server = createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400).end()\n return\n }\n\n const url = new URL(req.url, `http://localhost`)\n\n if (url.pathname !== '/callback') {\n res.writeHead(404).end()\n return\n }\n\n const receivedState = url.searchParams.get('state')\n const clientKey = url.searchParams.get('clientKey')\n const secretKey = url.searchParams.get('secretKey')\n const tenant = url.searchParams.get('tenant')\n const tenantIdParam = url.searchParams.get('tenantId')\n const tenantsParam = url.searchParams.get('tenants')\n const error = url.searchParams.get('error')\n\n if (error) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(ERROR_HTML(error))\n console.error(pc.red(`Login failed: ${error}`))\n cleanup(1)\n return\n }\n\n if (receivedState !== options.state) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(ERROR_HTML('State mismatch — possible CSRF attack.'))\n console.error(pc.red('Login failed: state mismatch.'))\n cleanup(1)\n return\n }\n\n if (!clientKey || !secretKey || !tenant) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(ERROR_HTML('Missing credentials in callback.'))\n console.error(pc.red('Login failed: missing credentials.'))\n cleanup(1)\n return\n }\n\n // Save credentials using the provided save function\n options.saveFn({\n clientKey,\n secretKey,\n ...(tenantIdParam ? { tenantId: tenantIdParam } : {}),\n tenantName: tenant,\n })\n\n // Cache tenant list if provided\n if (tenantsParam) {\n try {\n const parsed = JSON.parse(tenantsParam)\n if (Array.isArray(parsed)) {\n const valid = parsed.filter(\n (t): t is TenantInfo => typeof t?.id === 'string' && typeof t?.name === 'string',\n )\n if (valid.length > 0) saveTenantList(valid)\n }\n } catch {\n // Ignore malformed tenants param\n }\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }).end(SUCCESS_HTML)\n\n console.log(pc.green(`\\nLogged in successfully!`))\n console.log(pc.dim(`Tenant: ${tenant}`))\n cleanup(0)\n })\n\n let timeout: ReturnType<typeof setTimeout>\n let completed = false\n\n function cleanup(exitCode = 0) {\n if (completed) return\n completed = true\n clearTimeout(timeout)\n server.close(() => process.exit(exitCode))\n }\n\n server.listen(0, '127.0.0.1', () => {\n const addr = server.address()\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to start local server.'))\n return\n }\n\n timeout = setTimeout(() => {\n console.error(pc.red('\\nLogin timed out (3 minutes). Please try again.'))\n cleanup(1)\n }, TIMEOUT_MS)\n\n resolve({ port: addr.port, cleanup })\n })\n\n server.on('error', (err) => {\n reject(err)\n })\n })\n}\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command('login')\n .description('Login via browser and store credentials')\n .action(async () => {\n const state = randomBytes(32).toString('hex')\n\n try {\n const { port } = await startAuthServer({\n state,\n saveFn: (creds) => {\n saveCredentials(creds)\n console.log(pc.dim(`Credentials saved to ${getCredentialsPath()}`))\n },\n })\n\n const params = new URLSearchParams({ port: String(port), state })\n const loginUrl = `${WEB_URL}/cli-auth?${params.toString()}`\n\n console.log(pc.dim('Opening browser for login...'))\n console.log(pc.dim(`If the browser does not open, visit:\\n${loginUrl}`))\n openBrowser(loginUrl)\n } catch (err) {\n console.error(pc.red(`Server error: ${err instanceof Error ? err.message : String(err)}`))\n process.exit(1)\n }\n })\n\n program\n .command('logout')\n .description('Remove stored credentials')\n .action(() => {\n const deleted = deleteCredentials()\n if (deleted) {\n console.log(pc.green('Logged out. Credentials removed.'))\n } else {\n console.log(pc.dim('No stored credentials found.'))\n }\n })\n\n program\n .command('whoami')\n .description('Show current authentication status')\n .action(() => {\n // Check local credentials first\n const localCreds = loadLocalCredentials()\n const globalCreds = loadCredentials()\n const creds = localCreds || globalCreds\n const isLocal = !!localCreds\n\n if (!creds) {\n console.log(pc.dim('Not logged in. Run \"01 login\" to authenticate.'))\n return\n }\n\n const masked = creds.clientKey.length > 8\n ? creds.clientKey.slice(0, 4) + '...' + creds.clientKey.slice(-4)\n : '****'\n\n const scope = isLocal ? pc.cyan(' (local)') : ''\n console.log(`Tenant: ${pc.bold(creds.tenantName)}${scope}`)\n console.log(`Client Key: ${pc.dim(masked)}`)\n console.log(`Stored at: ${pc.dim(creds.storedAt)}`)\n console.log(`File: ${pc.dim(isLocal ? getLocalCredentialsPath() : getCredentialsPath())}`)\n })\n\n // -------------------------------------------------------------------------\n // tenant subcommands\n // -------------------------------------------------------------------------\n const tenant = program\n .command('tenant')\n .description('Manage tenant switching')\n\n tenant\n .command('list')\n .description('Show cached tenant list')\n .action(() => {\n const tenants = loadTenantList()\n if (!tenants || tenants.length === 0) {\n console.log(pc.dim('No cached tenants. Run \"01 login\" first.'))\n return\n }\n\n // Determine active tenant\n const localCreds = loadLocalCredentials()\n const globalCreds = loadCredentials()\n const activeCreds = localCreds || globalCreds\n const activeId = activeCreds?.tenantId\n const activeName = activeCreds?.tenantName\n\n console.log(pc.bold('Cached tenants:\\n'))\n for (const t of tenants) {\n const active = (activeId ? t.id === activeId : t.name === activeName)\n ? pc.green(' *')\n : ''\n console.log(` ${t.name}${active}`)\n }\n console.log()\n if (activeName) {\n const scope = localCreds ? '(local)' : '(global)'\n console.log(pc.dim(`* active ${scope}`))\n }\n })\n\n tenant\n .command('use <name>')\n .description('Switch to a different tenant via browser')\n .option('--local', 'Save credentials locally in the current project')\n .action(async (name: string, opts: { local?: boolean }) => {\n const tenants = loadTenantList()\n if (!tenants || tenants.length === 0) {\n console.error(pc.red('No cached tenants. Run \"01 login\" first.'))\n process.exit(1)\n }\n\n const match = tenants.find((t) => t.name.toLowerCase() === name.toLowerCase())\n if (!match) {\n console.error(pc.red(`Tenant \"${name}\" not found in cache.`))\n console.error(pc.dim(`Available: ${tenants.map((t) => t.name).join(', ')}`))\n process.exit(1)\n }\n\n const state = randomBytes(32).toString('hex')\n const isLocal = !!opts.local\n\n try {\n const { port } = await startAuthServer({\n state,\n saveFn: (creds) => {\n if (isLocal) {\n saveLocalCredentials(creds)\n console.log(pc.dim(`Credentials saved to ${getLocalCredentialsPath()}`))\n } else {\n saveCredentials(creds)\n console.log(pc.dim(`Credentials saved to ${getCredentialsPath()}`))\n }\n },\n })\n\n const params = new URLSearchParams({\n port: String(port),\n state,\n tenantId: match.id,\n })\n const loginUrl = `${WEB_URL}/cli-auth?${params.toString()}`\n\n console.log(pc.dim(`Switching to tenant \"${match.name}\"...`))\n console.log(pc.dim(`If the browser does not open, visit:\\n${loginUrl}`))\n openBrowser(loginUrl)\n } catch (err) {\n console.error(pc.red(`Server error: ${err instanceof Error ? err.message : String(err)}`))\n process.exit(1)\n }\n })\n}\n"],"mappings":";;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;;;ACDxB,SAAS,kBAAkB,UAAU,SAAS,YAAY,mBAAmB;AAC7E,OAAO,QAAQ;;;ACDf,SAAS,YAAY,WAAW,cAAc,eAAe,YAAY,sBAAsB;AAC/F,SAAS,YAAY;AACrB,SAAS,eAAe;AAexB,IAAM,WAAW;AACjB,IAAM,YAAY;AAClB,IAAM,eAAe;AAMd,SAAS,qBAA6B;AAC3C,SAAO,KAAK,QAAQ,GAAG,UAAU,SAAS;AAC5C;AAEO,SAAS,kBAA4C;AAC1D,SAAO,oBAAoB,mBAAmB,CAAC;AACjD;AAEO,SAAS,gBAAgB,OAAkD;AAChF,QAAM,MAAM,KAAK,QAAQ,GAAG,QAAQ;AACpC,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAAA,EACjD;AAEA,QAAM,WAAW,mBAAmB;AACpC,QAAM,OAA0B,EAAE,GAAG,OAAO,WAAU,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC/E,gBAAc,UAAU,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,EAAE,UAAU,SAAS,MAAM,IAAM,CAAC;AAC3F;AAEO,SAAS,oBAA6B;AAC3C,QAAM,WAAW,mBAAmB;AACpC,MAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAElC,aAAW,QAAQ;AACnB,SAAO;AACT;AAMO,SAAS,0BAAkC;AAChD,SAAO,KAAK,QAAQ,IAAI,GAAG,UAAU,SAAS;AAChD;AAEO,SAAS,uBAAiD;AAC/D,SAAO,oBAAoB,wBAAwB,CAAC;AACtD;AAEO,SAAS,qBAAqB,OAAkD;AACrF,QAAM,MAAM,KAAK,QAAQ,IAAI,GAAG,QAAQ;AACxC,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAAA,EACjD;AAEA,QAAM,WAAW,wBAAwB;AACzC,QAAM,OAA0B,EAAE,GAAG,OAAO,WAAU,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC/E,gBAAc,UAAU,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,EAAE,UAAU,SAAS,MAAM,IAAM,CAAC;AAGzF,kBAAgB;AAClB;AAMO,SAAS,eAAe,SAA6B;AAC1D,QAAM,MAAM,KAAK,QAAQ,GAAG,QAAQ;AACpC,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAAA,EACjD;AAEA,QAAM,WAAW,KAAK,QAAQ,GAAG,UAAU,YAAY;AACvD,gBAAc,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,EAAE,UAAU,SAAS,MAAM,IAAM,CAAC;AAC9F;AAEO,SAAS,iBAAsC;AACpD,QAAM,WAAW,KAAK,QAAQ,GAAG,UAAU,YAAY;AACvD,MAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAElC,MAAI;AACF,UAAM,MAAM,aAAa,UAAU,OAAO;AAC1C,UAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO;AACjC,UAAM,QAAQ,KAAK;AAAA,MACjB,CAAC,MAAuB,OAAO,GAAG,OAAO,YAAY,OAAO,GAAG,SAAS;AAAA,IAC1E;AACA,WAAO,MAAM,SAAS,IAAI,QAAQ;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,SAAS,oBAAoB,UAA4C;AACvE,MAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAElC,MAAI;AACF,UAAM,MAAM,aAAa,UAAU,OAAO;AAC1C,UAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,UAAW,QAAO;AAC/C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAwB;AAC/B,QAAM,gBAAgB,KAAK,QAAQ,IAAI,GAAG,YAAY;AACtD,QAAM,QAAQ;AAEd,MAAI,WAAW,aAAa,GAAG;AAC7B,UAAM,UAAU,aAAa,eAAe,OAAO;AACnD,QAAI,QAAQ,SAAS,KAAK,EAAG;AAC7B,mBAAe,eAAe;AAAA,EAAK,KAAK;AAAA,GAAM,OAAO;AAAA,EACvD,OAAO;AACL,kBAAc,eAAe,GAAG,KAAK;AAAA,GAAM,OAAO;AAAA,EACpD;AACF;;;AD9HO,SAAS,cAAc,YAAqC;AACjE,MAAI;AACJ,MAAI;AAEJ,MAAI,YAAY;AACd,QAAI;AACF,YAAM,SAAS,YAAY,UAAU;AACrC,kBAAY,OAAO;AACnB,kBAAY,OAAO;AAAA,IACrB,QAAQ;AACN,cAAQ,MAAM,GAAG,IAAI,yEAAyE,CAAC;AAC/F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AACL,gBAAY,QAAQ,IAAI;AACxB,gBAAY,QAAQ,IAAI;AAAA,EAC1B;AAGA,MAAI,CAAC,aAAa,CAAC,WAAW;AAC5B,UAAM,QAAQ,qBAAqB;AACnC,QAAI,OAAO;AACT,kBAAY,MAAM;AAClB,kBAAY,MAAM;AAAA,IACpB;AAAA,EACF;AAGA,MAAI,CAAC,aAAa,CAAC,WAAW;AAC5B,UAAM,SAAS,gBAAgB;AAC/B,QAAI,QAAQ;AACV,kBAAY,OAAO;AACnB,kBAAY,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,CAAC,WAAW;AAC5B,YAAQ,MAAM,GAAG,IAAI,0BAA0B,CAAC;AAChD,YAAQ;AAAA,MACN,GAAG;AAAA,QACD;AAAA,MAGF;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,EAAE,WAAW,UAAU;AAEvC,SAAO;AAAA,IACL,aAAa,IAAI,iBAAiB,WAAW,SAAS;AAAA,IACtD,KAAK,IAAI,SAAS,OAAO;AAAA,IACzB,MAAM,IAAI,QAAQ,OAAO;AAAA,IACzB,SAAS,IAAI,WAAW,OAAO;AAAA,EACjC;AACF;;;AEnEA,OAAOA,SAAQ;AAER,SAAS,UAAU,MAAqB;AAC7C,UAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAC3C;AAEO,SAAS,WAAW,MAAqB;AAC9C,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,QAAI,KAAK,WAAW,GAAG;AACrB,cAAQ,IAAIA,IAAG,IAAI,SAAS,CAAC;AAC7B;AAAA,IACF;AACA,UAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAA4B;AAC3D,UAAM,SAAS,KAAK;AAAA,MAAI,CAAC,MACvB,KAAK,IAAI,EAAE,QAAQ,GAAG,KAAK,IAAI,CAAC,QAAQ,OAAQ,IAAgC,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC;AAAA,IACnG;AAGA,YAAQ,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,OAAO,OAAO,CAAC,CAAE,CAAC,EAAE,KAAK,IAAI,CAAC;AAC/D,YAAQ,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,OAAO,CAAC,CAAE,CAAC,EAAE,KAAK,IAAI,CAAC;AAGjE,eAAW,OAAO,MAAM;AACtB,cAAQ;AAAA,QACN,KAAK,IAAI,CAAC,GAAG,MAAM,OAAQ,IAAgC,CAAC,KAAK,EAAE,EAAE,OAAO,OAAO,CAAC,CAAE,CAAC,EAAE,KAAK,IAAI;AAAA,MACpG;AAAA,IACF;AAAA,EACF,WAAW,QAAQ,OAAO,SAAS,UAAU;AAC3C,UAAM,UAAU,OAAO,QAAQ,IAA+B;AAC9D,UAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;AACzD,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,YAAM,UAAU,OAAO,UAAU,WAAW,KAAK,UAAU,KAAK,IAAI,OAAO,KAAK;AAChF,cAAQ,IAAI,GAAGA,IAAG,KAAK,IAAI,OAAO,MAAM,CAAC,CAAC,KAAK,OAAO,EAAE;AAAA,IAC1D;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,OAAO,IAAI,CAAC;AAAA,EAC1B;AACF;AAEO,SAAS,YAAY,MAAe,QAAsB;AAC/D,MAAI,WAAW,SAAS;AAEtB,QAAI,QAAQ,OAAO,SAAS,YAAY,UAAW,MAAkC;AACnF,YAAM,OAAO;AACb,iBAAW,KAAK,IAAI;AACpB,cAAQ,IAAIA,IAAG,IAAI;AAAA,EAAK,KAAK,SAAS,iBAAiB,KAAK,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;AACtF;AAAA,IACF;AACA,eAAW,IAAI;AAAA,EACjB,OAAO;AACL,cAAU,IAAI;AAAA,EAChB;AACF;AAEO,SAAS,WAAW,OAAsB;AAC/C,MAAI,SAAS,OAAO,UAAU,YAAY,aAAa,OAAO;AAC5D,UAAM,MAAM;AACZ,YAAQ,MAAMA,IAAG,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;AAC7C,QAAI,IAAI,KAAM,SAAQ,MAAMA,IAAG,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;AACvD,QAAI,IAAI,OAAQ,SAAQ,MAAMA,IAAG,IAAI,WAAW,IAAI,MAAM,EAAE,CAAC;AAC7D,QAAI,IAAI,WAAY,SAAQ,MAAMA,IAAG,OAAO,IAAI,UAAU,CAAC;AAAA,EAC7D,OAAO;AACL,YAAQ,MAAMA,IAAG,IAAI,OAAO,KAAK,CAAC,CAAC;AAAA,EACrC;AACF;;;AChEA,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,gBAAgB;AAEzB,SAAS,mBAAmB;;;ACH5B,OAAOC,SAAQ;AAER,SAAS,UAAU,OAAe,OAAwC;AAC/E,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,cAAQ,MAAMA,IAAG,IAAI,KAAK,KAAK,yBAAyB,CAAC;AACzD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,YAAQ,MAAMA,IAAG,IAAI,sBAAsB,KAAK,KAAK,KAAK,EAAE,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEO,SAAS,eAAe,OAAe,OAA0B;AACtE,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,cAAQ,MAAMA,IAAG,IAAI,KAAK,KAAK,wBAAwB,CAAC;AACxD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,YAAQ,MAAMA,IAAG,IAAI,sBAAsB,KAAK,KAAK,KAAK,EAAE,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;ADnBA,SAAS,eAAe,UAAoD;AAC1E,QAAM,SAASC,cAAa,QAAQ;AACpC,SAAO,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,UAAU,SAAS,QAAQ,EAAE;AAClE;AAEA,SAAS,mBAAmB,MAAsB;AAChD,MAAI,CAAE,YAAkC,SAAS,IAAI,GAAG;AACtD,UAAM,aAAa,KAAK,QAAQ,MAAM,EAAE,EAAE,YAAY;AACtD,UAAM,cAAc,YAAY,OAAO,CAAC,MAAM;AAC5C,YAAM,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,YAAY;AAC3C,aAAO,GAAG,WAAW,UAAU,KAAK,WAAW,WAAW,EAAE,KAAM,WAAW,UAAU,KAAK,GAAG,SAAS,UAAU;AAAA,IACpH,CAAC,EAAE,MAAM,GAAG,CAAC;AACb,UAAM,OAAO,YAAY,SAAS,IAC9B,iBAAiB,YAAY,KAAK,IAAI,CAAC,MACvC;AACJ,UAAM,IAAI,MAAM,uBAAuB,IAAI,MAAM,IAAI,EAAE;AAAA,EACzD;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAwC;AAC3D,SAAO,OAAO,YAAY,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;AACzE;AAEO,SAAS,qBAAqBC,UAAkBC,YAAiCC,YAAyB;AAC/G,EAAAF,SACG,QAAQ,oBAAoB,EAC5B,YAAY,mCAAmC,EAC/C,OAAO,kBAAkB,0BAA0B,EACnD,OAAO,eAAe,eAAe,CAAC,MAAc,SAAS,GAAG,EAAE,CAAC,EACnE,OAAO,cAAc,eAAe,CAAC,MAAc,SAAS,GAAG,EAAE,CAAC,EAClE,OAAO,kBAAkB,2CAA2C,EACpE,OAAO,eAAe,0CAA0C,CAAC,MAAc,SAAS,GAAG,EAAE,CAAC,EAC9F,OAAO,qBAAqB,kCAAkC,EAC9D,OAAO,OAAO,YAAoB,SAAS;AAC1C,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,UAAmC,CAAC;AAC1C,UAAI,KAAK,MAAO,SAAQ,QAAQ,UAAU,KAAK,OAAO,OAAO;AAC7D,UAAI,KAAK,MAAO,SAAQ,QAAQ,KAAK;AACrC,UAAI,KAAK,KAAM,SAAQ,OAAO,KAAK;AACnC,UAAI,KAAK,KAAM,SAAQ,OAAO,KAAK;AACnC,UAAI,KAAK,SAAS,KAAM,SAAQ,QAAQ,KAAK;AAC7C,UAAI,KAAK,OAAQ,SAAQ,SAAS,YAAY,KAAK,MAAM;AACzD,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,KAAK,OAAO;AAC5F,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAF,SACG,QAAQ,uBAAuB,EAC/B,YAAY,sBAAsB,EAClC,OAAO,eAAe,0CAA0C,CAAC,MAAc,SAAS,GAAG,EAAE,CAAC,EAC9F,OAAO,qBAAqB,kCAAkC,EAC9D,OAAO,OAAO,YAAoB,IAAY,SAAS;AACtD,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,UAAmC,CAAC;AAC1C,UAAI,KAAK,SAAS,KAAM,SAAQ,QAAQ,KAAK;AAC7C,UAAI,KAAK,OAAQ,SAAQ,SAAS,YAAY,KAAK,MAAM;AACzD,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,SAAS,IAAI,OAAO;AACpG,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAF,SACG,QAAQ,qBAAqB,EAC7B,YAAY,uBAAuB,EACnC,eAAe,iBAAiB,sBAAsB,EACtD,OAAO,iBAAiB,yCAAyC,EACjE,OAAO,OAAO,YAAoB,SAAS;AAC1C,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,OAAO,UAAU,KAAK,MAAM,MAAM;AACxC,UAAI;AACJ,UAAI,KAAK,MAAM;AACb,cAAM,EAAE,MAAM,SAAS,IAAI,eAAe,KAAK,IAAI;AACnD,mBAAW,EAAE,MAAM,MAAM,SAAS;AAAA,MACpC;AACA,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,OAAO,MAAM,QAAQ;AACrG,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAF,SACG,QAAQ,0BAA0B,EAClC,YAAY,yBAAyB,EACrC,eAAe,iBAAiB,sBAAsB,EACtD,OAAO,iBAAiB,yCAAyC,EACjE,OAAO,OAAO,YAAoB,IAAY,SAAS;AACtD,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,OAAO,UAAU,KAAK,MAAM,MAAM;AACxC,UAAI;AACJ,UAAI,KAAK,MAAM;AACb,cAAM,EAAE,MAAM,SAAS,IAAI,eAAe,KAAK,IAAI;AACnD,mBAAW,EAAE,MAAM,MAAM,SAAS;AAAA,MACpC;AACA,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,OAAO,IAAI,MAAM,QAAQ;AACzG,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAF,SACG,QAAQ,0BAA0B,EAClC,YAAY,yBAAyB,EACrC,OAAO,OAAO,YAAoB,OAAe;AAChD,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,OAAO,EAAE;AACzF,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAF,SACG,QAAQ,0BAA0B,EAClC,YAAY,6CAA6C,EACzD,eAAe,kBAAkB,0BAA0B,EAC3D,eAAe,iBAAiB,oBAAoB,EACpD,OAAO,OAAO,YAAoB,SAAS;AAC1C,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,QAAQ,UAAU,KAAK,OAAO,OAAO;AAC3C,YAAM,OAAO,UAAU,KAAK,MAAM,MAAM;AACxC,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,WAAW,OAAO,IAAI;AACtG,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAF,SACG,QAAQ,0BAA0B,EAClC,YAAY,6CAA6C,EACzD,eAAe,kBAAkB,0BAA0B,EAC3D,OAAO,OAAO,YAAoB,SAAS;AAC1C,QAAI;AACF,YAAM,MAAM,mBAAmB,UAAU;AACzC,YAAM,SAASC,WAAU;AACzB,YAAM,QAAQ,UAAU,KAAK,OAAO,OAAO;AAC3C,YAAM,SAAS,MAAM,OAAO,YAAY,KAAK,GAAiC,EAAE,WAAW,KAAK;AAChG,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;AE7KO,SAAS,sBAAsBC,UAAkBC,YAAiCC,YAAyB;AAChH,QAAM,QAAQF,SAAQ,QAAQ,OAAO,EAAE,YAAY,kBAAkB;AAErE,QACG,QAAQ,QAAQ,EAChB,YAAY,oBAAoB,EAChC,eAAe,qBAAqB,YAAY,EAChD,eAAe,wBAAwB,cAAc,EACrD,eAAe,mBAAmB,gBAAgB,EAClD,eAAe,6BAA6B,yBAAyB,EACrE,eAAe,qBAAqB,6BAA6B,EACjE,eAAe,sBAAsB,gBAAgB,UAAU,EAC/D,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,SAASC,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,YAAY;AAAA,QAC1C,WAAW,KAAK;AAAA,QAChB,aAAa,KAAK;AAAA,QAClB,OAAO,KAAK;AAAA,QACZ,iBAAiB,UAAU,KAAK,iBAAiB,kBAAkB;AAAA,QACnE,eAAe,eAAe,KAAK,UAAU,UAAU;AAAA,QACvD,aAAa,KAAK;AAAA,MACpB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,mBAAmB,EAC3B,YAAY,8BAA8B,EAC1C,OAAO,OAAO,gBAAwB;AACrC,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,SAAS,EAAE,YAAY,CAAC;AACxD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,sBAAsB,EAC9B,YAAY,qBAAqB,EACjC,eAAe,qBAAqB,YAAY,EAChD,OAAO,OAAO,aAAqB,SAAS;AAC3C,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,YAAY;AAAA,QAC1C;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,4BAA4B,EACxC,eAAe,kBAAkB,SAAS,EAC1C,eAAe,qBAAqB,YAAY,EAChD,eAAe,wBAAwB,cAAc,EACrD,eAAe,qBAAqB,0BAA0B,EAC9D,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,SAAS;AAAA,QACvC,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK;AAAA,QAChB,aAAa,KAAK;AAAA,QAClB,kBAAkB,UAAU,KAAK,UAAU,UAAU;AAAA,MACvD,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,uBAAuB,EAC/B,YAAY,mCAAmC,EAC/C,eAAe,kBAAkB,gCAAgC,EACjE,OAAO,oBAAoB,kBAAkB,EAC7C,OAAO,2BAA2B,iBAAiB,EACnD,OAAO,OAAO,aAAqB,SAAS;AAC3C,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,kBAAkB;AAAA,QAChD;AAAA,QACA,OAAO,eAAe,KAAK,OAAO,OAAO;AAAA,QACzC,SAAS,KAAK;AAAA,QACd,gBAAgB,KAAK;AAAA,MACvB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;AC1GO,SAAS,uBAAuBC,UAAkBC,YAAiCC,YAAyB;AACjH,QAAM,MAAMF,SAAQ,QAAQ,QAAQ,EAAE,YAAY,mBAAmB;AAErE,MACG,QAAQ,sBAAsB,EAC9B,YAAY,yBAAyB,EACrC,eAAe,qBAAqB,8BAA8B,EAClE,eAAe,uBAAuB,iBAAiB,UAAU,EACjE,OAAO,qBAAqB,2EAA2E,EACvG,OAAO,0BAA0B,iBAAiB,EAClD,OAAO,OAAO,aAAqB,SAAS;AAC3C,QAAI;AACF,YAAM,SAASC,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa;AAAA,QAC3C;AAAA,QACA,gBAAgB,eAAe,KAAK,UAAU,UAAU;AAAA,QACxD,cAAc,KAAK;AAAA,QACnB,QAAQ,KAAK;AAAA,QACb,cAAc,KAAK;AAAA,MACrB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,MACG,QAAQ,mBAAmB,EAC3B,YAAY,sBAAsB,EAClC,eAAe,qBAAqB,wDAAwD,EAC5F,OAAO,OAAO,UAAkB,SAAS;AACxC,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa;AAAA,QAC3C;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,MACG,QAAQ,sBAAsB,EAC9B,YAAY,oBAAoB,EAChC,eAAe,qBAAqB,8BAA8B,EAClE,eAAe,uBAAuB,iBAAiB,UAAU,EACjE,eAAe,qBAAqB,YAAY,EAChD,OAAO,qBAAqB,eAAe,EAC3C,OAAO,0BAA0B,iBAAiB,EAClD,OAAO,8BAA8B,oBAAoB,EACzD,OAAO,OAAO,aAAqB,SAAS;AAC3C,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,iBAAiB;AAAA,QAC/C;AAAA,QACA,gBAAgB,eAAe,KAAK,UAAU,UAAU;AAAA,QACxD,cAAc,KAAK;AAAA,QACnB,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,cAAc,KAAK;AAAA,QACnB,kBAAkB,KAAK;AAAA,MACzB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;ACzEO,SAAS,qBAAqBC,UAAkBC,YAAiCC,YAAyB;AAC/G,QAAM,OAAOF,SAAQ,QAAQ,MAAM,EAAE,YAAY,iBAAiB;AAElE,OACG,QAAQ,cAAc,EACtB,YAAY,qBAAqB,EACjC,eAAe,kBAAkB,YAAY,EAC7C,eAAe,kBAAkB,YAAY,EAC7C,eAAe,iBAAiB,WAAW,EAC3C,eAAe,kBAAkB,YAAY,CAAC,MAAc,SAAS,GAAG,EAAE,CAAC,EAC3E,OAAO,OAAO,QAAgB,SAAS;AACtC,QAAI;AACF,YAAM,SAASC,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,KAAK,QAAQ;AAAA,QACvC;AAAA,QACA,SAAS,KAAK;AAAA,QACd,SAAS,KAAK;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK;AAAA,MACjB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,qBAAqB,EAC7B,YAAY,2BAA2B,EACvC,eAAe,kBAAkB,gBAAgB,CAAC,MAAc,SAAS,GAAG,EAAE,CAAC,EAC/E,OAAO,OAAO,YAAoB,SAAS;AAC1C,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,KAAK,WAAW;AAAA,QAC1C;AAAA,QACA,UAAU,KAAK;AAAA,MACjB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,qBAAqB,EAC7B,YAAY,0BAA0B,EACtC,OAAO,OAAO,eAAuB;AACpC,QAAI;AACF,YAAM,SAASD,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,KAAK,WAAW,EAAE,WAAW,CAAC;AAC1D,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;ACzDO,SAAS,sBAAsBC,UAAkBC,YAAiCC,YAAyB;AAChH,QAAM,QAAQF,SAAQ,QAAQ,OAAO,EAAE,YAAY,kBAAkB;AAErE,QACG,QAAQ,OAAO,EACf,YAAY,0BAA0B,EACtC,eAAe,kBAAkB,uDAAuD,EACxF,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,SAASC,WAAU;AACzB,YAAM,QAAQ,eAAe,KAAK,OAAO,OAAO;AAChD,YAAM,SAAS,MAAM,OAAO,QAAQ,WAAW,EAAE,MAAM,CAAC;AACxD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;ACnBO,SAAS,4BAA4BC,UAAkBC,YAAiCC,YAAyB;AACtH,QAAM,KAAKF,SAAQ,QAAQ,aAAa,EAAE,YAAY,wBAAwB;AAE9E,KACG,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC,eAAe,qBAAqB,YAAY,EAChD,eAAe,qBAAqB,8CAA8C,EAClF,eAAe,6BAA6B,gBAAgB,EAC5D,eAAe,uBAAuB,aAAa,EACnD,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,SAASC,WAAU;AACzB,YAAM,SAAS,MAAM,OAAO,IAAI,kBAAkB;AAAA,QAChD,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,eAAe,KAAK;AAAA,QACpB,YAAY,KAAK;AAAA,MACnB,CAAC;AACD,kBAAY,QAAQC,WAAU,CAAC;AAAA,IACjC,SAAS,GAAG;AACV,iBAAW,CAAC;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;AC7BA,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,UAAU,YAAY;AAC/B,SAAS,gBAAgB;AACzB,SAAS,WAAW;AAEpB,OAAOC,SAAQ;AAcf,IAAM,UAAU,QAAQ,IAAI,oBAAoB;AAChD,IAAM,aAAa,IAAI,KAAK;AAE5B,SAAS,WAAW,GAAmB;AACrC,SAAO,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,QAAQ;AACpG;AAEA,SAAS,YAAY,KAAmB;AACtC,QAAM,KAAK,SAAS;AAEpB,QAAM,UAAU,MAAM;AACpB,YAAQ,IAAIC,IAAG,OAAO;AAAA,EAAkE,GAAG,EAAE,CAAC;AAAA,EAChG;AAEA,MAAI,OAAO,SAAS;AAClB,SAAK,aAAa,GAAG,KAAK,CAAC,QAAQ;AAAE,UAAI,IAAK,SAAQ;AAAA,IAAE,CAAC;AAAA,EAC3D,OAAO;AACL,UAAM,MAAM,OAAO,WAAW,SAAS;AACvC,aAAS,KAAK,CAAC,GAAG,GAAG,CAAC,QAAQ;AAAE,UAAI,IAAK,SAAQ;AAAA,IAAE,CAAC;AAAA,EACtD;AACF;AAEA,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWnB,IAAM,eAAe;AAAA;AAAA,SAEZ,UAAU;AAAA;AAGnB,IAAM,aAAa,CAAC,QAAgB;AAAA;AAAA,SAE3B,UAAU;AAAA,+FAC4E,WAAW,GAAG,CAAC;AAM9G,SAAS,gBAAgB,SAG2C;AAClE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,aAAa,CAAC,KAAK,QAAQ;AACxC,UAAI,CAAC,IAAI,KAAK;AACZ,YAAI,UAAU,GAAG,EAAE,IAAI;AACvB;AAAA,MACF;AAEA,YAAM,MAAM,IAAI,IAAI,IAAI,KAAK,kBAAkB;AAE/C,UAAI,IAAI,aAAa,aAAa;AAChC,YAAI,UAAU,GAAG,EAAE,IAAI;AACvB;AAAA,MACF;AAEA,YAAM,gBAAgB,IAAI,aAAa,IAAI,OAAO;AAClD,YAAM,YAAY,IAAI,aAAa,IAAI,WAAW;AAClD,YAAM,YAAY,IAAI,aAAa,IAAI,WAAW;AAClD,YAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,YAAM,gBAAgB,IAAI,aAAa,IAAI,UAAU;AACrD,YAAM,eAAe,IAAI,aAAa,IAAI,SAAS;AACnD,YAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAE1C,UAAI,OAAO;AACT,YAAI,UAAU,KAAK,EAAE,gBAAgB,2BAA2B,CAAC,EAAE,IAAI,WAAW,KAAK,CAAC;AACxF,gBAAQ,MAAMA,IAAG,IAAI,iBAAiB,KAAK,EAAE,CAAC;AAC9C,gBAAQ,CAAC;AACT;AAAA,MACF;AAEA,UAAI,kBAAkB,QAAQ,OAAO;AACnC,YAAI,UAAU,KAAK,EAAE,gBAAgB,2BAA2B,CAAC,EAAE,IAAI,WAAW,6CAAwC,CAAC;AAC3H,gBAAQ,MAAMA,IAAG,IAAI,+BAA+B,CAAC;AACrD,gBAAQ,CAAC;AACT;AAAA,MACF;AAEA,UAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ;AACvC,YAAI,UAAU,KAAK,EAAE,gBAAgB,2BAA2B,CAAC,EAAE,IAAI,WAAW,kCAAkC,CAAC;AACrH,gBAAQ,MAAMA,IAAG,IAAI,oCAAoC,CAAC;AAC1D,gBAAQ,CAAC;AACT;AAAA,MACF;AAGA,cAAQ,OAAO;AAAA,QACb;AAAA,QACA;AAAA,QACA,GAAI,gBAAgB,EAAE,UAAU,cAAc,IAAI,CAAC;AAAA,QACnD,YAAY;AAAA,MACd,CAAC;AAGD,UAAI,cAAc;AAChB,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,YAAY;AACtC,cAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,kBAAM,QAAQ,OAAO;AAAA,cACnB,CAAC,MAAuB,OAAO,GAAG,OAAO,YAAY,OAAO,GAAG,SAAS;AAAA,YAC1E;AACA,gBAAI,MAAM,SAAS,EAAG,gBAAe,KAAK;AAAA,UAC5C;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,UAAI,UAAU,KAAK,EAAE,gBAAgB,2BAA2B,CAAC,EAAE,IAAI,YAAY;AAEnF,cAAQ,IAAIA,IAAG,MAAM;AAAA,wBAA2B,CAAC;AACjD,cAAQ,IAAIA,IAAG,IAAI,WAAW,MAAM,EAAE,CAAC;AACvC,cAAQ,CAAC;AAAA,IACX,CAAC;AAED,QAAI;AACJ,QAAI,YAAY;AAEhB,aAAS,QAAQ,WAAW,GAAG;AAC7B,UAAI,UAAW;AACf,kBAAY;AACZ,mBAAa,OAAO;AACpB,aAAO,MAAM,MAAM,QAAQ,KAAK,QAAQ,CAAC;AAAA,IAC3C;AAEA,WAAO,OAAO,GAAG,aAAa,MAAM;AAClC,YAAM,OAAO,OAAO,QAAQ;AAC5B,UAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,eAAO,IAAI,MAAM,+BAA+B,CAAC;AACjD;AAAA,MACF;AAEA,gBAAU,WAAW,MAAM;AACzB,gBAAQ,MAAMA,IAAG,IAAI,kDAAkD,CAAC;AACxE,gBAAQ,CAAC;AAAA,MACX,GAAG,UAAU;AAEb,cAAQ,EAAE,MAAM,KAAK,MAAM,QAAQ,CAAC;AAAA,IACtC,CAAC;AAED,WAAO,GAAG,SAAS,CAAC,QAAQ;AAC1B,aAAO,GAAG;AAAA,IACZ,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,qBAAqBC,UAAwB;AAC3D,EAAAA,SACG,QAAQ,OAAO,EACf,YAAY,yCAAyC,EACrD,OAAO,YAAY;AAClB,UAAM,QAAQ,YAAY,EAAE,EAAE,SAAS,KAAK;AAE5C,QAAI;AACF,YAAM,EAAE,KAAK,IAAI,MAAM,gBAAgB;AAAA,QACrC;AAAA,QACA,QAAQ,CAAC,UAAU;AACjB,0BAAgB,KAAK;AACrB,kBAAQ,IAAID,IAAG,IAAI,wBAAwB,mBAAmB,CAAC,EAAE,CAAC;AAAA,QACpE;AAAA,MACF,CAAC;AAED,YAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,OAAO,IAAI,GAAG,MAAM,CAAC;AAChE,YAAM,WAAW,GAAG,OAAO,aAAa,OAAO,SAAS,CAAC;AAEzD,cAAQ,IAAIA,IAAG,IAAI,8BAA8B,CAAC;AAClD,cAAQ,IAAIA,IAAG,IAAI;AAAA,EAAyC,QAAQ,EAAE,CAAC;AACvE,kBAAY,QAAQ;AAAA,IACtB,SAAS,KAAK;AACZ,cAAQ,MAAMA,IAAG,IAAI,iBAAiB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE,CAAC;AACzF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,EAAAC,SACG,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC,OAAO,MAAM;AACZ,UAAM,UAAU,kBAAkB;AAClC,QAAI,SAAS;AACX,cAAQ,IAAID,IAAG,MAAM,kCAAkC,CAAC;AAAA,IAC1D,OAAO;AACL,cAAQ,IAAIA,IAAG,IAAI,8BAA8B,CAAC;AAAA,IACpD;AAAA,EACF,CAAC;AAEH,EAAAC,SACG,QAAQ,QAAQ,EAChB,YAAY,oCAAoC,EAChD,OAAO,MAAM;AAEZ,UAAM,aAAa,qBAAqB;AACxC,UAAM,cAAc,gBAAgB;AACpC,UAAM,QAAQ,cAAc;AAC5B,UAAM,UAAU,CAAC,CAAC;AAElB,QAAI,CAAC,OAAO;AACV,cAAQ,IAAID,IAAG,IAAI,gDAAgD,CAAC;AACpE;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,UAAU,SAAS,IACpC,MAAM,UAAU,MAAM,GAAG,CAAC,IAAI,QAAQ,MAAM,UAAU,MAAM,EAAE,IAC9D;AAEJ,UAAM,QAAQ,UAAUA,IAAG,KAAK,UAAU,IAAI;AAC9C,YAAQ,IAAI,eAAeA,IAAG,KAAK,MAAM,UAAU,CAAC,GAAG,KAAK,EAAE;AAC9D,YAAQ,IAAI,eAAeA,IAAG,IAAI,MAAM,CAAC,EAAE;AAC3C,YAAQ,IAAI,eAAeA,IAAG,IAAI,MAAM,QAAQ,CAAC,EAAE;AACnD,YAAQ,IAAI,eAAeA,IAAG,IAAI,UAAU,wBAAwB,IAAI,mBAAmB,CAAC,CAAC,EAAE;AAAA,EACjG,CAAC;AAKH,QAAM,SAASC,SACZ,QAAQ,QAAQ,EAChB,YAAY,yBAAyB;AAExC,SACG,QAAQ,MAAM,EACd,YAAY,yBAAyB,EACrC,OAAO,MAAM;AACZ,UAAM,UAAU,eAAe;AAC/B,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,cAAQ,IAAID,IAAG,IAAI,0CAA0C,CAAC;AAC9D;AAAA,IACF;AAGA,UAAM,aAAa,qBAAqB;AACxC,UAAM,cAAc,gBAAgB;AACpC,UAAM,cAAc,cAAc;AAClC,UAAM,WAAW,aAAa;AAC9B,UAAM,aAAa,aAAa;AAEhC,YAAQ,IAAIA,IAAG,KAAK,mBAAmB,CAAC;AACxC,eAAW,KAAK,SAAS;AACvB,YAAM,UAAU,WAAW,EAAE,OAAO,WAAW,EAAE,SAAS,cACtDA,IAAG,MAAM,IAAI,IACb;AACJ,cAAQ,IAAI,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE;AAAA,IACpC;AACA,YAAQ,IAAI;AACZ,QAAI,YAAY;AACd,YAAM,QAAQ,aAAa,YAAY;AACvC,cAAQ,IAAIA,IAAG,IAAI,YAAY,KAAK,EAAE,CAAC;AAAA,IACzC;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,YAAY,EACpB,YAAY,0CAA0C,EACtD,OAAO,WAAW,iDAAiD,EACnE,OAAO,OAAO,MAAc,SAA8B;AACzD,UAAM,UAAU,eAAe;AAC/B,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,cAAQ,MAAMA,IAAG,IAAI,0CAA0C,CAAC;AAChE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,KAAK,YAAY,CAAC;AAC7E,QAAI,CAAC,OAAO;AACV,cAAQ,MAAMA,IAAG,IAAI,WAAW,IAAI,uBAAuB,CAAC;AAC5D,cAAQ,MAAMA,IAAG,IAAI,cAAc,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAC3E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,QAAQ,YAAY,EAAE,EAAE,SAAS,KAAK;AAC5C,UAAM,UAAU,CAAC,CAAC,KAAK;AAEvB,QAAI;AACF,YAAM,EAAE,KAAK,IAAI,MAAM,gBAAgB;AAAA,QACrC;AAAA,QACA,QAAQ,CAAC,UAAU;AACjB,cAAI,SAAS;AACX,iCAAqB,KAAK;AAC1B,oBAAQ,IAAIA,IAAG,IAAI,wBAAwB,wBAAwB,CAAC,EAAE,CAAC;AAAA,UACzE,OAAO;AACL,4BAAgB,KAAK;AACrB,oBAAQ,IAAIA,IAAG,IAAI,wBAAwB,mBAAmB,CAAC,EAAE,CAAC;AAAA,UACpE;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,SAAS,IAAI,gBAAgB;AAAA,QACjC,MAAM,OAAO,IAAI;AAAA,QACjB;AAAA,QACA,UAAU,MAAM;AAAA,MAClB,CAAC;AACD,YAAM,WAAW,GAAG,OAAO,aAAa,OAAO,SAAS,CAAC;AAEzD,cAAQ,IAAIA,IAAG,IAAI,wBAAwB,MAAM,IAAI,MAAM,CAAC;AAC5D,cAAQ,IAAIA,IAAG,IAAI;AAAA,EAAyC,QAAQ,EAAE,CAAC;AACvE,kBAAY,QAAQ;AAAA,IACtB,SAAS,KAAK;AACZ,cAAQ,MAAMA,IAAG,IAAI,iBAAiB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE,CAAC;AACzF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;;;AX7TA,IAAME,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,QAAQ,GAAG,sBAAsB,CAAC,QAAQ;AACxC,aAAW,GAAG;AACd,UAAQ,KAAK,CAAC;AAChB,CAAC;AAED,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,IAAI,EACT,YAAY,kCAAkC,EAC9C,QAAQ,OAAO,EACf,OAAO,sBAAsB,8CAA8C,EAC3E,OAAO,qBAAqB,0CAA0C,MAAM;AAE/E,IAAM,YAAY,MAAM,QAAQ,KAAK,EAAE;AACvC,IAAM,YAAY,MAAM,cAAc,QAAQ,KAAK,EAAE,MAA4B;AAEjF,qBAAqB,SAAS,WAAW,SAAS;AAClD,sBAAsB,SAAS,WAAW,SAAS;AACnD,uBAAuB,SAAS,WAAW,SAAS;AACpD,qBAAqB,SAAS,WAAW,SAAS;AAClD,sBAAsB,SAAS,WAAW,SAAS;AACnD,4BAA4B,SAAS,WAAW,SAAS;AACzD,qBAAqB,OAAO;AAE5B,QAAQ,MAAM;","names":["pc","readFileSync","pc","readFileSync","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","program","getClient","getFormat","pc","pc","program","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@01.software/cli",
3
- "version": "0.1.1",
3
+ "version": "0.2.0-dev.260306.4e16dd4",
4
4
  "description": "CLI tool for 01.software platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,7 +15,7 @@
15
15
  "dependencies": {
16
16
  "commander": "^14.0.3",
17
17
  "picocolors": "^1.1.1",
18
- "@01.software/sdk": "0.2.8"
18
+ "@01.software/sdk": "0.2.9-dev.260306.4e16dd4"
19
19
  },
20
20
  "devDependencies": {
21
21
  "tsup": "^8.5.0",