@pakento/cms-sdk 4.2.0 → 4.3.1
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.d.mts +56 -4
- package/dist/index.d.ts +56 -4
- package/dist/index.js +75 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +72 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -69,6 +69,15 @@ interface Entity {
|
|
|
69
69
|
featured_image_width: string;
|
|
70
70
|
featured_image_height: string;
|
|
71
71
|
}
|
|
72
|
+
interface ApiResponse<T> {
|
|
73
|
+
data: T[] | null;
|
|
74
|
+
totalDocs?: number;
|
|
75
|
+
totalPages?: number;
|
|
76
|
+
prevPage?: number | null;
|
|
77
|
+
nextPage?: number | null;
|
|
78
|
+
error?: boolean;
|
|
79
|
+
errorMessage?: string | null;
|
|
80
|
+
}
|
|
72
81
|
interface WhereEquals {
|
|
73
82
|
equals?: string;
|
|
74
83
|
}
|
|
@@ -135,12 +144,43 @@ interface SendContactUsEmailParams {
|
|
|
135
144
|
notes?: string;
|
|
136
145
|
subject?: string;
|
|
137
146
|
}
|
|
147
|
+
interface ItemEcommerceRaw {
|
|
148
|
+
id: string;
|
|
149
|
+
name: string;
|
|
150
|
+
featured: boolean;
|
|
151
|
+
description: string;
|
|
152
|
+
url_safe_name: string;
|
|
153
|
+
images: {
|
|
154
|
+
url: string;
|
|
155
|
+
thumbnailURL: string;
|
|
156
|
+
}[];
|
|
157
|
+
coverImage: {
|
|
158
|
+
url: string;
|
|
159
|
+
thumbnailURL: string;
|
|
160
|
+
} | null;
|
|
161
|
+
item_prices: {
|
|
162
|
+
docs: {
|
|
163
|
+
amount: number;
|
|
164
|
+
old_price: number;
|
|
165
|
+
price_text: string;
|
|
166
|
+
price_notes: string;
|
|
167
|
+
}[];
|
|
168
|
+
};
|
|
169
|
+
brand: {
|
|
170
|
+
id: string;
|
|
171
|
+
name: string;
|
|
172
|
+
} | null;
|
|
173
|
+
item_category: {
|
|
174
|
+
id: string;
|
|
175
|
+
name: string;
|
|
176
|
+
} | null;
|
|
177
|
+
}
|
|
138
178
|
interface ItemsRawResponse {
|
|
139
179
|
totalDocs: number;
|
|
140
180
|
totalPages: number;
|
|
141
181
|
prevPage: number | null;
|
|
142
182
|
nextPage: number | null;
|
|
143
|
-
docs:
|
|
183
|
+
docs: ItemEcommerceRaw[];
|
|
144
184
|
}
|
|
145
185
|
interface CategoriesRawResponse {
|
|
146
186
|
docs: Category[];
|
|
@@ -163,7 +203,6 @@ interface EntityRawResponse {
|
|
|
163
203
|
}
|
|
164
204
|
interface ItemsApiResponse {
|
|
165
205
|
data: ItemsRawResponse | null;
|
|
166
|
-
items: Item[];
|
|
167
206
|
totalDocs: number;
|
|
168
207
|
totalPages: number;
|
|
169
208
|
prevPage: number | null;
|
|
@@ -232,7 +271,7 @@ declare class PakentoCMSAPI {
|
|
|
232
271
|
});
|
|
233
272
|
private handleApiError;
|
|
234
273
|
private fetchGraphQL;
|
|
235
|
-
getItems(params?: GetItemsParams): Promise<
|
|
274
|
+
getItems(params?: GetItemsParams): Promise<ApiResponse<Item>>;
|
|
236
275
|
private fetchItemsFromAPI;
|
|
237
276
|
getCategories(params?: GetCategoriesParams): Promise<CategoriesApiResponse>;
|
|
238
277
|
private fetchCategoriesFromAPI;
|
|
@@ -300,4 +339,17 @@ declare class CacheService {
|
|
|
300
339
|
}>;
|
|
301
340
|
}
|
|
302
341
|
|
|
303
|
-
|
|
342
|
+
/**
|
|
343
|
+
* Parses a raw GraphQL response item to the normalized Item type
|
|
344
|
+
* @param rawItem - The raw item from GraphQL response
|
|
345
|
+
* @returns Normalized Item object
|
|
346
|
+
*/
|
|
347
|
+
declare function parseRawItemToItem(rawItem: ItemEcommerceRaw): Item;
|
|
348
|
+
/**
|
|
349
|
+
* Parses an array of raw GraphQL response items to normalized Item types
|
|
350
|
+
* @param rawItems - Array of raw items from GraphQL response
|
|
351
|
+
* @returns Array of normalized Item objects
|
|
352
|
+
*/
|
|
353
|
+
declare function parseRawItemsToItems(rawItems: ItemEcommerceRaw[]): Item[];
|
|
354
|
+
|
|
355
|
+
export { type Brand, type BrandsApiResponse, type BrandsRawResponse, CacheService, type CategoriesApiResponse, type CategoriesRawResponse, type CategoriesWhere, type Category, type CreateEcommerceOrderParams, type CreateEcommerceOrderResponse, type CustomGraphQLParams, type CustomGraphQLResponse, type Entity, type EntityApiResponse, type EntityRawResponse, type GetBrandsParams, type GetCategoriesParams, type GetEntityParams, type GetItemsParams, type Item, type ItemImage, type ItemsApiResponse, type ItemsRawResponse, type ItemsWhere, type SendContactUsEmailParams, type SendContactUsEmailResponse, type WhereEquals, pakentoCMSAPI, parseRawItemToItem, parseRawItemsToItems };
|
package/dist/index.d.ts
CHANGED
|
@@ -69,6 +69,15 @@ interface Entity {
|
|
|
69
69
|
featured_image_width: string;
|
|
70
70
|
featured_image_height: string;
|
|
71
71
|
}
|
|
72
|
+
interface ApiResponse<T> {
|
|
73
|
+
data: T[] | null;
|
|
74
|
+
totalDocs?: number;
|
|
75
|
+
totalPages?: number;
|
|
76
|
+
prevPage?: number | null;
|
|
77
|
+
nextPage?: number | null;
|
|
78
|
+
error?: boolean;
|
|
79
|
+
errorMessage?: string | null;
|
|
80
|
+
}
|
|
72
81
|
interface WhereEquals {
|
|
73
82
|
equals?: string;
|
|
74
83
|
}
|
|
@@ -135,12 +144,43 @@ interface SendContactUsEmailParams {
|
|
|
135
144
|
notes?: string;
|
|
136
145
|
subject?: string;
|
|
137
146
|
}
|
|
147
|
+
interface ItemEcommerceRaw {
|
|
148
|
+
id: string;
|
|
149
|
+
name: string;
|
|
150
|
+
featured: boolean;
|
|
151
|
+
description: string;
|
|
152
|
+
url_safe_name: string;
|
|
153
|
+
images: {
|
|
154
|
+
url: string;
|
|
155
|
+
thumbnailURL: string;
|
|
156
|
+
}[];
|
|
157
|
+
coverImage: {
|
|
158
|
+
url: string;
|
|
159
|
+
thumbnailURL: string;
|
|
160
|
+
} | null;
|
|
161
|
+
item_prices: {
|
|
162
|
+
docs: {
|
|
163
|
+
amount: number;
|
|
164
|
+
old_price: number;
|
|
165
|
+
price_text: string;
|
|
166
|
+
price_notes: string;
|
|
167
|
+
}[];
|
|
168
|
+
};
|
|
169
|
+
brand: {
|
|
170
|
+
id: string;
|
|
171
|
+
name: string;
|
|
172
|
+
} | null;
|
|
173
|
+
item_category: {
|
|
174
|
+
id: string;
|
|
175
|
+
name: string;
|
|
176
|
+
} | null;
|
|
177
|
+
}
|
|
138
178
|
interface ItemsRawResponse {
|
|
139
179
|
totalDocs: number;
|
|
140
180
|
totalPages: number;
|
|
141
181
|
prevPage: number | null;
|
|
142
182
|
nextPage: number | null;
|
|
143
|
-
docs:
|
|
183
|
+
docs: ItemEcommerceRaw[];
|
|
144
184
|
}
|
|
145
185
|
interface CategoriesRawResponse {
|
|
146
186
|
docs: Category[];
|
|
@@ -163,7 +203,6 @@ interface EntityRawResponse {
|
|
|
163
203
|
}
|
|
164
204
|
interface ItemsApiResponse {
|
|
165
205
|
data: ItemsRawResponse | null;
|
|
166
|
-
items: Item[];
|
|
167
206
|
totalDocs: number;
|
|
168
207
|
totalPages: number;
|
|
169
208
|
prevPage: number | null;
|
|
@@ -232,7 +271,7 @@ declare class PakentoCMSAPI {
|
|
|
232
271
|
});
|
|
233
272
|
private handleApiError;
|
|
234
273
|
private fetchGraphQL;
|
|
235
|
-
getItems(params?: GetItemsParams): Promise<
|
|
274
|
+
getItems(params?: GetItemsParams): Promise<ApiResponse<Item>>;
|
|
236
275
|
private fetchItemsFromAPI;
|
|
237
276
|
getCategories(params?: GetCategoriesParams): Promise<CategoriesApiResponse>;
|
|
238
277
|
private fetchCategoriesFromAPI;
|
|
@@ -300,4 +339,17 @@ declare class CacheService {
|
|
|
300
339
|
}>;
|
|
301
340
|
}
|
|
302
341
|
|
|
303
|
-
|
|
342
|
+
/**
|
|
343
|
+
* Parses a raw GraphQL response item to the normalized Item type
|
|
344
|
+
* @param rawItem - The raw item from GraphQL response
|
|
345
|
+
* @returns Normalized Item object
|
|
346
|
+
*/
|
|
347
|
+
declare function parseRawItemToItem(rawItem: ItemEcommerceRaw): Item;
|
|
348
|
+
/**
|
|
349
|
+
* Parses an array of raw GraphQL response items to normalized Item types
|
|
350
|
+
* @param rawItems - Array of raw items from GraphQL response
|
|
351
|
+
* @returns Array of normalized Item objects
|
|
352
|
+
*/
|
|
353
|
+
declare function parseRawItemsToItems(rawItems: ItemEcommerceRaw[]): Item[];
|
|
354
|
+
|
|
355
|
+
export { type Brand, type BrandsApiResponse, type BrandsRawResponse, CacheService, type CategoriesApiResponse, type CategoriesRawResponse, type CategoriesWhere, type Category, type CreateEcommerceOrderParams, type CreateEcommerceOrderResponse, type CustomGraphQLParams, type CustomGraphQLResponse, type Entity, type EntityApiResponse, type EntityRawResponse, type GetBrandsParams, type GetCategoriesParams, type GetEntityParams, type GetItemsParams, type Item, type ItemImage, type ItemsApiResponse, type ItemsRawResponse, type ItemsWhere, type SendContactUsEmailParams, type SendContactUsEmailResponse, type WhereEquals, pakentoCMSAPI, parseRawItemToItem, parseRawItemsToItems };
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CacheService: () => CacheService,
|
|
34
|
-
pakentoCMSAPI: () => pakentoCMSAPI
|
|
34
|
+
pakentoCMSAPI: () => pakentoCMSAPI,
|
|
35
|
+
parseRawItemToItem: () => parseRawItemToItem,
|
|
36
|
+
parseRawItemsToItems: () => parseRawItemsToItems
|
|
35
37
|
});
|
|
36
38
|
module.exports = __toCommonJS(index_exports);
|
|
37
39
|
|
|
@@ -273,6 +275,43 @@ var CacheService = class {
|
|
|
273
275
|
|
|
274
276
|
// src/services/api.ts
|
|
275
277
|
var import_zod = require("zod");
|
|
278
|
+
|
|
279
|
+
// src/utils/itemParser.ts
|
|
280
|
+
function parseRawItemToItem(rawItem) {
|
|
281
|
+
const firstPrice = rawItem.item_prices.docs[0];
|
|
282
|
+
const images = rawItem.images.map((img) => ({
|
|
283
|
+
url: img.url,
|
|
284
|
+
thumbnail_url: img.thumbnailURL
|
|
285
|
+
}));
|
|
286
|
+
const coverImageUrl = rawItem.coverImage?.url || rawItem.images[0]?.url || "";
|
|
287
|
+
const coverImageThumbnailUrl = rawItem.coverImage?.thumbnailURL || rawItem.images[0]?.thumbnailURL || "";
|
|
288
|
+
return {
|
|
289
|
+
id: rawItem.id,
|
|
290
|
+
name: rawItem.name,
|
|
291
|
+
featured: rawItem.featured,
|
|
292
|
+
url_safe_name: rawItem.url_safe_name,
|
|
293
|
+
currency_prefix: "$",
|
|
294
|
+
// Default currency prefix, could be made configurable
|
|
295
|
+
description: rawItem.description,
|
|
296
|
+
old_price: firstPrice?.old_price || 0,
|
|
297
|
+
item_category_name: rawItem.item_category?.name || "",
|
|
298
|
+
item_category_id: parseInt(rawItem.item_category?.id || "0"),
|
|
299
|
+
price_text: firstPrice?.price_text || "",
|
|
300
|
+
price_notes: firstPrice?.price_notes || "",
|
|
301
|
+
// Not available in raw response
|
|
302
|
+
price: firstPrice?.amount || 0,
|
|
303
|
+
brand_id: parseInt(rawItem.brand?.id || "0"),
|
|
304
|
+
brand_name: rawItem.brand?.name || "",
|
|
305
|
+
cover_image_url: coverImageUrl,
|
|
306
|
+
cover_image_thumbnail_url: coverImageThumbnailUrl,
|
|
307
|
+
images
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
function parseRawItemsToItems(rawItems) {
|
|
311
|
+
return rawItems.map(parseRawItemToItem);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// src/services/api.ts
|
|
276
315
|
var PakentoCMSAPI = class {
|
|
277
316
|
constructor(config) {
|
|
278
317
|
this.defaultTTL = 86400;
|
|
@@ -360,7 +399,6 @@ var PakentoCMSAPI = class {
|
|
|
360
399
|
);
|
|
361
400
|
return {
|
|
362
401
|
data: null,
|
|
363
|
-
items: [],
|
|
364
402
|
totalDocs: 0,
|
|
365
403
|
totalPages: 0,
|
|
366
404
|
prevPage: null,
|
|
@@ -371,18 +409,26 @@ var PakentoCMSAPI = class {
|
|
|
371
409
|
}
|
|
372
410
|
const { skipCache = false, cacheTTL, ...rest } = validatedParams.data;
|
|
373
411
|
const cacheKey = this.cache.buildCacheKey("GetEcommerceItems", rest);
|
|
374
|
-
|
|
412
|
+
const finalData = await this.cache.getCachedOrFetch(
|
|
375
413
|
cacheKey,
|
|
376
414
|
() => this.fetchItemsFromAPI(rest),
|
|
377
415
|
cacheTTL,
|
|
378
416
|
skipCache
|
|
379
417
|
);
|
|
418
|
+
return {
|
|
419
|
+
data: finalData.data,
|
|
420
|
+
totalDocs: finalData.totalDocs,
|
|
421
|
+
totalPages: finalData.totalPages,
|
|
422
|
+
prevPage: finalData.prevPage,
|
|
423
|
+
nextPage: finalData.nextPage,
|
|
424
|
+
error: false,
|
|
425
|
+
errorMessage: null
|
|
426
|
+
};
|
|
380
427
|
}
|
|
381
428
|
async fetchItemsFromAPI(params = {}) {
|
|
382
429
|
if (!this.baseURL || !this.apiKey) {
|
|
383
430
|
return {
|
|
384
431
|
data: null,
|
|
385
|
-
items: [],
|
|
386
432
|
totalDocs: 0,
|
|
387
433
|
totalPages: 0,
|
|
388
434
|
prevPage: null,
|
|
@@ -420,22 +466,31 @@ var PakentoCMSAPI = class {
|
|
|
420
466
|
id
|
|
421
467
|
name
|
|
422
468
|
featured
|
|
423
|
-
old_price
|
|
424
|
-
currency_prefix
|
|
425
469
|
description
|
|
426
|
-
price_text
|
|
427
|
-
price_notes
|
|
428
470
|
url_safe_name
|
|
429
|
-
price
|
|
430
|
-
brand_id
|
|
431
|
-
brand_name
|
|
432
|
-
cover_image_url
|
|
433
|
-
cover_image_thumbnail_url
|
|
434
|
-
item_category_name
|
|
435
|
-
item_category_id
|
|
436
471
|
images {
|
|
437
472
|
url
|
|
438
|
-
|
|
473
|
+
thumbnailURL
|
|
474
|
+
}
|
|
475
|
+
coverImage {
|
|
476
|
+
url
|
|
477
|
+
thumbnailURL
|
|
478
|
+
}
|
|
479
|
+
item_prices {
|
|
480
|
+
docs {
|
|
481
|
+
amount
|
|
482
|
+
old_price
|
|
483
|
+
price_text
|
|
484
|
+
price_notes
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
brand {
|
|
488
|
+
id
|
|
489
|
+
name
|
|
490
|
+
}
|
|
491
|
+
item_category {
|
|
492
|
+
id
|
|
493
|
+
name
|
|
439
494
|
}
|
|
440
495
|
}
|
|
441
496
|
}
|
|
@@ -470,7 +525,6 @@ var PakentoCMSAPI = class {
|
|
|
470
525
|
if (error) {
|
|
471
526
|
return {
|
|
472
527
|
data: null,
|
|
473
|
-
items: [],
|
|
474
528
|
totalDocs: 0,
|
|
475
529
|
totalPages: 0,
|
|
476
530
|
prevPage: null,
|
|
@@ -480,8 +534,7 @@ var PakentoCMSAPI = class {
|
|
|
480
534
|
};
|
|
481
535
|
}
|
|
482
536
|
return {
|
|
483
|
-
data,
|
|
484
|
-
items: data.docs,
|
|
537
|
+
data: parseRawItemsToItems(data.docs),
|
|
485
538
|
totalDocs: data.totalDocs,
|
|
486
539
|
totalPages: data.totalPages,
|
|
487
540
|
prevPage: data.prevPage,
|
|
@@ -929,6 +982,8 @@ var pakentoCMSAPI = new PakentoCMSAPI();
|
|
|
929
982
|
// Annotate the CommonJS export names for ESM import in node:
|
|
930
983
|
0 && (module.exports = {
|
|
931
984
|
CacheService,
|
|
932
|
-
pakentoCMSAPI
|
|
985
|
+
pakentoCMSAPI,
|
|
986
|
+
parseRawItemToItem,
|
|
987
|
+
parseRawItemsToItems
|
|
933
988
|
});
|
|
934
989
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/services/api.ts","../src/services/cache.ts"],"sourcesContent":["// Services\nexport { pakentoCMSAPI } from \"./services/api\";\nexport { CacheService } from \"./services/cache\";\n\n// Types\nexport type {\n // Base types\n Item,\n ItemImage,\n Category,\n Brand,\n Entity,\n\n // GraphQL Where conditions\n WhereEquals,\n ItemsWhere,\n CategoriesWhere,\n\n // API Parameters\n GetItemsParams,\n GetCategoriesParams,\n GetBrandsParams,\n GetEntityParams,\n CreateEcommerceOrderParams,\n SendContactUsEmailParams,\n CustomGraphQLParams,\n\n // Raw API Response types\n ItemsRawResponse,\n CategoriesRawResponse,\n BrandsRawResponse,\n EntityRawResponse,\n\n // API Response types with error handling\n ItemsApiResponse,\n CategoriesApiResponse,\n BrandsApiResponse,\n EntityApiResponse,\n CreateEcommerceOrderResponse,\n SendContactUsEmailResponse,\n CustomGraphQLResponse,\n} from \"./types\";\n","import axios, { AxiosInstance, AxiosError } from \"axios\";\nimport type {\n GetItemsParams,\n GetCategoriesParams,\n GetBrandsParams,\n GetEntityParams,\n CreateEcommerceOrderParams,\n SendContactUsEmailParams,\n CustomGraphQLParams,\n ItemsApiResponse,\n CategoriesApiResponse,\n BrandsApiResponse,\n EntityApiResponse,\n CreateEcommerceOrderResponse,\n SendContactUsEmailResponse,\n CustomGraphQLResponse,\n ItemsRawResponse,\n CategoriesRawResponse,\n BrandsRawResponse,\n ItemsWhere,\n} from \"../types\";\n\nimport { CacheService } from \"./cache\";\nimport { z } from \"zod\";\n\nclass PakentoCMSAPI {\n private client: AxiosInstance;\n private cache: CacheService;\n private defaultTTL: number = 86400;\n private baseURL: string;\n private apiKey: string;\n\n constructor(config?: { cacheTTL?: number }) {\n this.baseURL = process.env.PAKENTO_CMS_BASE_URL || \"\";\n this.apiKey = process.env.PAKENTO_API_KEY || \"\";\n\n if (config?.cacheTTL && typeof config.cacheTTL === \"number\") {\n this.defaultTTL = config.cacheTTL;\n }\n\n this.cache = new CacheService(this.defaultTTL, this.apiKey);\n\n this.client = axios.create({\n baseURL: this.baseURL,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `users API-Key ${this.apiKey}`,\n },\n });\n\n // Interceptor para imprimir las URLs de las llamadas a la API\n this.client.interceptors.request.use(\n (config) => {\n const fullUrl = `${config.baseURL}${config.url}`;\n console.log(`🌐 API Call: ${config.method?.toUpperCase()} ${fullUrl}`);\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n }\n\n // Centralized error handler\n private handleApiError(error: unknown, context: string): string {\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const responseMessage = error.response?.data?.message;\n if (status === 401) return \"API Key inválida o expirada\";\n if (status === 404) return `${context} no encontrado`;\n if (status && status >= 500) return \"Error del servidor CMS\";\n return (\n responseMessage || `Error de conexión en ${context}: ${error.message}`\n );\n } else if (error instanceof z.ZodError) {\n return `Validación fallida: ${error.issues\n .map((e: { message: string }) => e.message)\n .join(\", \")}`;\n } else if (error instanceof Error) {\n return error.message;\n }\n return \"Error desconocido\";\n }\n\n // Generic GraphQL fetcher\n private async fetchGraphQL<T>(\n query: string,\n variables: any,\n extractData: (responseData: any) => T\n ): Promise<{ data: T | null; error: boolean; errorMessage: string | null }> {\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query,\n variables,\n });\n\n if (response.data.errors) {\n const errorMessage = `GraphQL Error: ${response.data.errors[0].message}`;\n return { data: null, error: true, errorMessage };\n }\n\n const data = extractData(response.data.data);\n return { data, error: false, errorMessage: null };\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"GraphQL query\");\n return { data: null, error: true, errorMessage };\n }\n }\n\n async getItems(params: GetItemsParams = {}): Promise<ItemsApiResponse> {\n // Zod schema for validation\n const itemsSchema = z.object({\n where: z\n .object({\n item_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n item_super_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n brand_id: z.object({ equals: z.string().optional() }).optional(),\n id: z.object({ equals: z.string().optional() }).optional(),\n })\n .optional(),\n onlyOffers: z.boolean().optional(),\n limit: z.coerce.number().optional(),\n page: z.coerce.number().optional(),\n search: z.string().optional(),\n sort: z.string().optional(),\n minPrice: z.coerce.number().optional(),\n maxPrice: z.coerce.number().optional(),\n skipCache: z.boolean().optional(),\n cacheTTL: z.number().optional(),\n });\n\n const validatedParams = itemsSchema.safeParse(params);\n if (!validatedParams.success) {\n const errorMessage = this.handleApiError(\n validatedParams.error,\n \"getItems validation\"\n );\n return {\n data: null,\n items: [],\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n const { skipCache = false, cacheTTL, ...rest } = validatedParams.data;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceItems\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchItemsFromAPI(rest as GetItemsParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchItemsFromAPI(\n params: GetItemsParams = {}\n ): Promise<ItemsApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n items: [],\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Use generic fetchGraphQL\n const query = `\n query GetEcommerceItems(\n $where: EcommerceItemsWhere\n $onlyOffers: Boolean\n $limit: Int\n $page: Int\n $search: String\n $sort: String\n $minPrice: Float\n $maxPrice: Float\n ) {\n GetEcommerceItems(\n where: $where\n onlyOffers: $onlyOffers\n limit: $limit\n page: $page\n search: $search\n sort: $sort\n minPrice: $minPrice\n maxPrice: $maxPrice\n ) {\n totalDocs\n totalPages\n prevPage\n nextPage\n docs {\n id\n name\n featured\n old_price\n currency_prefix\n description\n price_text\n price_notes\n url_safe_name\n price\n brand_id\n brand_name\n cover_image_url\n cover_image_thumbnail_url\n item_category_name\n item_category_id\n images {\n url\n thumbnail_url\n }\n }\n }\n }\n `;\n\n // Construir variables (similar to before)\n const whereConditions: ItemsWhere = {};\n if (params.where?.item_category_id?.equals) {\n whereConditions.item_category_id = {\n equals: params.where.item_category_id.equals,\n };\n }\n\n if (params.where?.item_super_category_id?.equals) {\n whereConditions.item_super_category_id = {\n equals: params.where.item_super_category_id.equals,\n };\n }\n\n if (params.where?.brand_id?.equals) {\n whereConditions.brand_id = { equals: params.where.brand_id.equals };\n }\n\n if (params.where?.id?.equals) {\n whereConditions.id = { equals: params.where.id.equals };\n }\n\n const variables = {\n ...params,\n where:\n Object.keys(whereConditions).length > 0 ? whereConditions : undefined,\n };\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<ItemsRawResponse>(\n query,\n variables,\n (responseData) => responseData.GetEcommerceItems\n );\n\n if (error) {\n return {\n data: null,\n items: [],\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data,\n items: data!.docs,\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n prevPage: data!.prevPage,\n nextPage: data!.nextPage,\n error: false,\n errorMessage: null,\n };\n }\n\n async getCategories(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n const {\n skipCache = false,\n cacheTTL,\n ...rest\n } = params as GetCategoriesParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceCategories\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchCategoriesFromAPI(rest as GetCategoriesParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchCategoriesFromAPI(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceCategories(\n $where: EcommerceCategoriesWhere\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceCategories(\n where: $where\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n image_url\n }\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<CategoriesRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceCategories\n );\n\n if (error) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!.docs,\n categories: data!.docs,\n error: false,\n errorMessage: null,\n };\n }\n\n async getBrands(params: GetBrandsParams = {}): Promise<BrandsApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetBrandsParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceBrands\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchBrandsFromAPI(rest as GetBrandsParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchBrandsFromAPI(\n params: GetBrandsParams = {}\n ): Promise<BrandsApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceBrands(\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceBrands(\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n description\n items_count\n image_url\n image_thumbnail_url\n image_alt\n }\n hasNextPage\n hasPrevPage\n limit\n nextPage\n offset\n page\n pagingCounter\n prevPage\n totalDocs\n totalPages\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<BrandsRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceBrands\n );\n\n if (error) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n brands: data!.docs,\n hasNextPage: data!.hasNextPage,\n hasPrevPage: data!.hasPrevPage,\n limit: data!.limit,\n nextPage: data!.nextPage,\n offset: data!.offset,\n page: data!.page,\n pagingCounter: data!.pagingCounter,\n prevPage: data!.prevPage,\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n error: false,\n errorMessage: null,\n };\n }\n\n async getEntity(params: GetEntityParams = {}): Promise<EntityApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetEntityParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEntity\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchEntityFromAPI(rest as GetEntityParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchEntityFromAPI(\n params: GetEntityParams = {}\n ): Promise<EntityApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEntity {\n GetEntity {\n id\n tin\n name\n web\n address\n country\n city\n currency_id\n currency_name\n currency_prefix\n currency_suffix\n logo_url\n logo_alt\n logo_thumbnail_url\n logo_sizes_thumbnail_filename\n logo_filename\n logo_width\n logo_height\n logo_2_url\n logo_2_alt\n logo_2_thumbnail_url\n logo_2_sizes_thumbnail_filename\n logo_2_filename\n logo_2_width\n logo_2_height\n featured_image_url\n featured_image_alt\n featured_image_thumbnail_url\n featured_image_sizes_thumbnail_filename\n featured_image_filename\n featured_image_width\n featured_image_height\n }\n }\n `;\n\n const { data, error, errorMessage } = await this.fetchGraphQL<any>(\n query,\n params,\n (responseData) => responseData.GetEntity\n );\n\n if (error) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n entity: data!,\n error: false,\n errorMessage: null,\n };\n }\n\n async createEcommerceOrder(\n params: CreateEcommerceOrderParams\n ): Promise<CreateEcommerceOrderResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message: \"SDK no configurado\",\n error: true,\n errorMessage: \"SDK no configurado\",\n };\n }\n\n const orderSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n phone: z.string().optional(),\n notes: z.string().optional(),\n tin: z.string().optional(),\n items: z\n .array(\n z.object({\n id: z.number().positive(),\n quantity: z.number().positive(),\n })\n )\n .min(1),\n delivery_address: z.string().optional(),\n delivery_instructions: z.string().optional(),\n payment_method: z.enum([\"cash\", \"transfer\"]).optional(),\n });\n\n const validated = orderSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"createEcommerceOrder validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/orders/create-ecommerce-order\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Orden creada exitosamente\",\n order_id: response.data.order_id,\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage = response.data.message || \"Error al crear la orden\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"createEcommerceOrder\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n async executeCustomQuery<T>(\n params: CustomGraphQLParams\n ): Promise<CustomGraphQLResponse<T>> {\n // Validar configuración antes de continuar\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null as T,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Validar que se proporcione un query\n if (\n !params.query ||\n typeof params.query !== \"string\" ||\n params.query.trim() === \"\"\n ) {\n return {\n data: null as T,\n error: true,\n errorMessage: \"Se requiere un query GraphQL válido.\",\n };\n }\n\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query: params.query,\n variables: params.variables || {},\n });\n\n // Si hay errores de GraphQL, los incluimos en la respuesta pero no como error fatal\n if (response.data.errors && response.data.errors.length > 0) {\n return {\n data: response.data.data || (null as T),\n errors: response.data.errors,\n error: true,\n errorMessage: `GraphQL Errors: ${response.data.errors\n .map((err: unknown) => (err as Error).message)\n .join(\", \")}`,\n };\n }\n\n return {\n data: response.data.data,\n error: false,\n errorMessage: null,\n };\n } catch (error) {\n let errorMessage = \"Error desconocido\";\n\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n if (status === 401) {\n errorMessage = \"API Key inválida o expirada\";\n } else if (status === 404) {\n errorMessage = \"Endpoint GraphQL no encontrado\";\n } else if (status === 400) {\n errorMessage = \"Query GraphQL inválido o malformado\";\n } else if (status && status >= 500) {\n errorMessage = \"Error del servidor CMS\";\n } else {\n errorMessage = `Error de conexión: ${error.message}`;\n }\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n return {\n data: null as T,\n error: true,\n errorMessage,\n };\n }\n }\n\n async sendContactUsEmail(\n params: SendContactUsEmailParams\n ): Promise<SendContactUsEmailResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const contactUsSchema = z.object({\n name: z.string().min(1),\n email: z.email(),\n phone: z.string().optional(),\n subject: z.string().optional(),\n message: z.string().min(1),\n });\n\n const validated = contactUsSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"sendContactUsEmail validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/entities/send-contact-us-email\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Mensaje enviado exitosamente\",\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage =\n response.data.message || \"Error al enviar el mensaje\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"sendContactUsEmail\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n /**\n * Verifica si existe cache para una función y parámetros específicos\n */\n async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.hasCache(functionName, params);\n }\n\n /**\n * Obtiene la key de cache para una función y parámetros específicos\n */\n getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.cache.getCacheKey(functionName, params);\n }\n\n /**\n * Limpia el cache para una función y parámetros específicos\n */\n async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.clearCache(functionName, params);\n }\n\n /**\n * Limpia todo el cache relacionado con este API Key\n */\n async clearAllCache(): Promise<boolean> {\n return this.cache.clearAllCache();\n }\n\n /**\n * Obtiene información del cache (útil para debugging)\n */\n async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n return this.cache.getCacheInfo(functionName, params);\n }\n\n /**\n * Limpia un cache específico que pueda estar corrupto\n */\n async clearCorruptedCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n const key = this.cache.getCacheKey(functionName, params);\n return this.cache.clearCorruptedCache(key);\n }\n}\n\nexport const pakentoCMSAPI = new PakentoCMSAPI();\n","import { Redis } from \"@upstash/redis\";\nimport { createHash } from \"crypto\";\n\nexport class CacheService {\n private redis?: Redis;\n private defaultTTL: number;\n private apiKeyHash: string;\n\n private isCacheEnvelope<U>(value: unknown): value is {\n __pakento_cache_version: string;\n __pakento_timestamp: number;\n data: U;\n } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__pakento_cache_version\" in value &&\n \"data\" in value\n );\n }\n\n constructor(defaultTTL: number, apiKey: string) {\n this.defaultTTL = defaultTTL;\n this.apiKeyHash = createHash(\"sha256\")\n .update(apiKey)\n .digest(\"hex\")\n .substring(0, 8);\n\n if (\n process.env.UPSTASH_REDIS_REST_URL &&\n process.env.UPSTASH_REDIS_REST_TOKEN\n ) {\n this.redis = new Redis({\n url: process.env.UPSTASH_REDIS_REST_URL,\n token: process.env.UPSTASH_REDIS_REST_TOKEN,\n });\n }\n }\n\n private generateParamsHash(params: Record<string, unknown>): string {\n const canonicalize = (value: unknown): unknown => {\n if (value === undefined) return undefined; // omit later\n if (value === null) return null;\n\n if (Array.isArray(value)) {\n // Preserve order for arrays but canonicalize elements\n return value.map((v) => canonicalize(v));\n }\n\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n Object.keys(obj)\n .sort()\n .forEach((key) => {\n const canon = canonicalize(obj[key]);\n if (canon !== undefined) {\n result[key] = canon;\n }\n });\n return result;\n }\n\n // For primitives (string, number, boolean) return as is\n return value;\n };\n\n const canonicalParams = canonicalize(params) as Record<string, unknown>;\n const paramsString = JSON.stringify(canonicalParams);\n\n return createHash(\"sha256\")\n .update(paramsString)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n public buildCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n const paramsHash = this.generateParamsHash(params);\n return `pakento:${this.apiKeyHash}:${functionName}:${paramsHash}`;\n }\n\n private safeJsonParse<T>(data: unknown): T | null {\n try {\n // Si data ya es un objeto/array y no un string, lo retornamos directamente\n if (typeof data === \"object\" && data !== null) {\n return data as T;\n }\n\n // Si es un string, intentamos parsearlo\n if (typeof data === \"string\") {\n return JSON.parse(data) as T;\n }\n\n // Si es otro tipo primitivo, lo retornamos tal como está\n return data as T;\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en safeJsonParse:\", error);\n console.warn(\"[PakentoSDK] Datos que causaron error:\", {\n type: typeof data,\n isArray: Array.isArray(data),\n data: data,\n });\n return null;\n }\n }\n\n private serializeForCache(value: unknown): string {\n try {\n // Crear un wrapper con metadata para verificar integridad\n const cacheData = {\n __pakento_cache_version: \"2.0\",\n __pakento_timestamp: Date.now(),\n data: value,\n };\n return JSON.stringify(cacheData);\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en serializeForCache:\", error);\n // Fallback a serialización simple\n return JSON.stringify(value);\n }\n }\n\n public async getCachedOrFetch<T>(\n key: string,\n fetcher: () => Promise<T>,\n ttl?: number,\n skipCache: boolean = false\n ): Promise<T> {\n if (!this.redis || skipCache) {\n return fetcher();\n }\n\n try {\n const cached = await this.redis.get(key);\n\n if (cached !== null && cached !== undefined) {\n try {\n const parsed = this.safeJsonParse<unknown>(cached);\n\n if (parsed !== null) {\n // Verificar si es el nuevo formato con metadata\n if (this.isCacheEnvelope<T>(parsed)) {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed.data as T;\n }\n // Formato legacy sin metadata\n else {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed as T;\n }\n } else {\n console.warn(`[PakentoSDK] ⚠️ Error parseando cache para: ${key}`);\n console.warn(`[PakentoSDK] Datos raw del cache:`, {\n type: typeof cached,\n value: cached,\n });\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(\n `[PakentoSDK] Error limpiando cache corrupto: ${err}`\n )\n );\n }\n } catch (parseError) {\n console.warn(\n `[PakentoSDK] ⚠️ Excepción parseando cache para: ${key}:`,\n parseError\n );\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(`[PakentoSDK] Error limpiando cache corrupto: ${err}`)\n );\n }\n }\n } catch (err) {\n console.warn(\"[PakentoSDK] Error leyendo cache Redis\", err);\n }\n\n const result = await fetcher();\n\n try {\n const serializedData = this.serializeForCache(result);\n await this.redis.set(key, serializedData, {\n ex: ttl ?? this.defaultTTL,\n });\n console.log(\n \"[PakentoSDK] Cache no encontrado, se guarda y se devuelve uno nuevo\"\n );\n } catch (err) {\n console.warn(\"[PakentoSDK] Error escribiendo cache Redis\", err);\n console.warn(\"[PakentoSDK] Detalles del error:\", {\n error: err,\n key: key,\n resultType: typeof result,\n resultSize: JSON.stringify(result).length,\n });\n }\n\n return result;\n }\n\n public async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const cached = await this.redis.get(key);\n\n if (cached === null || cached === undefined) {\n return false;\n }\n\n // Verificar que el cache se puede parsear correctamente\n const parsed = this.safeJsonParse(cached);\n return parsed !== null;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error verificando cache\", err);\n return false;\n }\n }\n\n /**\n * Limpia un cache específico si está corrupto\n */\n public async clearCorruptedCache(key: string): Promise<boolean> {\n if (!this.redis) {\n return false;\n }\n\n try {\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache corrupto\", err);\n return false;\n }\n }\n\n public getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.buildCacheKey(functionName, params);\n }\n\n public async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache\", err);\n return false;\n }\n }\n\n public async clearAllCache(): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const pattern = `pakento:${this.apiKeyHash}:*`;\n const keys = await this.redis.keys(pattern);\n\n if (keys.length > 0) {\n await this.redis.del(...keys);\n }\n\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando todo el cache\", err);\n return false;\n }\n }\n\n public async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const exists = await this.redis.exists(key);\n const ttl = exists ? await this.redis.ttl(key) : undefined;\n\n return {\n exists: exists === 1,\n key,\n ttl: ttl === -1 ? undefined : ttl,\n };\n } catch (err) {\n console.warn(\"[PakentoSDK] Error obteniendo info del cache\", err);\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAiD;;;ACAjD,mBAAsB;AACtB,oBAA2B;AAEpB,IAAM,eAAN,MAAmB;AAAA,EAKhB,gBAAmB,OAIzB;AACA,WACE,OAAO,UAAU,YACjB,UAAU,QACV,6BAA6B,SAC7B,UAAU;AAAA,EAEd;AAAA,EAEA,YAAY,YAAoB,QAAgB;AAC9C,SAAK,aAAa;AAClB,SAAK,iBAAa,0BAAW,QAAQ,EAClC,OAAO,MAAM,EACb,OAAO,KAAK,EACZ,UAAU,GAAG,CAAC;AAEjB,QACE,QAAQ,IAAI,0BACZ,QAAQ,IAAI,0BACZ;AACA,WAAK,QAAQ,IAAI,mBAAM;AAAA,QACrB,KAAK,QAAQ,IAAI;AAAA,QACjB,OAAO,QAAQ,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,mBAAmB,QAAyC;AAClE,UAAM,eAAe,CAAC,UAA4B;AAChD,UAAI,UAAU,OAAW,QAAO;AAChC,UAAI,UAAU,KAAM,QAAO;AAE3B,UAAI,MAAM,QAAQ,KAAK,GAAG;AAExB,eAAO,MAAM,IAAI,CAAC,MAAM,aAAa,CAAC,CAAC;AAAA,MACzC;AAEA,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,MAAM;AACZ,cAAM,SAAkC,CAAC;AACzC,eAAO,KAAK,GAAG,EACZ,KAAK,EACL,QAAQ,CAAC,QAAQ;AAChB,gBAAM,QAAQ,aAAa,IAAI,GAAG,CAAC;AACnC,cAAI,UAAU,QAAW;AACvB,mBAAO,GAAG,IAAI;AAAA,UAChB;AAAA,QACF,CAAC;AACH,eAAO;AAAA,MACT;AAGA,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,aAAa,MAAM;AAC3C,UAAM,eAAe,KAAK,UAAU,eAAe;AAEnD,eAAO,0BAAW,QAAQ,EACvB,OAAO,YAAY,EACnB,OAAO,KAAK,EACZ,UAAU,GAAG,EAAE;AAAA,EACpB;AAAA,EAEO,cACL,cACA,SAAkC,CAAC,GAC3B;AACR,UAAM,aAAa,KAAK,mBAAmB,MAAM;AACjD,WAAO,WAAW,KAAK,UAAU,IAAI,YAAY,IAAI,UAAU;AAAA,EACjE;AAAA,EAEQ,cAAiB,MAAyB;AAChD,QAAI;AAEF,UAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,eAAO;AAAA,MACT;AAGA,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,KAAK,MAAM,IAAI;AAAA,MACxB;AAGA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,KAAK,wCAAwC,KAAK;AAC1D,cAAQ,KAAK,0CAA0C;AAAA,QACrD,MAAM,OAAO;AAAA,QACb,SAAS,MAAM,QAAQ,IAAI;AAAA,QAC3B;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,kBAAkB,OAAwB;AAChD,QAAI;AAEF,YAAM,YAAY;AAAA,QAChB,yBAAyB;AAAA,QACzB,qBAAqB,KAAK,IAAI;AAAA,QAC9B,MAAM;AAAA,MACR;AACA,aAAO,KAAK,UAAU,SAAS;AAAA,IACjC,SAAS,OAAO;AACd,cAAQ,KAAK,4CAA4C,KAAK;AAE9D,aAAO,KAAK,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAa,iBACX,KACA,SACA,KACA,YAAqB,OACT;AACZ,QAAI,CAAC,KAAK,SAAS,WAAW;AAC5B,aAAO,QAAQ;AAAA,IACjB;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,MAAM,IAAI,GAAG;AAEvC,UAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,YAAI;AACF,gBAAM,SAAS,KAAK,cAAuB,MAAM;AAEjD,cAAI,WAAW,MAAM;AAEnB,gBAAI,KAAK,gBAAmB,MAAM,GAAG;AACnC,sBAAQ,IAAI,0CAA0C;AACtD,qBAAO,OAAO;AAAA,YAChB,OAEK;AACH,sBAAQ,IAAI,0CAA0C;AACtD,qBAAO;AAAA,YACT;AAAA,UACF,OAAO;AACL,oBAAQ,KAAK,yDAA+C,GAAG,EAAE;AACjE,oBAAQ,KAAK,qCAAqC;AAAA,cAChD,MAAM,OAAO;AAAA,cACb,OAAO;AAAA,YACT,CAAC;AAED,iBAAK,oBAAoB,GAAG,EAAE;AAAA,cAAM,CAAC,QACnC,QAAQ;AAAA,gBACN,gDAAgD,GAAG;AAAA,cACrD;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,YAAY;AACnB,kBAAQ;AAAA,YACN,gEAAmD,GAAG;AAAA,YACtD;AAAA,UACF;AAEA,eAAK,oBAAoB,GAAG,EAAE;AAAA,YAAM,CAAC,QACnC,QAAQ,KAAK,gDAAgD,GAAG,EAAE;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,0CAA0C,GAAG;AAAA,IAC5D;AAEA,UAAM,SAAS,MAAM,QAAQ;AAE7B,QAAI;AACF,YAAM,iBAAiB,KAAK,kBAAkB,MAAM;AACpD,YAAM,KAAK,MAAM,IAAI,KAAK,gBAAgB;AAAA,QACxC,IAAI,OAAO,KAAK;AAAA,MAClB,CAAC;AACD,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,8CAA8C,GAAG;AAC9D,cAAQ,KAAK,oCAAoC;AAAA,QAC/C,OAAO;AAAA,QACP;AAAA,QACA,YAAY,OAAO;AAAA,QACnB,YAAY,KAAK,UAAU,MAAM,EAAE;AAAA,MACrC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,SACX,cACA,SAAkC,CAAC,GACjB;AAClB,QAAI,CAAC,KAAK,OAAO;AACf,cAAQ,KAAK,mCAAmC;AAChD,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,MAAM,KAAK,cAAc,cAAc,MAAM;AACnD,YAAM,SAAS,MAAM,KAAK,MAAM,IAAI,GAAG;AAEvC,UAAI,WAAW,QAAQ,WAAW,QAAW;AAC3C,eAAO;AAAA,MACT;AAGA,YAAM,SAAS,KAAK,cAAc,MAAM;AACxC,aAAO,WAAW;AAAA,IACpB,SAAS,KAAK;AACZ,cAAQ,KAAK,wCAAwC,GAAG;AACxD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,oBAAoB,KAA+B;AAC9D,QAAI,CAAC,KAAK,OAAO;AACf,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,KAAK,MAAM,IAAI,GAAG;AACxB,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,KAAK,+CAA+C,GAAG;AAC/D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEO,YACL,cACA,SAAkC,CAAC,GAC3B;AACR,WAAO,KAAK,cAAc,cAAc,MAAM;AAAA,EAChD;AAAA,EAEA,MAAa,WACX,cACA,SAAkC,CAAC,GACjB;AAClB,QAAI,CAAC,KAAK,OAAO;AACf,cAAQ,KAAK,mCAAmC;AAChD,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,MAAM,KAAK,cAAc,cAAc,MAAM;AACnD,YAAM,KAAK,MAAM,IAAI,GAAG;AACxB,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,KAAK,sCAAsC,GAAG;AACtD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,gBAAkC;AAC7C,QAAI,CAAC,KAAK,OAAO;AACf,cAAQ,KAAK,mCAAmC;AAChD,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,UAAU,WAAW,KAAK,UAAU;AAC1C,YAAM,OAAO,MAAM,KAAK,MAAM,KAAK,OAAO;AAE1C,UAAI,KAAK,SAAS,GAAG;AACnB,cAAM,KAAK,MAAM,IAAI,GAAG,IAAI;AAAA,MAC9B;AAEA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,KAAK,8CAA8C,GAAG;AAC9D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,aACX,cACA,SAAkC,CAAC,GAKlC;AACD,QAAI,CAAC,KAAK,OAAO;AACf,cAAQ,KAAK,mCAAmC;AAChD,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK,KAAK,cAAc,cAAc,MAAM;AAAA,MAC9C;AAAA,IACF;AAEA,QAAI;AACF,YAAM,MAAM,KAAK,cAAc,cAAc,MAAM;AACnD,YAAM,SAAS,MAAM,KAAK,MAAM,OAAO,GAAG;AAC1C,YAAM,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI,GAAG,IAAI;AAEjD,aAAO;AAAA,QACL,QAAQ,WAAW;AAAA,QACnB;AAAA,QACA,KAAK,QAAQ,KAAK,SAAY;AAAA,MAChC;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,gDAAgD,GAAG;AAChE,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK,KAAK,cAAc,cAAc,MAAM;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AACF;;;ADjTA,iBAAkB;AAElB,IAAM,gBAAN,MAAoB;AAAA,EAOlB,YAAY,QAAgC;AAJ5C,SAAQ,aAAqB;AAK3B,SAAK,UAAU,QAAQ,IAAI,wBAAwB;AACnD,SAAK,SAAS,QAAQ,IAAI,mBAAmB;AAE7C,QAAI,QAAQ,YAAY,OAAO,OAAO,aAAa,UAAU;AAC3D,WAAK,aAAa,OAAO;AAAA,IAC3B;AAEA,SAAK,QAAQ,IAAI,aAAa,KAAK,YAAY,KAAK,MAAM;AAE1D,SAAK,SAAS,aAAAA,QAAM,OAAO;AAAA,MACzB,SAAS,KAAK;AAAA,MACd,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,iBAAiB,KAAK,MAAM;AAAA,MAC7C;AAAA,IACF,CAAC;AAGD,SAAK,OAAO,aAAa,QAAQ;AAAA,MAC/B,CAACC,YAAW;AACV,cAAM,UAAU,GAAGA,QAAO,OAAO,GAAGA,QAAO,GAAG;AAC9C,gBAAQ,IAAI,uBAAgBA,QAAO,QAAQ,YAAY,CAAC,IAAI,OAAO,EAAE;AACrE,eAAOA;AAAA,MACT;AAAA,MACA,CAAC,UAAU;AACT,eAAO,QAAQ,OAAO,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGQ,eAAe,OAAgB,SAAyB;AAC9D,QAAI,iBAAiB,yBAAY;AAC/B,YAAM,SAAS,MAAM,UAAU;AAC/B,YAAM,kBAAkB,MAAM,UAAU,MAAM;AAC9C,UAAI,WAAW,IAAK,QAAO;AAC3B,UAAI,WAAW,IAAK,QAAO,GAAG,OAAO;AACrC,UAAI,UAAU,UAAU,IAAK,QAAO;AACpC,aACE,mBAAmB,2BAAwB,OAAO,KAAK,MAAM,OAAO;AAAA,IAExE,WAAW,iBAAiB,aAAE,UAAU;AACtC,aAAO,0BAAuB,MAAM,OACjC,IAAI,CAAC,MAA2B,EAAE,OAAO,EACzC,KAAK,IAAI,CAAC;AAAA,IACf,WAAW,iBAAiB,OAAO;AACjC,aAAO,MAAM;AAAA,IACf;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAc,aACZ,OACA,WACA,aAC0E;AAC1E,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,gBAAgB;AAAA,QACtD;AAAA,QACA;AAAA,MACF,CAAC;AAED,UAAI,SAAS,KAAK,QAAQ;AACxB,cAAM,eAAe,kBAAkB,SAAS,KAAK,OAAO,CAAC,EAAE,OAAO;AACtE,eAAO,EAAE,MAAM,MAAM,OAAO,MAAM,aAAa;AAAA,MACjD;AAEA,YAAM,OAAO,YAAY,SAAS,KAAK,IAAI;AAC3C,aAAO,EAAE,MAAM,OAAO,OAAO,cAAc,KAAK;AAAA,IAClD,SAAS,OAAO;AACd,YAAM,eAAe,KAAK,eAAe,OAAO,eAAe;AAC/D,aAAO,EAAE,MAAM,MAAM,OAAO,MAAM,aAAa;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,SAAyB,CAAC,GAA8B;AAErE,UAAM,cAAc,aAAE,OAAO;AAAA,MAC3B,OAAO,aACJ,OAAO;AAAA,QACN,kBAAkB,aACf,OAAO,EAAE,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EACxC,SAAS;AAAA,QACZ,wBAAwB,aACrB,OAAO,EAAE,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EACxC,SAAS;AAAA,QACZ,UAAU,aAAE,OAAO,EAAE,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS;AAAA,QAC/D,IAAI,aAAE,OAAO,EAAE,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS;AAAA,MAC3D,CAAC,EACA,SAAS;AAAA,MACZ,YAAY,aAAE,QAAQ,EAAE,SAAS;AAAA,MACjC,OAAO,aAAE,OAAO,OAAO,EAAE,SAAS;AAAA,MAClC,MAAM,aAAE,OAAO,OAAO,EAAE,SAAS;AAAA,MACjC,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,MAC5B,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,UAAU,aAAE,OAAO,OAAO,EAAE,SAAS;AAAA,MACrC,UAAU,aAAE,OAAO,OAAO,EAAE,SAAS;AAAA,MACrC,WAAW,aAAE,QAAQ,EAAE,SAAS;AAAA,MAChC,UAAU,aAAE,OAAO,EAAE,SAAS;AAAA,IAChC,CAAC;AAED,UAAM,kBAAkB,YAAY,UAAU,MAAM;AACpD,QAAI,CAAC,gBAAgB,SAAS;AAC5B,YAAM,eAAe,KAAK;AAAA,QACxB,gBAAgB;AAAA,QAChB;AAAA,MACF;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,CAAC;AAAA,QACR,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA,QACV,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,YAAY,OAAO,UAAU,GAAG,KAAK,IAAI,gBAAgB;AACjE,UAAM,WAAW,KAAK,MAAM,cAAc,qBAAqB,IAAI;AACnE,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,kBAAkB,IAAsB;AAAA,MACnD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,kBACZ,SAAyB,CAAC,GACC;AAC3B,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,CAAC;AAAA,QACR,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA,QACV,OAAO;AAAA,QACP,cACE;AAAA,MACJ;AAAA,IACF;AAGA,UAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDd,UAAM,kBAA8B,CAAC;AACrC,QAAI,OAAO,OAAO,kBAAkB,QAAQ;AAC1C,sBAAgB,mBAAmB;AAAA,QACjC,QAAQ,OAAO,MAAM,iBAAiB;AAAA,MACxC;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,wBAAwB,QAAQ;AAChD,sBAAgB,yBAAyB;AAAA,QACvC,QAAQ,OAAO,MAAM,uBAAuB;AAAA,MAC9C;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,UAAU,QAAQ;AAClC,sBAAgB,WAAW,EAAE,QAAQ,OAAO,MAAM,SAAS,OAAO;AAAA,IACpE;AAEA,QAAI,OAAO,OAAO,IAAI,QAAQ;AAC5B,sBAAgB,KAAK,EAAE,QAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,IACxD;AAEA,UAAM,YAAY;AAAA,MAChB,GAAG;AAAA,MACH,OACE,OAAO,KAAK,eAAe,EAAE,SAAS,IAAI,kBAAkB;AAAA,IAChE;AAEA,UAAM,EAAE,MAAM,OAAO,aAAa,IAChC,MAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,MACA,CAAC,iBAAiB,aAAa;AAAA,IACjC;AAEF,QAAI,OAAO;AACT,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,CAAC;AAAA,QACR,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA,QACV,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAO,KAAM;AAAA,MACb,WAAW,KAAM;AAAA,MACjB,YAAY,KAAM;AAAA,MAClB,UAAU,KAAM;AAAA,MAChB,UAAU,KAAM;AAAA,MAChB,OAAO;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,SAA8B,CAAC,GACC;AAChC,UAAM;AAAA,MACJ,YAAY;AAAA,MACZ;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AACJ,UAAM,WAAW,KAAK,MAAM,cAAc,0BAA0B,IAAI;AACxE,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,uBAAuB,IAA2B;AAAA,MAC7D;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,uBACZ,SAA8B,CAAC,GACC;AAChC,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC;AAAA,QACb,OAAO;AAAA,QACP,cACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBd,UAAM,EAAE,MAAM,OAAO,aAAa,IAChC,MAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,MACA,CAAC,iBAAiB,aAAa;AAAA,IACjC;AAEF,QAAI,OAAO;AACT,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC;AAAA,QACb,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM,KAAM;AAAA,MACZ,YAAY,KAAM;AAAA,MAClB,OAAO;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,SAA0B,CAAC,GAA+B;AACxE,UAAM,EAAE,YAAY,OAAO,UAAU,GAAG,KAAK,IAAI;AACjD,UAAM,WAAW,KAAK,MAAM,cAAc,sBAAsB,IAAI;AACpE,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,mBAAmB,IAAuB;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,SAA0B,CAAC,GACC;AAC5B,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,CAAC;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,eAAe;AAAA,QACf,UAAU;AAAA,QACV,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,cACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCd,UAAM,EAAE,MAAM,OAAO,aAAa,IAChC,MAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,MACA,CAAC,iBAAiB,aAAa;AAAA,IACjC;AAEF,QAAI,OAAO;AACT,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,CAAC;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,eAAe;AAAA,QACf,UAAU;AAAA,QACV,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,KAAM;AAAA,MACd,aAAa,KAAM;AAAA,MACnB,aAAa,KAAM;AAAA,MACnB,OAAO,KAAM;AAAA,MACb,UAAU,KAAM;AAAA,MAChB,QAAQ,KAAM;AAAA,MACd,MAAM,KAAM;AAAA,MACZ,eAAe,KAAM;AAAA,MACrB,UAAU,KAAM;AAAA,MAChB,WAAW,KAAM;AAAA,MACjB,YAAY,KAAM;AAAA,MAClB,OAAO;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,SAA0B,CAAC,GAA+B;AACxE,UAAM,EAAE,YAAY,OAAO,UAAU,GAAG,KAAK,IAAI;AACjD,UAAM,WAAW,KAAK,MAAM,cAAc,aAAa,IAAI;AAC3D,WAAO,KAAK,MAAM;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,mBAAmB,IAAuB;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,SAA0B,CAAC,GACC;AAC5B,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,cACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuCd,UAAM,EAAE,MAAM,OAAO,aAAa,IAAI,MAAM,KAAK;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,CAAC,iBAAiB,aAAa;AAAA,IACjC;AAEA,QAAI,OAAO;AACT,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,qBACJ,QACuC;AACvC,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,cAAc;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,cAAc,aAAE,OAAO;AAAA,MAC3B,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACtB,OAAO,aAAE,OAAO,EAAE,MAAM;AAAA,MACxB,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,KAAK,aAAE,OAAO,EAAE,SAAS;AAAA,MACzB,OAAO,aACJ;AAAA,QACC,aAAE,OAAO;AAAA,UACP,IAAI,aAAE,OAAO,EAAE,SAAS;AAAA,UACxB,UAAU,aAAE,OAAO,EAAE,SAAS;AAAA,QAChC,CAAC;AAAA,MACH,EACC,IAAI,CAAC;AAAA,MACR,kBAAkB,aAAE,OAAO,EAAE,SAAS;AAAA,MACtC,uBAAuB,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3C,gBAAgB,aAAE,KAAK,CAAC,QAAQ,UAAU,CAAC,EAAE,SAAS;AAAA,IACxD,CAAC;AAED,UAAM,YAAY,YAAY,UAAU,MAAM;AAC9C,QAAI,CAAC,UAAU,SAAS;AACtB,YAAM,eAAe,KAAK;AAAA,QACxB,UAAU;AAAA,QACV;AAAA,MACF;AACA,aAAO,EAAE,SAAS,cAAc,OAAO,MAAM,aAAa;AAAA,IAC5D;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO;AAAA,QACjC;AAAA,QACA,UAAU;AAAA,MACZ;AAEA,UAAI,SAAS,WAAW,KAAK;AAC3B,eAAO;AAAA,UACL,SAAS,SAAS,KAAK,WAAW;AAAA,UAClC,UAAU,SAAS,KAAK;AAAA,UACxB,OAAO;AAAA,UACP,cAAc;AAAA,QAChB;AAAA,MACF,OAAO;AACL,cAAM,eAAe,SAAS,KAAK,WAAW;AAC9C,eAAO,EAAE,SAAS,cAAc,OAAO,MAAM,aAAa;AAAA,MAC5D;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,KAAK,eAAe,OAAO,sBAAsB;AACtE,aAAO,EAAE,SAAS,cAAc,OAAO,MAAM,aAAa;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,mBACJ,QACmC;AAEnC,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,cACE;AAAA,MACJ;AAAA,IACF;AAGA,QACE,CAAC,OAAO,SACR,OAAO,OAAO,UAAU,YACxB,OAAO,MAAM,KAAK,MAAM,IACxB;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,cAAc;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,gBAAgB;AAAA,QACtD,OAAO,OAAO;AAAA,QACd,WAAW,OAAO,aAAa,CAAC;AAAA,MAClC,CAAC;AAGD,UAAI,SAAS,KAAK,UAAU,SAAS,KAAK,OAAO,SAAS,GAAG;AAC3D,eAAO;AAAA,UACL,MAAM,SAAS,KAAK,QAAS;AAAA,UAC7B,QAAQ,SAAS,KAAK;AAAA,UACtB,OAAO;AAAA,UACP,cAAc,mBAAmB,SAAS,KAAK,OAC5C,IAAI,CAAC,QAAkB,IAAc,OAAO,EAC5C,KAAK,IAAI,CAAC;AAAA,QACf;AAAA,MACF;AAEA,aAAO;AAAA,QACL,MAAM,SAAS,KAAK;AAAA,QACpB,OAAO;AAAA,QACP,cAAc;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,eAAe;AAEnB,UAAI,iBAAiB,yBAAY;AAC/B,cAAM,SAAS,MAAM,UAAU;AAC/B,YAAI,WAAW,KAAK;AAClB,yBAAe;AAAA,QACjB,WAAW,WAAW,KAAK;AACzB,yBAAe;AAAA,QACjB,WAAW,WAAW,KAAK;AACzB,yBAAe;AAAA,QACjB,WAAW,UAAU,UAAU,KAAK;AAClC,yBAAe;AAAA,QACjB,OAAO;AACL,yBAAe,yBAAsB,MAAM,OAAO;AAAA,QACpD;AAAA,MACF,WAAW,iBAAiB,OAAO;AACjC,uBAAe,MAAM;AAAA,MACvB;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mBACJ,QACqC;AACrC,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,QAAQ;AACjC,aAAO;AAAA,QACL,SACE;AAAA,QACF,OAAO;AAAA,QACP,cACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,kBAAkB,aAAE,OAAO;AAAA,MAC/B,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACtB,OAAO,aAAE,MAAM;AAAA,MACf,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,SAAS,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC3B,CAAC;AAED,UAAM,YAAY,gBAAgB,UAAU,MAAM;AAClD,QAAI,CAAC,UAAU,SAAS;AACtB,YAAM,eAAe,KAAK;AAAA,QACxB,UAAU;AAAA,QACV;AAAA,MACF;AACA,aAAO,EAAE,SAAS,cAAc,OAAO,MAAM,aAAa;AAAA,IAC5D;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO;AAAA,QACjC;AAAA,QACA,UAAU;AAAA,MACZ;AAEA,UAAI,SAAS,WAAW,KAAK;AAC3B,eAAO;AAAA,UACL,SAAS,SAAS,KAAK,WAAW;AAAA,UAClC,OAAO;AAAA,UACP,cAAc;AAAA,QAChB;AAAA,MACF,OAAO;AACL,cAAM,eACJ,SAAS,KAAK,WAAW;AAC3B,eAAO,EAAE,SAAS,cAAc,OAAO,MAAM,aAAa;AAAA,MAC5D;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eAAe,KAAK,eAAe,OAAO,oBAAoB;AACpE,aAAO,EAAE,SAAS,cAAc,OAAO,MAAM,aAAa;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,cACA,SAAkC,CAAC,GACjB;AAClB,WAAO,KAAK,MAAM,SAAS,cAAc,MAAM;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,YACE,cACA,SAAkC,CAAC,GAC3B;AACR,WAAO,KAAK,MAAM,YAAY,cAAc,MAAM;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WACJ,cACA,SAAkC,CAAC,GACjB;AAClB,WAAO,KAAK,MAAM,WAAW,cAAc,MAAM;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAkC;AACtC,WAAO,KAAK,MAAM,cAAc;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,cACA,SAAkC,CAAC,GAKlC;AACD,WAAO,KAAK,MAAM,aAAa,cAAc,MAAM;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBACJ,cACA,SAAkC,CAAC,GACjB;AAClB,UAAM,MAAM,KAAK,MAAM,YAAY,cAAc,MAAM;AACvD,WAAO,KAAK,MAAM,oBAAoB,GAAG;AAAA,EAC3C;AACF;AAEO,IAAM,gBAAgB,IAAI,cAAc;","names":["axios","config"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/services/api.ts","../src/services/cache.ts","../src/utils/itemParser.ts"],"sourcesContent":["// Services\nexport { pakentoCMSAPI } from \"./services/api\";\nexport { CacheService } from \"./services/cache\";\n\n// Utils\nexport * from \"./utils\";\n\n// Types\nexport type {\n // Base types\n Item,\n ItemImage,\n Category,\n Brand,\n Entity,\n\n // GraphQL Where conditions\n WhereEquals,\n ItemsWhere,\n CategoriesWhere,\n\n // API Parameters\n GetItemsParams,\n GetCategoriesParams,\n GetBrandsParams,\n GetEntityParams,\n CreateEcommerceOrderParams,\n SendContactUsEmailParams,\n CustomGraphQLParams,\n\n // Raw API Response types\n ItemsRawResponse,\n CategoriesRawResponse,\n BrandsRawResponse,\n EntityRawResponse,\n\n // API Response types with error handling\n ItemsApiResponse,\n CategoriesApiResponse,\n BrandsApiResponse,\n EntityApiResponse,\n CreateEcommerceOrderResponse,\n SendContactUsEmailResponse,\n CustomGraphQLResponse,\n} from \"./types\";\n","import axios, { AxiosInstance, AxiosError } from \"axios\";\nimport type {\n GetItemsParams,\n GetCategoriesParams,\n GetBrandsParams,\n GetEntityParams,\n CreateEcommerceOrderParams,\n SendContactUsEmailParams,\n CustomGraphQLParams,\n CategoriesApiResponse,\n BrandsApiResponse,\n EntityApiResponse,\n CreateEcommerceOrderResponse,\n SendContactUsEmailResponse,\n CustomGraphQLResponse,\n ItemsRawResponse,\n CategoriesRawResponse,\n BrandsRawResponse,\n ItemsWhere,\n ApiResponse,\n Item,\n} from \"../types\";\n\nimport { CacheService } from \"./cache\";\nimport { z } from \"zod\";\nimport { parseRawItemsToItems } from \"../utils\";\n\nclass PakentoCMSAPI {\n private client: AxiosInstance;\n private cache: CacheService;\n private defaultTTL: number = 86400;\n private baseURL: string;\n private apiKey: string;\n\n constructor(config?: { cacheTTL?: number }) {\n this.baseURL = process.env.PAKENTO_CMS_BASE_URL || \"\";\n this.apiKey = process.env.PAKENTO_API_KEY || \"\";\n\n if (config?.cacheTTL && typeof config.cacheTTL === \"number\") {\n this.defaultTTL = config.cacheTTL;\n }\n\n this.cache = new CacheService(this.defaultTTL, this.apiKey);\n\n this.client = axios.create({\n baseURL: this.baseURL,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `users API-Key ${this.apiKey}`,\n },\n });\n\n // Interceptor para imprimir las URLs de las llamadas a la API\n this.client.interceptors.request.use(\n (config) => {\n const fullUrl = `${config.baseURL}${config.url}`;\n console.log(`🌐 API Call: ${config.method?.toUpperCase()} ${fullUrl}`);\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n }\n\n // Centralized error handler\n private handleApiError(error: unknown, context: string): string {\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const responseMessage = error.response?.data?.message;\n if (status === 401) return \"API Key inválida o expirada\";\n if (status === 404) return `${context} no encontrado`;\n if (status && status >= 500) return \"Error del servidor CMS\";\n return (\n responseMessage || `Error de conexión en ${context}: ${error.message}`\n );\n } else if (error instanceof z.ZodError) {\n return `Validación fallida: ${error.issues\n .map((e: { message: string }) => e.message)\n .join(\", \")}`;\n } else if (error instanceof Error) {\n return error.message;\n }\n return \"Error desconocido\";\n }\n\n // Generic GraphQL fetcher\n private async fetchGraphQL<T>(\n query: string,\n variables: any,\n extractData: (responseData: any) => T\n ): Promise<{ data: T | null; error: boolean; errorMessage: string | null }> {\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query,\n variables,\n });\n\n if (response.data.errors) {\n const errorMessage = `GraphQL Error: ${response.data.errors[0].message}`;\n return { data: null, error: true, errorMessage };\n }\n\n const data = extractData(response.data.data);\n return { data, error: false, errorMessage: null };\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"GraphQL query\");\n return { data: null, error: true, errorMessage };\n }\n }\n\n async getItems(params: GetItemsParams = {}): Promise<ApiResponse<Item>> {\n // Zod schema for validation\n const itemsSchema = z.object({\n where: z\n .object({\n item_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n item_super_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n brand_id: z.object({ equals: z.string().optional() }).optional(),\n id: z.object({ equals: z.string().optional() }).optional(),\n })\n .optional(),\n onlyOffers: z.boolean().optional(),\n limit: z.coerce.number().optional(),\n page: z.coerce.number().optional(),\n search: z.string().optional(),\n sort: z.string().optional(),\n minPrice: z.coerce.number().optional(),\n maxPrice: z.coerce.number().optional(),\n skipCache: z.boolean().optional(),\n cacheTTL: z.number().optional(),\n });\n\n const validatedParams = itemsSchema.safeParse(params);\n if (!validatedParams.success) {\n const errorMessage = this.handleApiError(\n validatedParams.error,\n \"getItems validation\"\n );\n return {\n data: null,\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n const { skipCache = false, cacheTTL, ...rest } = validatedParams.data;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceItems\", rest);\n const finalData = await this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchItemsFromAPI(rest as GetItemsParams),\n cacheTTL,\n skipCache\n );\n\n return {\n data: finalData.data,\n totalDocs: finalData.totalDocs,\n totalPages: finalData.totalPages,\n prevPage: finalData.prevPage,\n nextPage: finalData.nextPage,\n error: false,\n errorMessage: null,\n };\n }\n\n private async fetchItemsFromAPI(\n params: GetItemsParams = {}\n ): Promise<ApiResponse<Item>> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Use generic fetchGraphQL\n const query = `\n query GetEcommerceItems(\n $where: EcommerceItemsWhere\n $onlyOffers: Boolean\n $limit: Int\n $page: Int\n $search: String\n $sort: String\n $minPrice: Float\n $maxPrice: Float\n ) {\n GetEcommerceItems(\n where: $where\n onlyOffers: $onlyOffers\n limit: $limit\n page: $page\n search: $search\n sort: $sort\n minPrice: $minPrice\n maxPrice: $maxPrice\n ) {\n totalDocs\n totalPages\n prevPage\n nextPage\n docs {\n id\n name\n featured\n description\n url_safe_name\n images {\n url\n thumbnailURL\n }\n coverImage {\n url\n thumbnailURL\n }\n item_prices {\n docs {\n amount\n old_price\n price_text\n price_notes\n }\n }\n brand {\n id\n name\n }\n item_category {\n id\n name\n }\n }\n }\n }\n `;\n\n // Construir variables\n const whereConditions: ItemsWhere = {};\n if (params.where?.item_category_id?.equals) {\n whereConditions.item_category_id = {\n equals: params.where.item_category_id.equals,\n };\n }\n\n if (params.where?.item_super_category_id?.equals) {\n whereConditions.item_super_category_id = {\n equals: params.where.item_super_category_id.equals,\n };\n }\n\n if (params.where?.brand_id?.equals) {\n whereConditions.brand_id = { equals: params.where.brand_id.equals };\n }\n\n if (params.where?.id?.equals) {\n whereConditions.id = { equals: params.where.id.equals };\n }\n\n const variables = {\n ...params,\n where:\n Object.keys(whereConditions).length > 0 ? whereConditions : undefined,\n };\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<ItemsRawResponse>(\n query,\n variables,\n (responseData) => responseData.GetEcommerceItems\n );\n\n if (error) {\n return {\n data: null,\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: parseRawItemsToItems(data!.docs),\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n prevPage: data!.prevPage,\n nextPage: data!.nextPage,\n error: false,\n errorMessage: null,\n };\n }\n\n async getCategories(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n const {\n skipCache = false,\n cacheTTL,\n ...rest\n } = params as GetCategoriesParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceCategories\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchCategoriesFromAPI(rest as GetCategoriesParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchCategoriesFromAPI(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceCategories(\n $where: EcommerceCategoriesWhere\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceCategories(\n where: $where\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n image_url\n }\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<CategoriesRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceCategories\n );\n\n if (error) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!.docs,\n categories: data!.docs,\n error: false,\n errorMessage: null,\n };\n }\n\n async getBrands(params: GetBrandsParams = {}): Promise<BrandsApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetBrandsParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceBrands\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchBrandsFromAPI(rest as GetBrandsParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchBrandsFromAPI(\n params: GetBrandsParams = {}\n ): Promise<BrandsApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceBrands(\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceBrands(\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n description\n items_count\n image_url\n image_thumbnail_url\n image_alt\n }\n hasNextPage\n hasPrevPage\n limit\n nextPage\n offset\n page\n pagingCounter\n prevPage\n totalDocs\n totalPages\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<BrandsRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceBrands\n );\n\n if (error) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n brands: data!.docs,\n hasNextPage: data!.hasNextPage,\n hasPrevPage: data!.hasPrevPage,\n limit: data!.limit,\n nextPage: data!.nextPage,\n offset: data!.offset,\n page: data!.page,\n pagingCounter: data!.pagingCounter,\n prevPage: data!.prevPage,\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n error: false,\n errorMessage: null,\n };\n }\n\n async getEntity(params: GetEntityParams = {}): Promise<EntityApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetEntityParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEntity\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchEntityFromAPI(rest as GetEntityParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchEntityFromAPI(\n params: GetEntityParams = {}\n ): Promise<EntityApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEntity {\n GetEntity {\n id\n tin\n name\n web\n address\n country\n city\n currency_id\n currency_name\n currency_prefix\n currency_suffix\n logo_url\n logo_alt\n logo_thumbnail_url\n logo_sizes_thumbnail_filename\n logo_filename\n logo_width\n logo_height\n logo_2_url\n logo_2_alt\n logo_2_thumbnail_url\n logo_2_sizes_thumbnail_filename\n logo_2_filename\n logo_2_width\n logo_2_height\n featured_image_url\n featured_image_alt\n featured_image_thumbnail_url\n featured_image_sizes_thumbnail_filename\n featured_image_filename\n featured_image_width\n featured_image_height\n }\n }\n `;\n\n const { data, error, errorMessage } = await this.fetchGraphQL<any>(\n query,\n params,\n (responseData) => responseData.GetEntity\n );\n\n if (error) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n entity: data!,\n error: false,\n errorMessage: null,\n };\n }\n\n async createEcommerceOrder(\n params: CreateEcommerceOrderParams\n ): Promise<CreateEcommerceOrderResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message: \"SDK no configurado\",\n error: true,\n errorMessage: \"SDK no configurado\",\n };\n }\n\n const orderSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n phone: z.string().optional(),\n notes: z.string().optional(),\n tin: z.string().optional(),\n items: z\n .array(\n z.object({\n id: z.number().positive(),\n quantity: z.number().positive(),\n })\n )\n .min(1),\n delivery_address: z.string().optional(),\n delivery_instructions: z.string().optional(),\n payment_method: z.enum([\"cash\", \"transfer\"]).optional(),\n });\n\n const validated = orderSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"createEcommerceOrder validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/orders/create-ecommerce-order\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Orden creada exitosamente\",\n order_id: response.data.order_id,\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage = response.data.message || \"Error al crear la orden\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"createEcommerceOrder\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n async executeCustomQuery<T>(\n params: CustomGraphQLParams\n ): Promise<CustomGraphQLResponse<T>> {\n // Validar configuración antes de continuar\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null as T,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Validar que se proporcione un query\n if (\n !params.query ||\n typeof params.query !== \"string\" ||\n params.query.trim() === \"\"\n ) {\n return {\n data: null as T,\n error: true,\n errorMessage: \"Se requiere un query GraphQL válido.\",\n };\n }\n\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query: params.query,\n variables: params.variables || {},\n });\n\n // Si hay errores de GraphQL, los incluimos en la respuesta pero no como error fatal\n if (response.data.errors && response.data.errors.length > 0) {\n return {\n data: response.data.data || (null as T),\n errors: response.data.errors,\n error: true,\n errorMessage: `GraphQL Errors: ${response.data.errors\n .map((err: unknown) => (err as Error).message)\n .join(\", \")}`,\n };\n }\n\n return {\n data: response.data.data,\n error: false,\n errorMessage: null,\n };\n } catch (error) {\n let errorMessage = \"Error desconocido\";\n\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n if (status === 401) {\n errorMessage = \"API Key inválida o expirada\";\n } else if (status === 404) {\n errorMessage = \"Endpoint GraphQL no encontrado\";\n } else if (status === 400) {\n errorMessage = \"Query GraphQL inválido o malformado\";\n } else if (status && status >= 500) {\n errorMessage = \"Error del servidor CMS\";\n } else {\n errorMessage = `Error de conexión: ${error.message}`;\n }\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n return {\n data: null as T,\n error: true,\n errorMessage,\n };\n }\n }\n\n async sendContactUsEmail(\n params: SendContactUsEmailParams\n ): Promise<SendContactUsEmailResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const contactUsSchema = z.object({\n name: z.string().min(1),\n email: z.email(),\n phone: z.string().optional(),\n subject: z.string().optional(),\n message: z.string().min(1),\n });\n\n const validated = contactUsSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"sendContactUsEmail validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/entities/send-contact-us-email\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Mensaje enviado exitosamente\",\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage =\n response.data.message || \"Error al enviar el mensaje\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"sendContactUsEmail\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n /**\n * Verifica si existe cache para una función y parámetros específicos\n */\n async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.hasCache(functionName, params);\n }\n\n /**\n * Obtiene la key de cache para una función y parámetros específicos\n */\n getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.cache.getCacheKey(functionName, params);\n }\n\n /**\n * Limpia el cache para una función y parámetros específicos\n */\n async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.clearCache(functionName, params);\n }\n\n /**\n * Limpia todo el cache relacionado con este API Key\n */\n async clearAllCache(): Promise<boolean> {\n return this.cache.clearAllCache();\n }\n\n /**\n * Obtiene información del cache (útil para debugging)\n */\n async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n return this.cache.getCacheInfo(functionName, params);\n }\n\n /**\n * Limpia un cache específico que pueda estar corrupto\n */\n async clearCorruptedCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n const key = this.cache.getCacheKey(functionName, params);\n return this.cache.clearCorruptedCache(key);\n }\n}\n\nexport const pakentoCMSAPI = new PakentoCMSAPI();\n","import { Redis } from \"@upstash/redis\";\nimport { createHash } from \"crypto\";\n\nexport class CacheService {\n private redis?: Redis;\n private defaultTTL: number;\n private apiKeyHash: string;\n\n private isCacheEnvelope<U>(value: unknown): value is {\n __pakento_cache_version: string;\n __pakento_timestamp: number;\n data: U;\n } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__pakento_cache_version\" in value &&\n \"data\" in value\n );\n }\n\n constructor(defaultTTL: number, apiKey: string) {\n this.defaultTTL = defaultTTL;\n this.apiKeyHash = createHash(\"sha256\")\n .update(apiKey)\n .digest(\"hex\")\n .substring(0, 8);\n\n if (\n process.env.UPSTASH_REDIS_REST_URL &&\n process.env.UPSTASH_REDIS_REST_TOKEN\n ) {\n this.redis = new Redis({\n url: process.env.UPSTASH_REDIS_REST_URL,\n token: process.env.UPSTASH_REDIS_REST_TOKEN,\n });\n }\n }\n\n private generateParamsHash(params: Record<string, unknown>): string {\n const canonicalize = (value: unknown): unknown => {\n if (value === undefined) return undefined; // omit later\n if (value === null) return null;\n\n if (Array.isArray(value)) {\n // Preserve order for arrays but canonicalize elements\n return value.map((v) => canonicalize(v));\n }\n\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n Object.keys(obj)\n .sort()\n .forEach((key) => {\n const canon = canonicalize(obj[key]);\n if (canon !== undefined) {\n result[key] = canon;\n }\n });\n return result;\n }\n\n // For primitives (string, number, boolean) return as is\n return value;\n };\n\n const canonicalParams = canonicalize(params) as Record<string, unknown>;\n const paramsString = JSON.stringify(canonicalParams);\n\n return createHash(\"sha256\")\n .update(paramsString)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n public buildCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n const paramsHash = this.generateParamsHash(params);\n return `pakento:${this.apiKeyHash}:${functionName}:${paramsHash}`;\n }\n\n private safeJsonParse<T>(data: unknown): T | null {\n try {\n // Si data ya es un objeto/array y no un string, lo retornamos directamente\n if (typeof data === \"object\" && data !== null) {\n return data as T;\n }\n\n // Si es un string, intentamos parsearlo\n if (typeof data === \"string\") {\n return JSON.parse(data) as T;\n }\n\n // Si es otro tipo primitivo, lo retornamos tal como está\n return data as T;\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en safeJsonParse:\", error);\n console.warn(\"[PakentoSDK] Datos que causaron error:\", {\n type: typeof data,\n isArray: Array.isArray(data),\n data: data,\n });\n return null;\n }\n }\n\n private serializeForCache(value: unknown): string {\n try {\n // Crear un wrapper con metadata para verificar integridad\n const cacheData = {\n __pakento_cache_version: \"2.0\",\n __pakento_timestamp: Date.now(),\n data: value,\n };\n return JSON.stringify(cacheData);\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en serializeForCache:\", error);\n // Fallback a serialización simple\n return JSON.stringify(value);\n }\n }\n\n public async getCachedOrFetch<T>(\n key: string,\n fetcher: () => Promise<T>,\n ttl?: number,\n skipCache: boolean = false\n ): Promise<T> {\n if (!this.redis || skipCache) {\n return fetcher();\n }\n\n try {\n const cached = await this.redis.get(key);\n\n if (cached !== null && cached !== undefined) {\n try {\n const parsed = this.safeJsonParse<unknown>(cached);\n\n if (parsed !== null) {\n // Verificar si es el nuevo formato con metadata\n if (this.isCacheEnvelope<T>(parsed)) {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed.data as T;\n }\n // Formato legacy sin metadata\n else {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed as T;\n }\n } else {\n console.warn(`[PakentoSDK] ⚠️ Error parseando cache para: ${key}`);\n console.warn(`[PakentoSDK] Datos raw del cache:`, {\n type: typeof cached,\n value: cached,\n });\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(\n `[PakentoSDK] Error limpiando cache corrupto: ${err}`\n )\n );\n }\n } catch (parseError) {\n console.warn(\n `[PakentoSDK] ⚠️ Excepción parseando cache para: ${key}:`,\n parseError\n );\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(`[PakentoSDK] Error limpiando cache corrupto: ${err}`)\n );\n }\n }\n } catch (err) {\n console.warn(\"[PakentoSDK] Error leyendo cache Redis\", err);\n }\n\n const result = await fetcher();\n\n try {\n const serializedData = this.serializeForCache(result);\n await this.redis.set(key, serializedData, {\n ex: ttl ?? this.defaultTTL,\n });\n console.log(\n \"[PakentoSDK] Cache no encontrado, se guarda y se devuelve uno nuevo\"\n );\n } catch (err) {\n console.warn(\"[PakentoSDK] Error escribiendo cache Redis\", err);\n console.warn(\"[PakentoSDK] Detalles del error:\", {\n error: err,\n key: key,\n resultType: typeof result,\n resultSize: JSON.stringify(result).length,\n });\n }\n\n return result;\n }\n\n public async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const cached = await this.redis.get(key);\n\n if (cached === null || cached === undefined) {\n return false;\n }\n\n // Verificar que el cache se puede parsear correctamente\n const parsed = this.safeJsonParse(cached);\n return parsed !== null;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error verificando cache\", err);\n return false;\n }\n }\n\n /**\n * Limpia un cache específico si está corrupto\n */\n public async clearCorruptedCache(key: string): Promise<boolean> {\n if (!this.redis) {\n return false;\n }\n\n try {\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache corrupto\", err);\n return false;\n }\n }\n\n public getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.buildCacheKey(functionName, params);\n }\n\n public async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache\", err);\n return false;\n }\n }\n\n public async clearAllCache(): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const pattern = `pakento:${this.apiKeyHash}:*`;\n const keys = await this.redis.keys(pattern);\n\n if (keys.length > 0) {\n await this.redis.del(...keys);\n }\n\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando todo el cache\", err);\n return false;\n }\n }\n\n public async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const exists = await this.redis.exists(key);\n const ttl = exists ? await this.redis.ttl(key) : undefined;\n\n return {\n exists: exists === 1,\n key,\n ttl: ttl === -1 ? undefined : ttl,\n };\n } catch (err) {\n console.warn(\"[PakentoSDK] Error obteniendo info del cache\", err);\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n }\n}\n","import { Item, ItemEcommerceRaw } from \"../types\";\n\n/**\n * Parses a raw GraphQL response item to the normalized Item type\n * @param rawItem - The raw item from GraphQL response\n * @returns Normalized Item object\n */\nexport function parseRawItemToItem(rawItem: ItemEcommerceRaw): Item {\n // Get the first price from item_prices (assuming there's always at least one)\n const firstPrice = rawItem.item_prices.docs[0];\n\n // Transform images from GraphQL format to ItemImage format\n const images = rawItem.images.map((img) => ({\n url: img.url,\n thumbnail_url: img.thumbnailURL,\n }));\n\n // Get cover image URLs, fallback to first image if coverImage is null\n const coverImageUrl = rawItem.coverImage?.url || rawItem.images[0]?.url || \"\";\n const coverImageThumbnailUrl =\n rawItem.coverImage?.thumbnailURL || rawItem.images[0]?.thumbnailURL || \"\";\n\n return {\n id: rawItem.id,\n name: rawItem.name,\n featured: rawItem.featured,\n url_safe_name: rawItem.url_safe_name,\n currency_prefix: \"$\", // Default currency prefix, could be made configurable\n description: rawItem.description,\n old_price: firstPrice?.old_price || 0,\n item_category_name: rawItem.item_category?.name || \"\",\n item_category_id: parseInt(rawItem.item_category?.id || \"0\"),\n price_text: firstPrice?.price_text || \"\",\n price_notes: firstPrice?.price_notes || \"\", // Not available in raw response\n price: firstPrice?.amount || 0,\n brand_id: parseInt(rawItem.brand?.id || \"0\"),\n brand_name: rawItem.brand?.name || \"\",\n cover_image_url: coverImageUrl,\n cover_image_thumbnail_url: coverImageThumbnailUrl,\n images: images,\n };\n}\n\n/**\n * Parses an array of raw GraphQL response items to normalized Item types\n * @param rawItems - Array of raw items from GraphQL response\n * @returns Array of normalized Item objects\n */\nexport function parseRawItemsToItems(rawItems: ItemEcommerceRaw[]): Item[] {\n return rawItems.map(parseRawItemToItem);\n}\n"],"mappings":"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","names":["axios","config"]}
|
package/dist/index.mjs
CHANGED
|
@@ -236,6 +236,43 @@ var CacheService = class {
|
|
|
236
236
|
|
|
237
237
|
// src/services/api.ts
|
|
238
238
|
import { z } from "zod";
|
|
239
|
+
|
|
240
|
+
// src/utils/itemParser.ts
|
|
241
|
+
function parseRawItemToItem(rawItem) {
|
|
242
|
+
const firstPrice = rawItem.item_prices.docs[0];
|
|
243
|
+
const images = rawItem.images.map((img) => ({
|
|
244
|
+
url: img.url,
|
|
245
|
+
thumbnail_url: img.thumbnailURL
|
|
246
|
+
}));
|
|
247
|
+
const coverImageUrl = rawItem.coverImage?.url || rawItem.images[0]?.url || "";
|
|
248
|
+
const coverImageThumbnailUrl = rawItem.coverImage?.thumbnailURL || rawItem.images[0]?.thumbnailURL || "";
|
|
249
|
+
return {
|
|
250
|
+
id: rawItem.id,
|
|
251
|
+
name: rawItem.name,
|
|
252
|
+
featured: rawItem.featured,
|
|
253
|
+
url_safe_name: rawItem.url_safe_name,
|
|
254
|
+
currency_prefix: "$",
|
|
255
|
+
// Default currency prefix, could be made configurable
|
|
256
|
+
description: rawItem.description,
|
|
257
|
+
old_price: firstPrice?.old_price || 0,
|
|
258
|
+
item_category_name: rawItem.item_category?.name || "",
|
|
259
|
+
item_category_id: parseInt(rawItem.item_category?.id || "0"),
|
|
260
|
+
price_text: firstPrice?.price_text || "",
|
|
261
|
+
price_notes: firstPrice?.price_notes || "",
|
|
262
|
+
// Not available in raw response
|
|
263
|
+
price: firstPrice?.amount || 0,
|
|
264
|
+
brand_id: parseInt(rawItem.brand?.id || "0"),
|
|
265
|
+
brand_name: rawItem.brand?.name || "",
|
|
266
|
+
cover_image_url: coverImageUrl,
|
|
267
|
+
cover_image_thumbnail_url: coverImageThumbnailUrl,
|
|
268
|
+
images
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function parseRawItemsToItems(rawItems) {
|
|
272
|
+
return rawItems.map(parseRawItemToItem);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/services/api.ts
|
|
239
276
|
var PakentoCMSAPI = class {
|
|
240
277
|
constructor(config) {
|
|
241
278
|
this.defaultTTL = 86400;
|
|
@@ -323,7 +360,6 @@ var PakentoCMSAPI = class {
|
|
|
323
360
|
);
|
|
324
361
|
return {
|
|
325
362
|
data: null,
|
|
326
|
-
items: [],
|
|
327
363
|
totalDocs: 0,
|
|
328
364
|
totalPages: 0,
|
|
329
365
|
prevPage: null,
|
|
@@ -334,18 +370,26 @@ var PakentoCMSAPI = class {
|
|
|
334
370
|
}
|
|
335
371
|
const { skipCache = false, cacheTTL, ...rest } = validatedParams.data;
|
|
336
372
|
const cacheKey = this.cache.buildCacheKey("GetEcommerceItems", rest);
|
|
337
|
-
|
|
373
|
+
const finalData = await this.cache.getCachedOrFetch(
|
|
338
374
|
cacheKey,
|
|
339
375
|
() => this.fetchItemsFromAPI(rest),
|
|
340
376
|
cacheTTL,
|
|
341
377
|
skipCache
|
|
342
378
|
);
|
|
379
|
+
return {
|
|
380
|
+
data: finalData.data,
|
|
381
|
+
totalDocs: finalData.totalDocs,
|
|
382
|
+
totalPages: finalData.totalPages,
|
|
383
|
+
prevPage: finalData.prevPage,
|
|
384
|
+
nextPage: finalData.nextPage,
|
|
385
|
+
error: false,
|
|
386
|
+
errorMessage: null
|
|
387
|
+
};
|
|
343
388
|
}
|
|
344
389
|
async fetchItemsFromAPI(params = {}) {
|
|
345
390
|
if (!this.baseURL || !this.apiKey) {
|
|
346
391
|
return {
|
|
347
392
|
data: null,
|
|
348
|
-
items: [],
|
|
349
393
|
totalDocs: 0,
|
|
350
394
|
totalPages: 0,
|
|
351
395
|
prevPage: null,
|
|
@@ -383,22 +427,31 @@ var PakentoCMSAPI = class {
|
|
|
383
427
|
id
|
|
384
428
|
name
|
|
385
429
|
featured
|
|
386
|
-
old_price
|
|
387
|
-
currency_prefix
|
|
388
430
|
description
|
|
389
|
-
price_text
|
|
390
|
-
price_notes
|
|
391
431
|
url_safe_name
|
|
392
|
-
price
|
|
393
|
-
brand_id
|
|
394
|
-
brand_name
|
|
395
|
-
cover_image_url
|
|
396
|
-
cover_image_thumbnail_url
|
|
397
|
-
item_category_name
|
|
398
|
-
item_category_id
|
|
399
432
|
images {
|
|
400
433
|
url
|
|
401
|
-
|
|
434
|
+
thumbnailURL
|
|
435
|
+
}
|
|
436
|
+
coverImage {
|
|
437
|
+
url
|
|
438
|
+
thumbnailURL
|
|
439
|
+
}
|
|
440
|
+
item_prices {
|
|
441
|
+
docs {
|
|
442
|
+
amount
|
|
443
|
+
old_price
|
|
444
|
+
price_text
|
|
445
|
+
price_notes
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
brand {
|
|
449
|
+
id
|
|
450
|
+
name
|
|
451
|
+
}
|
|
452
|
+
item_category {
|
|
453
|
+
id
|
|
454
|
+
name
|
|
402
455
|
}
|
|
403
456
|
}
|
|
404
457
|
}
|
|
@@ -433,7 +486,6 @@ var PakentoCMSAPI = class {
|
|
|
433
486
|
if (error) {
|
|
434
487
|
return {
|
|
435
488
|
data: null,
|
|
436
|
-
items: [],
|
|
437
489
|
totalDocs: 0,
|
|
438
490
|
totalPages: 0,
|
|
439
491
|
prevPage: null,
|
|
@@ -443,8 +495,7 @@ var PakentoCMSAPI = class {
|
|
|
443
495
|
};
|
|
444
496
|
}
|
|
445
497
|
return {
|
|
446
|
-
data,
|
|
447
|
-
items: data.docs,
|
|
498
|
+
data: parseRawItemsToItems(data.docs),
|
|
448
499
|
totalDocs: data.totalDocs,
|
|
449
500
|
totalPages: data.totalPages,
|
|
450
501
|
prevPage: data.prevPage,
|
|
@@ -891,6 +942,8 @@ var PakentoCMSAPI = class {
|
|
|
891
942
|
var pakentoCMSAPI = new PakentoCMSAPI();
|
|
892
943
|
export {
|
|
893
944
|
CacheService,
|
|
894
|
-
pakentoCMSAPI
|
|
945
|
+
pakentoCMSAPI,
|
|
946
|
+
parseRawItemToItem,
|
|
947
|
+
parseRawItemsToItems
|
|
895
948
|
};
|
|
896
949
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/api.ts","../src/services/cache.ts"],"sourcesContent":["import axios, { AxiosInstance, AxiosError } from \"axios\";\nimport type {\n GetItemsParams,\n GetCategoriesParams,\n GetBrandsParams,\n GetEntityParams,\n CreateEcommerceOrderParams,\n SendContactUsEmailParams,\n CustomGraphQLParams,\n ItemsApiResponse,\n CategoriesApiResponse,\n BrandsApiResponse,\n EntityApiResponse,\n CreateEcommerceOrderResponse,\n SendContactUsEmailResponse,\n CustomGraphQLResponse,\n ItemsRawResponse,\n CategoriesRawResponse,\n BrandsRawResponse,\n ItemsWhere,\n} from \"../types\";\n\nimport { CacheService } from \"./cache\";\nimport { z } from \"zod\";\n\nclass PakentoCMSAPI {\n private client: AxiosInstance;\n private cache: CacheService;\n private defaultTTL: number = 86400;\n private baseURL: string;\n private apiKey: string;\n\n constructor(config?: { cacheTTL?: number }) {\n this.baseURL = process.env.PAKENTO_CMS_BASE_URL || \"\";\n this.apiKey = process.env.PAKENTO_API_KEY || \"\";\n\n if (config?.cacheTTL && typeof config.cacheTTL === \"number\") {\n this.defaultTTL = config.cacheTTL;\n }\n\n this.cache = new CacheService(this.defaultTTL, this.apiKey);\n\n this.client = axios.create({\n baseURL: this.baseURL,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `users API-Key ${this.apiKey}`,\n },\n });\n\n // Interceptor para imprimir las URLs de las llamadas a la API\n this.client.interceptors.request.use(\n (config) => {\n const fullUrl = `${config.baseURL}${config.url}`;\n console.log(`🌐 API Call: ${config.method?.toUpperCase()} ${fullUrl}`);\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n }\n\n // Centralized error handler\n private handleApiError(error: unknown, context: string): string {\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const responseMessage = error.response?.data?.message;\n if (status === 401) return \"API Key inválida o expirada\";\n if (status === 404) return `${context} no encontrado`;\n if (status && status >= 500) return \"Error del servidor CMS\";\n return (\n responseMessage || `Error de conexión en ${context}: ${error.message}`\n );\n } else if (error instanceof z.ZodError) {\n return `Validación fallida: ${error.issues\n .map((e: { message: string }) => e.message)\n .join(\", \")}`;\n } else if (error instanceof Error) {\n return error.message;\n }\n return \"Error desconocido\";\n }\n\n // Generic GraphQL fetcher\n private async fetchGraphQL<T>(\n query: string,\n variables: any,\n extractData: (responseData: any) => T\n ): Promise<{ data: T | null; error: boolean; errorMessage: string | null }> {\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query,\n variables,\n });\n\n if (response.data.errors) {\n const errorMessage = `GraphQL Error: ${response.data.errors[0].message}`;\n return { data: null, error: true, errorMessage };\n }\n\n const data = extractData(response.data.data);\n return { data, error: false, errorMessage: null };\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"GraphQL query\");\n return { data: null, error: true, errorMessage };\n }\n }\n\n async getItems(params: GetItemsParams = {}): Promise<ItemsApiResponse> {\n // Zod schema for validation\n const itemsSchema = z.object({\n where: z\n .object({\n item_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n item_super_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n brand_id: z.object({ equals: z.string().optional() }).optional(),\n id: z.object({ equals: z.string().optional() }).optional(),\n })\n .optional(),\n onlyOffers: z.boolean().optional(),\n limit: z.coerce.number().optional(),\n page: z.coerce.number().optional(),\n search: z.string().optional(),\n sort: z.string().optional(),\n minPrice: z.coerce.number().optional(),\n maxPrice: z.coerce.number().optional(),\n skipCache: z.boolean().optional(),\n cacheTTL: z.number().optional(),\n });\n\n const validatedParams = itemsSchema.safeParse(params);\n if (!validatedParams.success) {\n const errorMessage = this.handleApiError(\n validatedParams.error,\n \"getItems validation\"\n );\n return {\n data: null,\n items: [],\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n const { skipCache = false, cacheTTL, ...rest } = validatedParams.data;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceItems\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchItemsFromAPI(rest as GetItemsParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchItemsFromAPI(\n params: GetItemsParams = {}\n ): Promise<ItemsApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n items: [],\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Use generic fetchGraphQL\n const query = `\n query GetEcommerceItems(\n $where: EcommerceItemsWhere\n $onlyOffers: Boolean\n $limit: Int\n $page: Int\n $search: String\n $sort: String\n $minPrice: Float\n $maxPrice: Float\n ) {\n GetEcommerceItems(\n where: $where\n onlyOffers: $onlyOffers\n limit: $limit\n page: $page\n search: $search\n sort: $sort\n minPrice: $minPrice\n maxPrice: $maxPrice\n ) {\n totalDocs\n totalPages\n prevPage\n nextPage\n docs {\n id\n name\n featured\n old_price\n currency_prefix\n description\n price_text\n price_notes\n url_safe_name\n price\n brand_id\n brand_name\n cover_image_url\n cover_image_thumbnail_url\n item_category_name\n item_category_id\n images {\n url\n thumbnail_url\n }\n }\n }\n }\n `;\n\n // Construir variables (similar to before)\n const whereConditions: ItemsWhere = {};\n if (params.where?.item_category_id?.equals) {\n whereConditions.item_category_id = {\n equals: params.where.item_category_id.equals,\n };\n }\n\n if (params.where?.item_super_category_id?.equals) {\n whereConditions.item_super_category_id = {\n equals: params.where.item_super_category_id.equals,\n };\n }\n\n if (params.where?.brand_id?.equals) {\n whereConditions.brand_id = { equals: params.where.brand_id.equals };\n }\n\n if (params.where?.id?.equals) {\n whereConditions.id = { equals: params.where.id.equals };\n }\n\n const variables = {\n ...params,\n where:\n Object.keys(whereConditions).length > 0 ? whereConditions : undefined,\n };\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<ItemsRawResponse>(\n query,\n variables,\n (responseData) => responseData.GetEcommerceItems\n );\n\n if (error) {\n return {\n data: null,\n items: [],\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data,\n items: data!.docs,\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n prevPage: data!.prevPage,\n nextPage: data!.nextPage,\n error: false,\n errorMessage: null,\n };\n }\n\n async getCategories(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n const {\n skipCache = false,\n cacheTTL,\n ...rest\n } = params as GetCategoriesParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceCategories\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchCategoriesFromAPI(rest as GetCategoriesParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchCategoriesFromAPI(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceCategories(\n $where: EcommerceCategoriesWhere\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceCategories(\n where: $where\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n image_url\n }\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<CategoriesRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceCategories\n );\n\n if (error) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!.docs,\n categories: data!.docs,\n error: false,\n errorMessage: null,\n };\n }\n\n async getBrands(params: GetBrandsParams = {}): Promise<BrandsApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetBrandsParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceBrands\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchBrandsFromAPI(rest as GetBrandsParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchBrandsFromAPI(\n params: GetBrandsParams = {}\n ): Promise<BrandsApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceBrands(\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceBrands(\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n description\n items_count\n image_url\n image_thumbnail_url\n image_alt\n }\n hasNextPage\n hasPrevPage\n limit\n nextPage\n offset\n page\n pagingCounter\n prevPage\n totalDocs\n totalPages\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<BrandsRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceBrands\n );\n\n if (error) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n brands: data!.docs,\n hasNextPage: data!.hasNextPage,\n hasPrevPage: data!.hasPrevPage,\n limit: data!.limit,\n nextPage: data!.nextPage,\n offset: data!.offset,\n page: data!.page,\n pagingCounter: data!.pagingCounter,\n prevPage: data!.prevPage,\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n error: false,\n errorMessage: null,\n };\n }\n\n async getEntity(params: GetEntityParams = {}): Promise<EntityApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetEntityParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEntity\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchEntityFromAPI(rest as GetEntityParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchEntityFromAPI(\n params: GetEntityParams = {}\n ): Promise<EntityApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEntity {\n GetEntity {\n id\n tin\n name\n web\n address\n country\n city\n currency_id\n currency_name\n currency_prefix\n currency_suffix\n logo_url\n logo_alt\n logo_thumbnail_url\n logo_sizes_thumbnail_filename\n logo_filename\n logo_width\n logo_height\n logo_2_url\n logo_2_alt\n logo_2_thumbnail_url\n logo_2_sizes_thumbnail_filename\n logo_2_filename\n logo_2_width\n logo_2_height\n featured_image_url\n featured_image_alt\n featured_image_thumbnail_url\n featured_image_sizes_thumbnail_filename\n featured_image_filename\n featured_image_width\n featured_image_height\n }\n }\n `;\n\n const { data, error, errorMessage } = await this.fetchGraphQL<any>(\n query,\n params,\n (responseData) => responseData.GetEntity\n );\n\n if (error) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n entity: data!,\n error: false,\n errorMessage: null,\n };\n }\n\n async createEcommerceOrder(\n params: CreateEcommerceOrderParams\n ): Promise<CreateEcommerceOrderResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message: \"SDK no configurado\",\n error: true,\n errorMessage: \"SDK no configurado\",\n };\n }\n\n const orderSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n phone: z.string().optional(),\n notes: z.string().optional(),\n tin: z.string().optional(),\n items: z\n .array(\n z.object({\n id: z.number().positive(),\n quantity: z.number().positive(),\n })\n )\n .min(1),\n delivery_address: z.string().optional(),\n delivery_instructions: z.string().optional(),\n payment_method: z.enum([\"cash\", \"transfer\"]).optional(),\n });\n\n const validated = orderSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"createEcommerceOrder validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/orders/create-ecommerce-order\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Orden creada exitosamente\",\n order_id: response.data.order_id,\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage = response.data.message || \"Error al crear la orden\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"createEcommerceOrder\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n async executeCustomQuery<T>(\n params: CustomGraphQLParams\n ): Promise<CustomGraphQLResponse<T>> {\n // Validar configuración antes de continuar\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null as T,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Validar que se proporcione un query\n if (\n !params.query ||\n typeof params.query !== \"string\" ||\n params.query.trim() === \"\"\n ) {\n return {\n data: null as T,\n error: true,\n errorMessage: \"Se requiere un query GraphQL válido.\",\n };\n }\n\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query: params.query,\n variables: params.variables || {},\n });\n\n // Si hay errores de GraphQL, los incluimos en la respuesta pero no como error fatal\n if (response.data.errors && response.data.errors.length > 0) {\n return {\n data: response.data.data || (null as T),\n errors: response.data.errors,\n error: true,\n errorMessage: `GraphQL Errors: ${response.data.errors\n .map((err: unknown) => (err as Error).message)\n .join(\", \")}`,\n };\n }\n\n return {\n data: response.data.data,\n error: false,\n errorMessage: null,\n };\n } catch (error) {\n let errorMessage = \"Error desconocido\";\n\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n if (status === 401) {\n errorMessage = \"API Key inválida o expirada\";\n } else if (status === 404) {\n errorMessage = \"Endpoint GraphQL no encontrado\";\n } else if (status === 400) {\n errorMessage = \"Query GraphQL inválido o malformado\";\n } else if (status && status >= 500) {\n errorMessage = \"Error del servidor CMS\";\n } else {\n errorMessage = `Error de conexión: ${error.message}`;\n }\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n return {\n data: null as T,\n error: true,\n errorMessage,\n };\n }\n }\n\n async sendContactUsEmail(\n params: SendContactUsEmailParams\n ): Promise<SendContactUsEmailResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const contactUsSchema = z.object({\n name: z.string().min(1),\n email: z.email(),\n phone: z.string().optional(),\n subject: z.string().optional(),\n message: z.string().min(1),\n });\n\n const validated = contactUsSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"sendContactUsEmail validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/entities/send-contact-us-email\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Mensaje enviado exitosamente\",\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage =\n response.data.message || \"Error al enviar el mensaje\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"sendContactUsEmail\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n /**\n * Verifica si existe cache para una función y parámetros específicos\n */\n async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.hasCache(functionName, params);\n }\n\n /**\n * Obtiene la key de cache para una función y parámetros específicos\n */\n getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.cache.getCacheKey(functionName, params);\n }\n\n /**\n * Limpia el cache para una función y parámetros específicos\n */\n async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.clearCache(functionName, params);\n }\n\n /**\n * Limpia todo el cache relacionado con este API Key\n */\n async clearAllCache(): Promise<boolean> {\n return this.cache.clearAllCache();\n }\n\n /**\n * Obtiene información del cache (útil para debugging)\n */\n async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n return this.cache.getCacheInfo(functionName, params);\n }\n\n /**\n * Limpia un cache específico que pueda estar corrupto\n */\n async clearCorruptedCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n const key = this.cache.getCacheKey(functionName, params);\n return this.cache.clearCorruptedCache(key);\n }\n}\n\nexport const pakentoCMSAPI = new PakentoCMSAPI();\n","import { Redis } from \"@upstash/redis\";\nimport { createHash } from \"crypto\";\n\nexport class CacheService {\n private redis?: Redis;\n private defaultTTL: number;\n private apiKeyHash: string;\n\n private isCacheEnvelope<U>(value: unknown): value is {\n __pakento_cache_version: string;\n __pakento_timestamp: number;\n data: U;\n } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__pakento_cache_version\" in value &&\n \"data\" in value\n );\n }\n\n constructor(defaultTTL: number, apiKey: string) {\n this.defaultTTL = defaultTTL;\n this.apiKeyHash = createHash(\"sha256\")\n .update(apiKey)\n .digest(\"hex\")\n .substring(0, 8);\n\n if (\n process.env.UPSTASH_REDIS_REST_URL &&\n process.env.UPSTASH_REDIS_REST_TOKEN\n ) {\n this.redis = new Redis({\n url: process.env.UPSTASH_REDIS_REST_URL,\n token: process.env.UPSTASH_REDIS_REST_TOKEN,\n });\n }\n }\n\n private generateParamsHash(params: Record<string, unknown>): string {\n const canonicalize = (value: unknown): unknown => {\n if (value === undefined) return undefined; // omit later\n if (value === null) return null;\n\n if (Array.isArray(value)) {\n // Preserve order for arrays but canonicalize elements\n return value.map((v) => canonicalize(v));\n }\n\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n Object.keys(obj)\n .sort()\n .forEach((key) => {\n const canon = canonicalize(obj[key]);\n if (canon !== undefined) {\n result[key] = canon;\n }\n });\n return result;\n }\n\n // For primitives (string, number, boolean) return as is\n return value;\n };\n\n const canonicalParams = canonicalize(params) as Record<string, unknown>;\n const paramsString = JSON.stringify(canonicalParams);\n\n return createHash(\"sha256\")\n .update(paramsString)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n public buildCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n const paramsHash = this.generateParamsHash(params);\n return `pakento:${this.apiKeyHash}:${functionName}:${paramsHash}`;\n }\n\n private safeJsonParse<T>(data: unknown): T | null {\n try {\n // Si data ya es un objeto/array y no un string, lo retornamos directamente\n if (typeof data === \"object\" && data !== null) {\n return data as T;\n }\n\n // Si es un string, intentamos parsearlo\n if (typeof data === \"string\") {\n return JSON.parse(data) as T;\n }\n\n // Si es otro tipo primitivo, lo retornamos tal como está\n return data as T;\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en safeJsonParse:\", error);\n console.warn(\"[PakentoSDK] Datos que causaron error:\", {\n type: typeof data,\n isArray: Array.isArray(data),\n data: data,\n });\n return null;\n }\n }\n\n private serializeForCache(value: unknown): string {\n try {\n // Crear un wrapper con metadata para verificar integridad\n const cacheData = {\n __pakento_cache_version: \"2.0\",\n __pakento_timestamp: Date.now(),\n data: value,\n };\n return JSON.stringify(cacheData);\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en serializeForCache:\", error);\n // Fallback a serialización simple\n return JSON.stringify(value);\n }\n }\n\n public async getCachedOrFetch<T>(\n key: string,\n fetcher: () => Promise<T>,\n ttl?: number,\n skipCache: boolean = false\n ): Promise<T> {\n if (!this.redis || skipCache) {\n return fetcher();\n }\n\n try {\n const cached = await this.redis.get(key);\n\n if (cached !== null && cached !== undefined) {\n try {\n const parsed = this.safeJsonParse<unknown>(cached);\n\n if (parsed !== null) {\n // Verificar si es el nuevo formato con metadata\n if (this.isCacheEnvelope<T>(parsed)) {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed.data as T;\n }\n // Formato legacy sin metadata\n else {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed as T;\n }\n } else {\n console.warn(`[PakentoSDK] ⚠️ Error parseando cache para: ${key}`);\n console.warn(`[PakentoSDK] Datos raw del cache:`, {\n type: typeof cached,\n value: cached,\n });\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(\n `[PakentoSDK] Error limpiando cache corrupto: ${err}`\n )\n );\n }\n } catch (parseError) {\n console.warn(\n `[PakentoSDK] ⚠️ Excepción parseando cache para: ${key}:`,\n parseError\n );\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(`[PakentoSDK] Error limpiando cache corrupto: ${err}`)\n );\n }\n }\n } catch (err) {\n console.warn(\"[PakentoSDK] Error leyendo cache Redis\", err);\n }\n\n const result = await fetcher();\n\n try {\n const serializedData = this.serializeForCache(result);\n await this.redis.set(key, serializedData, {\n ex: ttl ?? this.defaultTTL,\n });\n console.log(\n \"[PakentoSDK] Cache no encontrado, se guarda y se devuelve uno nuevo\"\n );\n } catch (err) {\n console.warn(\"[PakentoSDK] Error escribiendo cache Redis\", err);\n console.warn(\"[PakentoSDK] Detalles del error:\", {\n error: err,\n key: key,\n resultType: typeof result,\n resultSize: JSON.stringify(result).length,\n });\n }\n\n return result;\n }\n\n public async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const cached = await this.redis.get(key);\n\n if (cached === null || cached === undefined) {\n return false;\n }\n\n // Verificar que el cache se puede parsear correctamente\n const parsed = this.safeJsonParse(cached);\n return parsed !== null;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error verificando cache\", err);\n return false;\n }\n }\n\n /**\n * Limpia un cache específico si está corrupto\n */\n public async clearCorruptedCache(key: string): Promise<boolean> {\n if (!this.redis) {\n return false;\n }\n\n try {\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache corrupto\", err);\n return false;\n }\n }\n\n public getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.buildCacheKey(functionName, params);\n }\n\n public async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache\", err);\n return false;\n }\n }\n\n public async clearAllCache(): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const pattern = `pakento:${this.apiKeyHash}:*`;\n const keys = await this.redis.keys(pattern);\n\n if (keys.length > 0) {\n await this.redis.del(...keys);\n }\n\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando todo el cache\", err);\n return false;\n }\n }\n\n public async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const exists = await this.redis.exists(key);\n const ttl = exists ? await this.redis.ttl(key) : undefined;\n\n return {\n exists: exists === 1,\n key,\n ttl: ttl === -1 ? undefined : ttl,\n };\n } catch (err) {\n console.warn(\"[PakentoSDK] Error obteniendo info del cache\", err);\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n }\n}\n"],"mappings":"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","names":["config"]}
|
|
1
|
+
{"version":3,"sources":["../src/services/api.ts","../src/services/cache.ts","../src/utils/itemParser.ts"],"sourcesContent":["import axios, { AxiosInstance, AxiosError } from \"axios\";\nimport type {\n GetItemsParams,\n GetCategoriesParams,\n GetBrandsParams,\n GetEntityParams,\n CreateEcommerceOrderParams,\n SendContactUsEmailParams,\n CustomGraphQLParams,\n CategoriesApiResponse,\n BrandsApiResponse,\n EntityApiResponse,\n CreateEcommerceOrderResponse,\n SendContactUsEmailResponse,\n CustomGraphQLResponse,\n ItemsRawResponse,\n CategoriesRawResponse,\n BrandsRawResponse,\n ItemsWhere,\n ApiResponse,\n Item,\n} from \"../types\";\n\nimport { CacheService } from \"./cache\";\nimport { z } from \"zod\";\nimport { parseRawItemsToItems } from \"../utils\";\n\nclass PakentoCMSAPI {\n private client: AxiosInstance;\n private cache: CacheService;\n private defaultTTL: number = 86400;\n private baseURL: string;\n private apiKey: string;\n\n constructor(config?: { cacheTTL?: number }) {\n this.baseURL = process.env.PAKENTO_CMS_BASE_URL || \"\";\n this.apiKey = process.env.PAKENTO_API_KEY || \"\";\n\n if (config?.cacheTTL && typeof config.cacheTTL === \"number\") {\n this.defaultTTL = config.cacheTTL;\n }\n\n this.cache = new CacheService(this.defaultTTL, this.apiKey);\n\n this.client = axios.create({\n baseURL: this.baseURL,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `users API-Key ${this.apiKey}`,\n },\n });\n\n // Interceptor para imprimir las URLs de las llamadas a la API\n this.client.interceptors.request.use(\n (config) => {\n const fullUrl = `${config.baseURL}${config.url}`;\n console.log(`🌐 API Call: ${config.method?.toUpperCase()} ${fullUrl}`);\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n }\n\n // Centralized error handler\n private handleApiError(error: unknown, context: string): string {\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const responseMessage = error.response?.data?.message;\n if (status === 401) return \"API Key inválida o expirada\";\n if (status === 404) return `${context} no encontrado`;\n if (status && status >= 500) return \"Error del servidor CMS\";\n return (\n responseMessage || `Error de conexión en ${context}: ${error.message}`\n );\n } else if (error instanceof z.ZodError) {\n return `Validación fallida: ${error.issues\n .map((e: { message: string }) => e.message)\n .join(\", \")}`;\n } else if (error instanceof Error) {\n return error.message;\n }\n return \"Error desconocido\";\n }\n\n // Generic GraphQL fetcher\n private async fetchGraphQL<T>(\n query: string,\n variables: any,\n extractData: (responseData: any) => T\n ): Promise<{ data: T | null; error: boolean; errorMessage: string | null }> {\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query,\n variables,\n });\n\n if (response.data.errors) {\n const errorMessage = `GraphQL Error: ${response.data.errors[0].message}`;\n return { data: null, error: true, errorMessage };\n }\n\n const data = extractData(response.data.data);\n return { data, error: false, errorMessage: null };\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"GraphQL query\");\n return { data: null, error: true, errorMessage };\n }\n }\n\n async getItems(params: GetItemsParams = {}): Promise<ApiResponse<Item>> {\n // Zod schema for validation\n const itemsSchema = z.object({\n where: z\n .object({\n item_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n item_super_category_id: z\n .object({ equals: z.string().optional() })\n .optional(),\n brand_id: z.object({ equals: z.string().optional() }).optional(),\n id: z.object({ equals: z.string().optional() }).optional(),\n })\n .optional(),\n onlyOffers: z.boolean().optional(),\n limit: z.coerce.number().optional(),\n page: z.coerce.number().optional(),\n search: z.string().optional(),\n sort: z.string().optional(),\n minPrice: z.coerce.number().optional(),\n maxPrice: z.coerce.number().optional(),\n skipCache: z.boolean().optional(),\n cacheTTL: z.number().optional(),\n });\n\n const validatedParams = itemsSchema.safeParse(params);\n if (!validatedParams.success) {\n const errorMessage = this.handleApiError(\n validatedParams.error,\n \"getItems validation\"\n );\n return {\n data: null,\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n const { skipCache = false, cacheTTL, ...rest } = validatedParams.data;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceItems\", rest);\n const finalData = await this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchItemsFromAPI(rest as GetItemsParams),\n cacheTTL,\n skipCache\n );\n\n return {\n data: finalData.data,\n totalDocs: finalData.totalDocs,\n totalPages: finalData.totalPages,\n prevPage: finalData.prevPage,\n nextPage: finalData.nextPage,\n error: false,\n errorMessage: null,\n };\n }\n\n private async fetchItemsFromAPI(\n params: GetItemsParams = {}\n ): Promise<ApiResponse<Item>> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Use generic fetchGraphQL\n const query = `\n query GetEcommerceItems(\n $where: EcommerceItemsWhere\n $onlyOffers: Boolean\n $limit: Int\n $page: Int\n $search: String\n $sort: String\n $minPrice: Float\n $maxPrice: Float\n ) {\n GetEcommerceItems(\n where: $where\n onlyOffers: $onlyOffers\n limit: $limit\n page: $page\n search: $search\n sort: $sort\n minPrice: $minPrice\n maxPrice: $maxPrice\n ) {\n totalDocs\n totalPages\n prevPage\n nextPage\n docs {\n id\n name\n featured\n description\n url_safe_name\n images {\n url\n thumbnailURL\n }\n coverImage {\n url\n thumbnailURL\n }\n item_prices {\n docs {\n amount\n old_price\n price_text\n price_notes\n }\n }\n brand {\n id\n name\n }\n item_category {\n id\n name\n }\n }\n }\n }\n `;\n\n // Construir variables\n const whereConditions: ItemsWhere = {};\n if (params.where?.item_category_id?.equals) {\n whereConditions.item_category_id = {\n equals: params.where.item_category_id.equals,\n };\n }\n\n if (params.where?.item_super_category_id?.equals) {\n whereConditions.item_super_category_id = {\n equals: params.where.item_super_category_id.equals,\n };\n }\n\n if (params.where?.brand_id?.equals) {\n whereConditions.brand_id = { equals: params.where.brand_id.equals };\n }\n\n if (params.where?.id?.equals) {\n whereConditions.id = { equals: params.where.id.equals };\n }\n\n const variables = {\n ...params,\n where:\n Object.keys(whereConditions).length > 0 ? whereConditions : undefined,\n };\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<ItemsRawResponse>(\n query,\n variables,\n (responseData) => responseData.GetEcommerceItems\n );\n\n if (error) {\n return {\n data: null,\n totalDocs: 0,\n totalPages: 0,\n prevPage: null,\n nextPage: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: parseRawItemsToItems(data!.docs),\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n prevPage: data!.prevPage,\n nextPage: data!.nextPage,\n error: false,\n errorMessage: null,\n };\n }\n\n async getCategories(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n const {\n skipCache = false,\n cacheTTL,\n ...rest\n } = params as GetCategoriesParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceCategories\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchCategoriesFromAPI(rest as GetCategoriesParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchCategoriesFromAPI(\n params: GetCategoriesParams = {}\n ): Promise<CategoriesApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceCategories(\n $where: EcommerceCategoriesWhere\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceCategories(\n where: $where\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n image_url\n }\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<CategoriesRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceCategories\n );\n\n if (error) {\n return {\n data: null,\n categories: [],\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!.docs,\n categories: data!.docs,\n error: false,\n errorMessage: null,\n };\n }\n\n async getBrands(params: GetBrandsParams = {}): Promise<BrandsApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetBrandsParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEcommerceBrands\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchBrandsFromAPI(rest as GetBrandsParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchBrandsFromAPI(\n params: GetBrandsParams = {}\n ): Promise<BrandsApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEcommerceBrands(\n $limit: Int\n $page: Int\n $sort: String\n ) {\n GetEcommerceBrands(\n limit: $limit\n page: $page\n sort: $sort\n ) {\n docs {\n id\n name\n description\n items_count\n image_url\n image_thumbnail_url\n image_alt\n }\n hasNextPage\n hasPrevPage\n limit\n nextPage\n offset\n page\n pagingCounter\n prevPage\n totalDocs\n totalPages\n }\n }\n `;\n\n const { data, error, errorMessage } =\n await this.fetchGraphQL<BrandsRawResponse>(\n query,\n params,\n (responseData) => responseData.GetEcommerceBrands\n );\n\n if (error) {\n return {\n data: null,\n brands: [],\n hasNextPage: false,\n hasPrevPage: false,\n limit: 0,\n nextPage: 0,\n offset: 0,\n page: 0,\n pagingCounter: 0,\n prevPage: 0,\n totalDocs: 0,\n totalPages: 0,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n brands: data!.docs,\n hasNextPage: data!.hasNextPage,\n hasPrevPage: data!.hasPrevPage,\n limit: data!.limit,\n nextPage: data!.nextPage,\n offset: data!.offset,\n page: data!.page,\n pagingCounter: data!.pagingCounter,\n prevPage: data!.prevPage,\n totalDocs: data!.totalDocs,\n totalPages: data!.totalPages,\n error: false,\n errorMessage: null,\n };\n }\n\n async getEntity(params: GetEntityParams = {}): Promise<EntityApiResponse> {\n const { skipCache = false, cacheTTL, ...rest } = params as GetEntityParams;\n const cacheKey = this.cache.buildCacheKey(\"GetEntity\", rest);\n return this.cache.getCachedOrFetch(\n cacheKey,\n () => this.fetchEntityFromAPI(rest as GetEntityParams),\n cacheTTL,\n skipCache\n );\n }\n\n private async fetchEntityFromAPI(\n params: GetEntityParams = {}\n ): Promise<EntityApiResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const query = `\n query GetEntity {\n GetEntity {\n id\n tin\n name\n web\n address\n country\n city\n currency_id\n currency_name\n currency_prefix\n currency_suffix\n logo_url\n logo_alt\n logo_thumbnail_url\n logo_sizes_thumbnail_filename\n logo_filename\n logo_width\n logo_height\n logo_2_url\n logo_2_alt\n logo_2_thumbnail_url\n logo_2_sizes_thumbnail_filename\n logo_2_filename\n logo_2_width\n logo_2_height\n featured_image_url\n featured_image_alt\n featured_image_thumbnail_url\n featured_image_sizes_thumbnail_filename\n featured_image_filename\n featured_image_width\n featured_image_height\n }\n }\n `;\n\n const { data, error, errorMessage } = await this.fetchGraphQL<any>(\n query,\n params,\n (responseData) => responseData.GetEntity\n );\n\n if (error) {\n return {\n data: null,\n entity: null,\n error: true,\n errorMessage,\n };\n }\n\n return {\n data: data!,\n entity: data!,\n error: false,\n errorMessage: null,\n };\n }\n\n async createEcommerceOrder(\n params: CreateEcommerceOrderParams\n ): Promise<CreateEcommerceOrderResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message: \"SDK no configurado\",\n error: true,\n errorMessage: \"SDK no configurado\",\n };\n }\n\n const orderSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n phone: z.string().optional(),\n notes: z.string().optional(),\n tin: z.string().optional(),\n items: z\n .array(\n z.object({\n id: z.number().positive(),\n quantity: z.number().positive(),\n })\n )\n .min(1),\n delivery_address: z.string().optional(),\n delivery_instructions: z.string().optional(),\n payment_method: z.enum([\"cash\", \"transfer\"]).optional(),\n });\n\n const validated = orderSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"createEcommerceOrder validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/orders/create-ecommerce-order\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Orden creada exitosamente\",\n order_id: response.data.order_id,\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage = response.data.message || \"Error al crear la orden\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"createEcommerceOrder\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n async executeCustomQuery<T>(\n params: CustomGraphQLParams\n ): Promise<CustomGraphQLResponse<T>> {\n // Validar configuración antes de continuar\n if (!this.baseURL || !this.apiKey) {\n return {\n data: null as T,\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n // Validar que se proporcione un query\n if (\n !params.query ||\n typeof params.query !== \"string\" ||\n params.query.trim() === \"\"\n ) {\n return {\n data: null as T,\n error: true,\n errorMessage: \"Se requiere un query GraphQL válido.\",\n };\n }\n\n try {\n const response = await this.client.post(\"/api/graphql\", {\n query: params.query,\n variables: params.variables || {},\n });\n\n // Si hay errores de GraphQL, los incluimos en la respuesta pero no como error fatal\n if (response.data.errors && response.data.errors.length > 0) {\n return {\n data: response.data.data || (null as T),\n errors: response.data.errors,\n error: true,\n errorMessage: `GraphQL Errors: ${response.data.errors\n .map((err: unknown) => (err as Error).message)\n .join(\", \")}`,\n };\n }\n\n return {\n data: response.data.data,\n error: false,\n errorMessage: null,\n };\n } catch (error) {\n let errorMessage = \"Error desconocido\";\n\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n if (status === 401) {\n errorMessage = \"API Key inválida o expirada\";\n } else if (status === 404) {\n errorMessage = \"Endpoint GraphQL no encontrado\";\n } else if (status === 400) {\n errorMessage = \"Query GraphQL inválido o malformado\";\n } else if (status && status >= 500) {\n errorMessage = \"Error del servidor CMS\";\n } else {\n errorMessage = `Error de conexión: ${error.message}`;\n }\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n return {\n data: null as T,\n error: true,\n errorMessage,\n };\n }\n }\n\n async sendContactUsEmail(\n params: SendContactUsEmailParams\n ): Promise<SendContactUsEmailResponse> {\n if (!this.baseURL || !this.apiKey) {\n return {\n message:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n error: true,\n errorMessage:\n \"SDK no configurado: PAKENTO_CMS_BASE_URL o PAKENTO_API_KEY faltantes.\",\n };\n }\n\n const contactUsSchema = z.object({\n name: z.string().min(1),\n email: z.email(),\n phone: z.string().optional(),\n subject: z.string().optional(),\n message: z.string().min(1),\n });\n\n const validated = contactUsSchema.safeParse(params);\n if (!validated.success) {\n const errorMessage = this.handleApiError(\n validated.error,\n \"sendContactUsEmail validation\"\n );\n return { message: errorMessage, error: true, errorMessage };\n }\n\n try {\n const response = await this.client.post(\n \"/api/entities/send-contact-us-email\",\n validated.data\n );\n\n if (response.status === 200) {\n return {\n message: response.data.message || \"Mensaje enviado exitosamente\",\n error: false,\n errorMessage: null,\n };\n } else {\n const errorMessage =\n response.data.message || \"Error al enviar el mensaje\";\n return { message: errorMessage, error: true, errorMessage };\n }\n } catch (error) {\n const errorMessage = this.handleApiError(error, \"sendContactUsEmail\");\n return { message: errorMessage, error: true, errorMessage };\n }\n }\n\n /**\n * Verifica si existe cache para una función y parámetros específicos\n */\n async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.hasCache(functionName, params);\n }\n\n /**\n * Obtiene la key de cache para una función y parámetros específicos\n */\n getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.cache.getCacheKey(functionName, params);\n }\n\n /**\n * Limpia el cache para una función y parámetros específicos\n */\n async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n return this.cache.clearCache(functionName, params);\n }\n\n /**\n * Limpia todo el cache relacionado con este API Key\n */\n async clearAllCache(): Promise<boolean> {\n return this.cache.clearAllCache();\n }\n\n /**\n * Obtiene información del cache (útil para debugging)\n */\n async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n return this.cache.getCacheInfo(functionName, params);\n }\n\n /**\n * Limpia un cache específico que pueda estar corrupto\n */\n async clearCorruptedCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n const key = this.cache.getCacheKey(functionName, params);\n return this.cache.clearCorruptedCache(key);\n }\n}\n\nexport const pakentoCMSAPI = new PakentoCMSAPI();\n","import { Redis } from \"@upstash/redis\";\nimport { createHash } from \"crypto\";\n\nexport class CacheService {\n private redis?: Redis;\n private defaultTTL: number;\n private apiKeyHash: string;\n\n private isCacheEnvelope<U>(value: unknown): value is {\n __pakento_cache_version: string;\n __pakento_timestamp: number;\n data: U;\n } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__pakento_cache_version\" in value &&\n \"data\" in value\n );\n }\n\n constructor(defaultTTL: number, apiKey: string) {\n this.defaultTTL = defaultTTL;\n this.apiKeyHash = createHash(\"sha256\")\n .update(apiKey)\n .digest(\"hex\")\n .substring(0, 8);\n\n if (\n process.env.UPSTASH_REDIS_REST_URL &&\n process.env.UPSTASH_REDIS_REST_TOKEN\n ) {\n this.redis = new Redis({\n url: process.env.UPSTASH_REDIS_REST_URL,\n token: process.env.UPSTASH_REDIS_REST_TOKEN,\n });\n }\n }\n\n private generateParamsHash(params: Record<string, unknown>): string {\n const canonicalize = (value: unknown): unknown => {\n if (value === undefined) return undefined; // omit later\n if (value === null) return null;\n\n if (Array.isArray(value)) {\n // Preserve order for arrays but canonicalize elements\n return value.map((v) => canonicalize(v));\n }\n\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n Object.keys(obj)\n .sort()\n .forEach((key) => {\n const canon = canonicalize(obj[key]);\n if (canon !== undefined) {\n result[key] = canon;\n }\n });\n return result;\n }\n\n // For primitives (string, number, boolean) return as is\n return value;\n };\n\n const canonicalParams = canonicalize(params) as Record<string, unknown>;\n const paramsString = JSON.stringify(canonicalParams);\n\n return createHash(\"sha256\")\n .update(paramsString)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n public buildCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n const paramsHash = this.generateParamsHash(params);\n return `pakento:${this.apiKeyHash}:${functionName}:${paramsHash}`;\n }\n\n private safeJsonParse<T>(data: unknown): T | null {\n try {\n // Si data ya es un objeto/array y no un string, lo retornamos directamente\n if (typeof data === \"object\" && data !== null) {\n return data as T;\n }\n\n // Si es un string, intentamos parsearlo\n if (typeof data === \"string\") {\n return JSON.parse(data) as T;\n }\n\n // Si es otro tipo primitivo, lo retornamos tal como está\n return data as T;\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en safeJsonParse:\", error);\n console.warn(\"[PakentoSDK] Datos que causaron error:\", {\n type: typeof data,\n isArray: Array.isArray(data),\n data: data,\n });\n return null;\n }\n }\n\n private serializeForCache(value: unknown): string {\n try {\n // Crear un wrapper con metadata para verificar integridad\n const cacheData = {\n __pakento_cache_version: \"2.0\",\n __pakento_timestamp: Date.now(),\n data: value,\n };\n return JSON.stringify(cacheData);\n } catch (error) {\n console.warn(\"[PakentoSDK] Error en serializeForCache:\", error);\n // Fallback a serialización simple\n return JSON.stringify(value);\n }\n }\n\n public async getCachedOrFetch<T>(\n key: string,\n fetcher: () => Promise<T>,\n ttl?: number,\n skipCache: boolean = false\n ): Promise<T> {\n if (!this.redis || skipCache) {\n return fetcher();\n }\n\n try {\n const cached = await this.redis.get(key);\n\n if (cached !== null && cached !== undefined) {\n try {\n const parsed = this.safeJsonParse<unknown>(cached);\n\n if (parsed !== null) {\n // Verificar si es el nuevo formato con metadata\n if (this.isCacheEnvelope<T>(parsed)) {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed.data as T;\n }\n // Formato legacy sin metadata\n else {\n console.log(\"[PakentoSDK] Cache encontrado y devuelto\");\n return parsed as T;\n }\n } else {\n console.warn(`[PakentoSDK] ⚠️ Error parseando cache para: ${key}`);\n console.warn(`[PakentoSDK] Datos raw del cache:`, {\n type: typeof cached,\n value: cached,\n });\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(\n `[PakentoSDK] Error limpiando cache corrupto: ${err}`\n )\n );\n }\n } catch (parseError) {\n console.warn(\n `[PakentoSDK] ⚠️ Excepción parseando cache para: ${key}:`,\n parseError\n );\n // Limpiar cache corrupto de manera asíncrona\n this.clearCorruptedCache(key).catch((err) =>\n console.warn(`[PakentoSDK] Error limpiando cache corrupto: ${err}`)\n );\n }\n }\n } catch (err) {\n console.warn(\"[PakentoSDK] Error leyendo cache Redis\", err);\n }\n\n const result = await fetcher();\n\n try {\n const serializedData = this.serializeForCache(result);\n await this.redis.set(key, serializedData, {\n ex: ttl ?? this.defaultTTL,\n });\n console.log(\n \"[PakentoSDK] Cache no encontrado, se guarda y se devuelve uno nuevo\"\n );\n } catch (err) {\n console.warn(\"[PakentoSDK] Error escribiendo cache Redis\", err);\n console.warn(\"[PakentoSDK] Detalles del error:\", {\n error: err,\n key: key,\n resultType: typeof result,\n resultSize: JSON.stringify(result).length,\n });\n }\n\n return result;\n }\n\n public async hasCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const cached = await this.redis.get(key);\n\n if (cached === null || cached === undefined) {\n return false;\n }\n\n // Verificar que el cache se puede parsear correctamente\n const parsed = this.safeJsonParse(cached);\n return parsed !== null;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error verificando cache\", err);\n return false;\n }\n }\n\n /**\n * Limpia un cache específico si está corrupto\n */\n public async clearCorruptedCache(key: string): Promise<boolean> {\n if (!this.redis) {\n return false;\n }\n\n try {\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache corrupto\", err);\n return false;\n }\n }\n\n public getCacheKey(\n functionName: string,\n params: Record<string, unknown> = {}\n ): string {\n return this.buildCacheKey(functionName, params);\n }\n\n public async clearCache(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n await this.redis.del(key);\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando cache\", err);\n return false;\n }\n }\n\n public async clearAllCache(): Promise<boolean> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return false;\n }\n\n try {\n const pattern = `pakento:${this.apiKeyHash}:*`;\n const keys = await this.redis.keys(pattern);\n\n if (keys.length > 0) {\n await this.redis.del(...keys);\n }\n\n return true;\n } catch (err) {\n console.warn(\"[PakentoSDK] Error limpiando todo el cache\", err);\n return false;\n }\n }\n\n public async getCacheInfo(\n functionName: string,\n params: Record<string, unknown> = {}\n ): Promise<{\n exists: boolean;\n key: string;\n ttl?: number;\n }> {\n if (!this.redis) {\n console.warn(\"[PakentoSDK] Redis no configurado\");\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n\n try {\n const key = this.buildCacheKey(functionName, params);\n const exists = await this.redis.exists(key);\n const ttl = exists ? await this.redis.ttl(key) : undefined;\n\n return {\n exists: exists === 1,\n key,\n ttl: ttl === -1 ? undefined : ttl,\n };\n } catch (err) {\n console.warn(\"[PakentoSDK] Error obteniendo info del cache\", err);\n return {\n exists: false,\n key: this.buildCacheKey(functionName, params),\n };\n }\n }\n}\n","import { Item, ItemEcommerceRaw } from \"../types\";\n\n/**\n * Parses a raw GraphQL response item to the normalized Item type\n * @param rawItem - The raw item from GraphQL response\n * @returns Normalized Item object\n */\nexport function parseRawItemToItem(rawItem: ItemEcommerceRaw): Item {\n // Get the first price from item_prices (assuming there's always at least one)\n const firstPrice = rawItem.item_prices.docs[0];\n\n // Transform images from GraphQL format to ItemImage format\n const images = rawItem.images.map((img) => ({\n url: img.url,\n thumbnail_url: img.thumbnailURL,\n }));\n\n // Get cover image URLs, fallback to first image if coverImage is null\n const coverImageUrl = rawItem.coverImage?.url || rawItem.images[0]?.url || \"\";\n const coverImageThumbnailUrl =\n rawItem.coverImage?.thumbnailURL || rawItem.images[0]?.thumbnailURL || \"\";\n\n return {\n id: rawItem.id,\n name: rawItem.name,\n featured: rawItem.featured,\n url_safe_name: rawItem.url_safe_name,\n currency_prefix: \"$\", // Default currency prefix, could be made configurable\n description: rawItem.description,\n old_price: firstPrice?.old_price || 0,\n item_category_name: rawItem.item_category?.name || \"\",\n item_category_id: parseInt(rawItem.item_category?.id || \"0\"),\n price_text: firstPrice?.price_text || \"\",\n price_notes: firstPrice?.price_notes || \"\", // Not available in raw response\n price: firstPrice?.amount || 0,\n brand_id: parseInt(rawItem.brand?.id || \"0\"),\n brand_name: rawItem.brand?.name || \"\",\n cover_image_url: coverImageUrl,\n cover_image_thumbnail_url: coverImageThumbnailUrl,\n images: images,\n };\n}\n\n/**\n * Parses an array of raw GraphQL response items to normalized Item types\n * @param rawItems - Array of raw items from GraphQL response\n * @returns Array of normalized Item objects\n */\nexport function parseRawItemsToItems(rawItems: ItemEcommerceRaw[]): Item[] {\n return rawItems.map(parseRawItemToItem);\n}\n"],"mappings":"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","names":["config"]}
|