sizebay-core-sdk 1.14.1 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -220,6 +220,12 @@ Find visually similar items from an uploaded image.
220
220
  #### Returns
221
221
 
222
222
  <!-- DOCGEN:returns GetSimilarProductsResponse -->
223
+ > **`GetSimilarProductsResponse`**
224
+ > * `data`: `ProductDto[]` — An array of products that are visually similar to the reference item.<br>The results are ordered by their similarity score.
225
+ > * `page`: `number` — The current page number of the results.
226
+ > * `perPage`: `number` — The number of items per page.
227
+ > * `total`: `number` — The total number of similar products found.
228
+ > * `invalidPersonaHash`: `boolean` — Indicates if the provided persona hash is invalid or expired,<br>which may affect personalized results.
223
229
  <!-- /DOCGEN -->
224
230
 
225
231
  #### Example
@@ -298,6 +304,127 @@ console.log(imgComp.baseProduct, imgComp.complementary);
298
304
 
299
305
  ---
300
306
 
307
+ ### `searchSimilarByPermalink(payload: GetSimilarByPermalinkBodyDto): Promise<GetSimilarProductsResponse>`
308
+
309
+ Find similar products by permalink or productId via POST body. Use when you need filter hints (ageRange, gender, style, color) not available in the GET endpoint.
310
+
311
+ #### Payload
312
+
313
+ <!-- DOCGEN:params GetSimilarByPermalinkBodyDto -->
314
+ | Field | Type | Required | Description |
315
+ | ----- | ---- | :------: | ----------- |
316
+ | `permalink` | string | No | Product base permalink (either permalink or productId must be provided). |
317
+ | `productId` | string | No | Product ID (either permalink or productId must be provided). |
318
+ | `similarityThreshold` | number | No | Similarity threshold for the search (0.0–1.0). |
319
+ | `ageRange` | string | No | Target age range for filtering results. |
320
+ | `gender` | string | No | User gender for filtering. |
321
+ | `style` | string | No | Preferred style hint for results. |
322
+ | `color` | string | No | Main color of interest for filtering. |
323
+ | `productClass` | ProductClass | No | Target product class for filtering. |
324
+ | `clothType` | ClothType | No | Target cloth type for filtering results. |
325
+ | `availability` | "in stock" | "out of stock" | "all" | No | Filter recommendations by stock status. |
326
+ | `page` | number | No | Page number for pagination. |
327
+ | `perPage` | number | No | Items per page. |
328
+ | `tenantId` | number | Yes | Tenant (client) ID. |
329
+ | `collectionName` | string | Yes | Embeddings collection name (namespace). |
330
+ | `sid` | string | Yes | Session identifier (`sid`) for the user. |
331
+ | `sizeSystem` | string | Yes | Size system code (e.g., 'BR', 'EU', 'US'). |
332
+ | `locale` | string | Yes | Locale for internationalized responses (language and region). |
333
+ | `currency` | string | Yes | Currency code for pricing information in responses. |
334
+ | `filterByWhatFitsMe` | boolean | No | Whether to apply What Fits Me logic. |
335
+ | `personaHash` | string | No | Hash representing the user persona (required if WFM is enabled). |
336
+ <!-- /DOCGEN -->
337
+
338
+ #### Returns
339
+
340
+ <!-- DOCGEN:returns GetSimilarProductsResponse -->
341
+ > **`GetSimilarProductsResponse`**
342
+ > * `data`: `ProductDto[]` — An array of products that are visually similar to the reference item.<br>The results are ordered by their similarity score.
343
+ > * `page`: `number` — The current page number of the results.
344
+ > * `perPage`: `number` — The number of items per page.
345
+ > * `total`: `number` — The total number of similar products found.
346
+ > * `invalidPersonaHash`: `boolean` — Indicates if the provided persona hash is invalid or expired,<br>which may affect personalized results.
347
+ <!-- /DOCGEN -->
348
+
349
+ #### Example
350
+
351
+ ```typescript
352
+ const similarByPermalink = await client.searchSimilarByPermalink({
353
+ tenantId: 123,
354
+ collectionName: 'clothing',
355
+ sid: 'abc123',
356
+ permalink: 'https://domain.com/product/xyz',
357
+ sizeSystem: 'US',
358
+ similarityThreshold: 0.5,
359
+ style: 'Casual',
360
+ });
361
+ console.log(similarByPermalink.data);
362
+ ```
363
+
364
+ ---
365
+
366
+ ### `searchComplementaryByPermalink(payload: GetComplementaryByPermalinkBodyDto): Promise<GetComplementaryProductsByImageResponse>`
367
+
368
+ Get complementary products by permalink or productId via POST body. Requires baseClothType and targetClothType.
369
+
370
+ #### Payload
371
+
372
+ <!-- DOCGEN:params GetComplementaryByPermalinkBodyDto -->
373
+ | Field | Type | Required | Description |
374
+ | ----- | ---- | :------: | ----------- |
375
+ | `permalink` | string | No | Product base permalink (either permalink or productId must be provided). |
376
+ | `productId` | string | No | Product ID (either permalink or productId must be provided). |
377
+ | `similarityThreshold` | number | No | Similarity threshold for complementary search (0.0–1.0). |
378
+ | `baseClothType` | ClothType | Yes | Base cloth type of the product identified by permalink. |
379
+ | `targetClothType` | ClothType | Yes | Target cloth type complementary to the base.<br>E.g., if base is TOP, target can be BOTTOM or SHOE_ACCESSORY. |
380
+ | `ageRange` | string | No | Target age range for filtering. |
381
+ | `gender` | string | No | User gender for filtering. |
382
+ | `style` | string | No | Preferred style hint. |
383
+ | `color` | string | No | Main color of interest. |
384
+ | `productClass` | ProductClass | No | Target product class. |
385
+ | `clothType` | ClothType | No | Target cloth type for filtering. |
386
+ | `page` | number | No | Page number for pagination. |
387
+ | `perPage` | number | No | Items per page. |
388
+ | `tenantId` | number | Yes | Tenant (client) ID. |
389
+ | `collectionName` | string | Yes | Embeddings collection name (namespace). |
390
+ | `sid` | string | Yes | Session identifier (`sid`) for the user. |
391
+ | `sizeSystem` | string | Yes | Size system code (e.g., 'BR', 'EU', 'US'). |
392
+ | `locale` | string | Yes | Locale for internationalized responses (language and region). |
393
+ | `currency` | string | Yes | Currency code for pricing information in responses. |
394
+ | `filterByWhatFitsMe` | boolean | No | Whether to apply What Fits Me logic. |
395
+ | `personaHash` | string | No | Hash representing the user persona (required if WFM is enabled). |
396
+ <!-- /DOCGEN -->
397
+
398
+ #### Returns
399
+
400
+ <!-- DOCGEN:returns GetComplementaryProductsByImageResponse -->
401
+ > **`GetComplementaryProductsByImageResponse`**
402
+ > * `baseProduct`: `ProductDto` — The product identified in the reference image.
403
+ > * `complementary`: `ProductDto[]` — A list of recommended products that are complementary to the base product.
404
+ > * `page`: `number` — The current page number of the results.
405
+ > * `perPage`: `number` — The number of items per page.
406
+ > * `total`: `number` — The total number of complementary products found.
407
+ > * `invalidPersonaHash`: `boolean` — Indicates if the provided persona hash is invalid or has expired.
408
+ <!-- /DOCGEN -->
409
+
410
+ #### Example
411
+
412
+ ```typescript
413
+ const compByPermalink = await client.searchComplementaryByPermalink({
414
+ tenantId: 123,
415
+ collectionName: 'clothing',
416
+ sid: 'abc123',
417
+ permalink: 'https://domain.com/product/xyz',
418
+ sizeSystem: 'US',
419
+ similarityThreshold: 0.5,
420
+ baseClothType: ClothType.TOP,
421
+ targetClothType: ClothType.BOTTOM,
422
+ });
423
+ console.log(compByPermalink.baseProduct, compByPermalink.complementary);
424
+ ```
425
+
426
+ ---
427
+
301
428
  ## Fashion Looks Module
302
429
 
303
430
  ### `getGroupedLooks(params: GetGroupedLooksParams): Promise<GroupedLooksListResponse>`
@@ -319,6 +446,7 @@ Get grouped looks with optional filters and pagination (Public endpoint).
319
446
  | `style` | Style | No | Filter by style category.<br>Show only looks matching the desired style (casual, formal, party, etc.). |
320
447
  | `collection` | Collection | No | Filter by seasonal collection.<br>Show only looks from a specific season (spring, summer, fall, winter). |
321
448
  | `language` | Language | No | Language/locale for filtering localizations.<br>Use this to get product information in the specified language. |
449
+ | `currency` | string | No | Currency code for pricing (e.g., EUR, USD, BRL). |
322
450
  <!-- /DOCGEN -->
323
451
 
324
452
  #### Returns
@@ -596,10 +724,22 @@ ClothType.SHOE_ACCESSORY // For shoes, accessories
596
724
  | `ageGroup` | string | No | Product age group.<br>Use to filter or categorize products by target age. |
597
725
  | `brand` | string | No | Product brand name.<br>Use to display brand information or filter by brand. |
598
726
  | `category` | string | No | Product category (e.g., 'TOP', 'BOTTOM', 'SHOE_ACCESSORY').<br>Use to categorize products or filter by type. |
599
- | `availability` | string | No | Product availability status.<br>Use to show stock status or availability badges. |
600
- | `description` | string | No | Product description.<br>Use to display product descriptions. |
601
- | `link` | string | No | Product page URL.<br>Use to create links to product pages. |
602
- | `title` | string | No | Product title/name.<br>Use to display product names. |
727
+ | `price` | string | No | Product price (extracted from localizations when currency is provided).<br>Use to display product pricing. |
728
+ | `salePrice` | string | No | Product sale price (extracted from localizations when currency is provided).<br>Use to display product sale pricing. |
729
+ | `localizations` | { [locale: string]: ProductLocalization; } | No | Product localizations by locale code (e.g., 'en-US', 'pt-BR', 'es-ES', 'it-IT').<br>Each locale contains availability, description, link, title, price, and salePrice.<br>Use to display product information in the user's language. |
730
+ <!-- /DOCGEN -->
731
+
732
+ ### `ProductLocalization`
733
+
734
+ <!-- DOCGEN:params ProductLocalization -->
735
+ | Field | Type | Required | Description |
736
+ | ----- | ---- | :------: | ----------- |
737
+ | `availability` | string | No | Product availability status in this locale.<br>Use to show stock status or availability badges. |
738
+ | `description` | string | No | Product description in this locale.<br>Use to display localized product descriptions. |
739
+ | `link` | string | No | Product page URL in this locale.<br>Use to create localized links to product pages. |
740
+ | `title` | string | No | Product title/name in this locale.<br>Use to display localized product names. |
741
+ | `price` | string | No | Product price in this locale.<br>Use to display localized pricing. |
742
+ | `salePrice` | string | No | Product sale price in this locale.<br>Use to display localized sale pricing. |
603
743
  <!-- /DOCGEN -->
604
744
 
605
745
  ### `BmiGroupDto`
@@ -1,11 +1,13 @@
1
1
  import { Config } from '../config';
2
- import { GetSimilarProductsParams, GetComplementaryProductsParams, GetSimilarByImageBodyDto, GetComplementaryByImageBodyDto, GetSimilarProductsResponse, GetComplementaryProductsResponse, GetComplementaryProductsByImageResponse } from '../types/ai-image';
2
+ import { GetSimilarProductsParams, GetComplementaryProductsParams, GetSimilarByImageBodyDto, GetComplementaryByImageBodyDto, GetSimilarByPermalinkBodyDto, GetComplementaryByPermalinkBodyDto, GetSimilarProductsResponse, GetComplementaryProductsResponse, GetComplementaryProductsByImageResponse } from '../types/ai-image';
3
3
  export declare class AIImageService {
4
- private endpoint;
4
+ private readonly endpoint;
5
5
  constructor(config: Config);
6
6
  private appendQueryParams;
7
7
  getSimilarProducts(params: GetSimilarProductsParams): Promise<GetSimilarProductsResponse>;
8
8
  getComplementaryProducts(params: GetComplementaryProductsParams): Promise<GetComplementaryProductsResponse>;
9
9
  searchSimilarByImage(payload: GetSimilarByImageBodyDto): Promise<GetSimilarProductsResponse>;
10
10
  searchComplementaryByImage(payload: GetComplementaryByImageBodyDto): Promise<GetComplementaryProductsByImageResponse>;
11
+ searchSimilarByPermalink(payload: GetSimilarByPermalinkBodyDto): Promise<GetSimilarProductsResponse>;
12
+ searchComplementaryByPermalink(payload: GetComplementaryByPermalinkBodyDto): Promise<GetComplementaryProductsByImageResponse>;
11
13
  }
@@ -41,7 +41,7 @@ class l {
41
41
  return this.serviceOverrides[t] || {};
42
42
  }
43
43
  }
44
- class u {
44
+ class S {
45
45
  constructor(t) {
46
46
  this.endpoint = t.getEndpoint("tracker");
47
47
  }
@@ -97,7 +97,8 @@ async function a(i, t) {
97
97
  throw new c(e.status, n);
98
98
  return JSON.parse(n);
99
99
  }
100
- class S {
100
+ const E = "/recommendations/similar", T = "/recommendations/complementary", u = "/image-search/similar", O = "/image-search/similar-by-permalink", m = "/image-search/complementary", y = "/image-search/complementary-by-permalink";
101
+ class f {
101
102
  constructor(t) {
102
103
  this.endpoint = t.getEndpoint("aiImageService");
103
104
  }
@@ -114,15 +115,12 @@ class S {
114
115
  /**
115
116
  * Fetches similar product recommendations by permalink or productId.
116
117
  *
117
- * Get similar products by product permalink or productId (at least one must be provided).
118
- * Sends a GET to `/recommendations/similar` with the given query parameters.
119
- *
120
- * @param params - parameters for the request. Either permalink or productId must be provided.
121
- * @returns Promise resolving to the parsed JSON response
122
- * @throws {ApiError} if the HTTP status is not 2xx or on network failure
118
+ * @param params - Query parameters. Either permalink or productId must be provided.
119
+ * @returns Similar products response with pagination.
120
+ * @throws {ApiError} when HTTP status is not 2xx or on network failure.
123
121
  */
124
122
  getSimilarProducts(t) {
125
- const e = new URL(`${this.endpoint}/recommendations/similar`);
123
+ const e = new URL(`${this.endpoint}${E}`);
126
124
  return this.appendQueryParams(e, t), a(e.toString(), {
127
125
  method: "GET",
128
126
  headers: { "Content-Type": "application/json" }
@@ -131,31 +129,26 @@ class S {
131
129
  /**
132
130
  * Fetches complementary product recommendation pairs by permalink or productId.
133
131
  *
134
- * Get complementary products by product permalink or productId (at least one must be provided).
135
- * Sends a GET to `/recommendations/complementary` with the given query parameters.
136
- *
137
- * @param params - parameters for the request. Either permalink or productId must be provided.
138
- * @returns Promise resolving to the parsed JSON response
139
- * @throws {ApiError} if the HTTP status is not 2xx or on network failure
132
+ * @param params - Query parameters. Either permalink or productId must be provided.
133
+ * @returns Complementary products response with base product and pairs.
134
+ * @throws {ApiError} when HTTP status is not 2xx or on network failure.
140
135
  */
141
136
  getComplementaryProducts(t) {
142
- const e = new URL(`${this.endpoint}/recommendations/complementary`);
137
+ const e = new URL(`${this.endpoint}${T}`);
143
138
  return this.appendQueryParams(e, t), a(e.toString(), {
144
139
  method: "GET",
145
140
  headers: { "Content-Type": "application/json" }
146
141
  });
147
142
  }
148
143
  /**
149
- * Fetches similar product recommendations by image.
150
- *
151
- * Sends a POST to `/image-search/similar` with the image data.
144
+ * Fetches similar product recommendations from a base64-encoded image.
152
145
  *
153
- * @param payload - parameters for the request
154
- * @returns Promise resolving to the parsed JSON response
155
- * @throws {ApiError} if the HTTP status is not 2xx or on network failure
146
+ * @param payload - Request body with image and search filters.
147
+ * @returns Similar products response with pagination.
148
+ * @throws {ApiError} when HTTP status is not 2xx or on network failure.
156
149
  */
157
150
  searchSimilarByImage(t) {
158
- const e = `${this.endpoint}/image-search/similar`;
151
+ const e = `${this.endpoint}${u}`;
159
152
  return a(e, {
160
153
  method: "POST",
161
154
  headers: { "Content-Type": "application/json" },
@@ -163,16 +156,44 @@ class S {
163
156
  });
164
157
  }
165
158
  /**
166
- * Fetches complementary product recommendations by image.
167
- *
168
- * Sends a POST to `/image-search/complementary` with the image data.
159
+ * Fetches complementary product recommendations from a base64-encoded image.
169
160
  *
170
- * @param payload - parameters for the request
171
- * @returns Promise resolving to the parsed JSON response
172
- * @throws {ApiError} if the HTTP status is not 2xx or on network failure
161
+ * @param payload - Request body with image, cloth types, and filters.
162
+ * @returns Complementary products response with base product and pagination.
163
+ * @throws {ApiError} when HTTP status is not 2xx or on network failure.
173
164
  */
174
165
  searchComplementaryByImage(t) {
175
- const e = `${this.endpoint}/image-search/complementary`;
166
+ const e = `${this.endpoint}${m}`;
167
+ return a(e, {
168
+ method: "POST",
169
+ headers: { "Content-Type": "application/json" },
170
+ body: JSON.stringify(t)
171
+ });
172
+ }
173
+ /**
174
+ * Fetches similar product recommendations by permalink or productId with filter hints.
175
+ *
176
+ * @param payload - Request body. Either permalink or productId must be provided.
177
+ * @returns Similar products response with pagination.
178
+ * @throws {ApiError} when HTTP status is not 2xx or on network failure.
179
+ */
180
+ searchSimilarByPermalink(t) {
181
+ const e = `${this.endpoint}${O}`;
182
+ return a(e, {
183
+ method: "POST",
184
+ headers: { "Content-Type": "application/json" },
185
+ body: JSON.stringify(t)
186
+ });
187
+ }
188
+ /**
189
+ * Fetches complementary product recommendations by permalink or productId.
190
+ *
191
+ * @param payload - Request body. Either permalink or productId must be provided.
192
+ * @returns Complementary products response with base product and pagination.
193
+ * @throws {ApiError} when HTTP status is not 2xx or on network failure.
194
+ */
195
+ searchComplementaryByPermalink(t) {
196
+ const e = `${this.endpoint}${y}`;
176
197
  return a(e, {
177
198
  method: "POST",
178
199
  headers: { "Content-Type": "application/json" },
@@ -180,7 +201,7 @@ class S {
180
201
  });
181
202
  }
182
203
  }
183
- class T {
204
+ class I {
184
205
  constructor(t) {
185
206
  this.sid = null, this.sessionId = null;
186
207
  const e = t.getEndpoint("session");
@@ -236,7 +257,7 @@ class T {
236
257
  }
237
258
  }
238
259
  }
239
- class E {
260
+ class g {
240
261
  constructor(t) {
241
262
  this.endpoint = t.getEndpoint("fashionLooks");
242
263
  }
@@ -294,14 +315,14 @@ class E {
294
315
  });
295
316
  }
296
317
  }
297
- const O = [
298
- u,
318
+ const R = [
299
319
  S,
300
- T,
301
- E
320
+ f,
321
+ I,
322
+ g
302
323
  ];
303
- function m(i = {}) {
304
- const t = new l(i), e = O.map((s) => new s(t)), n = {};
324
+ function P(i = {}) {
325
+ const t = new l(i), e = R.map((s) => new s(t)), n = {};
305
326
  return e.forEach((s) => {
306
327
  [
307
328
  ...Object.getOwnPropertyNames(s),
@@ -313,7 +334,7 @@ function m(i = {}) {
313
334
  });
314
335
  }), n;
315
336
  }
316
- const f = {
337
+ const A = {
317
338
  TOP: "TOP",
318
339
  BOTTOM: "BOTTOM",
319
340
  SHOE_ACCESSORY: "SHOE_ACCESSORY",
@@ -324,7 +345,7 @@ const f = {
324
345
  WETSUIT_FULL_BODY: "WETSUIT_FULL_BODY",
325
346
  WETSUIT_BOTTOM: "WETSUIT_BOTTOM",
326
347
  WETSUIT_TOP: "WETSUIT_TOP"
327
- }, g = {
348
+ }, _ = {
328
349
  T_SHIRT: "t-shirt",
329
350
  SHIRT: "shirt",
330
351
  BLOUSE: "blouse",
@@ -366,7 +387,7 @@ const f = {
366
387
  WETSUIT: "wetsuit"
367
388
  };
368
389
  export {
369
- f as ClothType,
370
- g as ProductClass,
371
- m as createClient
390
+ A as ClothType,
391
+ _ as ProductClass,
392
+ P as createClient
372
393
  };
@@ -1 +1 @@
1
- (function(i,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(i=typeof globalThis<"u"?globalThis:i||self,c(i["sizebay-core-sdk"]={}))})(this,(function(i){"use strict";const c={tracker:{production:"https://data-event-service.internalsizebay.com",development:"https://data-event-service-dev.internalsizebay.com"},aiImageService:{production:"https://ai-image-service.internalsizebay.com",development:"https://ai-image-service-dev.internalsizebay.com"},session:{production:"https://vfr-v3-production.sizebay.technology/api/me",development:"https://vfr-v3-staging.sizebay.eu/api/me"},fashionLooks:{production:"https://fashion-looks.internalsizebay.com",development:"https://fashion-looks-dev.internalsizebay.com"}};class l{constructor(e){const t=e.env||"development";this.serviceOverrides=e.services||{},this.endpoints={};for(const n in c)if(Object.prototype.hasOwnProperty.call(c,n)){const o=c[n][t];if(!o)continue;this.endpoints[n]=o}}getEndpoint(e){const t=this.endpoints[e];if(!t)throw new Error(`Endpoint for service '${e}' is not configured.`);return t}getServiceConfig(e){return this.serviceOverrides[e]||{}}}class u{constructor(e){this.endpoint=e.getEndpoint("tracker")}async track(e,t){const n={eventName:e,...t},s=new URL(`${this.endpoint}/events`);try{const o=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok){const a=await o.text();throw new Error(`Request error: ${o.status} - ${a}`)}try{return await o.json()}catch{return{statusCode:201,message:"Event successfully created."}}}catch(o){throw o}}}class d extends Error{constructor(e,t){let n;try{const s=JSON.parse(t);n=(s==null?void 0:s.message)||t}catch{n=t}super(n),this.statusCode=e,this.details=t,Object.setPrototypeOf(this,d.prototype)}}async function p(r,e){let t;try{t=await fetch(r,e)}catch(s){throw new d(0,s.message)}const n=await t.text();if(!t.ok)throw new d(t.status,n);return JSON.parse(n)}class S{constructor(e){this.endpoint=e.getEndpoint("aiImageService")}appendQueryParams(e,t){Object.entries(t).forEach(([n,s])=>{s!=null&&e.searchParams.append(n,String(s))})}getSimilarProducts(e){const t=new URL(`${this.endpoint}/recommendations/similar`);return this.appendQueryParams(t,e),p(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}getComplementaryProducts(e){const t=new URL(`${this.endpoint}/recommendations/complementary`);return this.appendQueryParams(t,e),p(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}searchSimilarByImage(e){const t=`${this.endpoint}/image-search/similar`;return p(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchComplementaryByImage(e){const t=`${this.endpoint}/image-search/complementary`;return p(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}}class T{constructor(e){this.sid=null,this.sessionId=null;const t=e.getEndpoint("session");this.sessionEndpoint=`${t}/`,this.profileEndpoint=`${t}/user/profile`}async getSessionInfo(){if(this.sid&&this.sessionId!==null)return{sid:this.sid,sessionId:this.sessionId};const e=await fetch(this.sessionEndpoint,{credentials:"include"});if(!e.ok){const n=await e.text();throw new Error(`Failed to fetch session info: ${e.status} – ${n}`)}const t=await e.json();return this.sid=t.catalogUser.id,this.sessionId=t.sessionId,{sid:this.sid,sessionId:this.sessionId}}async sendProfile(e,t){const n=t??(await this.getSessionInfo()).sid,s=new URL(this.profileEndpoint);s.searchParams.set("sid",n);const o=await fetch(s.toString(),{credentials:"include",method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:n,id:null,...e})});if(!o.ok){const a=await o.text();throw new Error(`Failed to send profile: ${o.status} – ${a}`)}}}class f{constructor(e){this.endpoint=e.getEndpoint("fashionLooks")}appendQueryParams(e,t){Object.entries(t).forEach(([n,s])=>{s!=null&&e.searchParams.append(n,String(s))})}getGroupedLooks(e){const t=new URL(`${this.endpoint}/api/public/grouped-looks`);return this.appendQueryParams(t,e),p(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}getGroupedLookById(e,t,n){const s=new URL(`${this.endpoint}/api/public/grouped-looks/${e}`);return s.searchParams.set("tenantId",String(t)),s.searchParams.set("language",n),p(s.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}}const O=[u,S,T,f];function E(r={}){const e=new l(r),t=O.map(s=>new s(e)),n={};return t.forEach(s=>{[...Object.getOwnPropertyNames(s),...Object.getOwnPropertyNames(Object.getPrototypeOf(s))].forEach(a=>{if(a==="constructor")return;const h=s[a];typeof h=="function"&&(n[a]||(n[a]=(...y)=>h.apply(s,y)))})}),n}const m={TOP:"TOP",BOTTOM:"BOTTOM",SHOE_ACCESSORY:"SHOE_ACCESSORY",FULL_BODY:"FULL_BODY",UNDERWEAR_FULL_BODY:"UNDERWEAR_FULL_BODY",UNDERWEAR_BOTTOM:"UNDERWEAR_BOTTOM",UNDERWEAR_TOP:"UNDERWEAR_TOP",WETSUIT_FULL_BODY:"WETSUIT_FULL_BODY",WETSUIT_BOTTOM:"WETSUIT_BOTTOM",WETSUIT_TOP:"WETSUIT_TOP"},g={T_SHIRT:"t-shirt",SHIRT:"shirt",BLOUSE:"blouse",SWEATER:"sweater",HOODIE:"hoodie",JACKET:"jacket",COAT:"coat",CARDIGAN:"cardigan",BLAZER:"blazer",VEST:"vest",SWEATSHIRT:"sweatshirt",POLO_SHIRT:"polo shirt",TANK_TOP:"tank top",SKIRT:"skirt",TROUSERS:"trousers",JEANS:"jeans",SHORTS:"shorts",SNEAKERS:"sneakers",RUNNING_SHOES:"running shoes",BOOTS:"boots",ANKLE_BOOTS:"ankle boots",HIGH_HEELS:"high heels",FLATS:"flats",LOAFERS:"loafers",OXFORDS:"oxfords",SLIPPERS:"slippers",SANDALS:"sandals",DRESS:"dress",JUMPSUIT:"jumpsuit",SUIT:"suit",PANTIES:"panties",BRA:"bra",BIKINI:"bikini",BRIEFS:"briefs",BOXERS:"boxers",THONG:"thong",SWIMSUIT:"swimsuit",ONE_PIECE_SWIMSUIT:"one-piece swimsuit",WETSUIT:"wetsuit"};i.ClothType=m,i.ProductClass=g,i.createClient=E,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(i,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(i=typeof globalThis<"u"?globalThis:i||self,p(i["sizebay-core-sdk"]={}))})(this,(function(i){"use strict";const p={tracker:{production:"https://data-event-service.internalsizebay.com",development:"https://data-event-service-dev.internalsizebay.com"},aiImageService:{production:"https://ai-image-service.internalsizebay.com",development:"https://ai-image-service-dev.internalsizebay.com"},session:{production:"https://vfr-v3-production.sizebay.technology/api/me",development:"https://vfr-v3-staging.sizebay.eu/api/me"},fashionLooks:{production:"https://fashion-looks.internalsizebay.com",development:"https://fashion-looks-dev.internalsizebay.com"}};class l{constructor(e){const t=e.env||"development";this.serviceOverrides=e.services||{},this.endpoints={};for(const n in p)if(Object.prototype.hasOwnProperty.call(p,n)){const o=p[n][t];if(!o)continue;this.endpoints[n]=o}}getEndpoint(e){const t=this.endpoints[e];if(!t)throw new Error(`Endpoint for service '${e}' is not configured.`);return t}getServiceConfig(e){return this.serviceOverrides[e]||{}}}class u{constructor(e){this.endpoint=e.getEndpoint("tracker")}async track(e,t){const n={eventName:e,...t},s=new URL(`${this.endpoint}/events`);try{const o=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok){const c=await o.text();throw new Error(`Request error: ${o.status} - ${c}`)}try{return await o.json()}catch{return{statusCode:201,message:"Event successfully created."}}}catch(o){throw o}}}class d extends Error{constructor(e,t){let n;try{const s=JSON.parse(t);n=(s==null?void 0:s.message)||t}catch{n=t}super(n),this.statusCode=e,this.details=t,Object.setPrototypeOf(this,d.prototype)}}async function r(a,e){let t;try{t=await fetch(a,e)}catch(s){throw new d(0,s.message)}const n=await t.text();if(!t.ok)throw new d(t.status,n);return JSON.parse(n)}const S="/recommendations/similar",T="/recommendations/complementary",E="/image-search/similar",O="/image-search/similar-by-permalink",m="/image-search/complementary",f="/image-search/complementary-by-permalink";class y{constructor(e){this.endpoint=e.getEndpoint("aiImageService")}appendQueryParams(e,t){Object.entries(t).forEach(([n,s])=>{s!=null&&e.searchParams.append(n,String(s))})}getSimilarProducts(e){const t=new URL(`${this.endpoint}${S}`);return this.appendQueryParams(t,e),r(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}getComplementaryProducts(e){const t=new URL(`${this.endpoint}${T}`);return this.appendQueryParams(t,e),r(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}searchSimilarByImage(e){const t=`${this.endpoint}${E}`;return r(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchComplementaryByImage(e){const t=`${this.endpoint}${m}`;return r(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchSimilarByPermalink(e){const t=`${this.endpoint}${O}`;return r(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchComplementaryByPermalink(e){const t=`${this.endpoint}${f}`;return r(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}}class g{constructor(e){this.sid=null,this.sessionId=null;const t=e.getEndpoint("session");this.sessionEndpoint=`${t}/`,this.profileEndpoint=`${t}/user/profile`}async getSessionInfo(){if(this.sid&&this.sessionId!==null)return{sid:this.sid,sessionId:this.sessionId};const e=await fetch(this.sessionEndpoint,{credentials:"include"});if(!e.ok){const n=await e.text();throw new Error(`Failed to fetch session info: ${e.status} – ${n}`)}const t=await e.json();return this.sid=t.catalogUser.id,this.sessionId=t.sessionId,{sid:this.sid,sessionId:this.sessionId}}async sendProfile(e,t){const n=t??(await this.getSessionInfo()).sid,s=new URL(this.profileEndpoint);s.searchParams.set("sid",n);const o=await fetch(s.toString(),{credentials:"include",method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:n,id:null,...e})});if(!o.ok){const c=await o.text();throw new Error(`Failed to send profile: ${o.status} – ${c}`)}}}class I{constructor(e){this.endpoint=e.getEndpoint("fashionLooks")}appendQueryParams(e,t){Object.entries(t).forEach(([n,s])=>{s!=null&&e.searchParams.append(n,String(s))})}getGroupedLooks(e){const t=new URL(`${this.endpoint}/api/public/grouped-looks`);return this.appendQueryParams(t,e),r(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}getGroupedLookById(e,t,n){const s=new URL(`${this.endpoint}/api/public/grouped-looks/${e}`);return s.searchParams.set("tenantId",String(t)),s.searchParams.set("language",n),r(s.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}}const R=[u,y,g,I];function P(a={}){const e=new l(a),t=R.map(s=>new s(e)),n={};return t.forEach(s=>{[...Object.getOwnPropertyNames(s),...Object.getOwnPropertyNames(Object.getPrototypeOf(s))].forEach(c=>{if(c==="constructor")return;const h=s[c];typeof h=="function"&&(n[c]||(n[c]=(...C)=>h.apply(s,C)))})}),n}const A={TOP:"TOP",BOTTOM:"BOTTOM",SHOE_ACCESSORY:"SHOE_ACCESSORY",FULL_BODY:"FULL_BODY",UNDERWEAR_FULL_BODY:"UNDERWEAR_FULL_BODY",UNDERWEAR_BOTTOM:"UNDERWEAR_BOTTOM",UNDERWEAR_TOP:"UNDERWEAR_TOP",WETSUIT_FULL_BODY:"WETSUIT_FULL_BODY",WETSUIT_BOTTOM:"WETSUIT_BOTTOM",WETSUIT_TOP:"WETSUIT_TOP"},_={T_SHIRT:"t-shirt",SHIRT:"shirt",BLOUSE:"blouse",SWEATER:"sweater",HOODIE:"hoodie",JACKET:"jacket",COAT:"coat",CARDIGAN:"cardigan",BLAZER:"blazer",VEST:"vest",SWEATSHIRT:"sweatshirt",POLO_SHIRT:"polo shirt",TANK_TOP:"tank top",SKIRT:"skirt",TROUSERS:"trousers",JEANS:"jeans",SHORTS:"shorts",SNEAKERS:"sneakers",RUNNING_SHOES:"running shoes",BOOTS:"boots",ANKLE_BOOTS:"ankle boots",HIGH_HEELS:"high heels",FLATS:"flats",LOAFERS:"loafers",OXFORDS:"oxfords",SLIPPERS:"slippers",SANDALS:"sandals",DRESS:"dress",JUMPSUIT:"jumpsuit",SUIT:"suit",PANTIES:"panties",BRA:"bra",BIKINI:"bikini",BRIEFS:"briefs",BOXERS:"boxers",THONG:"thong",SWIMSUIT:"swimsuit",ONE_PIECE_SWIMSUIT:"one-piece swimsuit",WETSUIT:"wetsuit"};i.ClothType=A,i.ProductClass=_,i.createClient=P,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
@@ -4,6 +4,8 @@ export * from './params/get-similar-products.dto';
4
4
  export * from './params/get-complementary-products.dto';
5
5
  export * from './params/get-similar-by-image.dto';
6
6
  export * from './params/get-complementary-by-image.dto';
7
+ export * from './params/get-similar-by-permalink.dto';
8
+ export * from './params/get-complementary-by-permalink.dto';
7
9
  export * from './responses/get-similar-products-response.dto';
8
10
  export * from './responses/get-complementary-products-response.dto';
9
11
  export * from './responses/get-complementary-products-by-image-response.dto';
@@ -0,0 +1,18 @@
1
+ import { BaseSearchParams } from '../base/base-search.dto';
2
+ import { ClothType } from '../../common/cloth-type.type';
3
+ import { ProductClass } from '../../common/product-class.type';
4
+ export interface GetComplementaryByPermalinkBodyDto extends BaseSearchParams {
5
+ permalink?: string;
6
+ productId?: string;
7
+ similarityThreshold?: number;
8
+ baseClothType: ClothType;
9
+ targetClothType: ClothType;
10
+ ageRange?: string;
11
+ gender?: string;
12
+ style?: string;
13
+ color?: string;
14
+ productClass?: ProductClass;
15
+ clothType?: ClothType;
16
+ page?: number;
17
+ perPage?: number;
18
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseSearchParams } from '../base/base-search.dto';
2
+ import { ClothType } from '../../common/cloth-type.type';
3
+ import { ProductClass } from '../../common/product-class.type';
4
+ export interface GetSimilarByPermalinkBodyDto extends BaseSearchParams {
5
+ permalink?: string;
6
+ productId?: string;
7
+ similarityThreshold?: number;
8
+ ageRange?: string;
9
+ gender?: string;
10
+ style?: string;
11
+ color?: string;
12
+ productClass?: ProductClass;
13
+ clothType?: ClothType;
14
+ availability?: 'in stock' | 'out of stock' | 'all';
15
+ page?: number;
16
+ perPage?: number;
17
+ }
@@ -16,4 +16,5 @@ export interface GetGroupedLooksParams {
16
16
  style?: Style;
17
17
  collection?: Collection;
18
18
  language?: Language;
19
+ currency?: string;
19
20
  }
@@ -1,3 +1,11 @@
1
+ export interface ProductLocalization {
2
+ availability?: string;
3
+ description?: string;
4
+ link?: string;
5
+ title?: string;
6
+ price?: string;
7
+ salePrice?: string;
8
+ }
1
9
  export interface FashionLookProductDto {
2
10
  id: string;
3
11
  imageUrl: string;
@@ -5,8 +13,9 @@ export interface FashionLookProductDto {
5
13
  ageGroup?: string;
6
14
  brand?: string;
7
15
  category?: string;
8
- availability?: string;
9
- description?: string;
10
- link?: string;
11
- title?: string;
16
+ price?: string;
17
+ salePrice?: string;
18
+ localizations?: {
19
+ [locale: string]: ProductLocalization;
20
+ };
12
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sizebay-core-sdk",
3
- "version": "1.14.1",
3
+ "version": "1.16.0",
4
4
  "description": "A SDK designed for integrating multiple services (such as event tracking, AI services, etc.) into your application.",
5
5
  "main": "dist/sizebay-core-sdk.umd.js",
6
6
  "module": "dist/sizebay-core-sdk.es.js",