@bacano/sdk 1.2.7 → 1.2.9
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/CATALOG_MANAGEMENT.md +304 -0
- package/README.md +14 -5
- package/STOREFRONT_FORMS.md +38 -0
- package/STOREFRONT_LEADS.md +5 -1
- package/STOREFRONT_PAYMENTS.md +49 -2
- package/catalog-draft-types.d.ts +145 -0
- package/catalog-import-preflight.d.ts +19 -0
- package/catalog-management-types.d.ts +143 -0
- package/catalog-management.cjs +173 -0
- package/catalog-management.d.ts +38 -0
- package/catalog-management.js +150 -0
- package/index.cjs +153 -63
- package/index.js +153 -63
- package/modules/checkout-contact.d.ts +4 -0
- package/package.json +6 -1
- package/react.cjs +153 -63
- package/react.js +153 -63
- package/skills/bacano-web/SKILL.md +10 -3
- package/skills/bacano-web/references/common.md +5 -0
- package/skills/bacano-web/references/forms.md +2 -0
- package/skills/bacano-web/references/storefront.md +15 -0
- package/skills/bacano-web/scripts/cli.mjs +28 -5
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
export interface CatalogCapabilities {
|
|
2
|
+
references: true;
|
|
3
|
+
drafts: boolean;
|
|
4
|
+
images: boolean;
|
|
5
|
+
content: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface CatalogManagementContext {
|
|
8
|
+
companyId: string;
|
|
9
|
+
grantId: string;
|
|
10
|
+
capabilities: CatalogCapabilities;
|
|
11
|
+
allProducts: boolean;
|
|
12
|
+
productIds: string[];
|
|
13
|
+
branchIds: string[];
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
/** Only draft writes; never confirmation or direct product edits. */
|
|
16
|
+
writesAvailable: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface CatalogReferences {
|
|
19
|
+
contractVersion: 1;
|
|
20
|
+
company: {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
country_code: string;
|
|
24
|
+
is_vat_responsible: boolean;
|
|
25
|
+
sales_prices_include_tax_default: boolean;
|
|
26
|
+
};
|
|
27
|
+
priceTypes: Array<{
|
|
28
|
+
price_type: string;
|
|
29
|
+
is_enabled: boolean;
|
|
30
|
+
is_enabled_for_sales: boolean;
|
|
31
|
+
sort_order: number;
|
|
32
|
+
}>;
|
|
33
|
+
taxProfiles: Array<{
|
|
34
|
+
code: string;
|
|
35
|
+
name: string;
|
|
36
|
+
category: string;
|
|
37
|
+
rate: number;
|
|
38
|
+
}>;
|
|
39
|
+
branches: Array<{
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
chains_warehouses: Array<{
|
|
43
|
+
warehouse: {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
};
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
websites: Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
chain_id: string | null;
|
|
53
|
+
is_active: boolean;
|
|
54
|
+
}>;
|
|
55
|
+
categories: Array<{
|
|
56
|
+
name: string;
|
|
57
|
+
product_subcategories: Array<{
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
}>;
|
|
61
|
+
}>;
|
|
62
|
+
measurementUnits: Array<{
|
|
63
|
+
name: string;
|
|
64
|
+
}>;
|
|
65
|
+
rules: {
|
|
66
|
+
saleMustBeLowerThanClient: true;
|
|
67
|
+
existingProductsContentOnly: true;
|
|
68
|
+
humanConfirmationRequired: true;
|
|
69
|
+
inventoryRequiresExistingWarehouse: true;
|
|
70
|
+
taxonomyEndpoint: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export interface CatalogAttributeRule {
|
|
74
|
+
attribute_id: string;
|
|
75
|
+
sort_order: number;
|
|
76
|
+
usage_scope: string;
|
|
77
|
+
is_required: boolean;
|
|
78
|
+
is_filterable: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface CatalogTaxonomy {
|
|
81
|
+
attribute_categories: Array<CatalogAttributeRule & {
|
|
82
|
+
category: string;
|
|
83
|
+
}>;
|
|
84
|
+
attribute_subcategories: Array<CatalogAttributeRule & {
|
|
85
|
+
subcategory_id: string;
|
|
86
|
+
}>;
|
|
87
|
+
attribute_subcategory_exclusions: Array<{
|
|
88
|
+
subcategory_id: string;
|
|
89
|
+
attribute_id: string;
|
|
90
|
+
reason: string | null;
|
|
91
|
+
}>;
|
|
92
|
+
attributes: Array<{
|
|
93
|
+
id: string;
|
|
94
|
+
name: string;
|
|
95
|
+
is_multiple: boolean;
|
|
96
|
+
tooltip: string | null;
|
|
97
|
+
values: unknown;
|
|
98
|
+
attribute_values: Array<{
|
|
99
|
+
id: string;
|
|
100
|
+
code: string;
|
|
101
|
+
sort_order: number;
|
|
102
|
+
metadata: unknown;
|
|
103
|
+
}>;
|
|
104
|
+
attribute_value_sets: Array<{
|
|
105
|
+
id: string;
|
|
106
|
+
code: string;
|
|
107
|
+
category: string;
|
|
108
|
+
attribute_id: string;
|
|
109
|
+
product_subcategory_attribute_value_sets: Array<{
|
|
110
|
+
subcategory_id: string;
|
|
111
|
+
position: number;
|
|
112
|
+
}>;
|
|
113
|
+
attribute_value_set_values: Array<{
|
|
114
|
+
position: number;
|
|
115
|
+
attribute_value: {
|
|
116
|
+
id: string;
|
|
117
|
+
code: string;
|
|
118
|
+
metadata: unknown;
|
|
119
|
+
};
|
|
120
|
+
}>;
|
|
121
|
+
}>;
|
|
122
|
+
}>;
|
|
123
|
+
}
|
|
124
|
+
export interface CatalogProductContent {
|
|
125
|
+
id: string;
|
|
126
|
+
name: string;
|
|
127
|
+
sku: string | null;
|
|
128
|
+
description: string | null;
|
|
129
|
+
long_description: unknown;
|
|
130
|
+
seo_title: string | null;
|
|
131
|
+
seo_description: string | null;
|
|
132
|
+
updated_at: string | null;
|
|
133
|
+
}
|
|
134
|
+
export interface CatalogProductPage {
|
|
135
|
+
items: CatalogProductContent[];
|
|
136
|
+
hasMore: boolean;
|
|
137
|
+
nextOffset: number | null;
|
|
138
|
+
}
|
|
139
|
+
export interface CatalogManagementConfig {
|
|
140
|
+
apiUrl: string;
|
|
141
|
+
accessToken: string | (() => string | Promise<string>);
|
|
142
|
+
fetch?: typeof fetch;
|
|
143
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// libs/sdk/src/catalog-management.ts
|
|
21
|
+
var catalog_management_exports = {};
|
|
22
|
+
__export(catalog_management_exports, {
|
|
23
|
+
CatalogManagementError: () => CatalogManagementError,
|
|
24
|
+
createCatalogManagementClient: () => createCatalogManagementClient,
|
|
25
|
+
getCatalogImportPreflight: () => getCatalogImportPreflight
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(catalog_management_exports);
|
|
28
|
+
|
|
29
|
+
// libs/sdk/src/catalog-import-preflight.ts
|
|
30
|
+
function getCatalogImportPreflight(references) {
|
|
31
|
+
const taxBasis = references.company.sales_prices_include_tax_default ? "included" : "excluded";
|
|
32
|
+
return {
|
|
33
|
+
taxBasis,
|
|
34
|
+
soleWarehouseDefaults: references.branches.flatMap((branch) => {
|
|
35
|
+
const link = branch.chains_warehouses[0];
|
|
36
|
+
return branch.chains_warehouses.length === 1 && link ? [
|
|
37
|
+
{
|
|
38
|
+
chainId: branch.id,
|
|
39
|
+
warehouseId: link.warehouse.id,
|
|
40
|
+
warehouseName: link.warehouse.name
|
|
41
|
+
}
|
|
42
|
+
] : [];
|
|
43
|
+
}),
|
|
44
|
+
questions: [
|
|
45
|
+
{
|
|
46
|
+
id: "destinations",
|
|
47
|
+
prompt: "\xBFEn qu\xE9 sucursales se crear\xE1n los productos, en qu\xE9 webs se mostrar\xE1n y con qu\xE9 estado inicial?",
|
|
48
|
+
options: references.branches.map((branch) => ({
|
|
49
|
+
id: branch.id,
|
|
50
|
+
name: branch.name
|
|
51
|
+
}))
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "prices",
|
|
55
|
+
prompt: "\xBFUsaremos solo el precio normal o tambi\xE9n otros precios habilitados? \xBFQu\xE9 importe corresponde a cada sucursal?",
|
|
56
|
+
options: references.priceTypes.filter((type) => type.is_enabled).map((type) => ({ id: type.price_type, name: type.price_type }))
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "tax",
|
|
60
|
+
prompt: `\xBFQu\xE9 perfil de IVA corresponde? \xBFLos precios de origen incluyen o excluyen IVA? La empresa espera precios con IVA ${taxBasis === "included" ? "incluido" : "excluido"}.`,
|
|
61
|
+
options: references.taxProfiles.map((profile) => ({
|
|
62
|
+
id: profile.code,
|
|
63
|
+
name: `${profile.name} (${profile.rate} %)`
|
|
64
|
+
}))
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "inventory",
|
|
68
|
+
prompt: "\xBFCargaremos inventario inicial? Si s\xED, \xBFqu\xE9 cantidad va en cada variante, sucursal y bodega? Confirma la bodega \xFAnica o elige entre las disponibles."
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// libs/sdk/src/catalog-management.ts
|
|
75
|
+
var CatalogManagementError = class extends Error {
|
|
76
|
+
constructor(code, status, message, details) {
|
|
77
|
+
super(message);
|
|
78
|
+
this.code = code;
|
|
79
|
+
this.status = status;
|
|
80
|
+
this.details = details;
|
|
81
|
+
this.name = "CatalogManagementError";
|
|
82
|
+
}
|
|
83
|
+
code;
|
|
84
|
+
status;
|
|
85
|
+
details;
|
|
86
|
+
};
|
|
87
|
+
function createCatalogManagementClient(config) {
|
|
88
|
+
const base = config.apiUrl.trim().replace(/\/+$/, "");
|
|
89
|
+
const url = new URL(base);
|
|
90
|
+
if (url.username || url.password || url.search || url.hash || !(url.protocol === "https:" || url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
|
|
91
|
+
throw new CatalogManagementError(
|
|
92
|
+
"CATALOG_CONFIG_INVALID",
|
|
93
|
+
0,
|
|
94
|
+
"Usa HTTPS o localhost para el acceso temporal."
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
const fetcher = config.fetch ?? globalThis.fetch;
|
|
98
|
+
async function request(path, input) {
|
|
99
|
+
const token = typeof config.accessToken === "function" ? await config.accessToken() : config.accessToken;
|
|
100
|
+
if (!token.trim())
|
|
101
|
+
throw new CatalogManagementError(
|
|
102
|
+
"CATALOG_ACCESS_INVALID",
|
|
103
|
+
401,
|
|
104
|
+
"Falta el acceso temporal."
|
|
105
|
+
);
|
|
106
|
+
const response = await fetcher(`${base}/api/v1/catalog-management${path}`, {
|
|
107
|
+
method: input ? "POST" : "GET",
|
|
108
|
+
headers: {
|
|
109
|
+
Authorization: `Bearer ${token.trim()}`,
|
|
110
|
+
Accept: "application/json",
|
|
111
|
+
...input ? {
|
|
112
|
+
"Content-Type": input.bytes ? "application/octet-stream" : "application/json"
|
|
113
|
+
} : {}
|
|
114
|
+
},
|
|
115
|
+
...input ? { body: input.bytes ?? JSON.stringify(input.json) } : {},
|
|
116
|
+
cache: "no-store",
|
|
117
|
+
redirect: "error",
|
|
118
|
+
credentials: "omit"
|
|
119
|
+
});
|
|
120
|
+
const payload = await response.json().catch(() => ({}));
|
|
121
|
+
if (!response.ok || payload.success !== true || payload.data === void 0) {
|
|
122
|
+
throw new CatalogManagementError(
|
|
123
|
+
payload.error?.code ?? "CATALOG_REQUEST_FAILED",
|
|
124
|
+
response.status,
|
|
125
|
+
payload.error?.message ?? payload.message ?? "No fue posible consultar el cat\xE1logo.",
|
|
126
|
+
payload.error?.details
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
return payload.data;
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
createBatch: (input) => request("/batches", { json: input }),
|
|
133
|
+
getBatch: (batchId, input = {}) => {
|
|
134
|
+
const query = new URLSearchParams();
|
|
135
|
+
if (input.limit !== void 0) query.set("limit", String(input.limit));
|
|
136
|
+
if (input.after !== void 0) query.set("after", input.after);
|
|
137
|
+
return request(
|
|
138
|
+
`/batches/${encodeURIComponent(batchId)}${query.size ? `?${query}` : ""}`
|
|
139
|
+
);
|
|
140
|
+
},
|
|
141
|
+
getDraft: (batchId, itemId) => request(
|
|
142
|
+
`/batches/${encodeURIComponent(batchId)}/items/${encodeURIComponent(itemId)}`
|
|
143
|
+
),
|
|
144
|
+
sendProposals: (batchId, items) => request(
|
|
145
|
+
`/batches/${encodeURIComponent(batchId)}/items`,
|
|
146
|
+
{ json: { items } }
|
|
147
|
+
),
|
|
148
|
+
uploadImage: (input) => {
|
|
149
|
+
const query = new URLSearchParams({
|
|
150
|
+
source_key: input.source_key,
|
|
151
|
+
expected_revision: String(input.expected_revision),
|
|
152
|
+
request_id: input.request_id
|
|
153
|
+
});
|
|
154
|
+
return request(
|
|
155
|
+
`/batches/${encodeURIComponent(input.batchId)}/items/${encodeURIComponent(input.itemId)}/images?${query}`,
|
|
156
|
+
{ bytes: input.bytes }
|
|
157
|
+
);
|
|
158
|
+
},
|
|
159
|
+
getContext: () => request("/context"),
|
|
160
|
+
getReferences: () => request("/references"),
|
|
161
|
+
getTaxonomy: (category) => request(
|
|
162
|
+
`/references/taxonomy?category=${encodeURIComponent(category)}`
|
|
163
|
+
),
|
|
164
|
+
listProducts: (input = {}) => {
|
|
165
|
+
const query = new URLSearchParams();
|
|
166
|
+
if (input.limit !== void 0) query.set("limit", String(input.limit));
|
|
167
|
+
if (input.offset !== void 0) query.set("offset", String(input.offset));
|
|
168
|
+
return request(
|
|
169
|
+
`/products${query.size ? `?${query}` : ""}`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CatalogManagementConfig, CatalogManagementContext, CatalogProductPage, CatalogReferences, CatalogTaxonomy } from "./catalog-management-types";
|
|
2
|
+
export * from "./catalog-draft-types";
|
|
3
|
+
export * from "./catalog-import-preflight";
|
|
4
|
+
export * from "./catalog-management-types";
|
|
5
|
+
import type { CatalogDraftBatch, CatalogDraftBatchPage, CatalogDraftChunkResult, CatalogDraftImageResult, CatalogDraftResult, CatalogDraftWrite } from "./catalog-draft-types";
|
|
6
|
+
export declare class CatalogManagementError extends Error {
|
|
7
|
+
readonly code: string;
|
|
8
|
+
readonly status: number;
|
|
9
|
+
readonly details?: unknown | undefined;
|
|
10
|
+
constructor(code: string, status: number, message: string, details?: unknown | undefined);
|
|
11
|
+
}
|
|
12
|
+
export declare function createCatalogManagementClient(config: CatalogManagementConfig): {
|
|
13
|
+
createBatch: (input: {
|
|
14
|
+
request_id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
}) => Promise<CatalogDraftBatch>;
|
|
17
|
+
getBatch: (batchId: string, input?: {
|
|
18
|
+
limit?: number;
|
|
19
|
+
after?: string;
|
|
20
|
+
}) => Promise<CatalogDraftBatchPage>;
|
|
21
|
+
getDraft: (batchId: string, itemId: string) => Promise<CatalogDraftResult>;
|
|
22
|
+
sendProposals: (batchId: string, items: CatalogDraftWrite[]) => Promise<CatalogDraftChunkResult>;
|
|
23
|
+
uploadImage: (input: {
|
|
24
|
+
batchId: string;
|
|
25
|
+
itemId: string;
|
|
26
|
+
source_key: string;
|
|
27
|
+
expected_revision: number;
|
|
28
|
+
request_id: string;
|
|
29
|
+
bytes: Blob;
|
|
30
|
+
}) => Promise<CatalogDraftImageResult>;
|
|
31
|
+
getContext: () => Promise<CatalogManagementContext>;
|
|
32
|
+
getReferences: () => Promise<CatalogReferences>;
|
|
33
|
+
getTaxonomy: (category: string) => Promise<CatalogTaxonomy>;
|
|
34
|
+
listProducts: (input?: {
|
|
35
|
+
limit?: number;
|
|
36
|
+
offset?: number;
|
|
37
|
+
}) => Promise<CatalogProductPage>;
|
|
38
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// libs/sdk/src/catalog-import-preflight.ts
|
|
2
|
+
function getCatalogImportPreflight(references) {
|
|
3
|
+
const taxBasis = references.company.sales_prices_include_tax_default ? "included" : "excluded";
|
|
4
|
+
return {
|
|
5
|
+
taxBasis,
|
|
6
|
+
soleWarehouseDefaults: references.branches.flatMap((branch) => {
|
|
7
|
+
const link = branch.chains_warehouses[0];
|
|
8
|
+
return branch.chains_warehouses.length === 1 && link ? [
|
|
9
|
+
{
|
|
10
|
+
chainId: branch.id,
|
|
11
|
+
warehouseId: link.warehouse.id,
|
|
12
|
+
warehouseName: link.warehouse.name
|
|
13
|
+
}
|
|
14
|
+
] : [];
|
|
15
|
+
}),
|
|
16
|
+
questions: [
|
|
17
|
+
{
|
|
18
|
+
id: "destinations",
|
|
19
|
+
prompt: "\xBFEn qu\xE9 sucursales se crear\xE1n los productos, en qu\xE9 webs se mostrar\xE1n y con qu\xE9 estado inicial?",
|
|
20
|
+
options: references.branches.map((branch) => ({
|
|
21
|
+
id: branch.id,
|
|
22
|
+
name: branch.name
|
|
23
|
+
}))
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "prices",
|
|
27
|
+
prompt: "\xBFUsaremos solo el precio normal o tambi\xE9n otros precios habilitados? \xBFQu\xE9 importe corresponde a cada sucursal?",
|
|
28
|
+
options: references.priceTypes.filter((type) => type.is_enabled).map((type) => ({ id: type.price_type, name: type.price_type }))
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "tax",
|
|
32
|
+
prompt: `\xBFQu\xE9 perfil de IVA corresponde? \xBFLos precios de origen incluyen o excluyen IVA? La empresa espera precios con IVA ${taxBasis === "included" ? "incluido" : "excluido"}.`,
|
|
33
|
+
options: references.taxProfiles.map((profile) => ({
|
|
34
|
+
id: profile.code,
|
|
35
|
+
name: `${profile.name} (${profile.rate} %)`
|
|
36
|
+
}))
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "inventory",
|
|
40
|
+
prompt: "\xBFCargaremos inventario inicial? Si s\xED, \xBFqu\xE9 cantidad va en cada variante, sucursal y bodega? Confirma la bodega \xFAnica o elige entre las disponibles."
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// libs/sdk/src/catalog-management.ts
|
|
47
|
+
var CatalogManagementError = class extends Error {
|
|
48
|
+
constructor(code, status, message, details) {
|
|
49
|
+
super(message);
|
|
50
|
+
this.code = code;
|
|
51
|
+
this.status = status;
|
|
52
|
+
this.details = details;
|
|
53
|
+
this.name = "CatalogManagementError";
|
|
54
|
+
}
|
|
55
|
+
code;
|
|
56
|
+
status;
|
|
57
|
+
details;
|
|
58
|
+
};
|
|
59
|
+
function createCatalogManagementClient(config) {
|
|
60
|
+
const base = config.apiUrl.trim().replace(/\/+$/, "");
|
|
61
|
+
const url = new URL(base);
|
|
62
|
+
if (url.username || url.password || url.search || url.hash || !(url.protocol === "https:" || url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
|
|
63
|
+
throw new CatalogManagementError(
|
|
64
|
+
"CATALOG_CONFIG_INVALID",
|
|
65
|
+
0,
|
|
66
|
+
"Usa HTTPS o localhost para el acceso temporal."
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const fetcher = config.fetch ?? globalThis.fetch;
|
|
70
|
+
async function request(path, input) {
|
|
71
|
+
const token = typeof config.accessToken === "function" ? await config.accessToken() : config.accessToken;
|
|
72
|
+
if (!token.trim())
|
|
73
|
+
throw new CatalogManagementError(
|
|
74
|
+
"CATALOG_ACCESS_INVALID",
|
|
75
|
+
401,
|
|
76
|
+
"Falta el acceso temporal."
|
|
77
|
+
);
|
|
78
|
+
const response = await fetcher(`${base}/api/v1/catalog-management${path}`, {
|
|
79
|
+
method: input ? "POST" : "GET",
|
|
80
|
+
headers: {
|
|
81
|
+
Authorization: `Bearer ${token.trim()}`,
|
|
82
|
+
Accept: "application/json",
|
|
83
|
+
...input ? {
|
|
84
|
+
"Content-Type": input.bytes ? "application/octet-stream" : "application/json"
|
|
85
|
+
} : {}
|
|
86
|
+
},
|
|
87
|
+
...input ? { body: input.bytes ?? JSON.stringify(input.json) } : {},
|
|
88
|
+
cache: "no-store",
|
|
89
|
+
redirect: "error",
|
|
90
|
+
credentials: "omit"
|
|
91
|
+
});
|
|
92
|
+
const payload = await response.json().catch(() => ({}));
|
|
93
|
+
if (!response.ok || payload.success !== true || payload.data === void 0) {
|
|
94
|
+
throw new CatalogManagementError(
|
|
95
|
+
payload.error?.code ?? "CATALOG_REQUEST_FAILED",
|
|
96
|
+
response.status,
|
|
97
|
+
payload.error?.message ?? payload.message ?? "No fue posible consultar el cat\xE1logo.",
|
|
98
|
+
payload.error?.details
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return payload.data;
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
createBatch: (input) => request("/batches", { json: input }),
|
|
105
|
+
getBatch: (batchId, input = {}) => {
|
|
106
|
+
const query = new URLSearchParams();
|
|
107
|
+
if (input.limit !== void 0) query.set("limit", String(input.limit));
|
|
108
|
+
if (input.after !== void 0) query.set("after", input.after);
|
|
109
|
+
return request(
|
|
110
|
+
`/batches/${encodeURIComponent(batchId)}${query.size ? `?${query}` : ""}`
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
getDraft: (batchId, itemId) => request(
|
|
114
|
+
`/batches/${encodeURIComponent(batchId)}/items/${encodeURIComponent(itemId)}`
|
|
115
|
+
),
|
|
116
|
+
sendProposals: (batchId, items) => request(
|
|
117
|
+
`/batches/${encodeURIComponent(batchId)}/items`,
|
|
118
|
+
{ json: { items } }
|
|
119
|
+
),
|
|
120
|
+
uploadImage: (input) => {
|
|
121
|
+
const query = new URLSearchParams({
|
|
122
|
+
source_key: input.source_key,
|
|
123
|
+
expected_revision: String(input.expected_revision),
|
|
124
|
+
request_id: input.request_id
|
|
125
|
+
});
|
|
126
|
+
return request(
|
|
127
|
+
`/batches/${encodeURIComponent(input.batchId)}/items/${encodeURIComponent(input.itemId)}/images?${query}`,
|
|
128
|
+
{ bytes: input.bytes }
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
getContext: () => request("/context"),
|
|
132
|
+
getReferences: () => request("/references"),
|
|
133
|
+
getTaxonomy: (category) => request(
|
|
134
|
+
`/references/taxonomy?category=${encodeURIComponent(category)}`
|
|
135
|
+
),
|
|
136
|
+
listProducts: (input = {}) => {
|
|
137
|
+
const query = new URLSearchParams();
|
|
138
|
+
if (input.limit !== void 0) query.set("limit", String(input.limit));
|
|
139
|
+
if (input.offset !== void 0) query.set("offset", String(input.offset));
|
|
140
|
+
return request(
|
|
141
|
+
`/products${query.size ? `?${query}` : ""}`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
export {
|
|
147
|
+
CatalogManagementError,
|
|
148
|
+
createCatalogManagementClient,
|
|
149
|
+
getCatalogImportPreflight
|
|
150
|
+
};
|