@tarileo/avileo-catalog-cli 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -14675,6 +14675,7 @@ var AgentHttpClient = class {
14675
14675
  headers: {
14676
14676
  ...formData || options.body === void 0 ? {} : { "content-type": "application/json" },
14677
14677
  ...operationId ? { "idempotency-key": operationId } : {},
14678
+ ...options.approvalId ? { "x-avileo-approval-id": options.approvalId } : {},
14678
14679
  ...this.#apiKey ? { "x-avileo-agent-key": this.#apiKey } : {}
14679
14680
  },
14680
14681
  body,
@@ -14731,6 +14732,8 @@ var AGENT_CAPABILITY_ACTIONS = [
14731
14732
  "inventory:write"
14732
14733
  ];
14733
14734
  var AgentCapabilityActionSchema = external_exports.enum(AGENT_CAPABILITY_ACTIONS);
14735
+ var AGENT_KEY_MODES = ["read", "mutate"];
14736
+ var AgentKeyModeSchema = external_exports.enum(AGENT_KEY_MODES);
14734
14737
  var AGENT_CATALOG_KEY_PRESET_ACTIONS = [
14735
14738
  "business:read",
14736
14739
  "catalog:read",
@@ -14909,7 +14912,7 @@ var AgentStorefrontDtoSchema = external_exports.object({
14909
14912
  }).strict();
14910
14913
  var AgentBusinessDtoSchema = external_exports.object({
14911
14914
  name: nonEmptyTextSchema.max(255),
14912
- businessMode: external_exports.literal("tienda"),
14915
+ businessMode: external_exports.string().trim().min(1).max(50),
14913
14916
  currency: external_exports.string().trim().length(3),
14914
14917
  isActive: external_exports.literal(true),
14915
14918
  tenantState: external_exports.literal("active"),
@@ -15140,14 +15143,96 @@ var AgentCatalogImportResultDtoSchema = external_exports.object({
15140
15143
  updatedAt: timestampSchema,
15141
15144
  completedAt: timestampSchema.nullable()
15142
15145
  }).strict();
15146
+ var AGENT_OPERATION_NAMES = [
15147
+ "catalog.products.create",
15148
+ "catalog.products.update",
15149
+ "catalog.products.deactivate",
15150
+ "catalog.variants.create",
15151
+ "catalog.variants.reorder",
15152
+ "catalog.variants.update",
15153
+ "catalog.variants.deactivate",
15154
+ "catalog.categories.create",
15155
+ "catalog.categories.update",
15156
+ "catalog.categories.delete",
15157
+ "catalog.tags.create",
15158
+ "catalog.tags.update",
15159
+ "catalog.tags.delete",
15160
+ "catalog.assets.upload",
15161
+ "catalog.assets.import",
15162
+ "catalog.inventory.adjust",
15163
+ "catalog.inventory.set",
15164
+ "catalog.imports.preview",
15165
+ "catalog.imports.apply",
15166
+ "business.profile.update",
15167
+ "catalog.client_keys.create"
15168
+ ];
15169
+ var AgentOperationNameSchema = external_exports.enum(AGENT_OPERATION_NAMES);
15170
+ var AGENT_OPERATION_STATES = [
15171
+ "awaiting_approval",
15172
+ "approved",
15173
+ "rejected",
15174
+ "succeeded",
15175
+ "failed",
15176
+ "expired",
15177
+ "conflict"
15178
+ ];
15179
+ var AgentOperationStateSchema = external_exports.enum(AGENT_OPERATION_STATES);
15180
+ var AgentOperationProposalInputSchema = external_exports.object({
15181
+ operationName: AgentOperationNameSchema,
15182
+ payload: external_exports.record(external_exports.string(), external_exports.unknown())
15183
+ }).strict();
15184
+ var AgentOperationProposalDtoSchema = external_exports.object({
15185
+ id: uuidSchema,
15186
+ operationName: AgentOperationNameSchema,
15187
+ state: external_exports.literal("awaiting_approval"),
15188
+ input: external_exports.record(external_exports.string(), external_exports.unknown()),
15189
+ summary: nonEmptyTextSchema.max(500),
15190
+ diff: external_exports.record(external_exports.string(), external_exports.unknown()),
15191
+ approvalUrl: external_exports.string().url(),
15192
+ createdAt: timestampSchema,
15193
+ expiresAt: timestampSchema
15194
+ }).strict();
15195
+ var AgentOperationStatusDtoSchema = external_exports.object({
15196
+ id: uuidSchema,
15197
+ operationName: AgentOperationNameSchema,
15198
+ state: AgentOperationStateSchema,
15199
+ input: external_exports.record(external_exports.string(), external_exports.unknown()),
15200
+ summary: nonEmptyTextSchema.max(500),
15201
+ diff: external_exports.record(external_exports.string(), external_exports.unknown()),
15202
+ approvalUrl: external_exports.string().url(),
15203
+ result: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
15204
+ error: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
15205
+ approvedAt: timestampSchema.nullable(),
15206
+ rejectedAt: timestampSchema.nullable(),
15207
+ completedAt: timestampSchema.nullable(),
15208
+ createdAt: timestampSchema,
15209
+ updatedAt: timestampSchema,
15210
+ expiresAt: timestampSchema
15211
+ }).strict();
15212
+ var AgentOperationProposalEnvelopeSchema = external_exports.object({
15213
+ success: external_exports.literal(true),
15214
+ data: AgentOperationProposalDtoSchema
15215
+ }).strict();
15216
+ var AgentOperationStatusEnvelopeSchema = external_exports.object({
15217
+ success: external_exports.literal(true),
15218
+ data: AgentOperationStatusDtoSchema
15219
+ }).strict();
15220
+ var AgentOperationApplyEnvelopeSchema = external_exports.object({
15221
+ success: external_exports.literal(true),
15222
+ data: external_exports.record(external_exports.string(), external_exports.unknown())
15223
+ }).strict();
15143
15224
  var AGENT_DEVICE_AUTH_STATUSES = ["pending", "approved", "denied", "expired"];
15144
- var AGENT_DEVICE_AUTH_DEFAULT_PERMISSIONS = [...AGENT_CATALOG_KEY_PRESET_ACTIONS];
15225
+ var AGENT_DEVICE_AUTH_DEFAULT_PERMISSIONS = [
15226
+ ...AGENT_CATALOG_KEY_PRESET_ACTIONS
15227
+ ];
15145
15228
  function parsePollResponse(value) {
15146
15229
  if (!AGENT_DEVICE_AUTH_STATUSES.includes(value.status)) {
15147
15230
  throw new Error("La API de Avileo devolvi\xF3 un estado de autorizaci\xF3n inv\xE1lido");
15148
15231
  }
15149
15232
  if (value.permissions) {
15150
- const parsed = value.permissions.map((permission) => AgentCapabilityActionSchema.parse(permission));
15233
+ const parsed = value.permissions.map(
15234
+ (permission) => AgentCapabilityActionSchema.parse(permission)
15235
+ );
15151
15236
  return { ...value, permissions: parsed };
15152
15237
  }
15153
15238
  return value;
@@ -15165,10 +15250,13 @@ var AvileoAgentDeviceAuthClient = class {
15165
15250
  }
15166
15251
  async poll(deviceCode) {
15167
15252
  if (!deviceCode.trim()) throw new Error("deviceCode es obligatorio");
15168
- const result = await this.http.request("/api/v1/agent-auth/device/poll", {
15169
- method: "POST",
15170
- body: { deviceCode }
15171
- });
15253
+ const result = await this.http.request(
15254
+ "/api/v1/agent-auth/device/poll",
15255
+ {
15256
+ method: "POST",
15257
+ body: { deviceCode }
15258
+ }
15259
+ );
15172
15260
  return parsePollResponse(result);
15173
15261
  }
15174
15262
  };
@@ -15191,6 +15279,9 @@ var AgentBusinessResource = class {
15191
15279
  get() {
15192
15280
  return this.http.request("/api/v1/agent/business");
15193
15281
  }
15282
+ profile() {
15283
+ return this.http.request("/api/v1/agent/business/profile");
15284
+ }
15194
15285
  };
15195
15286
  var AgentProductsResource = class {
15196
15287
  constructor(http) {
@@ -15203,24 +15294,26 @@ var AgentProductsResource = class {
15203
15294
  get(productId) {
15204
15295
  return this.http.request(`/api/v1/agent/catalog/products/${encodeURIComponent(productId)}`);
15205
15296
  }
15206
- create(input) {
15297
+ create(input, approvalId) {
15207
15298
  return this.http.request("/api/v1/agent/catalog/products", {
15208
15299
  method: "POST",
15209
15300
  body: input,
15210
- mutation: true
15301
+ mutation: true,
15302
+ approvalId
15211
15303
  });
15212
15304
  }
15213
- update(productId, input) {
15305
+ update(productId, input, approvalId) {
15214
15306
  return this.http.request(`/api/v1/agent/catalog/products/${encodeURIComponent(productId)}`, {
15215
15307
  method: "PATCH",
15216
15308
  body: input,
15217
- mutation: true
15309
+ mutation: true,
15310
+ approvalId
15218
15311
  });
15219
15312
  }
15220
- deactivate(productId) {
15313
+ deactivate(productId, approvalId) {
15221
15314
  return this.http.request(
15222
15315
  `/api/v1/agent/catalog/products/${encodeURIComponent(productId)}/deactivate`,
15223
- { method: "POST", mutation: true }
15316
+ { method: "POST", mutation: true, approvalId }
15224
15317
  );
15225
15318
  }
15226
15319
  };
@@ -15237,29 +15330,30 @@ var AgentVariantsResource = class {
15237
15330
  get(variantId) {
15238
15331
  return this.http.request(`/api/v1/agent/catalog/variants/${encodeURIComponent(variantId)}`);
15239
15332
  }
15240
- create(productId, input) {
15333
+ create(productId, input, approvalId) {
15241
15334
  return this.http.request(
15242
15335
  `/api/v1/agent/catalog/products/${encodeURIComponent(productId)}/variants`,
15243
- { method: "POST", body: input, mutation: true }
15336
+ { method: "POST", body: input, mutation: true, approvalId }
15244
15337
  );
15245
15338
  }
15246
- update(variantId, input) {
15339
+ update(variantId, input, approvalId) {
15247
15340
  return this.http.request(`/api/v1/agent/catalog/variants/${encodeURIComponent(variantId)}`, {
15248
15341
  method: "PATCH",
15249
15342
  body: input,
15250
- mutation: true
15343
+ mutation: true,
15344
+ approvalId
15251
15345
  });
15252
15346
  }
15253
- deactivate(variantId) {
15347
+ deactivate(variantId, approvalId) {
15254
15348
  return this.http.request(
15255
15349
  `/api/v1/agent/catalog/variants/${encodeURIComponent(variantId)}/deactivate`,
15256
- { method: "POST", mutation: true }
15350
+ { method: "POST", mutation: true, approvalId }
15257
15351
  );
15258
15352
  }
15259
- reorder(productId, input) {
15353
+ reorder(productId, input, approvalId) {
15260
15354
  return this.http.request(
15261
15355
  `/api/v1/agent/catalog/products/${encodeURIComponent(productId)}/variants/reorder`,
15262
- { method: "POST", body: input, mutation: true }
15356
+ { method: "POST", body: input, mutation: true, approvalId }
15263
15357
  );
15264
15358
  }
15265
15359
  };
@@ -15274,24 +15368,27 @@ var AgentCategoriesResource = class {
15274
15368
  get(categoryId) {
15275
15369
  return this.http.request(`/api/v1/agent/catalog/categories/${encodeURIComponent(categoryId)}`);
15276
15370
  }
15277
- create(input) {
15371
+ create(input, approvalId) {
15278
15372
  return this.http.request("/api/v1/agent/catalog/categories", {
15279
15373
  method: "POST",
15280
15374
  body: input,
15281
- mutation: true
15375
+ mutation: true,
15376
+ approvalId
15282
15377
  });
15283
15378
  }
15284
- update(categoryId, input) {
15379
+ update(categoryId, input, approvalId) {
15285
15380
  return this.http.request(`/api/v1/agent/catalog/categories/${encodeURIComponent(categoryId)}`, {
15286
15381
  method: "PATCH",
15287
15382
  body: input,
15288
- mutation: true
15383
+ mutation: true,
15384
+ approvalId
15289
15385
  });
15290
15386
  }
15291
- delete(categoryId) {
15387
+ delete(categoryId, approvalId) {
15292
15388
  return this.http.request(`/api/v1/agent/catalog/categories/${encodeURIComponent(categoryId)}`, {
15293
15389
  method: "DELETE",
15294
- mutation: true
15390
+ mutation: true,
15391
+ approvalId
15295
15392
  });
15296
15393
  }
15297
15394
  };
@@ -15306,24 +15403,27 @@ var AgentTagsResource = class {
15306
15403
  get(tagId) {
15307
15404
  return this.http.request(`/api/v1/agent/catalog/tags/${encodeURIComponent(tagId)}`);
15308
15405
  }
15309
- create(input) {
15406
+ create(input, approvalId) {
15310
15407
  return this.http.request("/api/v1/agent/catalog/tags", {
15311
15408
  method: "POST",
15312
15409
  body: input,
15313
- mutation: true
15410
+ mutation: true,
15411
+ approvalId
15314
15412
  });
15315
15413
  }
15316
- update(tagId, input) {
15414
+ update(tagId, input, approvalId) {
15317
15415
  return this.http.request(`/api/v1/agent/catalog/tags/${encodeURIComponent(tagId)}`, {
15318
15416
  method: "PATCH",
15319
15417
  body: input,
15320
- mutation: true
15418
+ mutation: true,
15419
+ approvalId
15321
15420
  });
15322
15421
  }
15323
- delete(tagId) {
15422
+ delete(tagId, approvalId) {
15324
15423
  return this.http.request(`/api/v1/agent/catalog/tags/${encodeURIComponent(tagId)}`, {
15325
15424
  method: "DELETE",
15326
- mutation: true
15425
+ mutation: true,
15426
+ approvalId
15327
15427
  });
15328
15428
  }
15329
15429
  };
@@ -15338,20 +15438,22 @@ var AgentAssetsResource = class {
15338
15438
  get(assetId) {
15339
15439
  return this.http.request(`/api/v1/agent/catalog/assets/${encodeURIComponent(assetId)}`);
15340
15440
  }
15341
- upload(file2) {
15441
+ upload(file2, approvalId) {
15342
15442
  const body = new FormData();
15343
15443
  body.set("file", file2);
15344
15444
  return this.http.request("/api/v1/agent/catalog/assets/upload", {
15345
15445
  method: "POST",
15346
15446
  body,
15347
- mutation: true
15447
+ mutation: true,
15448
+ approvalId
15348
15449
  });
15349
15450
  }
15350
- importFromUrl(input) {
15451
+ importFromUrl(input, approvalId) {
15351
15452
  return this.http.request("/api/v1/agent/catalog/assets/import", {
15352
15453
  method: "POST",
15353
15454
  body: input,
15354
- mutation: true
15455
+ mutation: true,
15456
+ approvalId
15355
15457
  });
15356
15458
  }
15357
15459
  };
@@ -15370,16 +15472,16 @@ var AgentInventoryResource = class {
15370
15472
  `/api/v1/agent/catalog/variants/${encodeURIComponent(variantId)}/inventory/movements${queryString(filters)}`
15371
15473
  );
15372
15474
  }
15373
- adjust(variantId, input) {
15475
+ adjust(variantId, input, approvalId) {
15374
15476
  return this.http.request(
15375
15477
  `/api/v1/agent/catalog/variants/${encodeURIComponent(variantId)}/inventory/adjust`,
15376
- { method: "POST", body: input, mutation: true }
15478
+ { method: "POST", body: input, mutation: true, approvalId }
15377
15479
  );
15378
15480
  }
15379
- set(variantId, input) {
15481
+ set(variantId, input, approvalId) {
15380
15482
  return this.http.request(
15381
15483
  `/api/v1/agent/catalog/variants/${encodeURIComponent(variantId)}/inventory`,
15382
- { method: "PUT", body: input, mutation: true }
15484
+ { method: "PUT", body: input, mutation: true, approvalId }
15383
15485
  );
15384
15486
  }
15385
15487
  };
@@ -15395,20 +15497,54 @@ var AgentImportsResource = class {
15395
15497
  mutation: true
15396
15498
  });
15397
15499
  }
15398
- apply(importId) {
15399
- return this.http.request(`/api/v1/agent/catalog/imports/${encodeURIComponent(importId)}/apply`, {
15500
+ apply(importId, approvalId) {
15501
+ return this.http.request(
15502
+ `/api/v1/agent/catalog/imports/${encodeURIComponent(importId)}/apply`,
15503
+ {
15504
+ method: "POST",
15505
+ mutation: true,
15506
+ approvalId
15507
+ }
15508
+ );
15509
+ }
15510
+ get(importId) {
15511
+ return this.http.request(`/api/v1/agent/catalog/imports/${encodeURIComponent(importId)}`);
15512
+ }
15513
+ };
15514
+ var AgentOperationsResource = class {
15515
+ constructor(http) {
15516
+ this.http = http;
15517
+ }
15518
+ http;
15519
+ propose(input) {
15520
+ return this.http.request("/api/v1/agent/operations", {
15400
15521
  method: "POST",
15522
+ body: input,
15401
15523
  mutation: true
15402
15524
  });
15403
15525
  }
15404
- get(importId) {
15405
- return this.http.request(`/api/v1/agent/catalog/imports/${encodeURIComponent(importId)}`);
15526
+ proposeClientKey(name) {
15527
+ return this.propose({
15528
+ operationName: "catalog.client_keys.create",
15529
+ payload: name === void 0 ? {} : { name }
15530
+ });
15531
+ }
15532
+ get(operationId) {
15533
+ return this.http.request(`/api/v1/agent/operations/${encodeURIComponent(operationId)}`);
15534
+ }
15535
+ apply(operationId) {
15536
+ return this.http.request(`/api/v1/agent/operations/${encodeURIComponent(operationId)}/apply`, {
15537
+ method: "POST",
15538
+ mutation: true,
15539
+ approvalId: operationId
15540
+ });
15406
15541
  }
15407
15542
  };
15408
15543
  function createAvileoAgent(config2) {
15409
15544
  const http = new AgentHttpClient(config2);
15410
15545
  return {
15411
15546
  business: new AgentBusinessResource(http),
15547
+ operations: new AgentOperationsResource(http),
15412
15548
  products: new AgentProductsResource(http),
15413
15549
  variants: new AgentVariantsResource(http),
15414
15550
  categories: new AgentCategoriesResource(http),
@@ -15554,7 +15690,8 @@ function emitFailure(failure) {
15554
15690
  function exitCodeFor(error51) {
15555
15691
  const candidate = error51;
15556
15692
  if (candidate.retryable) return 2;
15557
- if (candidate.status === 409 || /CONFLICT|IDEMPOTENCY|VERSION/.test(candidate.code ?? "")) return 4;
15693
+ if (candidate.status === 409 || /CONFLICT|IDEMPOTENCY|VERSION/.test(candidate.code ?? ""))
15694
+ return 4;
15558
15695
  if (candidate.status === 401 || candidate.status === 403 || candidate.status === 422 || /AUTH|PERMISSION|VALIDATION|UNSUPPORTED|QUOTA|POLICY/.test(candidate.code ?? "")) {
15559
15696
  return 3;
15560
15697
  }
@@ -15576,7 +15713,7 @@ function redact(value) {
15576
15713
  return Object.fromEntries(
15577
15714
  Object.entries(value).map(([key, item]) => [
15578
15715
  key,
15579
- /(?:api.?key|authorization|secret|token|password)/i.test(key) ? "[REDACTED]" : redact(item)
15716
+ /(?:agent.?key|api.?key|authorization|secret|token|password)/i.test(key) ? "[REDACTED]" : redact(item)
15580
15717
  ])
15581
15718
  );
15582
15719
  }
@@ -15592,8 +15729,9 @@ function registerBusinessCommands(root, getClient) {
15592
15729
  }
15593
15730
 
15594
15731
  // src/commands/catalog.ts
15595
- import { basename } from "path";
15732
+ import { createHash } from "crypto";
15596
15733
  import { readFile, stat } from "fs/promises";
15734
+ import { basename, extname } from "path";
15597
15735
  function requireId(value, name) {
15598
15736
  if (!value.trim()) throw new CliProtocolError("CLI_VALIDATION_ERROR", `${name} es obligatorio`);
15599
15737
  return value;
@@ -15634,7 +15772,7 @@ function normalizeInput(value) {
15634
15772
  }
15635
15773
  function withMutationOptions(command, includeFrom = true) {
15636
15774
  if (includeFrom) command.requiredOption("--from <json-file>", "Objeto JSON estructurado");
15637
- return command.option("--apply", "Ejecuta la mutaci\xF3n despu\xE9s de validarla localmente");
15775
+ return command.option("--apply", "Solicita aprobaci\xF3n o ejecuta una mutaci\xF3n aprobada").option("--approval-id <uuid>", "Aprobaci\xF3n emitida por Avileo");
15638
15776
  }
15639
15777
  function wantsApply(command) {
15640
15778
  return Boolean(command.optsWithGlobals().apply);
@@ -15652,7 +15790,8 @@ function addListOptions(command) {
15652
15790
  }
15653
15791
  function parseInteger(value) {
15654
15792
  const result = Number(value);
15655
- if (!Number.isInteger(result) || result < 0) throw new CliProtocolError("CLI_VALIDATION_ERROR", "Se esperaba un entero no negativo");
15793
+ if (!Number.isInteger(result) || result < 0)
15794
+ throw new CliProtocolError("CLI_VALIDATION_ERROR", "Se esperaba un entero no negativo");
15656
15795
  return result;
15657
15796
  }
15658
15797
  function parseBoolean(value) {
@@ -15660,12 +15799,17 @@ function parseBoolean(value) {
15660
15799
  if (value === "false") return false;
15661
15800
  throw new CliProtocolError("CLI_VALIDATION_ERROR", "Se esperaba true o false");
15662
15801
  }
15663
- async function applyOrPreview(command, input, run, current) {
15664
- if (wantsApply(command)) {
15665
- emitSuccess(await run());
15802
+ async function applyOrPreview(command, input, getClient, operationName, payload, run, current) {
15803
+ if (!wantsApply(command)) {
15804
+ emitSuccess(localResult(input, current ? await current() : void 0));
15666
15805
  return;
15667
15806
  }
15668
- emitSuccess(localResult(input, current ? await current() : void 0));
15807
+ const rawApprovalId = command.optsWithGlobals().approvalId;
15808
+ if (typeof rawApprovalId === "string") {
15809
+ emitSuccess(await run(requireId(rawApprovalId, "approvalId")));
15810
+ return;
15811
+ }
15812
+ emitSuccess(await getClient().operations.propose({ operationName, payload }));
15669
15813
  }
15670
15814
  function registerCatalogCommands(root, getClient) {
15671
15815
  const catalog = root.command("catalog").description("Gestiona recursos de cat\xE1logo de Avileo");
@@ -15680,165 +15824,363 @@ function registerCatalogCommands(root, getClient) {
15680
15824
  function registerProductCommands(catalog, getClient) {
15681
15825
  const product = catalog.command("product");
15682
15826
  addListOptions(product.command("list")).action(async (options) => {
15683
- const { active: isActive, categoryId, ...filters } = options;
15684
- emitSuccess(await getClient().products.list({ ...filters, ...categoryId ? { categoryId } : {}, ...isActive === void 0 ? {} : { isActive } }));
15827
+ const {
15828
+ active: isActive,
15829
+ categoryId,
15830
+ ...filters
15831
+ } = options;
15832
+ emitSuccess(
15833
+ await getClient().products.list({
15834
+ ...filters,
15835
+ ...categoryId ? { categoryId } : {},
15836
+ ...isActive === void 0 ? {} : { isActive }
15837
+ })
15838
+ );
15685
15839
  });
15686
- product.command("get <productId>").action(async (productId) => emitSuccess(await getClient().products.get(requireId(productId, "productId"))));
15687
- withMutationOptions(product.command("create")).action(async (options, command) => {
15688
- const input = await readMutationInput(options.from);
15689
- await applyOrPreview(command, input, () => getClient().products.create(input));
15840
+ product.command("get <productId>").action(async (productId) => {
15841
+ emitSuccess(await getClient().products.get(requireId(productId, "productId")));
15690
15842
  });
15691
- withMutationOptions(product.command("update <productId>")).action(async (productId, options, command) => {
15692
- const id = requireId(productId, "productId");
15843
+ withMutationOptions(product.command("create")).action(async (options, command) => {
15693
15844
  const input = await readMutationInput(options.from);
15694
- await applyOrPreview(command, input, () => getClient().products.update(id, input), () => getClient().products.get(id));
15695
- });
15696
- withMutationOptions(product.command("deactivate <productId>"), false).action(async (productId, _options, command) => {
15697
- const id = requireId(productId, "productId");
15698
- const input = { isActive: false };
15699
- await applyOrPreview(command, input, () => getClient().products.deactivate(id), () => getClient().products.get(id));
15845
+ await applyOrPreview(
15846
+ command,
15847
+ input,
15848
+ getClient,
15849
+ "catalog.products.create",
15850
+ { body: input },
15851
+ (approvalId) => getClient().products.create(input, approvalId)
15852
+ );
15700
15853
  });
15854
+ withMutationOptions(product.command("update <productId>")).action(
15855
+ async (productId, options, command) => {
15856
+ const id = requireId(productId, "productId");
15857
+ const input = await readMutationInput(options.from);
15858
+ await applyOrPreview(
15859
+ command,
15860
+ input,
15861
+ getClient,
15862
+ "catalog.products.update",
15863
+ { productId: id, body: input },
15864
+ (approvalId) => getClient().products.update(id, input, approvalId),
15865
+ () => getClient().products.get(id)
15866
+ );
15867
+ }
15868
+ );
15869
+ withMutationOptions(product.command("deactivate <productId>"), false).action(
15870
+ async (productId, _options, command) => {
15871
+ const id = requireId(productId, "productId");
15872
+ await applyOrPreview(
15873
+ command,
15874
+ { isActive: false },
15875
+ getClient,
15876
+ "catalog.products.deactivate",
15877
+ { productId: id },
15878
+ (approvalId) => getClient().products.deactivate(id, approvalId),
15879
+ () => getClient().products.get(id)
15880
+ );
15881
+ }
15882
+ );
15701
15883
  }
15702
15884
  function registerVariantCommands(catalog, getClient) {
15703
15885
  const variant = catalog.command("variant");
15704
- variant.command("list <productId>").action(async (productId) => emitSuccess(await getClient().variants.list(requireId(productId, "productId"))));
15705
- variant.command("get <variantId>").action(async (variantId) => emitSuccess(await getClient().variants.get(requireId(variantId, "variantId"))));
15706
- withMutationOptions(variant.command("create <productId>")).action(async (productId, options, command) => {
15707
- const input = await readMutationInput(options.from);
15708
- await applyOrPreview(command, input, () => getClient().variants.create(requireId(productId, "productId"), input));
15709
- });
15710
- withMutationOptions(variant.command("update <variantId>")).action(async (variantId, options, command) => {
15711
- const id = requireId(variantId, "variantId");
15712
- const input = await readMutationInput(options.from);
15713
- await applyOrPreview(command, input, () => getClient().variants.update(id, input), () => getClient().variants.get(id));
15714
- });
15715
- withMutationOptions(variant.command("deactivate <variantId>"), false).action(async (variantId, _options, command) => {
15716
- const id = requireId(variantId, "variantId");
15717
- const input = { isActive: false };
15718
- await applyOrPreview(command, input, () => getClient().variants.deactivate(id), () => getClient().variants.get(id));
15719
- });
15720
- withMutationOptions(variant.command("reorder <productId>")).action(async (productId, options, command) => {
15721
- const id = requireId(productId, "productId");
15722
- const input = await readMutationInput(options.from);
15723
- await applyOrPreview(command, input, () => getClient().variants.reorder(id, input), () => getClient().variants.list(id));
15724
- });
15886
+ variant.command("list <productId>").action(async (productId) => {
15887
+ emitSuccess(await getClient().variants.list(requireId(productId, "productId")));
15888
+ });
15889
+ variant.command("get <variantId>").action(async (variantId) => {
15890
+ emitSuccess(await getClient().variants.get(requireId(variantId, "variantId")));
15891
+ });
15892
+ withMutationOptions(variant.command("create <productId>")).action(
15893
+ async (productId, options, command) => {
15894
+ const id = requireId(productId, "productId");
15895
+ const input = await readMutationInput(options.from);
15896
+ await applyOrPreview(
15897
+ command,
15898
+ input,
15899
+ getClient,
15900
+ "catalog.variants.create",
15901
+ { productId: id, body: input },
15902
+ (approvalId) => getClient().variants.create(id, input, approvalId)
15903
+ );
15904
+ }
15905
+ );
15906
+ withMutationOptions(variant.command("update <variantId>")).action(
15907
+ async (variantId, options, command) => {
15908
+ const id = requireId(variantId, "variantId");
15909
+ const input = await readMutationInput(options.from);
15910
+ await applyOrPreview(
15911
+ command,
15912
+ input,
15913
+ getClient,
15914
+ "catalog.variants.update",
15915
+ { variantId: id, body: input },
15916
+ (approvalId) => getClient().variants.update(id, input, approvalId),
15917
+ () => getClient().variants.get(id)
15918
+ );
15919
+ }
15920
+ );
15921
+ withMutationOptions(variant.command("deactivate <variantId>"), false).action(
15922
+ async (variantId, _options, command) => {
15923
+ const id = requireId(variantId, "variantId");
15924
+ await applyOrPreview(
15925
+ command,
15926
+ { isActive: false },
15927
+ getClient,
15928
+ "catalog.variants.deactivate",
15929
+ { variantId: id },
15930
+ (approvalId) => getClient().variants.deactivate(id, approvalId),
15931
+ () => getClient().variants.get(id)
15932
+ );
15933
+ }
15934
+ );
15935
+ withMutationOptions(variant.command("reorder <productId>")).action(
15936
+ async (productId, options, command) => {
15937
+ const id = requireId(productId, "productId");
15938
+ const input = await readMutationInput(options.from);
15939
+ await applyOrPreview(
15940
+ command,
15941
+ input,
15942
+ getClient,
15943
+ "catalog.variants.reorder",
15944
+ { productId: id, body: input },
15945
+ (approvalId) => getClient().variants.reorder(id, input, approvalId),
15946
+ () => getClient().variants.list(id)
15947
+ );
15948
+ }
15949
+ );
15725
15950
  }
15726
15951
  function registerCategoryCommands(catalog, getClient) {
15727
15952
  const category = catalog.command("category");
15728
15953
  category.command("list").action(async () => emitSuccess(await getClient().categories.list()));
15729
- category.command("get <categoryId>").action(async (categoryId) => emitSuccess(await getClient().categories.get(requireId(categoryId, "categoryId"))));
15730
- withMutationOptions(category.command("create")).action(async (options, command) => {
15731
- const input = await readMutationInput(options.from);
15732
- await applyOrPreview(command, input, () => getClient().categories.create(input));
15954
+ category.command("get <categoryId>").action(async (categoryId) => {
15955
+ emitSuccess(await getClient().categories.get(requireId(categoryId, "categoryId")));
15733
15956
  });
15734
- withMutationOptions(category.command("update <categoryId>")).action(async (categoryId, options, command) => {
15735
- const id = requireId(categoryId, "categoryId");
15957
+ withMutationOptions(category.command("create")).action(async (options, command) => {
15736
15958
  const input = await readMutationInput(options.from);
15737
- await applyOrPreview(command, input, () => getClient().categories.update(id, input), () => getClient().categories.get(id));
15738
- });
15739
- withMutationOptions(category.command("delete <categoryId>"), false).action(async (categoryId, _options, command) => {
15740
- const id = requireId(categoryId, "categoryId");
15741
- await applyOrPreview(command, { delete: true }, () => getClient().categories.delete(id), () => getClient().categories.get(id));
15959
+ await applyOrPreview(
15960
+ command,
15961
+ input,
15962
+ getClient,
15963
+ "catalog.categories.create",
15964
+ { body: input },
15965
+ (approvalId) => getClient().categories.create(input, approvalId)
15966
+ );
15742
15967
  });
15968
+ withMutationOptions(category.command("update <categoryId>")).action(
15969
+ async (categoryId, options, command) => {
15970
+ const id = requireId(categoryId, "categoryId");
15971
+ const input = await readMutationInput(options.from);
15972
+ await applyOrPreview(
15973
+ command,
15974
+ input,
15975
+ getClient,
15976
+ "catalog.categories.update",
15977
+ { categoryId: id, body: input },
15978
+ (approvalId) => getClient().categories.update(id, input, approvalId),
15979
+ () => getClient().categories.get(id)
15980
+ );
15981
+ }
15982
+ );
15983
+ withMutationOptions(category.command("delete <categoryId>"), false).action(
15984
+ async (categoryId, _options, command) => {
15985
+ const id = requireId(categoryId, "categoryId");
15986
+ await applyOrPreview(
15987
+ command,
15988
+ { delete: true },
15989
+ getClient,
15990
+ "catalog.categories.delete",
15991
+ { categoryId: id },
15992
+ (approvalId) => getClient().categories.delete(id, approvalId),
15993
+ () => getClient().categories.get(id)
15994
+ );
15995
+ }
15996
+ );
15743
15997
  }
15744
15998
  function registerTagCommands(catalog, getClient) {
15745
15999
  const tag = catalog.command("tag");
15746
16000
  tag.command("list").action(async () => emitSuccess(await getClient().tags.list()));
15747
- tag.command("get <tagId>").action(async (tagId) => emitSuccess(await getClient().tags.get(requireId(tagId, "tagId"))));
16001
+ tag.command("get <tagId>").action(async (tagId) => {
16002
+ emitSuccess(await getClient().tags.get(requireId(tagId, "tagId")));
16003
+ });
15748
16004
  withMutationOptions(tag.command("create")).action(async (options, command) => {
15749
16005
  const input = await readMutationInput(options.from);
15750
- await applyOrPreview(command, input, () => getClient().tags.create(input));
16006
+ await applyOrPreview(
16007
+ command,
16008
+ input,
16009
+ getClient,
16010
+ "catalog.tags.create",
16011
+ { body: input },
16012
+ (approvalId) => getClient().tags.create(input, approvalId)
16013
+ );
15751
16014
  });
15752
16015
  withMutationOptions(tag.command("update <tagId>")).action(async (tagId, options, command) => {
15753
16016
  const id = requireId(tagId, "tagId");
15754
16017
  const input = await readMutationInput(options.from);
15755
- await applyOrPreview(command, input, () => getClient().tags.update(id, input), () => getClient().tags.get(id));
15756
- });
15757
- withMutationOptions(tag.command("delete <tagId>"), false).action(async (tagId, _options, command) => {
15758
- const id = requireId(tagId, "tagId");
15759
- await applyOrPreview(command, { delete: true }, () => getClient().tags.delete(id), () => getClient().tags.get(id));
16018
+ await applyOrPreview(
16019
+ command,
16020
+ input,
16021
+ getClient,
16022
+ "catalog.tags.update",
16023
+ { tagId: id, body: input },
16024
+ (approvalId) => getClient().tags.update(id, input, approvalId),
16025
+ () => getClient().tags.get(id)
16026
+ );
15760
16027
  });
16028
+ withMutationOptions(tag.command("delete <tagId>"), false).action(
16029
+ async (tagId, _options, command) => {
16030
+ const id = requireId(tagId, "tagId");
16031
+ await applyOrPreview(
16032
+ command,
16033
+ { delete: true },
16034
+ getClient,
16035
+ "catalog.tags.delete",
16036
+ { tagId: id },
16037
+ (approvalId) => getClient().tags.delete(id, approvalId),
16038
+ () => getClient().tags.get(id)
16039
+ );
16040
+ }
16041
+ );
15761
16042
  }
15762
16043
  function registerAssetCommands(catalog, getClient) {
15763
16044
  const asset = catalog.command("asset");
15764
16045
  asset.command("list").option("--search <text>").option("--limit <number>", "M\xE1ximo de resultados", parseInteger).option("--offset <number>", "Desplazamiento", parseInteger).action(async (options) => emitSuccess(await getClient().assets.list(options)));
15765
- asset.command("get <assetId>").action(async (assetId) => emitSuccess(await getClient().assets.get(requireId(assetId, "assetId"))));
15766
- asset.command("upload").requiredOption("--file <path>", "Archivo local").option("--apply", "Sube el archivo").action(async (options, command) => {
16046
+ asset.command("get <assetId>").action(async (assetId) => {
16047
+ emitSuccess(await getClient().assets.get(requireId(assetId, "assetId")));
16048
+ });
16049
+ withMutationOptions(
16050
+ asset.command("upload").requiredOption("--file <path>", "Archivo local"),
16051
+ false
16052
+ ).action(async (options, command) => {
15767
16053
  const filePath = options.file;
15768
16054
  const fileStat = await stat(filePath);
15769
- if (!fileStat.isFile()) throw new CliProtocolError("CLI_VALIDATION_ERROR", "--file debe apuntar a un archivo");
16055
+ if (!fileStat.isFile()) {
16056
+ throw new CliProtocolError("CLI_VALIDATION_ERROR", "--file debe apuntar a un archivo");
16057
+ }
15770
16058
  if (!wantsApply(command)) {
15771
- emitSuccess({ validated: "local", file: basename(filePath), sizeBytes: fileStat.size });
16059
+ emitSuccess({
16060
+ validated: "local",
16061
+ file: basename(filePath),
16062
+ sizeBytes: fileStat.size
16063
+ });
16064
+ return;
16065
+ }
16066
+ const extension = extname(filePath).toLowerCase();
16067
+ const mimeType = extension === ".jpg" || extension === ".jpeg" ? "image/jpeg" : extension === ".png" ? "image/png" : extension === ".webp" ? "image/webp" : void 0;
16068
+ if (!mimeType) {
16069
+ throw new CliProtocolError(
16070
+ "CLI_VALIDATION_ERROR",
16071
+ "Solo se permiten im\xE1genes JPEG, PNG o WebP"
16072
+ );
16073
+ }
16074
+ const contents = await readFile(filePath);
16075
+ const file2 = new File([contents], basename(filePath), { type: mimeType });
16076
+ const rawApprovalId = command.optsWithGlobals().approvalId;
16077
+ if (typeof rawApprovalId === "string") {
16078
+ emitSuccess(await getClient().assets.upload(file2, requireId(rawApprovalId, "approvalId")));
15772
16079
  return;
15773
16080
  }
15774
- const file2 = new File([await readFile(filePath)], basename(filePath));
15775
- emitSuccess(await getClient().assets.upload(file2));
16081
+ emitSuccess(
16082
+ await getClient().operations.propose({
16083
+ operationName: "catalog.assets.upload",
16084
+ payload: {
16085
+ filename: file2.name,
16086
+ mimeType: file2.type,
16087
+ sizeBytes: file2.size,
16088
+ contentHash: createHash("sha256").update(contents).digest("hex")
16089
+ }
16090
+ })
16091
+ );
15776
16092
  });
15777
16093
  withMutationOptions(asset.command("import-url")).action(async (options, command) => {
15778
16094
  const input = await readMutationInput(options.from);
15779
- await applyOrPreview(command, input, () => getClient().assets.importFromUrl(input));
16095
+ await applyOrPreview(
16096
+ command,
16097
+ input,
16098
+ getClient,
16099
+ "catalog.assets.import",
16100
+ input,
16101
+ (approvalId) => getClient().assets.importFromUrl(input, approvalId)
16102
+ );
15780
16103
  });
15781
16104
  }
15782
16105
  function registerInventoryCommands(catalog, getClient) {
15783
16106
  const inventory = catalog.command("inventory");
15784
- inventory.command("get <variantId>").action(async (variantId) => emitSuccess(await getClient().inventory.get(requireId(variantId, "variantId"))));
15785
- inventory.command("movements <variantId>").option("--reason <reason>").option("--limit <number>", "M\xE1ximo de resultados", parseInteger).option("--offset <number>", "Desplazamiento", parseInteger).action(async (variantId, options) => emitSuccess(await getClient().inventory.listMovements(requireId(variantId, "variantId"), options)));
15786
- withMutationOptions(inventory.command("adjust <variantId>")).action(async (variantId, options, command) => {
15787
- const id = requireId(variantId, "variantId");
15788
- const input = await readMutationInput(options.from);
15789
- await applyOrPreview(command, input, () => getClient().inventory.adjust(id, input), () => getClient().inventory.get(id));
16107
+ inventory.command("get <variantId>").action(async (variantId) => {
16108
+ emitSuccess(await getClient().inventory.get(requireId(variantId, "variantId")));
15790
16109
  });
15791
- withMutationOptions(inventory.command("set <variantId>")).action(async (variantId, options, command) => {
15792
- const id = requireId(variantId, "variantId");
15793
- const input = await readMutationInput(options.from);
15794
- await applyOrPreview(command, input, () => getClient().inventory.set(id, input), () => getClient().inventory.get(id));
16110
+ inventory.command("movements <variantId>").option("--reason <reason>").option("--limit <number>", "M\xE1ximo de resultados", parseInteger).option("--offset <number>", "Desplazamiento", parseInteger).action(async (variantId, options) => {
16111
+ emitSuccess(
16112
+ await getClient().inventory.listMovements(requireId(variantId, "variantId"), options)
16113
+ );
15795
16114
  });
15796
- }
15797
- async function resolveLocalFileSources(value, client) {
15798
- if (Array.isArray(value)) return Promise.all(value.map((item) => resolveLocalFileSources(item, client)));
15799
- if (!value || typeof value !== "object") return value;
15800
- const source = value;
15801
- if (source.kind === "file") {
15802
- if (typeof source.path !== "string" || Object.keys(source).length !== 2) {
15803
- throw new CliProtocolError(
15804
- "CLI_VALIDATION_ERROR",
15805
- 'Una imagen local debe tener exactamente kind: "file" y path'
16115
+ withMutationOptions(inventory.command("adjust <variantId>")).action(
16116
+ async (variantId, options, command) => {
16117
+ const id = requireId(variantId, "variantId");
16118
+ const input = await readMutationInput(options.from);
16119
+ await applyOrPreview(
16120
+ command,
16121
+ input,
16122
+ getClient,
16123
+ "catalog.inventory.adjust",
16124
+ { variantId: id, body: input },
16125
+ (approvalId) => getClient().inventory.adjust(id, input, approvalId),
16126
+ () => getClient().inventory.get(id)
15806
16127
  );
15807
16128
  }
15808
- const fileStat = await stat(source.path);
15809
- if (!fileStat.isFile()) {
15810
- throw new CliProtocolError("CLI_VALIDATION_ERROR", "La ruta de imagen local debe apuntar a un archivo");
16129
+ );
16130
+ withMutationOptions(inventory.command("set <variantId>")).action(
16131
+ async (variantId, options, command) => {
16132
+ const id = requireId(variantId, "variantId");
16133
+ const input = await readMutationInput(options.from);
16134
+ await applyOrPreview(
16135
+ command,
16136
+ input,
16137
+ getClient,
16138
+ "catalog.inventory.set",
16139
+ { variantId: id, body: input },
16140
+ (approvalId) => getClient().inventory.set(id, input, approvalId),
16141
+ () => getClient().inventory.get(id)
16142
+ );
15811
16143
  }
15812
- const asset = await client.assets.upload(
15813
- new File([await readFile(source.path)], basename(source.path))
16144
+ );
16145
+ }
16146
+ function rejectLocalFileSources(value) {
16147
+ if (Array.isArray(value)) {
16148
+ for (const item of value) rejectLocalFileSources(item);
16149
+ return;
16150
+ }
16151
+ if (!value || typeof value !== "object") return;
16152
+ const source = value;
16153
+ if (source.kind === "file") {
16154
+ throw new CliProtocolError(
16155
+ "CLI_VALIDATION_ERROR",
16156
+ "Sube cada imagen local con catalog asset upload, apru\xE9bala y usa su assetId"
15814
16157
  );
15815
- return { kind: "asset", assetId: asset.id };
15816
16158
  }
15817
- return Object.fromEntries(
15818
- await Promise.all(
15819
- Object.entries(source).map(async ([key, nested]) => [
15820
- key,
15821
- await resolveLocalFileSources(nested, client)
15822
- ])
15823
- )
15824
- );
16159
+ for (const nested of Object.values(source)) rejectLocalFileSources(nested);
15825
16160
  }
15826
16161
  function registerImportCommands(catalog, getClient) {
15827
16162
  const imports = catalog.command("import");
15828
16163
  imports.command("preview").requiredOption("--from <json-file>", "Lista estructurada para vista previa").action(async (options) => {
15829
16164
  const input = await readMutationInput(options.from);
15830
- const normalizedInput = await resolveLocalFileSources(input, getClient());
15831
- emitSuccess(await getClient().imports.preview(normalizedInput));
15832
- });
15833
- imports.command("apply <importId>").option("--apply", "Encola la importaci\xF3n aprobada").action(async (importId, _options, command) => {
15834
- const id = requireId(importId, "importId");
15835
- if (!wantsApply(command)) {
15836
- emitSuccess({ validated: "local", importId: id, action: "apply" });
15837
- return;
16165
+ rejectLocalFileSources(input);
16166
+ emitSuccess(await getClient().imports.preview(input));
16167
+ });
16168
+ withMutationOptions(imports.command("apply <importId>"), false).action(
16169
+ async (importId, _options, command) => {
16170
+ const id = requireId(importId, "importId");
16171
+ await applyOrPreview(
16172
+ command,
16173
+ { importId: id, action: "apply" },
16174
+ getClient,
16175
+ "catalog.imports.apply",
16176
+ { importId: id },
16177
+ (approvalId) => getClient().imports.apply(id, approvalId)
16178
+ );
15838
16179
  }
15839
- emitSuccess(await getClient().imports.apply(id));
16180
+ );
16181
+ imports.command("status <importId>").action(async (importId) => {
16182
+ emitSuccess(await getClient().imports.get(requireId(importId, "importId")));
15840
16183
  });
15841
- imports.command("status <importId>").action(async (importId) => emitSuccess(await getClient().imports.get(requireId(importId, "importId"))));
15842
16184
  }
15843
16185
 
15844
16186
  // src/commands/auth.ts
@@ -15902,12 +16244,10 @@ async function login(options) {
15902
16244
  const deviceAuth = options.deviceAuthFactory(baseUrl ? { baseUrl } : {});
15903
16245
  const start = await deviceAuth.start({ name: "Avileo CLI" });
15904
16246
  const browserOpened = await options.openBrowser(start.verificationUri);
15905
- if (!options.json()) {
15906
- process.stderr.write(
15907
- `Abr\xED ${start.verificationUri} y confirma el c\xF3digo ${start.userCode}. Esperando aprobaci\xF3n\u2026
16247
+ process.stderr.write(
16248
+ `Abr\xED ${start.verificationUri} y confirma el c\xF3digo ${start.userCode}. Esperando aprobaci\xF3n\u2026
15908
16249
  `
15909
- );
15910
- }
16250
+ );
15911
16251
  const expiresAt = Date.parse(start.expiresAt);
15912
16252
  const deadline = Number.isFinite(expiresAt) ? expiresAt : Date.now() + 10 * 60 * 1e3;
15913
16253
  while (Date.now() < deadline) {
@@ -16003,6 +16343,26 @@ function createProgram(options = {}) {
16003
16343
  });
16004
16344
  registerBusinessCommands(program, getClient);
16005
16345
  registerCatalogCommands(program, getClient);
16346
+ const operation = program.command("operation").description("Consulta y aplica operaciones aprobadas en Avileo");
16347
+ operation.command("status <id>").description("Consulta el estado de una operaci\xF3n").action(async (id) => {
16348
+ if (!id.trim()) {
16349
+ throw new CliProtocolError("CLI_VALIDATION_ERROR", "id es obligatorio");
16350
+ }
16351
+ emitSuccess(await getClient().operations.get(id));
16352
+ });
16353
+ operation.command("apply <id>").description("Aplica una operaci\xF3n aprobada").action(async (id) => {
16354
+ if (!id.trim()) {
16355
+ throw new CliProtocolError("CLI_VALIDATION_ERROR", "id es obligatorio");
16356
+ }
16357
+ emitSuccess(await getClient().operations.apply(id));
16358
+ });
16359
+ program.command("catalog-key").description("Gestiona la Client Key p\xFAblica del cat\xE1logo").command("create").requiredOption("--name <name>", "Nombre visible de la Client Key").description("Propone crear una Client Key para aprobaci\xF3n en Avileo").action(async (options2) => {
16360
+ const name = options2.name.trim();
16361
+ if (!name) {
16362
+ throw new CliProtocolError("CLI_VALIDATION_ERROR", "name es obligatorio");
16363
+ }
16364
+ emitSuccess(await getClient().operations.proposeClientKey(name));
16365
+ });
16006
16366
  const parseAsync3 = program.parseAsync.bind(program);
16007
16367
  program.parseAsync = (async (...args) => {
16008
16368
  try {