sizebay-core-sdk 1.10.1-dev.1 → 1.11.0-dev.2

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
@@ -296,6 +296,133 @@ console.log(imgComp.baseProduct, imgComp.complementary);
296
296
 
297
297
  ---
298
298
 
299
+ ## Permalink Search Services
300
+
301
+ ### `searchSimilarByPermalink(payload: GetSimilarByPermalinkBodyDto): Promise<GetSimilarProductsResponse>`
302
+
303
+ Find visually similar items from a product permalink or productId using AI-powered image analysis.
304
+
305
+ #### Payload
306
+
307
+ <!-- DOCGEN:params GetSimilarByPermalinkBodyDto -->
308
+ | Field | Type | Required | Description |
309
+ | ----- | ---- | :------: | ----------- |
310
+ | `permalink` | string | No | The URL permalink of the reference product for the similarity search. |
311
+ | `productId` | string | No | Product ID (either permalink or productId must be provided). |
312
+ | `ageRange` | string | No | Target age range. |
313
+ | `gender` | string | No | User gender (optional). |
314
+ | `style` | string | No | Preferred style hint. |
315
+ | `color` | string | No | Main color of interest. |
316
+ | `productClass` | ProductClass | No | Target product class. |
317
+ | `clothType` | ClothType | No | Target cloth type for filtering results. |
318
+ | `page` | number | No | Current page number. |
319
+ | `perPage` | number | No | Number of results per page. |
320
+ | `similarityThreshold` | number | No | Similarity threshold for matching (0-1). |
321
+ | `tenantId` | number | Yes | Tenant (client) ID. |
322
+ | `collectionName` | string | Yes | Embeddings collection name (namespace). |
323
+ | `sid` | string | Yes | Session identifier (`sid`) for the user. |
324
+ | `sizeSystem` | string | Yes | Size system code (e.g., 'BR', 'EU', 'US'). |
325
+ | `locale` | string | Yes | Locale for internationalized responses (language and region). |
326
+ | `currency` | string | Yes | Currency code for pricing information in responses. |
327
+ | `filterByWhatFitsMe` | boolean | No | Whether to apply What Fits Me logic. |
328
+ | `personaHash` | string | No | Hash representing the user persona (required if WFM is enabled). |
329
+ <!-- /DOCGEN -->
330
+
331
+ #### Returns
332
+
333
+ <!-- DOCGEN:returns GetSimilarProductsResponse -->
334
+ > **`GetSimilarProductsResponse`**
335
+ > * `data`: `ProductDto[]` — An array of products that are visually similar to the reference item.<br>The results are ordered by their similarity score.
336
+ > * `page`: `number` — The current page number of the results.
337
+ > * `perPage`: `number` — The number of items per page.
338
+ > * `total`: `number` — The total number of similar products found.
339
+ > * `invalidPersonaHash`: `boolean` — Indicates if the provided persona hash is invalid or expired,<br>which may affect personalized results.
340
+ <!-- /DOCGEN -->
341
+
342
+ #### Example
343
+
344
+ ```typescript
345
+ const similarProducts = await client.searchSimilarByPermalink({
346
+ tenantId: 123,
347
+ collectionName: "products",
348
+ sid: "session123",
349
+ sizeSystem: "BR",
350
+ locale: "pt-BR",
351
+ currency: "BRL",
352
+ permalink: "https://example.com/products/red-dress-456",
353
+ similarityThreshold: 0.7,
354
+ page: 1,
355
+ perPage: 10,
356
+ style: "Casual",
357
+ color: "red"
358
+ });
359
+ console.log(similarProducts.data);
360
+ ```
361
+
362
+ ### `searchComplementaryByPermalink(payload: GetComplementaryByPermalinkBodyDto): Promise<GetComplementaryProductsResponse>`
363
+
364
+ Find complementary products from a product permalink or productId using AI-powered analysis.
365
+
366
+ #### Payload
367
+
368
+ <!-- DOCGEN:params GetComplementaryByPermalinkBodyDto -->
369
+ | Field | Type | Required | Description |
370
+ | ----- | ---- | :------: | ----------- |
371
+ | `permalink` | string | No | The URL permalink of the reference product. |
372
+ | `productId` | string | No | Product ID (either permalink or productId must be provided). |
373
+ | `similarityThreshold` | number | Yes | The minimum similarity score (0-1) for recommended products.<br>A higher value yields more similar items, while a lower value provides more variety. |
374
+ | `baseClothType` | ClothType | No | Base cloth type for the reference product. |
375
+ | `targetClothType` | ClothType | No | Target cloth type for complementary products. |
376
+ | `ageRange` | string | No | Target age range. |
377
+ | `gender` | string | No | User gender (optional). |
378
+ | `style` | string | No | Preferred style hint. |
379
+ | `color` | string | No | Main color of interest. |
380
+ | `productClass` | ProductClass | No | Target product class. |
381
+ | `page` | number | No | Current page number. |
382
+ | `perPage` | number | No | Number of results per page. |
383
+ | `tenantId` | number | Yes | Tenant (client) ID. |
384
+ | `collectionName` | string | Yes | Embeddings collection name (namespace). |
385
+ | `sid` | string | Yes | Session identifier (`sid`) for the user. |
386
+ | `sizeSystem` | string | Yes | Size system code (e.g., 'BR', 'EU', 'US'). |
387
+ | `locale` | string | Yes | Locale for internationalized responses (language and region). |
388
+ | `currency` | string | Yes | Currency code for pricing information in responses. |
389
+ | `filterByWhatFitsMe` | boolean | No | Whether to apply What Fits Me logic. |
390
+ | `personaHash` | string | No | Hash representing the user persona (required if WFM is enabled). |
391
+ <!-- /DOCGEN -->
392
+
393
+ #### Returns
394
+
395
+ <!-- DOCGEN:returns GetComplementaryProductsResponse -->
396
+ > **`GetComplementaryProductsResponse`**
397
+ > * `baseProduct`: `ProductDto` — The reference product used to generate recommendations.<br>This is the item that corresponds to the permalink from the request.
398
+ > * `complementary`: `ComplementaryPairDto[]` — A list of recommended pairs of products that are complementary to the base product.
399
+ > * `invalidPersonaHash`: `boolean` — Indicates if the provided persona hash is invalid or has expired.<br>If true, personalization may be affected.
400
+ <!-- /DOCGEN -->
401
+
402
+ #### Example
403
+
404
+ ```typescript
405
+ const complementaryProducts = await client.searchComplementaryByPermalink({
406
+ tenantId: 123,
407
+ collectionName: "products",
408
+ sid: "session123",
409
+ sizeSystem: "BR",
410
+ locale: "pt-BR",
411
+ currency: "BRL",
412
+ productId: "12345",
413
+ similarityThreshold: 0.3,
414
+ baseClothType: ClothType.BOTTOM,
415
+ targetClothType: ClothType.TOP,
416
+ page: 1,
417
+ perPage: 10,
418
+ style: "Casual",
419
+ color: "blue"
420
+ });
421
+ console.log(complementaryProducts.baseProduct, complementaryProducts.complementary);
422
+ ```
423
+
424
+ ---
425
+
299
426
  ## Session Module
300
427
 
301
428
  Retrieves and caches session context:
@@ -1,5 +1,5 @@
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
4
  private endpoint;
5
5
  constructor(config: Config);
@@ -8,4 +8,6 @@ export declare class AIImageService {
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<GetComplementaryProductsResponse>;
11
13
  }
@@ -13,16 +13,16 @@ const p = {
13
13
  }
14
14
  // Adicione outros serviços conforme necessário
15
15
  };
16
- class S {
16
+ class l {
17
17
  constructor(t) {
18
18
  const e = t.env || "development";
19
19
  this.serviceOverrides = t.services || {}, this.endpoints = {};
20
20
  for (const s in p)
21
21
  if (Object.prototype.hasOwnProperty.call(p, s)) {
22
- const o = p[s][e];
23
- if (!o)
22
+ const i = p[s][e];
23
+ if (!i)
24
24
  continue;
25
- this.endpoints[s] = o;
25
+ this.endpoints[s] = i;
26
26
  }
27
27
  }
28
28
  getEndpoint(t) {
@@ -37,7 +37,7 @@ class S {
37
37
  return this.serviceOverrides[t] || {};
38
38
  }
39
39
  }
40
- class l {
40
+ class S {
41
41
  constructor(t) {
42
42
  this.endpoint = t.getEndpoint("tracker");
43
43
  }
@@ -47,18 +47,18 @@ class l {
47
47
  ...e
48
48
  }, n = new URL(`${this.endpoint}/events`);
49
49
  try {
50
- const o = await fetch(n, {
50
+ const i = await fetch(n, {
51
51
  method: "POST",
52
52
  headers: { "Content-Type": "application/json" },
53
53
  body: JSON.stringify(s)
54
54
  });
55
- if (!o.ok) {
56
- const i = await o.text();
57
- throw new Error(`Request error: ${o.status} - ${i}`);
55
+ if (!i.ok) {
56
+ const o = await i.text();
57
+ throw new Error(`Request error: ${i.status} - ${o}`);
58
58
  }
59
- return await o.json();
60
- } catch (o) {
61
- throw o;
59
+ return await i.json();
60
+ } catch (i) {
61
+ throw i;
62
62
  }
63
63
  }
64
64
  }
@@ -168,6 +168,147 @@ class T {
168
168
  body: JSON.stringify(t)
169
169
  });
170
170
  }
171
+ /**
172
+ * Fetches similar product recommendations by permalink or productId.
173
+ *
174
+ * This method searches for products that are visually similar to a reference product
175
+ * identified by either its permalink URL or productId. The search uses AI-powered
176
+ * image analysis to find products with similar visual characteristics like color,
177
+ * style, pattern, and overall appearance.
178
+ *
179
+ * Sends a POST request to `/image-search/similar-by-permalink` with the search parameters.
180
+ * At least one of permalink or productId must be provided in the payload.
181
+ *
182
+ * @param payload - Search parameters including:
183
+ * - `permalink` (optional): Full URL of the reference product
184
+ * - `productId` (optional): Unique identifier of the reference product
185
+ * - `tenantId`: Client/tenant identifier
186
+ * - `collectionName`: Embeddings collection namespace
187
+ * - `sid`: Session identifier for the user
188
+ * - `sizeSystem`: Size system code (e.g., 'BR', 'EU', 'US')
189
+ * - `locale`: Language and region (e.g., 'en-US', 'pt-BR')
190
+ * - `currency`: Currency code for pricing (e.g., 'USD', 'BRL')
191
+ * - `similarityThreshold`: Minimum similarity score (0-1, default: 0.5)
192
+ * - `page`: Page number for pagination (default: 1)
193
+ * - `perPage`: Items per page (default: 20)
194
+ * - `ageRange`: Target age range (optional)
195
+ * - `gender`: User gender (optional)
196
+ * - `style`: Preferred style hint (optional)
197
+ * - `color`: Main color of interest (optional)
198
+ * - `productClass`: Target product class (optional)
199
+ * - `clothType`: Target cloth type for filtering (optional)
200
+ * - `filterByWhatFitsMe`: Apply What Fits Me logic (optional)
201
+ * - `personaHash`: User persona hash for personalization (optional)
202
+ *
203
+ * @returns Promise resolving to a paginated list of similar products with:
204
+ * - `data`: Array of similar products ordered by similarity score
205
+ * - `page`: Current page number
206
+ * - `perPage`: Number of items per page
207
+ * - `total`: Total number of similar products found
208
+ * - `invalidPersonaHash`: Whether the persona hash is invalid/expired
209
+ *
210
+ * @throws {ApiError} if the HTTP status is not 2xx or on network failure
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * const similarProducts = await aiImageService.searchSimilarByPermalink({
215
+ * tenantId: 123,
216
+ * collectionName: "products",
217
+ * sid: "session123",
218
+ * sizeSystem: "BR",
219
+ * locale: "pt-BR",
220
+ * currency: "BRL",
221
+ * permalink: "https://example.com/products/red-dress-456",
222
+ * similarityThreshold: 0.7,
223
+ * page: 1,
224
+ * perPage: 10,
225
+ * style: "Casual",
226
+ * color: "red"
227
+ * });
228
+ * ```
229
+ */
230
+ searchSimilarByPermalink(t) {
231
+ const e = `${this.endpoint}/image-search/similar-by-permalink`;
232
+ return a(e, {
233
+ method: "POST",
234
+ headers: { "Content-Type": "application/json" },
235
+ body: JSON.stringify(t)
236
+ });
237
+ }
238
+ /**
239
+ * Fetches complementary product recommendations by permalink or productId.
240
+ *
241
+ * This method finds products that complement a reference product identified by either
242
+ * its permalink URL or productId. Complementary products are items that work well
243
+ * together in an outfit or ensemble, such as tops that go with bottoms, shoes that
244
+ * match a dress, or accessories that complement a main piece.
245
+ *
246
+ * The AI analyzes the reference product's style, color, and category to suggest
247
+ * complementary items that would create cohesive and fashionable combinations.
248
+ *
249
+ * Sends a POST request to `/image-search/complementary-by-permalink` with the search parameters.
250
+ * At least one of permalink or productId must be provided in the payload.
251
+ *
252
+ * @param payload - Search parameters including:
253
+ * - `permalink` (optional): Full URL of the reference product
254
+ * - `productId` (optional): Unique identifier of the reference product
255
+ * - `tenantId`: Client/tenant identifier
256
+ * - `collectionName`: Embeddings collection namespace
257
+ * - `sid`: Session identifier for the user
258
+ * - `sizeSystem`: Size system code (e.g., 'BR', 'EU', 'US')
259
+ * - `locale`: Language and region (e.g., 'en-US', 'pt-BR')
260
+ * - `currency`: Currency code for pricing (e.g., 'USD', 'BRL')
261
+ * - `similarityThreshold`: Minimum similarity score (0-1, default: 0.2)
262
+ * - `baseClothType` (optional): Cloth type of the reference product (e.g., ClothType.BOTTOM)
263
+ * - `targetClothType` (optional): Desired cloth type for complementary products (e.g., ClothType.TOP)
264
+ * - `page`: Page number for pagination (default: 1)
265
+ * - `perPage`: Items per page (default: 20)
266
+ * - `ageRange`: Target age range (optional)
267
+ * - `gender`: User gender (optional)
268
+ * - `style`: Preferred style hint (optional)
269
+ * - `color`: Main color of interest (optional)
270
+ * - `productClass`: Target product class (optional)
271
+ * - `filterByWhatFitsMe`: Apply What Fits Me logic (optional)
272
+ * - `personaHash`: User persona hash for personalization (optional)
273
+ *
274
+ * @returns Promise resolving to complementary product recommendations with:
275
+ * - `baseProduct`: The reference product information
276
+ * - `complementary`: Array of complementary product pairs
277
+ * - `page`: Current page number
278
+ * - `perPage`: Number of items per page
279
+ * - `total`: Total number of complementary products found
280
+ * - `invalidPersonaHash`: Whether the persona hash is invalid/expired
281
+ *
282
+ * @throws {ApiError} if the HTTP status is not 2xx or on network failure
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * const complementaryProducts = await aiImageService.searchComplementaryByPermalink({
287
+ * tenantId: 123,
288
+ * collectionName: "products",
289
+ * sid: "session123",
290
+ * sizeSystem: "BR",
291
+ * locale: "pt-BR",
292
+ * currency: "BRL",
293
+ * productId: "12345",
294
+ * similarityThreshold: 0.3,
295
+ * baseClothType: ClothType.BOTTOM,
296
+ * targetClothType: ClothType.TOP,
297
+ * page: 1,
298
+ * perPage: 10,
299
+ * style: "Casual",
300
+ * color: "blue"
301
+ * });
302
+ * ```
303
+ */
304
+ searchComplementaryByPermalink(t) {
305
+ const e = `${this.endpoint}/image-search/complementary-by-permalink`;
306
+ return a(e, {
307
+ method: "POST",
308
+ headers: { "Content-Type": "application/json" },
309
+ body: JSON.stringify(t)
310
+ });
311
+ }
171
312
  }
172
313
  class O {
173
314
  constructor(t) {
@@ -211,39 +352,39 @@ class O {
211
352
  async sendProfile(t, e) {
212
353
  const s = e ?? (await this.getSessionInfo()).sid, n = new URL(this.profileEndpoint);
213
354
  n.searchParams.set("sid", s);
214
- const o = await fetch(n.toString(), {
355
+ const i = await fetch(n.toString(), {
215
356
  credentials: "include",
216
357
  method: "POST",
217
358
  headers: { "Content-Type": "application/json" },
218
359
  body: JSON.stringify({ userId: s, id: null, ...t })
219
360
  });
220
- if (!o.ok) {
221
- const i = await o.text();
361
+ if (!i.ok) {
362
+ const o = await i.text();
222
363
  throw new Error(
223
- `Failed to send profile: ${o.status} – ${i}`
364
+ `Failed to send profile: ${i.status} – ${o}`
224
365
  );
225
366
  }
226
367
  }
227
368
  }
228
369
  const u = [
229
- l,
370
+ S,
230
371
  T,
231
372
  O
232
373
  ];
233
- function E(r = {}) {
234
- const t = new S(r), e = u.map((n) => new n(t)), s = {};
374
+ function m(r = {}) {
375
+ const t = new l(r), e = u.map((n) => new n(t)), s = {};
235
376
  return e.forEach((n) => {
236
377
  [
237
378
  ...Object.getOwnPropertyNames(n),
238
379
  ...Object.getOwnPropertyNames(Object.getPrototypeOf(n))
239
- ].forEach((i) => {
240
- if (i === "constructor") return;
241
- const d = n[i];
242
- typeof d == "function" && (s[i] || (s[i] = (...h) => d.apply(n, h)));
380
+ ].forEach((o) => {
381
+ if (o === "constructor") return;
382
+ const d = n[o];
383
+ typeof d == "function" && (s[o] || (s[o] = (...h) => d.apply(n, h)));
243
384
  });
244
385
  }), s;
245
386
  }
246
- const m = {
387
+ const E = {
247
388
  TOP: "TOP",
248
389
  BOTTOM: "BOTTOM",
249
390
  SHOE_ACCESSORY: "SHOE_ACCESSORY",
@@ -296,7 +437,7 @@ const m = {
296
437
  WETSUIT: "wetsuit"
297
438
  };
298
439
  export {
299
- m as ClothType,
440
+ E as ClothType,
300
441
  f as ProductClass,
301
- E as createClient
442
+ m as createClient
302
443
  };
@@ -1 +1 @@
1
- (function(i,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(i=typeof globalThis<"u"?globalThis:i||self,a(i["sizebay-core-sdk"]={}))})(this,(function(i){"use strict";const a={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"}};class l{constructor(e){const t=e.env||"development";this.serviceOverrides=e.services||{},this.endpoints={};for(const s in a)if(Object.prototype.hasOwnProperty.call(a,s)){const o=a[s][t];if(!o)continue;this.endpoints[s]=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 s={eventName:e,...t},n=new URL(`${this.endpoint}/events`);try{const o=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!o.ok){const r=await o.text();throw new Error(`Request error: ${o.status} - ${r}`)}return await o.json()}catch(o){throw o}}}class d extends Error{constructor(e,t){let s;try{const n=JSON.parse(t);s=(n==null?void 0:n.message)||t}catch{s=t}super(s),this.statusCode=e,this.details=t,Object.setPrototypeOf(this,d.prototype)}}async function p(c,e){let t;try{t=await fetch(c,e)}catch(n){throw new d(0,n.message)}const s=await t.text();if(!t.ok)throw new d(t.status,s);return JSON.parse(s)}class S{constructor(e){this.endpoint=e.getEndpoint("aiImageService")}appendQueryParams(e,t){Object.entries(t).forEach(([s,n])=>{n!=null&&e.searchParams.append(s,String(n))})}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 s=await e.text();throw new Error(`Failed to fetch session info: ${e.status} – ${s}`)}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 s=t??(await this.getSessionInfo()).sid,n=new URL(this.profileEndpoint);n.searchParams.set("sid",s);const o=await fetch(n.toString(),{credentials:"include",method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:s,id:null,...e})});if(!o.ok){const r=await o.text();throw new Error(`Failed to send profile: ${o.status} – ${r}`)}}}const O=[u,S,T];function E(c={}){const e=new l(c),t=O.map(n=>new n(e)),s={};return t.forEach(n=>{[...Object.getOwnPropertyNames(n),...Object.getOwnPropertyNames(Object.getPrototypeOf(n))].forEach(r=>{if(r==="constructor")return;const h=n[r];typeof h=="function"&&(s[r]||(s[r]=(...y)=>h.apply(n,y)))})}),s}const f={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"},m={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=f,i.ProductClass=m,i.createClient=E,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(o,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(o=typeof globalThis<"u"?globalThis:o||self,a(o["sizebay-core-sdk"]={}))})(this,(function(o){"use strict";const a={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"}};class l{constructor(e){const t=e.env||"development";this.serviceOverrides=e.services||{},this.endpoints={};for(const s in a)if(Object.prototype.hasOwnProperty.call(a,s)){const i=a[s][t];if(!i)continue;this.endpoints[s]=i}}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 S{constructor(e){this.endpoint=e.getEndpoint("tracker")}async track(e,t){const s={eventName:e,...t},n=new URL(`${this.endpoint}/events`);try{const i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok){const r=await i.text();throw new Error(`Request error: ${i.status} - ${r}`)}return await i.json()}catch(i){throw i}}}class p extends Error{constructor(e,t){let s;try{const n=JSON.parse(t);s=(n==null?void 0:n.message)||t}catch{s=t}super(s),this.statusCode=e,this.details=t,Object.setPrototypeOf(this,p.prototype)}}async function d(c,e){let t;try{t=await fetch(c,e)}catch(n){throw new p(0,n.message)}const s=await t.text();if(!t.ok)throw new p(t.status,s);return JSON.parse(s)}class u{constructor(e){this.endpoint=e.getEndpoint("aiImageService")}appendQueryParams(e,t){Object.entries(t).forEach(([s,n])=>{n!=null&&e.searchParams.append(s,String(n))})}getSimilarProducts(e){const t=new URL(`${this.endpoint}/recommendations/similar`);return this.appendQueryParams(t,e),d(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}getComplementaryProducts(e){const t=new URL(`${this.endpoint}/recommendations/complementary`);return this.appendQueryParams(t,e),d(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}searchSimilarByImage(e){const t=`${this.endpoint}/image-search/similar`;return d(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchComplementaryByImage(e){const t=`${this.endpoint}/image-search/complementary`;return d(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchSimilarByPermalink(e){const t=`${this.endpoint}/image-search/similar-by-permalink`;return d(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}searchComplementaryByPermalink(e){const t=`${this.endpoint}/image-search/complementary-by-permalink`;return d(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 s=await e.text();throw new Error(`Failed to fetch session info: ${e.status} – ${s}`)}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 s=t??(await this.getSessionInfo()).sid,n=new URL(this.profileEndpoint);n.searchParams.set("sid",s);const i=await fetch(n.toString(),{credentials:"include",method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:s,id:null,...e})});if(!i.ok){const r=await i.text();throw new Error(`Failed to send profile: ${i.status} – ${r}`)}}}const O=[S,u,T];function m(c={}){const e=new l(c),t=O.map(n=>new n(e)),s={};return t.forEach(n=>{[...Object.getOwnPropertyNames(n),...Object.getOwnPropertyNames(Object.getPrototypeOf(n))].forEach(r=>{if(r==="constructor")return;const h=n[r];typeof h=="function"&&(s[r]||(s[r]=(...y)=>h.apply(n,y)))})}),s}const f={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"},E={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"};o.ClothType=f,o.ProductClass=E,o.createClient=m,Object.defineProperty(o,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,17 @@
1
+ import { BaseSearchParams } from '../base/base-search.dto';
2
+ import { ProductClass } from '../../common/product-class.type';
3
+ import { ClothType } from '../../common/cloth-type.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
+ page?: number;
16
+ perPage?: number;
17
+ }
@@ -0,0 +1,16 @@
1
+ import { BaseSearchParams } from '../base/base-search.dto';
2
+ import { ProductClass } from '../../common/product-class.type';
3
+ import { ClothType } from '../../common/cloth-type.type';
4
+ export interface GetSimilarByPermalinkBodyDto extends BaseSearchParams {
5
+ permalink?: string;
6
+ productId?: string;
7
+ ageRange?: string;
8
+ gender?: string;
9
+ style?: string;
10
+ color?: string;
11
+ productClass?: ProductClass;
12
+ clothType?: ClothType;
13
+ page?: number;
14
+ perPage?: number;
15
+ similarityThreshold?: number;
16
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sizebay-core-sdk",
3
- "version": "1.10.1-dev.1",
3
+ "version": "1.11.0-dev.2",
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",