@tarileo/avileo-catalog-cli 0.3.4 → 0.3.5
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 +488 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3046,13 +3046,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3046
3046
|
}
|
|
3047
3047
|
return propValues;
|
|
3048
3048
|
});
|
|
3049
|
-
const
|
|
3049
|
+
const isObject4 = isObject;
|
|
3050
3050
|
const catchall = def.catchall;
|
|
3051
3051
|
let value;
|
|
3052
3052
|
inst._zod.parse = (payload, ctx) => {
|
|
3053
3053
|
value ?? (value = _normalized.value);
|
|
3054
3054
|
const input = payload.value;
|
|
3055
|
-
if (!
|
|
3055
|
+
if (!isObject4(input)) {
|
|
3056
3056
|
payload.issues.push({
|
|
3057
3057
|
expected: "object",
|
|
3058
3058
|
code: "invalid_type",
|
|
@@ -3179,7 +3179,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
3179
3179
|
return (payload, ctx) => fn(shape, payload, ctx);
|
|
3180
3180
|
};
|
|
3181
3181
|
let fastpass;
|
|
3182
|
-
const
|
|
3182
|
+
const isObject4 = isObject;
|
|
3183
3183
|
const jit = !globalConfig.jitless;
|
|
3184
3184
|
const allowsEval2 = allowsEval;
|
|
3185
3185
|
const fastEnabled = jit && allowsEval2.value;
|
|
@@ -3188,7 +3188,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
3188
3188
|
inst._zod.parse = (payload, ctx) => {
|
|
3189
3189
|
value ?? (value = _normalized.value);
|
|
3190
3190
|
const input = payload.value;
|
|
3191
|
-
if (!
|
|
3191
|
+
if (!isObject4(input)) {
|
|
3192
3192
|
payload.issues.push({
|
|
3193
3193
|
expected: "object",
|
|
3194
3194
|
code: "invalid_type",
|
|
@@ -14686,7 +14686,7 @@ var AgentHttpClient = class {
|
|
|
14686
14686
|
} catch {
|
|
14687
14687
|
abort.cancel();
|
|
14688
14688
|
if (retry && attempt < 2) {
|
|
14689
|
-
await new Promise((
|
|
14689
|
+
await new Promise((resolve2) => setTimeout(resolve2, retryDelayMs(attempt)));
|
|
14690
14690
|
continue;
|
|
14691
14691
|
}
|
|
14692
14692
|
throw new AgentNetworkError("No se pudo conectar con la API de Avileo", {
|
|
@@ -14697,7 +14697,7 @@ var AgentHttpClient = class {
|
|
|
14697
14697
|
}
|
|
14698
14698
|
abort.cancel();
|
|
14699
14699
|
if (retry && isRetryableStatus(response.status) && attempt < 2) {
|
|
14700
|
-
await new Promise((
|
|
14700
|
+
await new Promise((resolve2) => setTimeout(resolve2, retryDelayMs(attempt, response)));
|
|
14701
14701
|
continue;
|
|
14702
14702
|
}
|
|
14703
14703
|
let payload;
|
|
@@ -14822,6 +14822,73 @@ var UNIT_CATALOG = {
|
|
|
14822
14822
|
};
|
|
14823
14823
|
var UNIT_SLUGS = Object.keys(UNIT_CATALOG);
|
|
14824
14824
|
var UnitSlugSchema = external_exports.enum(UNIT_SLUGS);
|
|
14825
|
+
var ASSET_METADATA_NAMESPACE = "avileoAsset";
|
|
14826
|
+
var nullableText = (max) => external_exports.string().trim().min(1).max(max).nullable();
|
|
14827
|
+
var tagsSchema = external_exports.array(
|
|
14828
|
+
external_exports.string().trim().min(1).max(48).refine((tag) => !tag.includes(","), "Cada etiqueta debe ir separada, sin comas").transform((tag) => tag.toLowerCase())
|
|
14829
|
+
).max(20).transform((tags) => [...new Set(tags)]);
|
|
14830
|
+
var AssetVisualSchema = external_exports.object({
|
|
14831
|
+
view: external_exports.enum(["front", "back", "side", "detail", "packaging", "lifestyle", "other"]).nullable(),
|
|
14832
|
+
background: external_exports.enum(["light", "dark", "transparent", "mixed", "other"]).nullable(),
|
|
14833
|
+
hasTransparency: external_exports.boolean().nullable(),
|
|
14834
|
+
containsText: external_exports.boolean().nullable(),
|
|
14835
|
+
containsPrices: external_exports.boolean().nullable()
|
|
14836
|
+
}).strict();
|
|
14837
|
+
var AssetPresentationSchema = external_exports.object({
|
|
14838
|
+
version: external_exports.literal(1),
|
|
14839
|
+
title: nullableText(160),
|
|
14840
|
+
alt: nullableText(500),
|
|
14841
|
+
tags: tagsSchema,
|
|
14842
|
+
visual: AssetVisualSchema,
|
|
14843
|
+
reviewStatus: external_exports.enum(["incomplete", "reviewed"])
|
|
14844
|
+
}).strict();
|
|
14845
|
+
var hasValues = (value) => Object.values(value).some((item) => item !== void 0);
|
|
14846
|
+
var AssetPresentationPatchSchema = AssetPresentationSchema.omit({ version: true }).partial().extend({
|
|
14847
|
+
visual: AssetVisualSchema.partial().refine(hasValues, "Indica al menos un cambio visual").optional()
|
|
14848
|
+
}).strict().refine(hasValues, "Indica al menos un cambio de metadata");
|
|
14849
|
+
var AssetMetadataUpdateInputSchema = external_exports.object({
|
|
14850
|
+
expectedRevision: external_exports.string().trim().min(1).max(128),
|
|
14851
|
+
description: nullableText(1e3).optional(),
|
|
14852
|
+
presentation: AssetPresentationPatchSchema.optional()
|
|
14853
|
+
}).strict().refine(
|
|
14854
|
+
(input) => input.description !== void 0 || input.presentation !== void 0,
|
|
14855
|
+
"Indica al menos un cambio"
|
|
14856
|
+
);
|
|
14857
|
+
var PublicAssetPresentationSchema = AssetPresentationSchema.omit({ reviewStatus: true });
|
|
14858
|
+
var readableVisualSchema = external_exports.object({
|
|
14859
|
+
view: AssetVisualSchema.shape.view.catch(null),
|
|
14860
|
+
background: AssetVisualSchema.shape.background.catch(null),
|
|
14861
|
+
hasTransparency: AssetVisualSchema.shape.hasTransparency.catch(null),
|
|
14862
|
+
containsText: AssetVisualSchema.shape.containsText.catch(null),
|
|
14863
|
+
containsPrices: AssetVisualSchema.shape.containsPrices.catch(null)
|
|
14864
|
+
});
|
|
14865
|
+
var readablePresentationSchema = external_exports.object({
|
|
14866
|
+
version: external_exports.literal(1),
|
|
14867
|
+
title: AssetPresentationSchema.shape.title.catch(null),
|
|
14868
|
+
alt: AssetPresentationSchema.shape.alt.catch(null),
|
|
14869
|
+
tags: AssetPresentationSchema.shape.tags.catch(() => []),
|
|
14870
|
+
visual: readableVisualSchema.catch(() => readableVisualSchema.parse({})),
|
|
14871
|
+
reviewStatus: AssetPresentationSchema.shape.reviewStatus.catch("incomplete")
|
|
14872
|
+
});
|
|
14873
|
+
var metadataEnvelopeSchema = external_exports.object({
|
|
14874
|
+
[ASSET_METADATA_NAMESPACE]: readablePresentationSchema
|
|
14875
|
+
});
|
|
14876
|
+
var CatalogAssetSchema = external_exports.object({
|
|
14877
|
+
id: external_exports.string().uuid(),
|
|
14878
|
+
filename: external_exports.string(),
|
|
14879
|
+
originalName: external_exports.string(),
|
|
14880
|
+
description: external_exports.string().nullable(),
|
|
14881
|
+
url: external_exports.string().url(),
|
|
14882
|
+
mimeType: external_exports.string(),
|
|
14883
|
+
sizeBytes: external_exports.number().int().nonnegative(),
|
|
14884
|
+
width: external_exports.number().int().nonnegative().nullable(),
|
|
14885
|
+
height: external_exports.number().int().nonnegative().nullable(),
|
|
14886
|
+
presentation: AssetPresentationSchema,
|
|
14887
|
+
revision: external_exports.string().min(1).max(128),
|
|
14888
|
+
createdAt: external_exports.string(),
|
|
14889
|
+
updatedAt: external_exports.string(),
|
|
14890
|
+
updatedByActorId: external_exports.string().nullable()
|
|
14891
|
+
}).strict();
|
|
14825
14892
|
var uuidSchema = external_exports.string().uuid();
|
|
14826
14893
|
var timestampSchema = external_exports.string().datetime({ offset: true });
|
|
14827
14894
|
var nonEmptyTextSchema = external_exports.string().trim().min(1);
|
|
@@ -14844,7 +14911,13 @@ var AgentAssetDtoSchema = external_exports.object({
|
|
|
14844
14911
|
sizeBytes: external_exports.number().int().nonnegative(),
|
|
14845
14912
|
url: external_exports.string().url(),
|
|
14846
14913
|
description: nullableTextSchema,
|
|
14847
|
-
createdAt: timestampSchema
|
|
14914
|
+
createdAt: timestampSchema,
|
|
14915
|
+
presentation: AssetPresentationSchema.optional(),
|
|
14916
|
+
revision: external_exports.string().min(1).max(128).optional(),
|
|
14917
|
+
updatedAt: timestampSchema.optional(),
|
|
14918
|
+
updatedByActorId: external_exports.string().nullable().optional(),
|
|
14919
|
+
width: external_exports.number().int().positive().nullable().optional(),
|
|
14920
|
+
height: external_exports.number().int().positive().nullable().optional()
|
|
14848
14921
|
}).strict();
|
|
14849
14922
|
var AgentCategoryDtoSchema = external_exports.object({
|
|
14850
14923
|
id: uuidSchema,
|
|
@@ -14945,7 +15018,20 @@ var AgentProductFilterInputSchema = AgentPaginationInputSchema.extend({
|
|
|
14945
15018
|
isActive: external_exports.coerce.boolean().optional()
|
|
14946
15019
|
}).strict();
|
|
14947
15020
|
var AgentAssetFilterInputSchema = AgentPaginationInputSchema.extend({
|
|
14948
|
-
search: external_exports.string().trim().min(1).max(255).optional()
|
|
15021
|
+
search: external_exports.string().trim().min(1).max(255).optional(),
|
|
15022
|
+
tags: external_exports.union([external_exports.string().transform((value) => value.split(",")), external_exports.array(external_exports.string())]).pipe(
|
|
15023
|
+
external_exports.array(
|
|
15024
|
+
external_exports.string().trim().min(1).max(48).transform((tag) => tag.toLowerCase())
|
|
15025
|
+
).max(20)
|
|
15026
|
+
).transform((tags) => [...new Set(tags)]).optional(),
|
|
15027
|
+
containsPrices: external_exports.union([external_exports.boolean(), external_exports.enum(["true", "false"]).transform((value) => value === "true")]).optional(),
|
|
15028
|
+
reviewStatus: external_exports.enum(["incomplete", "reviewed"]).optional(),
|
|
15029
|
+
mimeType: external_exports.string().trim().min(1).max(100).optional()
|
|
15030
|
+
}).strict();
|
|
15031
|
+
var AgentUpdateAssetInputSchema = AssetMetadataUpdateInputSchema;
|
|
15032
|
+
var AgentUpdateAssetPayloadSchema = external_exports.object({
|
|
15033
|
+
assetId: uuidSchema,
|
|
15034
|
+
body: AgentUpdateAssetInputSchema
|
|
14949
15035
|
}).strict();
|
|
14950
15036
|
var AgentInventoryMovementFilterInputSchema = AgentPaginationInputSchema.extend({
|
|
14951
15037
|
reason: external_exports.string().trim().min(1).max(500).optional()
|
|
@@ -14957,6 +15043,18 @@ var AgentTagAssignmentInputSchema = external_exports.object({
|
|
|
14957
15043
|
var imageAssetIdsSchema = external_exports.array(uuidSchema).max(8).refine((assetIds) => new Set(assetIds).size === assetIds.length, {
|
|
14958
15044
|
message: "Las im\xE1genes no pueden repetirse"
|
|
14959
15045
|
});
|
|
15046
|
+
var AgentProductImageSourceSchema = external_exports.discriminatedUnion("kind", [
|
|
15047
|
+
external_exports.object({ kind: external_exports.literal("asset"), assetId: uuidSchema }).strict(),
|
|
15048
|
+
external_exports.object({ kind: external_exports.literal("temporary"), temporaryImageId: uuidSchema }).strict()
|
|
15049
|
+
]);
|
|
15050
|
+
var productImagesSchema = external_exports.array(AgentProductImageSourceSchema).max(8).refine(
|
|
15051
|
+
(images) => new Set(
|
|
15052
|
+
images.map(
|
|
15053
|
+
(image) => image.kind === "asset" ? `asset:${image.assetId}` : `temporary:${image.temporaryImageId}`
|
|
15054
|
+
)
|
|
15055
|
+
).size === images.length,
|
|
15056
|
+
{ message: "Las im\xE1genes no pueden repetirse" }
|
|
15057
|
+
);
|
|
14960
15058
|
var AgentCreateVariantInputSchema = external_exports.object({
|
|
14961
15059
|
name: nonEmptyTextSchema.max(50),
|
|
14962
15060
|
sku: external_exports.string().trim().min(1).max(50).optional(),
|
|
@@ -14997,8 +15095,11 @@ var AgentUpdateProductInputSchema = external_exports.object({
|
|
|
14997
15095
|
isActive: external_exports.boolean().optional(),
|
|
14998
15096
|
description: nullableTextSchema.optional(),
|
|
14999
15097
|
imageAssetIds: imageAssetIdsSchema.optional(),
|
|
15098
|
+
images: productImagesSchema.optional(),
|
|
15000
15099
|
tagAssignments: external_exports.array(AgentTagAssignmentInputSchema).max(20).optional()
|
|
15001
|
-
}).strict().refine((input) =>
|
|
15100
|
+
}).strict().refine((input) => input.images === void 0 || input.imageAssetIds === void 0, {
|
|
15101
|
+
message: "Usa images o imageAssetIds, no ambos"
|
|
15102
|
+
}).refine((input) => Object.keys(input).length > 0, {
|
|
15002
15103
|
message: "Debes indicar al menos un campo para actualizar"
|
|
15003
15104
|
});
|
|
15004
15105
|
var AgentCreateCategoryInputSchema = external_exports.object({
|
|
@@ -15040,8 +15141,21 @@ var AgentBackendImportImageSourceSchema = external_exports.discriminatedUnion("k
|
|
|
15040
15141
|
external_exports.object({
|
|
15041
15142
|
kind: external_exports.literal("url"),
|
|
15042
15143
|
url: httpsUrlSchema
|
|
15144
|
+
}).strict(),
|
|
15145
|
+
external_exports.object({
|
|
15146
|
+
kind: external_exports.literal("temporary"),
|
|
15147
|
+
temporaryImageId: uuidSchema
|
|
15043
15148
|
}).strict()
|
|
15044
15149
|
]);
|
|
15150
|
+
var AgentCatalogImportTemporaryImageDtoSchema = external_exports.object({
|
|
15151
|
+
id: uuidSchema,
|
|
15152
|
+
url: external_exports.string().url(),
|
|
15153
|
+
filename: nonEmptyTextSchema.max(255),
|
|
15154
|
+
mimeType: nonEmptyTextSchema.max(100),
|
|
15155
|
+
sizeBytes: external_exports.number().int().positive(),
|
|
15156
|
+
contentHash: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
15157
|
+
expiresAt: timestampSchema
|
|
15158
|
+
}).strict();
|
|
15045
15159
|
var ExternalRecordRefSchema = external_exports.object({
|
|
15046
15160
|
source: nonEmptyTextSchema.max(100),
|
|
15047
15161
|
externalId: external_exports.string().trim().min(1).max(500).optional(),
|
|
@@ -15162,6 +15276,7 @@ var AGENT_OPERATION_NAMES = [
|
|
|
15162
15276
|
"catalog.tags.delete",
|
|
15163
15277
|
"catalog.assets.upload",
|
|
15164
15278
|
"catalog.assets.import",
|
|
15279
|
+
"catalog.assets.update",
|
|
15165
15280
|
"catalog.inventory.adjust",
|
|
15166
15281
|
"catalog.inventory.set",
|
|
15167
15282
|
"catalog.imports.preview",
|
|
@@ -15184,6 +15299,15 @@ var AgentOperationProposalInputSchema = external_exports.object({
|
|
|
15184
15299
|
operationName: AgentOperationNameSchema,
|
|
15185
15300
|
payload: external_exports.record(external_exports.string(), external_exports.unknown())
|
|
15186
15301
|
}).strict();
|
|
15302
|
+
var AgentOperationBatchInputSchema = external_exports.object({
|
|
15303
|
+
operationIds: external_exports.array(external_exports.string().trim().toLowerCase().uuid()).min(1).max(50).transform((ids) => [...new Set(ids)])
|
|
15304
|
+
}).strict();
|
|
15305
|
+
var AgentOperationBatchDtoSchema = external_exports.object({
|
|
15306
|
+
id: uuidSchema,
|
|
15307
|
+
operationIds: external_exports.array(uuidSchema).min(1).max(50),
|
|
15308
|
+
approvalUrl: external_exports.string().url(),
|
|
15309
|
+
createdAt: timestampSchema
|
|
15310
|
+
}).strict();
|
|
15187
15311
|
var AgentOperationProposalDtoSchema = external_exports.object({
|
|
15188
15312
|
id: uuidSchema,
|
|
15189
15313
|
operationName: AgentOperationNameSchema,
|
|
@@ -15377,6 +15501,25 @@ var AgentBusinessResource = class {
|
|
|
15377
15501
|
return this.http.request("/api/v1/agent/business/profile");
|
|
15378
15502
|
}
|
|
15379
15503
|
};
|
|
15504
|
+
async function uploadTemporaryImage(http, file2, options = {}) {
|
|
15505
|
+
const body = new FormData();
|
|
15506
|
+
body.set("file", file2);
|
|
15507
|
+
const result = await http.request("/api/v1/agent/catalog/imports/images", {
|
|
15508
|
+
method: "POST",
|
|
15509
|
+
body,
|
|
15510
|
+
dispatchIdempotency: true,
|
|
15511
|
+
retry: options.retry
|
|
15512
|
+
});
|
|
15513
|
+
const parsed = AgentCatalogImportTemporaryImageDtoSchema.safeParse(result);
|
|
15514
|
+
if (!parsed.success) {
|
|
15515
|
+
throw new AgentError("La API de Avileo devolvi\xF3 una imagen temporal inv\xE1lida", {
|
|
15516
|
+
code: "INVALID_RESPONSE",
|
|
15517
|
+
status: 201,
|
|
15518
|
+
retryable: false
|
|
15519
|
+
});
|
|
15520
|
+
}
|
|
15521
|
+
return parsed.data;
|
|
15522
|
+
}
|
|
15380
15523
|
var AgentProductsResource = class {
|
|
15381
15524
|
constructor(http) {
|
|
15382
15525
|
this.http = http;
|
|
@@ -15388,6 +15531,10 @@ var AgentProductsResource = class {
|
|
|
15388
15531
|
get(productId) {
|
|
15389
15532
|
return this.http.request(`/api/v1/agent/catalog/products/${encodeURIComponent(productId)}`);
|
|
15390
15533
|
}
|
|
15534
|
+
/** Stage bytes for a product gallery proposal; this does not create a permanent asset. */
|
|
15535
|
+
uploadImage(file2, options) {
|
|
15536
|
+
return uploadTemporaryImage(this.http, file2, options);
|
|
15537
|
+
}
|
|
15391
15538
|
create(input, approvalId) {
|
|
15392
15539
|
return this.http.request("/api/v1/agent/catalog/products", {
|
|
15393
15540
|
method: "POST",
|
|
@@ -15527,11 +15674,24 @@ var AgentAssetsResource = class {
|
|
|
15527
15674
|
}
|
|
15528
15675
|
http;
|
|
15529
15676
|
list(filters = {}) {
|
|
15530
|
-
return this.http.request(
|
|
15677
|
+
return this.http.request(
|
|
15678
|
+
`/api/v1/agent/catalog/assets${queryString({
|
|
15679
|
+
...filters,
|
|
15680
|
+
tags: filters.tags?.length ? filters.tags.join(",") : void 0
|
|
15681
|
+
})}`
|
|
15682
|
+
);
|
|
15531
15683
|
}
|
|
15532
15684
|
get(assetId) {
|
|
15533
15685
|
return this.http.request(`/api/v1/agent/catalog/assets/${encodeURIComponent(assetId)}`);
|
|
15534
15686
|
}
|
|
15687
|
+
update(assetId, input, approvalId) {
|
|
15688
|
+
return this.http.request(`/api/v1/agent/catalog/assets/${encodeURIComponent(assetId)}`, {
|
|
15689
|
+
method: "PATCH",
|
|
15690
|
+
body: input,
|
|
15691
|
+
dispatchIdempotency: true,
|
|
15692
|
+
approvalId
|
|
15693
|
+
});
|
|
15694
|
+
}
|
|
15535
15695
|
upload(file2, approvalId) {
|
|
15536
15696
|
const body = new FormData();
|
|
15537
15697
|
body.set("file", file2);
|
|
@@ -15584,6 +15744,9 @@ var AgentImportsResource = class {
|
|
|
15584
15744
|
this.http = http;
|
|
15585
15745
|
}
|
|
15586
15746
|
http;
|
|
15747
|
+
uploadImage(file2, options) {
|
|
15748
|
+
return uploadTemporaryImage(this.http, file2, options);
|
|
15749
|
+
}
|
|
15587
15750
|
preview(input) {
|
|
15588
15751
|
return this.http.request("/api/v1/agent/catalog/imports/preview", {
|
|
15589
15752
|
method: "POST",
|
|
@@ -15625,6 +15788,15 @@ var AgentOperationsResource = class {
|
|
|
15625
15788
|
get(operationId) {
|
|
15626
15789
|
return this.http.request(`/api/v1/agent/operations/${encodeURIComponent(operationId)}`);
|
|
15627
15790
|
}
|
|
15791
|
+
createBatch(input) {
|
|
15792
|
+
return this.http.request("/api/v1/agent/operation-batches", {
|
|
15793
|
+
method: "POST",
|
|
15794
|
+
body: input
|
|
15795
|
+
});
|
|
15796
|
+
}
|
|
15797
|
+
getBatch(batchId) {
|
|
15798
|
+
return this.http.request(`/api/v1/agent/operation-batches/${encodeURIComponent(batchId)}`);
|
|
15799
|
+
}
|
|
15628
15800
|
apply(operationId) {
|
|
15629
15801
|
return this.http.request(`/api/v1/agent/operations/${encodeURIComponent(operationId)}/apply`, {
|
|
15630
15802
|
method: "POST",
|
|
@@ -16036,7 +16208,194 @@ function registerBusinessCommands(root, getClient) {
|
|
|
16036
16208
|
// src/commands/catalog.ts
|
|
16037
16209
|
import { createHash } from "crypto";
|
|
16038
16210
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
16039
|
-
import { basename, extname } from "path";
|
|
16211
|
+
import { basename as basename2, extname } from "path";
|
|
16212
|
+
|
|
16213
|
+
// src/commands/import-images.ts
|
|
16214
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
16215
|
+
import { constants } from "fs";
|
|
16216
|
+
import { open } from "fs/promises";
|
|
16217
|
+
import { basename, dirname as dirname2, resolve } from "path";
|
|
16218
|
+
var MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
16219
|
+
var MAX_TEMPORARY_IMAGES = 100;
|
|
16220
|
+
var MAX_TEMPORARY_BYTES = 100 * 1024 * 1024;
|
|
16221
|
+
function isObject3(value) {
|
|
16222
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16223
|
+
}
|
|
16224
|
+
function invalidInput(message) {
|
|
16225
|
+
throw new CliProtocolError("CLI_VALIDATION_ERROR", message);
|
|
16226
|
+
}
|
|
16227
|
+
function imageMimeType(bytes) {
|
|
16228
|
+
if (bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
16229
|
+
return "image/png";
|
|
16230
|
+
}
|
|
16231
|
+
if (bytes.length >= 3 && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
16232
|
+
return "image/jpeg";
|
|
16233
|
+
}
|
|
16234
|
+
const signature = bytes.subarray(0, 6).toString("ascii");
|
|
16235
|
+
if (signature === "GIF87a" || signature === "GIF89a") return "image/gif";
|
|
16236
|
+
if (bytes.length >= 12 && bytes.subarray(0, 4).toString("ascii") === "RIFF" && bytes.subarray(8, 12).toString("ascii") === "WEBP") {
|
|
16237
|
+
return "image/webp";
|
|
16238
|
+
}
|
|
16239
|
+
return void 0;
|
|
16240
|
+
}
|
|
16241
|
+
async function readImage(path, remainingBytes) {
|
|
16242
|
+
const handle = await open(path, constants.O_RDONLY | constants.O_NONBLOCK).catch(
|
|
16243
|
+
() => invalidInput("No se pudo abrir una imagen local del cat\xE1logo")
|
|
16244
|
+
);
|
|
16245
|
+
try {
|
|
16246
|
+
const stats = await handle.stat();
|
|
16247
|
+
if (!stats.isFile() || stats.size === 0 || stats.size > MAX_IMAGE_BYTES) {
|
|
16248
|
+
invalidInput("Cada imagen local debe ser un archivo de entre 1 byte y 5 MiB");
|
|
16249
|
+
}
|
|
16250
|
+
if (stats.size > remainingBytes) {
|
|
16251
|
+
invalidInput("Las im\xE1genes locales no pueden superar 100 MiB en total");
|
|
16252
|
+
}
|
|
16253
|
+
const buffer = Buffer.alloc(Math.min(stats.size + 1, MAX_IMAGE_BYTES + 1));
|
|
16254
|
+
let length = 0;
|
|
16255
|
+
while (length < buffer.length) {
|
|
16256
|
+
const { bytesRead } = await handle.read(buffer, length, buffer.length - length, null);
|
|
16257
|
+
if (bytesRead === 0) break;
|
|
16258
|
+
length += bytesRead;
|
|
16259
|
+
}
|
|
16260
|
+
if (length === 0 || length !== stats.size || length > MAX_IMAGE_BYTES) {
|
|
16261
|
+
invalidInput("La imagen local cambi\xF3 durante la lectura o supera 5 MiB");
|
|
16262
|
+
}
|
|
16263
|
+
const bytes = buffer.subarray(0, length);
|
|
16264
|
+
const mimeType = imageMimeType(bytes);
|
|
16265
|
+
if (!mimeType) invalidInput("Solo se permiten im\xE1genes JPEG, PNG, WebP o GIF");
|
|
16266
|
+
return new File([bytes], basename(path), { type: mimeType });
|
|
16267
|
+
} catch (error51) {
|
|
16268
|
+
if (error51 instanceof CliProtocolError) throw error51;
|
|
16269
|
+
invalidInput("No se pudo leer una imagen local del cat\xE1logo");
|
|
16270
|
+
} finally {
|
|
16271
|
+
await handle.close();
|
|
16272
|
+
}
|
|
16273
|
+
}
|
|
16274
|
+
function localImageSources(inputPath) {
|
|
16275
|
+
const paths = /* @__PURE__ */ new Map();
|
|
16276
|
+
const placeholders = /* @__PURE__ */ new Map();
|
|
16277
|
+
const baseDirectory = dirname2(resolve(inputPath));
|
|
16278
|
+
const normalizeImages = (value) => {
|
|
16279
|
+
if (!Array.isArray(value)) return value;
|
|
16280
|
+
return value.map((source) => {
|
|
16281
|
+
if (!isObject3(source) || source.kind !== "file") return source;
|
|
16282
|
+
if (Object.keys(source).some((key) => key !== "kind" && key !== "path") || typeof source.path !== "string" || source.path.trim().length === 0 || source.path.includes("\0")) {
|
|
16283
|
+
invalidInput("Cada imagen local requiere \xFAnicamente kind: file y un path v\xE1lido");
|
|
16284
|
+
}
|
|
16285
|
+
const path = resolve(baseDirectory, source.path);
|
|
16286
|
+
let placeholder = paths.get(path);
|
|
16287
|
+
if (!placeholder) {
|
|
16288
|
+
placeholder = randomUUID2();
|
|
16289
|
+
paths.set(path, placeholder);
|
|
16290
|
+
placeholders.set(placeholder, path);
|
|
16291
|
+
}
|
|
16292
|
+
return { kind: "temporary", temporaryImageId: placeholder };
|
|
16293
|
+
});
|
|
16294
|
+
};
|
|
16295
|
+
return { normalizeImages, paths: placeholders };
|
|
16296
|
+
}
|
|
16297
|
+
async function readLocalImages(paths) {
|
|
16298
|
+
if (paths.size > MAX_TEMPORARY_IMAGES) {
|
|
16299
|
+
invalidInput("La importaci\xF3n no puede preparar m\xE1s de 100 im\xE1genes locales \xFAnicas");
|
|
16300
|
+
}
|
|
16301
|
+
const files = /* @__PURE__ */ new Map();
|
|
16302
|
+
let totalBytes = 0;
|
|
16303
|
+
for (const [placeholder, path] of paths) {
|
|
16304
|
+
const file2 = await readImage(path, MAX_TEMPORARY_BYTES - totalBytes);
|
|
16305
|
+
totalBytes += file2.size;
|
|
16306
|
+
files.set(placeholder, file2);
|
|
16307
|
+
}
|
|
16308
|
+
return files;
|
|
16309
|
+
}
|
|
16310
|
+
async function prepareCatalogImport(input, inputPath, imports) {
|
|
16311
|
+
const { normalizeImages, paths } = localImageSources(inputPath);
|
|
16312
|
+
const normalizeProduct = (value, includeVariants) => {
|
|
16313
|
+
if (!isObject3(value)) return value;
|
|
16314
|
+
return {
|
|
16315
|
+
...value,
|
|
16316
|
+
..."images" in value ? { images: normalizeImages(value.images) } : {},
|
|
16317
|
+
...includeVariants && Array.isArray(value.variants) ? { variants: value.variants.map((variant) => normalizeProduct(variant, false)) } : {}
|
|
16318
|
+
};
|
|
16319
|
+
};
|
|
16320
|
+
const candidate = isObject3(input) && Array.isArray(input.products) ? { ...input, products: input.products.map((product) => normalizeProduct(product, true)) } : input;
|
|
16321
|
+
const parsed = AgentCatalogImportPreviewInputSchema.safeParse(candidate);
|
|
16322
|
+
if (!parsed.success) {
|
|
16323
|
+
invalidInput("La lista de importaci\xF3n contiene campos inv\xE1lidos o no permitidos");
|
|
16324
|
+
}
|
|
16325
|
+
const files = await readLocalImages(paths);
|
|
16326
|
+
const uploaded = /* @__PURE__ */ new Map();
|
|
16327
|
+
for (const [placeholder, file2] of files) {
|
|
16328
|
+
const temporary = await imports.uploadImage(file2);
|
|
16329
|
+
uploaded.set(placeholder, temporary.id);
|
|
16330
|
+
}
|
|
16331
|
+
const replaceImages = (images) => images?.map((source) => {
|
|
16332
|
+
if (source.kind !== "temporary") return source;
|
|
16333
|
+
const id = uploaded.get(source.temporaryImageId);
|
|
16334
|
+
return id ? { kind: "temporary", temporaryImageId: id } : source;
|
|
16335
|
+
});
|
|
16336
|
+
return {
|
|
16337
|
+
...parsed.data,
|
|
16338
|
+
products: parsed.data.products.map((product) => ({
|
|
16339
|
+
...product,
|
|
16340
|
+
...product.images ? { images: replaceImages(product.images) } : {},
|
|
16341
|
+
...product.variants ? {
|
|
16342
|
+
variants: product.variants.map((variant) => ({
|
|
16343
|
+
...variant,
|
|
16344
|
+
...variant.images ? { images: replaceImages(variant.images) } : {}
|
|
16345
|
+
}))
|
|
16346
|
+
} : {}
|
|
16347
|
+
}))
|
|
16348
|
+
};
|
|
16349
|
+
}
|
|
16350
|
+
|
|
16351
|
+
// src/commands/product-images.ts
|
|
16352
|
+
async function prepareProductUpdate(input, inputPath, allowFiles = true) {
|
|
16353
|
+
const { normalizeImages, paths } = localImageSources(inputPath);
|
|
16354
|
+
const candidate = {
|
|
16355
|
+
...input,
|
|
16356
|
+
..."images" in input ? { images: normalizeImages(input.images) } : {}
|
|
16357
|
+
};
|
|
16358
|
+
if (!allowFiles && paths.size > 0) {
|
|
16359
|
+
throw new CliProtocolError(
|
|
16360
|
+
"CLI_VALIDATION_ERROR",
|
|
16361
|
+
"Para aplicar im\xE1genes ya aprobadas, omite --from y usa --apply --approval-id. Los archivos cambiados requieren una nueva propuesta."
|
|
16362
|
+
);
|
|
16363
|
+
}
|
|
16364
|
+
const parsed = AgentUpdateProductInputSchema.safeParse(candidate);
|
|
16365
|
+
if (!parsed.success) {
|
|
16366
|
+
throw new CliProtocolError(
|
|
16367
|
+
"CLI_VALIDATION_ERROR",
|
|
16368
|
+
"La actualizaci\xF3n contiene campos inv\xE1lidos: usa images o imageAssetIds, con hasta 8 im\xE1genes \xFAnicas y sin URLs."
|
|
16369
|
+
);
|
|
16370
|
+
}
|
|
16371
|
+
const files = await readLocalImages(paths);
|
|
16372
|
+
return { body: parsed.data, files };
|
|
16373
|
+
}
|
|
16374
|
+
function approvedProductUpdate(operation, approvalId, productId) {
|
|
16375
|
+
const input = operation.input;
|
|
16376
|
+
if (operation.id !== approvalId || operation.operationName !== "catalog.products.update" || !input || typeof input !== "object" || Array.isArray(input) || input.productId !== productId || Object.keys(input).some((key) => key !== "productId" && key !== "body")) {
|
|
16377
|
+
throw new CliProtocolError(
|
|
16378
|
+
"CLI_VALIDATION_ERROR",
|
|
16379
|
+
"La aprobaci\xF3n no corresponde a esta actualizaci\xF3n de producto"
|
|
16380
|
+
);
|
|
16381
|
+
}
|
|
16382
|
+
if (operation.state !== "approved" || !Number.isFinite(Date.parse(operation.expiresAt)) || Date.parse(operation.expiresAt) <= Date.now()) {
|
|
16383
|
+
throw new CliProtocolError(
|
|
16384
|
+
"CLI_VALIDATION_ERROR",
|
|
16385
|
+
"La operaci\xF3n debe estar aprobada y vigente antes de aplicar"
|
|
16386
|
+
);
|
|
16387
|
+
}
|
|
16388
|
+
const parsed = AgentUpdateProductInputSchema.safeParse(input.body);
|
|
16389
|
+
if (!parsed.success) {
|
|
16390
|
+
throw new CliProtocolError(
|
|
16391
|
+
"CLI_VALIDATION_ERROR",
|
|
16392
|
+
"El payload aprobado no es una actualizaci\xF3n de producto v\xE1lida"
|
|
16393
|
+
);
|
|
16394
|
+
}
|
|
16395
|
+
return parsed.data;
|
|
16396
|
+
}
|
|
16397
|
+
|
|
16398
|
+
// src/commands/catalog.ts
|
|
16040
16399
|
function requireId(value, name) {
|
|
16041
16400
|
if (!value.trim()) throw new CliProtocolError("CLI_VALIDATION_ERROR", `${name} es obligatorio`);
|
|
16042
16401
|
return value;
|
|
@@ -16114,21 +16473,54 @@ function registerProductCommands(catalog, getClient) {
|
|
|
16114
16473
|
(approvalId) => getClient().products.create(input, approvalId)
|
|
16115
16474
|
);
|
|
16116
16475
|
});
|
|
16117
|
-
withMutationOptions(
|
|
16118
|
-
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16123
|
-
|
|
16124
|
-
|
|
16125
|
-
|
|
16126
|
-
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
|
|
16476
|
+
withMutationOptions(
|
|
16477
|
+
product.command("update <productId>").option("--from <json-file>", "Objeto JSON estructurado"),
|
|
16478
|
+
false
|
|
16479
|
+
).action(async (productId, options, command) => {
|
|
16480
|
+
const id = requireId(productId, "productId");
|
|
16481
|
+
const { approvalId: rawApprovalId } = command.optsWithGlobals();
|
|
16482
|
+
const approvalId = typeof rawApprovalId === "string" ? requireId(rawApprovalId, "approvalId") : void 0;
|
|
16483
|
+
if (!options.from) {
|
|
16484
|
+
if (!wantsApply(command) || !approvalId) {
|
|
16485
|
+
throw new CliProtocolError(
|
|
16486
|
+
"CLI_VALIDATION_ERROR",
|
|
16487
|
+
"--from es obligatorio salvo al aplicar con --apply --approval-id"
|
|
16488
|
+
);
|
|
16489
|
+
}
|
|
16490
|
+
const client = getClient();
|
|
16491
|
+
const operation = await client.operations.get(approvalId);
|
|
16492
|
+
const body = approvedProductUpdate(operation, approvalId, id);
|
|
16493
|
+
emitSuccess(await client.products.update(id, body, approvalId));
|
|
16494
|
+
return;
|
|
16130
16495
|
}
|
|
16131
|
-
|
|
16496
|
+
const input = await readMutationInput(options.from);
|
|
16497
|
+
const prepared = await prepareProductUpdate(input, options.from, approvalId === void 0);
|
|
16498
|
+
if (wantsApply(command) && !approvalId) {
|
|
16499
|
+
const uploaded = /* @__PURE__ */ new Map();
|
|
16500
|
+
for (const [placeholder, file2] of prepared.files) {
|
|
16501
|
+
const image = await getClient().products.uploadImage(file2);
|
|
16502
|
+
uploaded.set(placeholder, image.id);
|
|
16503
|
+
}
|
|
16504
|
+
if (prepared.body.images) {
|
|
16505
|
+
prepared.body.images = prepared.body.images.map((source) => {
|
|
16506
|
+
if (source.kind !== "temporary") return source;
|
|
16507
|
+
return {
|
|
16508
|
+
kind: "temporary",
|
|
16509
|
+
temporaryImageId: uploaded.get(source.temporaryImageId) ?? source.temporaryImageId
|
|
16510
|
+
};
|
|
16511
|
+
});
|
|
16512
|
+
}
|
|
16513
|
+
}
|
|
16514
|
+
await applyOrPreview(
|
|
16515
|
+
command,
|
|
16516
|
+
input,
|
|
16517
|
+
getClient,
|
|
16518
|
+
"catalog.products.update",
|
|
16519
|
+
{ productId: id, body: prepared.body },
|
|
16520
|
+
(approvalId2) => getClient().products.update(id, prepared.body, approvalId2),
|
|
16521
|
+
() => getClient().products.get(id)
|
|
16522
|
+
);
|
|
16523
|
+
});
|
|
16132
16524
|
withMutationOptions(product.command("deactivate <productId>"), false).action(
|
|
16133
16525
|
async (productId, _options, command) => {
|
|
16134
16526
|
const id = requireId(productId, "productId");
|
|
@@ -16305,10 +16697,38 @@ function registerTagCommands(catalog, getClient) {
|
|
|
16305
16697
|
}
|
|
16306
16698
|
function registerAssetCommands(catalog, getClient) {
|
|
16307
16699
|
const asset = catalog.command("asset");
|
|
16308
|
-
asset.command("list").option("--search <text>").option("--limit <number>", "M\xE1ximo de resultados", parseInteger).option("--offset <number>", "Desplazamiento", parseInteger).action(async (options) =>
|
|
16700
|
+
asset.command("list").option("--search <text>").option("--tags <tags>", "Etiquetas separadas por comas; deben coincidir todas").option("--contains-prices <true|false>", "Presencia de precios conocida", parseBoolean).option("--review-status <status>", "incomplete o reviewed").option("--mime-type <type>", "Formato MIME o prefijo image/").option("--limit <number>", "M\xE1ximo de resultados", parseInteger).option("--offset <number>", "Desplazamiento", parseInteger).action(async (options) => {
|
|
16701
|
+
const parsed = AgentAssetFilterInputSchema.safeParse(options);
|
|
16702
|
+
if (!parsed.success) {
|
|
16703
|
+
throw new CliProtocolError("CLI_VALIDATION_ERROR", "Los filtros de assets no son v\xE1lidos");
|
|
16704
|
+
}
|
|
16705
|
+
emitSuccess(await getClient().assets.list(parsed.data));
|
|
16706
|
+
});
|
|
16309
16707
|
asset.command("get <assetId>").action(async (assetId) => {
|
|
16310
16708
|
emitSuccess(await getClient().assets.get(requireId(assetId, "assetId")));
|
|
16311
16709
|
});
|
|
16710
|
+
withMutationOptions(
|
|
16711
|
+
asset.command("update <assetId>").option("--diff", "Incluye la ficha actual")
|
|
16712
|
+
).action(async (assetId, options, command) => {
|
|
16713
|
+
const id = requireId(assetId, "assetId");
|
|
16714
|
+
const parsed = AssetMetadataUpdateInputSchema.safeParse(await readMutationInput(options.from));
|
|
16715
|
+
if (!parsed.success) {
|
|
16716
|
+
throw new CliProtocolError(
|
|
16717
|
+
"CLI_VALIDATION_ERROR",
|
|
16718
|
+
"Metadata inv\xE1lida: incluye expectedRevision y cambios de description o presentation"
|
|
16719
|
+
);
|
|
16720
|
+
}
|
|
16721
|
+
const input = parsed.data;
|
|
16722
|
+
await applyOrPreview(
|
|
16723
|
+
command,
|
|
16724
|
+
input,
|
|
16725
|
+
getClient,
|
|
16726
|
+
"catalog.assets.update",
|
|
16727
|
+
{ assetId: id, body: input },
|
|
16728
|
+
(approvalId) => getClient().assets.update(id, input, approvalId),
|
|
16729
|
+
options.diff ? () => getClient().assets.get(id) : void 0
|
|
16730
|
+
);
|
|
16731
|
+
});
|
|
16312
16732
|
withMutationOptions(
|
|
16313
16733
|
asset.command("upload").requiredOption("--file <path>", "Archivo local"),
|
|
16314
16734
|
false
|
|
@@ -16321,7 +16741,7 @@ function registerAssetCommands(catalog, getClient) {
|
|
|
16321
16741
|
if (!wantsApply(command)) {
|
|
16322
16742
|
emitSuccess({
|
|
16323
16743
|
validated: "local",
|
|
16324
|
-
file:
|
|
16744
|
+
file: basename2(filePath),
|
|
16325
16745
|
sizeBytes: fileStat.size
|
|
16326
16746
|
});
|
|
16327
16747
|
return;
|
|
@@ -16335,7 +16755,7 @@ function registerAssetCommands(catalog, getClient) {
|
|
|
16335
16755
|
);
|
|
16336
16756
|
}
|
|
16337
16757
|
const contents = await readFile2(filePath);
|
|
16338
|
-
const file2 = new File([contents],
|
|
16758
|
+
const file2 = new File([contents], basename2(filePath), { type: mimeType });
|
|
16339
16759
|
const rawApprovalId = command.optsWithGlobals().approvalId;
|
|
16340
16760
|
if (typeof rawApprovalId === "string") {
|
|
16341
16761
|
emitSuccess(await getClient().assets.upload(file2, requireId(rawApprovalId, "approvalId")));
|
|
@@ -16406,27 +16826,13 @@ function registerInventoryCommands(catalog, getClient) {
|
|
|
16406
16826
|
}
|
|
16407
16827
|
);
|
|
16408
16828
|
}
|
|
16409
|
-
function rejectLocalFileSources(value) {
|
|
16410
|
-
if (Array.isArray(value)) {
|
|
16411
|
-
for (const item of value) rejectLocalFileSources(item);
|
|
16412
|
-
return;
|
|
16413
|
-
}
|
|
16414
|
-
if (!value || typeof value !== "object") return;
|
|
16415
|
-
const source = value;
|
|
16416
|
-
if (source.kind === "file") {
|
|
16417
|
-
throw new CliProtocolError(
|
|
16418
|
-
"CLI_VALIDATION_ERROR",
|
|
16419
|
-
"Sube cada imagen local con catalog asset upload, apru\xE9bala y usa su assetId"
|
|
16420
|
-
);
|
|
16421
|
-
}
|
|
16422
|
-
for (const nested of Object.values(source)) rejectLocalFileSources(nested);
|
|
16423
|
-
}
|
|
16424
16829
|
function registerImportCommands(catalog, getClient) {
|
|
16425
16830
|
const imports = catalog.command("import");
|
|
16426
16831
|
imports.command("preview").requiredOption("--from <json-file>", "Lista estructurada para vista previa").action(async (options) => {
|
|
16427
16832
|
const input = await readMutationInput(options.from);
|
|
16428
|
-
|
|
16429
|
-
|
|
16833
|
+
const client = getClient();
|
|
16834
|
+
const prepared = await prepareCatalogImport(input, options.from, client.imports);
|
|
16835
|
+
emitSuccess(await client.imports.preview(prepared));
|
|
16430
16836
|
});
|
|
16431
16837
|
withMutationOptions(imports.command("apply <importId>"), false).action(
|
|
16432
16838
|
async (importId, _options, command) => {
|
|
@@ -16446,6 +16852,36 @@ function registerImportCommands(catalog, getClient) {
|
|
|
16446
16852
|
});
|
|
16447
16853
|
}
|
|
16448
16854
|
|
|
16855
|
+
// src/commands/operation-batches.ts
|
|
16856
|
+
function registerOperationBatchCommands(operation, getClient) {
|
|
16857
|
+
const batch = operation.command("batch").description("Agrupa propuestas para revisarlas con un enlace corto");
|
|
16858
|
+
batch.command("create").description("Crea un grupo de revisi\xF3n; no aprueba ni aplica sus operaciones").requiredOption(
|
|
16859
|
+
"--from <json-file>",
|
|
16860
|
+
"Objeto JSON con operationIds de las propuestas existentes"
|
|
16861
|
+
).action(async (options) => {
|
|
16862
|
+
const parsed = AgentOperationBatchInputSchema.safeParse(
|
|
16863
|
+
await readMutationInput(options.from)
|
|
16864
|
+
);
|
|
16865
|
+
if (!parsed.success) {
|
|
16866
|
+
throw new CliProtocolError(
|
|
16867
|
+
"CLI_VALIDATION_ERROR",
|
|
16868
|
+
parsed.error.issues[0]?.message ?? "Grupo inv\xE1lido"
|
|
16869
|
+
);
|
|
16870
|
+
}
|
|
16871
|
+
emitSuccess(await getClient().operations.createBatch(parsed.data));
|
|
16872
|
+
});
|
|
16873
|
+
batch.command("get <id>").description("Consulta un grupo y recupera su enlace corto de revisi\xF3n").action(async (id) => {
|
|
16874
|
+
const parsed = AgentOperationBatchDtoSchema.shape.id.safeParse(id.trim());
|
|
16875
|
+
if (!parsed.success) {
|
|
16876
|
+
throw new CliProtocolError(
|
|
16877
|
+
"CLI_VALIDATION_ERROR",
|
|
16878
|
+
"El identificador del grupo debe ser un UUID v\xE1lido"
|
|
16879
|
+
);
|
|
16880
|
+
}
|
|
16881
|
+
emitSuccess(await getClient().operations.getBatch(parsed.data));
|
|
16882
|
+
});
|
|
16883
|
+
}
|
|
16884
|
+
|
|
16449
16885
|
// src/commands/auth.ts
|
|
16450
16886
|
import { spawn } from "child_process";
|
|
16451
16887
|
function safeStartResult(start, browserOpened) {
|
|
@@ -16473,7 +16909,7 @@ function safeFinalResult(start, browserOpened, result) {
|
|
|
16473
16909
|
};
|
|
16474
16910
|
}
|
|
16475
16911
|
function sleep(milliseconds) {
|
|
16476
|
-
return new Promise((
|
|
16912
|
+
return new Promise((resolve2) => setTimeout(resolve2, milliseconds));
|
|
16477
16913
|
}
|
|
16478
16914
|
function readAgentKeyFromTty(prompt = "Agent Key de Avileo: ") {
|
|
16479
16915
|
if (!process.stdin.isTTY || !process.stderr.isTTY) {
|
|
@@ -16482,7 +16918,7 @@ function readAgentKeyFromTty(prompt = "Agent Key de Avileo: ") {
|
|
|
16482
16918
|
"auth configure requiere una terminal interactiva; usa AVILEO_AGENT_API_KEY en CI/CD"
|
|
16483
16919
|
);
|
|
16484
16920
|
}
|
|
16485
|
-
return new Promise((
|
|
16921
|
+
return new Promise((resolve2, reject) => {
|
|
16486
16922
|
let value = "";
|
|
16487
16923
|
const input = process.stdin;
|
|
16488
16924
|
const output = process.stderr;
|
|
@@ -16496,7 +16932,7 @@ function readAgentKeyFromTty(prompt = "Agent Key de Avileo: ") {
|
|
|
16496
16932
|
cleanup();
|
|
16497
16933
|
output.write("\n");
|
|
16498
16934
|
if (result instanceof Error) reject(result);
|
|
16499
|
-
else
|
|
16935
|
+
else resolve2(result);
|
|
16500
16936
|
};
|
|
16501
16937
|
const onData = (chunk) => {
|
|
16502
16938
|
for (const character of String(chunk)) {
|
|
@@ -16527,12 +16963,12 @@ function readAgentKeyFromTty(prompt = "Agent Key de Avileo: ") {
|
|
|
16527
16963
|
});
|
|
16528
16964
|
}
|
|
16529
16965
|
async function openWithExecutable(command, args) {
|
|
16530
|
-
return new Promise((
|
|
16966
|
+
return new Promise((resolve2) => {
|
|
16531
16967
|
const child = spawn(command, args, { stdio: "ignore", shell: false, detached: true });
|
|
16532
|
-
child.once("error", () =>
|
|
16968
|
+
child.once("error", () => resolve2(false));
|
|
16533
16969
|
child.once("spawn", () => {
|
|
16534
16970
|
child.unref();
|
|
16535
|
-
|
|
16971
|
+
resolve2(true);
|
|
16536
16972
|
});
|
|
16537
16973
|
});
|
|
16538
16974
|
}
|
|
@@ -16700,6 +17136,7 @@ function createProgram(options = {}) {
|
|
|
16700
17136
|
registerBusinessCommands(program, getClient);
|
|
16701
17137
|
registerCatalogCommands(program, getClient);
|
|
16702
17138
|
const operation = program.command("operation").description("Consulta y aplica operaciones aprobadas en Avileo");
|
|
17139
|
+
registerOperationBatchCommands(operation, getClient);
|
|
16703
17140
|
operation.command("status <id>").description("Consulta el estado de una operaci\xF3n").action(async (id) => {
|
|
16704
17141
|
if (!id.trim()) {
|
|
16705
17142
|
throw new CliProtocolError("CLI_VALIDATION_ERROR", "id es obligatorio");
|