sizebay-core-sdk 1.4.1 → 1.6.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
@@ -1,133 +1,96 @@
1
1
  # Sizebay Core SDK
2
2
 
3
- A lightweight, modular, and extensible SDK designed for integrating multiple services (such as event tracking, AI services, etc.) into your application. This package includes environment-based endpoint management, async/await support, and full TypeScript definitions.
3
+ A modular SDK for integrating Sizebay services into your application. Features environment-based endpoint management, async/await support, built-in retry logic, and full TypeScript definitions.
4
4
 
5
- ## Installation
5
+ * Event tracking
6
+ * AI image recommendations (similar / complementary / sizing)
7
+ * Session & profile management
8
+ * Environment-aware endpoints (`-dev` / `-prod`)
9
+ * Full TypeScript typings
6
10
 
7
- Install the package via npm:
11
+ ---
8
12
 
9
- ```bash
10
- npm install sizebay-core-sdk
11
- ```
13
+ ## Table of Contents
12
14
 
13
- ## API Reference
15
+ 1. [Installation](#installation)
16
+ 2. [Quick Start](#quick-start)
17
+ 3. [Tracker Module](#tracker-module)
18
+ 4. [AI Image Service Module](#ai-image-service-module)
19
+ 5. [Image Search Services](#image-search-services)
20
+ 6. [Session Module](#session-module)
21
+ 7. [DTO Reference](#dto-reference)
14
22
 
15
- ### Client
23
+ ---
16
24
 
17
- #### `createClient(options: SDKConfigOptions): ClientType`
25
+ ## Installation
18
26
 
19
- Creates a new instance of the SDK with the provided configuration.
27
+ Install via npm:
20
28
 
21
- **Options**
29
+ ```bash
30
+ npm install sizebay-core-sdk
31
+ ```
22
32
 
23
- | Property | Type | Required | Description |
24
- | -------- | -------- | -------- | ---------------------------------------------------------------------------------------- |
25
- | `env` | `string` | No | The environment to use (`'development'` or `'production'`). Defaults to `'development'`. |
33
+ ---
34
+
35
+ ## Quick Start
26
36
 
27
- **Example**
37
+ ### Create a client
28
38
 
29
39
  ```typescript
30
40
  import { createClient } from 'sizebay-core-sdk';
31
41
 
32
- const client = createClient({
33
- env: 'development',
34
- });
42
+ const client = createClient({ env: 'development' });
43
+ // env: 'development' | 'production' (default: 'development')
35
44
  ```
36
45
 
37
46
  ---
38
47
 
39
48
  ## Tracker Module
40
49
 
41
- #### `track(eventName: string, payload: TrackData): Promise<TrackResponse>`
42
-
43
- Sends an event to the designated API endpoint, returning a standardized response.
44
-
45
- **Parameters**
46
-
47
- | Parameter | Type | Required | Description |
48
- | ----------- | ----------- | -------- | ------------------------------------------------------------------------ |
49
- | `eventName` | `string` | Yes | The name of the event (e.g., "ADD_TO_CART", "ORDER"). |
50
- | `payload` | `TrackData` | Yes | An object containing event data. See the structure of `TrackData` below. |
51
-
52
- **TrackData Structure**
53
-
54
- | Property | Type | Required | Description |
55
- | -------------- | --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
56
- | **sid** | `string` | Yes | Unique user identifier. |
57
- | **tenantId** | `number` | Yes | Identifier of the tenant (client) sending the event. |
58
- | **properties** | `Record<string, JSONValue>` | Yes | Object containing additional properties as key-value pairs. |
59
- | **permalink** | `string` (optional) | No | Product URL associated with the event. When the event is linked to product (e.g., ADD_TO_CART RECOMMENDATION_DONE), it is required. |
60
-
61
- **Returns**
62
-
63
- - **201** – Event successfully created.
64
- ```json
65
- {
66
- "statusCode": 201,
67
- "message": "Event successfully created."
68
- }
69
- ```
70
- - **400** – Invalid or missing fields.
71
- ```json
72
- {
73
- "statusCode": 400,
74
- "error": "Bad Request",
75
- "message": ["tenantId must be an integer number"]
76
- }
77
- ```
78
- - **500** – Internal server error.
79
- ```json
80
- {
81
- "statusCode": 500,
82
- "error": "Internal server error",
83
- "message": ["Unexpected error on server side"]
84
- }
85
- ```
86
-
87
- **Example**
50
+ ### `track(eventName: string, payload: TrackData): Promise<TrackResponse>`
88
51
 
89
- ```typescript
90
- const eventPayload: TrackData = {
91
- sid: 'A098AFD9F57SG54GD2H21341NK0',
92
- tenantId: 123,
93
- permalink: 'https://www.example.com/2IC-7370',
94
- properties: {
95
- quantity: 1,
96
- device: 'APP',
97
- country: 'BR',
98
- },
99
- };
52
+ Send an event to the API.
100
53
 
101
- async function trackEvent() {
102
- try {
103
- const response = await client.track('ADD_TO_CART', eventPayload);
104
-
105
- if (response.statusCode === 201) {
106
- console.log('Event tracked successfully:', response.message);
107
- } else {
108
- console.error(
109
- `Error tracking event (${response.statusCode}):`,
110
- response.error,
111
- response.message,
112
- );
113
- }
114
- } catch (error: any) {
115
- console.error('Unexpected error tracking event:', error.message);
116
- }
117
- }
54
+ #### Parameters
118
55
 
119
- trackEvent();
120
- ```
56
+ | Parameter | Type | Required | Description |
57
+ | ----------- | ----------- | :------: | ------------------------------- |
58
+ | `eventName` | string | Yes | e.g. `"ADD_TO_CART"`, `"ORDER"` |
59
+ | `payload` | `TrackData` | Yes | See structure below |
121
60
 
122
- Thought for a couple of seconds
61
+ #### `TrackData`
123
62
 
124
- Segue a documentação atualizada com os parâmetros `filterByWhatFitsMe`, `personaHash` e o campo de resposta `suitableSizes`.
63
+ | Field | Type | Required | Description |
64
+ | ------------ | --------------------------- | :------: | ------------------------------------------------------------------ |
65
+ | `sid` | string | Yes | String user ID (`catalogUser.id`) |
66
+ | `tenantId` | number | Yes | Tenant (client) ID |
67
+ | `sessionId` | number | No | Numeric session ID |
68
+ | `permalink` | string | Cond.\* | Required for product-related events (e.g. `"RECOMMENDATION_DONE"`) |
69
+ | `properties` | `Record<string, JSONValue>` | Yes | Additional event data |
125
70
 
126
- ---
71
+ \*Condition: enforced by SDK when needed.
72
+
73
+ #### Returns
74
+
75
+ > **Returns:** `TrackResponse`
76
+ >
77
+ > * `statusCode`: `number`
78
+ > * `message`: `string`
127
79
 
128
- Thought for a couple of seconds
80
+ #### Example
129
81
 
130
- Here’s a cleaned-up, fully English version with consistent terminology, corrected typos, and improved clarity:
82
+ ```typescript
83
+ const payload = {
84
+ sid: 'a0cf8559-926a-4a75-b4ca-7c4c13fed69c',
85
+ tenantId: 123,
86
+ sessionId: 456,
87
+ permalink: 'https://www.example.com/2IC-7370',
88
+ properties: { quantity: 1, device: 'APP', country: 'BR' },
89
+ };
90
+
91
+ const response = await client.track('ADD_TO_CART', payload);
92
+ console.log(response.statusCode, response.message);
93
+ ```
131
94
 
132
95
  ---
133
96
 
@@ -135,264 +98,239 @@ Here’s a cleaned-up, fully English version with consistent terminology, correc
135
98
 
136
99
  ### `getSimilarProducts(params: GetSimilarProductsParams): Promise<GetSimilarProductsResponse>`
137
100
 
138
- Fetch similar products based on the given parameters, returning a paginated result and—when requested—size recommendations.
101
+ Fetch products similar to a reference.
139
102
 
140
103
  #### Parameters
141
104
 
142
- | Parameter | Type | Required | Description |
143
- | -------------------- | --------- | :------: | ---------------------------------------------------------------------------- |
144
- | `tenantId` | `number` | **Yes** | Tenant ID initiating the request. |
145
- | `collectionName` | `string` | **Yes** | Name of the product collection. |
146
- | `sid` | `string` | **Yes** | Session ID for internal event tracking. |
147
- | `permalink` | `string` | **Yes** | Permanent link (URL) of the main product. |
148
- | `page` | `number` | No | Page number (pagination). |
149
- | `perPage` | `number` | No | Number of items per page. |
150
- | `sizeSystem` | `string` | **Yes** | Size system code (e.g., `'BR'`, `'US'`, `'EU'`). |
151
- | `filterByWhatFitsMe` | `boolean` | No | If `true`, apply “What Fits Me” size filter. Defaults to `false`. |
152
- | `personaHash` | `string` | Cond.\* | Persona hash from Size & Fit; **required** when `filterByWhatFitsMe = true`. |
153
-
154
- > **Returns:** `Promise<GetSimilarProductsResponse>`
105
+ | Field | Type | Required | Description |
106
+ | -------------------- | ----------- | :------: | ----------------------------------------------- |
107
+ | `tenantId` | number | Yes | Tenant ID |
108
+ | `collectionName` | string | Yes | Embeddings collection |
109
+ | `sid` | string | Yes | String user ID |
110
+ | `permalink` | string | Yes | Reference product URL |
111
+ | `sizeSystem` | string | Yes | e.g. `"BR"`, `"EU"` |
112
+ | `similarityThreshold`| number | Yes | Threshold for similarity-by-image search |
113
+ | `page` | number | No | Page number |
114
+ | `perPage` | number | No | Items per page |
115
+ | `filterByWhatFitsMe` | boolean | No | Enable “What Fits Me” filter (default: `false`) |
116
+ | `personaHash` | string | Cond.\* | Required when `filterByWhatFitsMe` is `true` |
117
+
118
+ #### Returns
119
+
120
+ > **Returns:** `GetSimilarProductsResponse`
155
121
  >
156
- > - `data`: `Product[]` — Array of product objects.
157
- > - `page`: `number` — Current page.
158
- > - `perPage`: `number` — Items per page.
159
- > - `total`: `number` — Total available items.
160
- > - `suitableSizes?`: `SuitableSizeDto[]` — Size recommendations (only if `filterByWhatFitsMe = true`).
122
+ > * `data`: `ProductDto[]` — Similar items
123
+ > * `page`: `number` — Current page
124
+ > * `perPage`: `number` — Items per page
125
+ > * `total`: `number` — Total matched items
161
126
 
162
127
  #### Example
163
128
 
164
129
  ```typescript
165
- import { GetSimilarProductsParams } from 'sizebay-core-sdk';
166
-
167
- const params: GetSimilarProductsParams = {
130
+ const similarResponse = await client.getSimilarProducts({
168
131
  tenantId: 123,
169
- collectionName: 'summer-collection',
170
- sid: 'A098AFD9F57SG54GD2H21341NK0',
171
- permalink: 'https://example.com/product',
132
+ collectionName: 'clothing',
133
+ sid: 'abc123',
134
+ permalink: 'https://domain.com/product/xyz',
135
+ sizeSystem: 'US',
136
+ similarityThreshold: 0.5,
172
137
  page: 1,
173
- perPage: 10,
174
- sizeSystem: 'BR',
175
- filterByWhatFitsMe: true,
176
- personaHash: '6b4f2e8b-0bb2-43d1-8bea-7f6d1c5d5a71',
177
- };
178
-
179
- async function fetchSimilar() {
180
- try {
181
- const response = await client.getSimilarProducts(params);
182
- console.log('Products:', response.data);
183
- if (response.suitableSizes) {
184
- console.log('Recommended sizes:', response.suitableSizes);
185
- }
186
- } catch (err: any) {
187
- console.error('Error:', err.message);
188
- }
189
- }
190
-
191
- fetchSimilar();
138
+ perPage: 10
139
+ });
140
+ console.log(similarResponse.data, similarResponse.total);
192
141
  ```
193
142
 
194
143
  ---
195
144
 
196
- ### `getRecommendedSizeByProducts(payload: GetRecommendedSizeByProductsParams): Promise<GetRecommendedSizeByProductsResponse[]>`
145
+ ### `getComplementaryProducts(params: GetComplementaryProductsParams): Promise<GetComplementaryProductsResponse>`
197
146
 
198
- Retrieve recommended sizes for multiple products.
147
+ Retrieve pairs of complementary products.
199
148
 
200
149
  #### Parameters
201
150
 
202
- | Parameter | Type | Required | Description |
203
- | ------------ | ---------- | :------: | ------------------------------------------------ |
204
- | `tenantId` | `number` | **Yes** | Tenant ID initiating the request. |
205
- | `sid` | `string` | No | Session ID for internal events. |
206
- | `sizeSystem` | `string` | **Yes** | Size system code (e.g., `'BR'`, `'US'`, `'EU'`). |
207
- | `permalinks` | `string[]` | **Yes** | Array of product permalinks. |
151
+ | Field | Type | Required | Description |
152
+ | -------------------- | ----------- | :------: | ------------------------------ |
153
+ | `tenantId` | number | Yes | Tenant ID |
154
+ | `collectionName` | string | Yes | Embeddings collection |
155
+ | `sid` | string | Yes | String user ID |
156
+ | `permalink` | string | Yes | Reference product URL |
157
+ | `sizeSystem` | string | Yes | e.g. `"BR"`, `"EU"` |
158
+ | `similarityThreshold`| number | Yes | Threshold for similarity-by-image search |
159
+ | `limit` | number | No | Max number of pairs |
160
+ | `filterByWhatFitsMe` | boolean | No | Enable WFM filter |
161
+ | `personaHash` | string | Cond.\* | Required when WFM filter is on |
162
+
163
+ #### Returns
208
164
 
209
- > **Returns:** `Promise<GetRecommendedSizeByProductsResponse[]>`
210
- > Each item includes:
165
+ > **Returns:** `GetComplementaryProductsResponse`
211
166
  >
212
- > - `id`: `string` — Internal product identifier.
213
- > - `permalink`: `string` — Product’s permalink.
214
- > - `recommendedSize`: `string \| null` — The suggested size or `null` if unavailable.
167
+ > * `baseProduct`: `ProductDto`
168
+ > * `complementary`: `ComplementaryPairDto[]`
169
+ >
170
+ > * `first`: `ProductDto` (required)
171
+ > * `secondary`: `ProductDto` (optional)
172
+ > * `page`: `number` — Current page
173
+ > * `perPage`: `number` — Items per page
174
+ > * `total`: `number` — Total matched items
215
175
 
216
176
  #### Example
217
177
 
218
178
  ```typescript
219
- import { GetRecommendedSizeByProductsParams } from 'sizebay-core-sdk';
220
-
221
- const payload: GetRecommendedSizeByProductsParams = {
179
+ const compResponse = await client.getComplementaryProducts({
222
180
  tenantId: 123,
223
- sid: 'A098AFD9F57SG54GD2H21341NK0',
224
- sizeSystem: 'BR',
225
- permalinks: ['https://example.com/product1', 'https://example.com/product2'],
226
- };
227
-
228
- async function fetchSizes() {
229
- try {
230
- const recommendations = await client.getRecommendedSizeByProducts(payload);
231
- recommendations.forEach(({ id, recommendedSize }) => {
232
- console.log(`Product ${id}: ${recommendedSize}`);
233
- });
234
- } catch (err: any) {
235
- console.error('Error:', err.message);
236
- }
237
- }
238
-
239
- fetchSizes();
181
+ collectionName: 'clothing',
182
+ sid: 'abc123',
183
+ permalink: 'https://domain.com/product/xyz',
184
+ sizeSystem: 'US',
185
+ similarityThreshold: 0.5,
186
+ limit: 5
187
+ });
188
+ console.log(compResponse.baseProduct, compResponse.complementary);
240
189
  ```
241
190
 
242
191
  ---
243
192
 
244
- ### `getComplementaryProducts(params: GetComplementaryProductsParams): Promise<GetComplementaryProductsResponse>`
193
+ ## Image Search Services
245
194
 
246
- Fetch complementary product pairs, optionally filtered by size.
195
+ ### `searchSimilarByImage(payload: GetSimilarByImageBodyDto): Promise<GetSimilarProductsResponse>`
247
196
 
248
- #### Parameters
197
+ Find visually similar items from an uploaded image.
198
+
199
+ #### Payload
200
+
201
+ | Field | Type | Required | Description |
202
+ | -------------------- | ----------- | :------: | ----------------------------------- |
203
+ | `image` | string | Yes | Base-64 data URL (`data:image/...`) |
204
+ | `tenantId` | number | Yes | Tenant ID |
205
+ | `collectionName` | string | Yes | Embeddings collection |
206
+ | `sid` | string | Yes | String user ID |
207
+ | `sizeSystem` | string | Yes | Size system |
208
+ | `similarityThreshold`| number | Yes | Threshold for similarity-by-image search |
209
+ | `filterByWhatFitsMe` | boolean | No | Apply WFM filter |
210
+ | `personaHash` | string | Cond.\* | Required when WFM is on |
211
+ | `gender` | string | No | User gender context |
212
+ | `style` | string | No | Preferred style |
213
+ | `color` | string | No | Main color hint |
214
+ | `category` | string | No | High-level category |
215
+ | `page` | number | No | Page number |
216
+ | `perPage` | number | No | Items per page |
217
+
218
+ #### Returns
249
219
 
250
- | Parameter | Type | Required | Description |
251
- | -------------------- | --------- | :------: | ---------------------------------------------------------------------------- |
252
- | `tenantId` | `string` | **Yes** | Tenant ID initiating the request. |
253
- | `collectionName` | `string` | **Yes** | Qdrant collection name for embeddings. |
254
- | `sid` | `string` | **Yes** | Session ID for event tracking. |
255
- | `permalink` | `string` | **Yes** | Permanent link (URL) of the base product. |
256
- | `limit` | `number` | No | Maximum number of complementary pairs. |
257
- | `sizeSystem` | `string` | **Yes** | Size system code (e.g., `'BR'`, `'US'`, `'EU'`). |
258
- | `filterByWhatFitsMe` | `boolean` | No | If `true`, apply “What Fits Me” size filter. Defaults to `false`. |
259
- | `personaHash` | `string` | Cond.\* | Persona hash from Size & Fit; **required** when `filterByWhatFitsMe = true`. |
260
-
261
- > **Returns:** `Promise<GetComplementaryProductsResponse>`
220
+ > **Returns:** `GetSimilarProductsResponse`
262
221
  >
263
- > - `baseProduct`: `ProductDto` — Seed product.
264
- > - `complementary`: `ComplementaryPairDto[]` — Array of pairs (`first` & `secondary`).
265
- > - `suitableSizes?`: `SuitableSizeDto[]` — Size recommendations when filtering by persona.
222
+ > * `data`: `ProductDto[]`
223
+ > * `page`: `number`
224
+ > * `perPage`: `number`
225
+ > * `total`: `number`
266
226
 
267
227
  #### Example
268
228
 
269
229
  ```typescript
270
- import { GetComplementaryProductsParams } from 'sizebay-core-sdk';
271
-
272
- const params: GetComplementaryProductsParams = {
273
- tenantId: '123',
274
- collectionName: 'summer-collection',
275
- sid: 'A098AFD9F57SG54GD2H21341NK0',
276
- permalink: 'https://example.com/product/base-1',
277
- limit: 5,
278
- sizeSystem: 'BR',
279
- filterByWhatFitsMe: true,
280
- personaHash: '6b4f2e8b-0bb2-43d1-8bea-7f6d1c5d5a71',
281
- };
282
-
283
- async function fetchPairs() {
284
- try {
285
- const response = await client.getComplementaryProducts(params);
286
- console.log('Base:', response.baseProduct);
287
- response.complementary.forEach(({ first, secondary }) => {
288
- console.log(`${first.title} ↔ ${secondary.title}`);
289
- });
290
- if (response.suitableSizes) {
291
- console.log('Size recommendations:', response.suitableSizes);
292
- }
293
- } catch (err: any) {
294
- console.error('Error:', err.message);
295
- }
296
- }
297
-
298
- fetchPairs();
230
+ const imgSimilar = await client.searchSimilarByImage({
231
+ image: 'data:image/png;base64,...',
232
+ tenantId: 123,
233
+ collectionName: 'clothing',
234
+ sid: 'abc123',
235
+ sizeSystem: 'US'
236
+ });
237
+ console.log(imgSimilar.data);
299
238
  ```
300
239
 
301
240
  ---
302
241
 
303
- ## DTO Definitions
304
-
305
- ### `Product` / `ProductDto`
306
-
307
- | Field | Type | Description |
308
- | ---------------------- | ------------------- | ------------------------------------------- |
309
- | `id` | `string` | Unique product identifier. |
310
- | `title` | `string` | Product title. |
311
- | `productType` | `string` | Product category/type. |
312
- | `link` | `string` | Product page URL. |
313
- | `imageLink` | `string` | Main image URL. |
314
- | `gender` | `string` | Gender segment (`"male"`, `"female"`, etc). |
315
- | `availability` | `string` | Stock status (e.g., `"in stock"`). |
316
- | `productHash` | `string` | Hash for deduplication. |
317
- | `price` | `string` | Formatted price (e.g., `"29.99 USD"`). |
318
- | `salePrice?` | `string` | Promotional price, if applicable. |
319
- | `itemGroupId` | `string` | Variant group ID. |
320
- | `brand` | `string` | Brand name. |
321
- | `color` | `string` | Color description. |
322
- | `gtin` | `string` | Global Trade Item Number. |
323
- | `additionalImageLinks` | `string[]` | Other image URLs. |
324
- | `suitableSizes?` | `SuitableSizeDto[]` | Size recommendations (when filtering). |
242
+ ### `searchComplementaryByImage(payload: GetComplementaryByImageBodyDto): Promise<GetComplementaryProductsByImageResponse>`
243
+
244
+ Get products that complete a look from an image.
245
+
246
+ #### Payload
247
+
248
+ | Field | Type | Required | Description |
249
+ | -------------------- | ------------------------------------------- | :------: | ----------------------- |
250
+ | `image` | string | Yes | Base-64 data URL |
251
+ | `tenantId` | number | Yes | Tenant ID |
252
+ | `collectionName` | string | Yes | Embeddings collection |
253
+ | `sid` | string | Yes | String user ID |
254
+ | `sizeSystem` | string | Yes | Size system |
255
+ | `similarityThreshold`| number | Yes | Threshold for similarity-by-image search |
256
+ | `productClass` | `"top" \| "bottom" \| "shoe" \| "fullbody"` | Yes | Base item class |
257
+ | `filterByWhatFitsMe` | boolean | No | Apply WFM filter |
258
+ | `personaHash` | string | Cond.\* | Required when WFM is on |
259
+ | `gender` | string | No | User gender context |
260
+ | `style` | string | No | Preferred style |
261
+ | `color` | string | No | Main color hint |
262
+ | `page` | number | No | Page number |
263
+ | `perPage` | number | No | Items per page |
325
264
 
326
- ### `SuitableSizeDto`
265
+ #### Returns
266
+
267
+ > **Returns:** `GetComplementaryProductsByImageResponse`
268
+ >
269
+ > * `baseProduct`: `ProductDto`
270
+ > * `complementary`: `ProductDto[]`
271
+ > * `page`: `number`
272
+ > * `perPage`: `number`
273
+ > * `total`: `number`
274
+
275
+ #### Example
327
276
 
328
- | Field | Type | Description |
329
- | ------------- | --------- | ---------------------------------------------------------------------- |
330
- | `size` | `string` | The recommended size label (e.g., `"S"`, `"M"`, `"L"`). |
331
- | `comfortable` | `number` | A comfort score (0–1) indicating how well this size fits the persona. |
332
- | `value` | `boolean` | Optional secondary metric (e.g., normalized preference or confidence). |
277
+ ```typescript
278
+ const imgComp = await client.searchComplementaryByImage({
279
+ image: 'data:image/png;base64,...',
280
+ tenantId: 123,
281
+ collectionName: 'clothing',
282
+ sid: 'abc123',
283
+ sizeSystem: 'US',
284
+ similarityThreshold: 0.5,
285
+ productClass: 'top'
286
+ });
287
+ console.log(imgComp.complementary);
288
+ ```
333
289
 
334
290
  ---
335
291
 
336
292
  ## Session Module
337
293
 
338
- ### `getSessionInfo(): Promise<SessionContext>`
294
+ Retrieves and caches session context:
339
295
 
340
- Retrieves (or reuses) the session context, containing:
296
+ * **sid** (`string`): Catalog user ID returned by session endpoint
297
+ * **sessionId** (`number`): Numeric session identifier
341
298
 
342
- - `sid` – the `catalogUser.id` returned by the endpoint
343
- - `sessionId` – the numeric session identifier
299
+ ### `getSessionInfo(): Promise<SessionContext>`
344
300
 
345
- If not already cached, it fetches both values from the session endpoint.
301
+ Fetches or reuses session context.
346
302
 
347
303
  #### Returns
348
304
 
349
- - A `Promise<SessionContext>` that resolves to an object with `sid` (string) and `sessionId` (number).
305
+ ```ts
306
+ interface SessionContext {
307
+ sid: string;
308
+ sessionId: number;
309
+ }
310
+ ```
350
311
 
351
312
  #### Example
352
313
 
353
314
  ```typescript
354
315
  const { sid, sessionId } = await client.getSessionInfo();
355
- console.log('Catalog SID:', sid);
356
- console.log('Numeric sessionId:', sessionId);
316
+ console.log('SID:', sid, 'sessionId:', sessionId);
357
317
  ```
358
318
 
359
- ---
360
-
361
319
  ### `sendProfile(payload: SessionProfilePayload, sid?: string): Promise<void>`
362
320
 
363
- Sends a user profile to the server. The profile is associated with the provided `sid`, or falls back to the internally stored one (via `getSessionInfo()`).
321
+ Sends user profile data. Uses cached `sid` if not provided.
364
322
 
365
323
  #### Parameters
366
324
 
367
- | Parameter | Type | Required | Description |
368
- | --------- | ----------------------- | -------- | -------------------------------------------------------------------------------------------- |
369
- | `payload` | `SessionProfilePayload` | Yes | An object containing user profile details. |
370
- | `sid` | `string` | No | The `catalogUser.id` to use. If omitted, the method will retrieve it via `getSessionInfo()`. |
371
-
372
- #### `SessionProfilePayload` Structure
373
-
374
- | Field | Type | Required | Description |
375
- | ---------------- | ----------------------------------------------------- | -------- | ------------------------------------------ |
376
- | `userId` | `string` | Yes | The user’s unique ID |
377
- | `name` | `string` | Yes | The profile name |
378
- | `skinType` | `number` | Yes | Skin type category |
379
- | `footShape` | `string \| null` | No | Optional foot shape |
380
- | `gender` | `string` | Yes | User’s gender (`'M'` or `'F'`) |
381
- | `age` | `string` | Yes | User’s age as a string |
382
- | `is3dFeel` | `boolean` | Yes | Whether 3D feel is enabled |
383
- | `weight` | `string` | Yes | User’s weight in string format |
384
- | `height` | `string` | Yes | User’s height in string format |
385
- | `measures` | `{ insoleLength: number; poundWeight: number\|null }` | Yes | Additional measurements |
386
- | `product` | `string \| null` | No | Optional product context |
387
- | `isMetric` | `boolean` | Yes | Whether measurements use the metric system |
388
- | `bodyShapeChest` | `number` | Yes | Chest shape index |
389
- | `bodyShapeWaist` | `number` | Yes | Waist shape index |
390
- | `bodyShapeHip` | `number` | Yes | Hip shape index |
325
+ | Field | Type | Required | Description |
326
+ | --------- | --------------------- | :------: | ------------------------------------ |
327
+ | `payload` | SessionProfilePayload | Yes | Profile details |
328
+ | `sid` | string | No | Catalog user ID (defaults to cached) |
391
329
 
392
330
  #### Example
393
331
 
394
332
  ```typescript
395
- const profile: SessionProfilePayload = {
333
+ const profilePayload: SessionProfilePayload = {
396
334
  userId: 'abc123',
397
335
  name: 'szb-profile-no-name',
398
336
  skinType: 0,
@@ -410,66 +348,74 @@ const profile: SessionProfilePayload = {
410
348
  bodyShapeHip: 0,
411
349
  };
412
350
 
413
- await client.sendProfile(profile);
351
+ await client.sendProfile(profilePayload);
414
352
  ```
415
353
 
416
- 💡 **React Tip:** To avoid recreating the SDK on every render, memoize your client with `useMemo`:
417
-
418
- ```tsx
419
- import { useMemo, useState } from 'react';
420
- import { createClient } from 'sizebay-core-sdk';
421
-
422
- export function MyComponent() {
423
- // client is only created once on mount
424
- const client = useMemo(() => createClient({ env: 'development' }), []);
425
-
426
- const [profileStatus, setProfileStatus] = useState<string | null>(null);
427
-
428
- const handleGetSessionInfo = async () => {
429
- const { sid } = await client.getSessionInfo();
430
- // …use sid…
431
- };
354
+ ---
432
355
 
433
- const handleSendProfile = async () => {
434
- await client.sendProfile(profilePayload);
435
- setProfileStatus('Profile sent successfully!');
436
- };
356
+ ## DTO Reference
357
+
358
+ ### `ProductDto`
359
+
360
+ | Field | Type | Description |
361
+ | ---------------------- | ------------------- | ----------------------------------------- |
362
+ | `id` | `string` | Unique product ID |
363
+ | `itemGroupId` | `string` | Variant group ID |
364
+ | **URLs** | | |
365
+ | `link` | `string` | Product page URL |
366
+ | `imageLink` | `string` | Main image URL |
367
+ | `additionalImageLinks` | `string[]` | Extra image URLs |
368
+ | **Details** | | |
369
+ | `title` | `string` | Product title |
370
+ | `productType` | `string` | Category/type |
371
+ | `gender` | `string` | Gender target |
372
+ | `availability` | `string` | Stock status |
373
+ | `price` | `string` | Price string |
374
+ | `salePrice?` | `string` | Sale price (optional) |
375
+ | `brand` | `string` | Brand name |
376
+ | `color` | `string` | Color description |
377
+ | `style` | `string` | Style description |
378
+ | `category` | `string` | High-level category |
379
+ | `gtin` | `string` | GTIN / barcode |
380
+ | `productHash` | `string` | Hash for de-duplication |
381
+ | **Sizing (WFM)** | | |
382
+ | `suitableSizes?` | `SuitableSizeDto[]` | Only when the “What Fits Me” filter is on |
437
383
 
438
- //
439
- }
440
- ```
384
+ ### `SuitableSizeDto`
441
385
 
442
- ---
386
+ | Field | Type | Description |
387
+ | ------------- | ------ | ------------------------- |
388
+ | `size` | string | Recommended size label |
389
+ | `comfortable` | number | Comfort score (0–1) |
390
+ | `value?` | boolean| if is suitable |
443
391
 
444
- 💡 **Framework-Agnostic Tip:** Expose a singleton so every part of your app shares the same instance:
392
+ ### `ComplementaryPairDto`
445
393
 
446
394
  ```ts
447
- // sdk.ts
448
- import { createClient } from 'sizebay-core-sdk';
449
- import type { ClientType } from '@src/types';
450
-
451
- let _client: ClientType | null = null;
452
- export function getClient(): ClientType {
453
- if (!_client) {
454
- _client = createClient({ env: 'development' });
455
- }
456
- return _client;
395
+ interface ComplementaryPairDto {
396
+ first: ProductDto;
397
+ secondary?: ProductDto;
457
398
  }
458
-
459
- // anywhere in your app
460
- import { getClient } from './sdk';
461
- const client = getClient();
462
- await client.getSessionInfo();
463
- await client.sendProfile(profilePayload);
464
399
  ```
465
400
 
466
- ---
467
-
468
- 💡 **Extra:** If you ever need to bypass the internal cache, you can pass the `sid` manually:
401
+ ### `SessionProfilePayload`
402
+
403
+ | Field | Type | Required | Description |
404
+ | ---------------- | ----------------------------------------------------- | :------: | ------------------------ |
405
+ | `userId` | string | Yes | User’s unique ID |
406
+ | `name` | string | Yes | Profile name |
407
+ | `skinType` | number | Yes | Skin type category |
408
+ | `footShape` | string \| null | No | Optional foot shape |
409
+ | `gender` | string | Yes | `'M'` or `'F'` |
410
+ | `age` | string | Yes | Age as string |
411
+ | `is3dFeel` | boolean | Yes | 3D feel enabled |
412
+ | `weight` | string | Yes | Weight as string |
413
+ | `height` | string | Yes | Height as string |
414
+ | `measures` | `{ insoleLength: number; poundWeight: number\|null }` | Yes | Additional measurements |
415
+ | `product` | string \| null | No | Optional product context |
416
+ | `isMetric` | boolean | Yes | Metric system enabled |
417
+ | `bodyShapeChest` | number | Yes | Chest shape index |
418
+ | `bodyShapeWaist` | number | Yes | Waist shape index |
419
+ | `bodyShapeHip` | number | Yes | Hip shape index |
469
420
 
470
- ```ts
471
- await client.sendProfile(
472
- profilePayload,
473
- '028BC4AF5791a68fbbf8c48b4300a6a3319165552a9d',
474
- );
475
- ```
421
+ ---
@@ -1,5 +1,5 @@
1
1
  import { Config } from '../config';
2
- import { GetComplementaryProductsParams, GetComplementaryProductsResponse, GetRecommendedSizeByProductsParams, GetRecommendedSizeByProductsResponse, GetSimilarProductsParams, GetSimilarProductsResponse } from '../types/ai-image-service.types';
2
+ import { GetComplementaryByImageBodyDto, GetComplementaryProductsByImageResponse, GetComplementaryProductsParams, GetComplementaryProductsResponse, GetRecommendedSizeByProductsParams, GetRecommendedSizeByProductsResponse, GetSimilarByImageBodyDto, GetSimilarProductsParams, GetSimilarProductsResponse } from '../types/ai-image-service.types';
3
3
  export declare class AIImageService {
4
4
  private endpoint;
5
5
  constructor(config: Config);
@@ -7,4 +7,6 @@ export declare class AIImageService {
7
7
  getSimilarProducts(params: GetSimilarProductsParams): Promise<GetSimilarProductsResponse>;
8
8
  getRecommendedSizeByProducts(payload: GetRecommendedSizeByProductsParams): Promise<GetRecommendedSizeByProductsResponse[]>;
9
9
  getComplementaryProducts(params: GetComplementaryProductsParams): Promise<GetComplementaryProductsResponse>;
10
+ searchSimilarByImage(payload: GetSimilarByImageBodyDto): Promise<GetSimilarProductsResponse>;
11
+ searchComplementaryByImage(payload: GetComplementaryByImageBodyDto): Promise<GetComplementaryProductsByImageResponse>;
10
12
  }
@@ -1,4 +1,4 @@
1
- const c = {
1
+ const d = {
2
2
  tracker: {
3
3
  production: "https://data-event-service.internalsizebay.com",
4
4
  development: "https://data-event-service-dev.internalsizebay.com"
@@ -17,9 +17,9 @@ class l {
17
17
  constructor(t) {
18
18
  const e = t.env || "development";
19
19
  this.serviceOverrides = t.services || {}, this.endpoints = {};
20
- for (const s in c)
21
- if (Object.prototype.hasOwnProperty.call(c, s)) {
22
- const o = c[s][e];
20
+ for (const s in d)
21
+ if (Object.prototype.hasOwnProperty.call(d, s)) {
22
+ const o = d[s][e];
23
23
  if (!o)
24
24
  continue;
25
25
  this.endpoints[s] = o;
@@ -62,7 +62,7 @@ class u {
62
62
  }
63
63
  }
64
64
  }
65
- class a extends Error {
65
+ class c extends Error {
66
66
  constructor(t, e) {
67
67
  let s;
68
68
  try {
@@ -71,22 +71,22 @@ class a extends Error {
71
71
  } catch {
72
72
  s = e;
73
73
  }
74
- super(s), this.statusCode = t, this.details = e, Object.setPrototypeOf(this, a.prototype);
74
+ super(s), this.statusCode = t, this.details = e, Object.setPrototypeOf(this, c.prototype);
75
75
  }
76
76
  }
77
- async function d(r, t) {
77
+ async function a(r, t) {
78
78
  let e;
79
79
  try {
80
80
  e = await fetch(r, t);
81
81
  } catch (n) {
82
- throw new a(0, n.message);
82
+ throw new c(0, n.message);
83
83
  }
84
84
  const s = await e.text();
85
85
  if (!e.ok)
86
- throw new a(e.status, s);
86
+ throw new c(e.status, s);
87
87
  return JSON.parse(s);
88
88
  }
89
- class f {
89
+ class m {
90
90
  constructor(t) {
91
91
  this.endpoint = t.getEndpoint("aiImageService");
92
92
  }
@@ -118,7 +118,7 @@ class f {
118
118
  */
119
119
  getSimilarProducts(t) {
120
120
  const e = new URL(`${this.endpoint}/recommendations/similar`);
121
- return this.appendQueryParams(e, t), d(e.toString(), {
121
+ return this.appendQueryParams(e, t), a(e.toString(), {
122
122
  method: "GET",
123
123
  headers: { "Content-Type": "application/json" }
124
124
  });
@@ -139,7 +139,7 @@ class f {
139
139
  */
140
140
  getRecommendedSizeByProducts(t) {
141
141
  const e = `${this.endpoint}/recommendations/size-by-products`;
142
- return d(e, {
142
+ return a(e, {
143
143
  method: "POST",
144
144
  headers: { "Content-Type": "application/json" },
145
145
  body: JSON.stringify(t)
@@ -162,13 +162,29 @@ class f {
162
162
  */
163
163
  getComplementaryProducts(t) {
164
164
  const e = new URL(`${this.endpoint}/recommendations/complementary`);
165
- return this.appendQueryParams(e, t), d(e.toString(), {
165
+ return this.appendQueryParams(e, t), a(e.toString(), {
166
166
  method: "GET",
167
167
  headers: { "Content-Type": "application/json" }
168
168
  });
169
169
  }
170
+ searchSimilarByImage(t) {
171
+ const e = `${this.endpoint}/image-search/similar`;
172
+ return a(e, {
173
+ method: "POST",
174
+ headers: { "Content-Type": "application/json" },
175
+ body: JSON.stringify(t)
176
+ });
177
+ }
178
+ searchComplementaryByImage(t) {
179
+ const e = `${this.endpoint}/image-search/complementary`;
180
+ return a(e, {
181
+ method: "POST",
182
+ headers: { "Content-Type": "application/json" },
183
+ body: JSON.stringify(t)
184
+ });
185
+ }
170
186
  }
171
- class m {
187
+ class f {
172
188
  constructor(t) {
173
189
  this.sid = null, this.sessionId = null;
174
190
  const e = t.getEndpoint("session");
@@ -226,8 +242,8 @@ class m {
226
242
  }
227
243
  const y = [
228
244
  u,
229
- f,
230
- m
245
+ m,
246
+ f
231
247
  ];
232
248
  function g(r = {}) {
233
249
  const t = new l(r), e = y.map((n) => new n(t)), s = {};
@@ -242,6 +258,13 @@ function g(r = {}) {
242
258
  });
243
259
  }), s;
244
260
  }
261
+ const w = {
262
+ FULL_BODY: "fullbody",
263
+ BOTTOM: "bottom",
264
+ TOP: "top",
265
+ SHOE: "shoe"
266
+ };
245
267
  export {
268
+ w as ClothType,
246
269
  g as createClient
247
270
  };
@@ -1 +1 @@
1
- (function(c,r){typeof exports=="object"&&typeof module<"u"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):(c=typeof globalThis<"u"?globalThis:c||self,r(c["sizebay-core-sdk"]={}))})(this,function(c){"use strict";const r={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 u{constructor(e){const t=e.env||"development";this.serviceOverrides=e.services||{},this.endpoints={};for(const s in r)if(Object.prototype.hasOwnProperty.call(r,s)){const o=r[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 l{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 i=await o.text();throw new Error(`Request error: ${o.status} - ${i}`)}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(a,e){let t;try{t=await fetch(a,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 f{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"}})}getRecommendedSizeByProducts(e){const t=`${this.endpoint}/recommendations/size-by-products`;return p(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}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"}})}}class m{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 i=await o.text();throw new Error(`Failed to send profile: ${o.status} – ${i}`)}}}const y=[l,f,m];function g(a={}){const e=new u(a),t=y.map(n=>new n(e)),s={};return t.forEach(n=>{[...Object.getOwnPropertyNames(n),...Object.getOwnPropertyNames(Object.getPrototypeOf(n))].forEach(i=>{if(i==="constructor")return;const h=n[i];typeof h=="function"&&(s[i]||(s[i]=(...w)=>h.apply(n,w)))})}),s}c.createClient=g,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
1
+ (function(r,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(r=typeof globalThis<"u"?globalThis:r||self,a(r["sizebay-core-sdk"]={}))})(this,function(r){"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 n in a)if(Object.prototype.hasOwnProperty.call(a,n)){const o=a[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 i=await o.text();throw new Error(`Request error: ${o.status} - ${i}`)}return await o.json()}catch(o){throw o}}}class p 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,p.prototype)}}async function d(c,e){let t;try{t=await fetch(c,e)}catch(s){throw new p(0,s.message)}const n=await t.text();if(!t.ok)throw new p(t.status,n);return JSON.parse(n)}class f{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),d(t.toString(),{method:"GET",headers:{"Content-Type":"application/json"}})}getRecommendedSizeByProducts(e){const t=`${this.endpoint}/recommendations/size-by-products`;return d(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}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)})}}class m{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 i=await o.text();throw new Error(`Failed to send profile: ${o.status} – ${i}`)}}}const y=[u,f,m];function g(c={}){const e=new l(c),t=y.map(s=>new s(e)),n={};return t.forEach(s=>{[...Object.getOwnPropertyNames(s),...Object.getOwnPropertyNames(Object.getPrototypeOf(s))].forEach(i=>{if(i==="constructor")return;const h=s[i];typeof h=="function"&&(n[i]||(n[i]=(...O)=>h.apply(s,O)))})}),n}const w={FULL_BODY:"fullbody",BOTTOM:"bottom",TOP:"top",SHOE:"shoe"};r.ClothType=w,r.createClient=g,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
@@ -1,3 +1,4 @@
1
+ import { ClothType } from './clothType.type';
1
2
  export interface GetSimilarProductsParams {
2
3
  tenantId: number;
3
4
  collectionName: string;
@@ -8,6 +9,7 @@ export interface GetSimilarProductsParams {
8
9
  sizeSystem: string;
9
10
  filterByWhatFitsMe?: boolean;
10
11
  personaHash?: string;
12
+ similarityThreshold: number;
11
13
  }
12
14
  export interface GetComplementaryProductsParams {
13
15
  tenantId: string;
@@ -18,6 +20,7 @@ export interface GetComplementaryProductsParams {
18
20
  sizeSystem: string;
19
21
  filterByWhatFitsMe?: boolean;
20
22
  personaHash?: string;
23
+ similarityThreshold: number;
21
24
  }
22
25
  export interface GetRecommendedSizeByProductsParams {
23
26
  tenantId: number;
@@ -39,12 +42,14 @@ export interface ProductDto {
39
42
  itemGroupId: string;
40
43
  brand: string;
41
44
  color: string;
45
+ style: string;
46
+ category: string;
42
47
  gtin: string;
43
48
  additionalImageLinks: string[];
44
49
  suitableSizes?: Array<{
45
50
  size: string;
46
51
  comfortable: number;
47
- value?: number;
52
+ value?: boolean;
48
53
  }>;
49
54
  }
50
55
  export interface GetSimilarProductsResponse {
@@ -66,3 +71,42 @@ export interface GetComplementaryProductsResponse {
66
71
  baseProduct: ProductDto;
67
72
  complementary: ComplementaryPairDto[];
68
73
  }
74
+ export interface GetSimilarByImageBodyDto {
75
+ image: string;
76
+ tenantId: number;
77
+ collectionName: string;
78
+ sid: string;
79
+ sizeSystem: string;
80
+ filterByWhatFitsMe?: boolean;
81
+ personaHash?: string;
82
+ gender?: string;
83
+ style?: string;
84
+ color?: string;
85
+ category?: string;
86
+ page?: number;
87
+ perPage?: number;
88
+ similarityThreshold?: number;
89
+ }
90
+ export interface GetComplementaryByImageBodyDto {
91
+ image: string;
92
+ tenantId: number;
93
+ collectionName: string;
94
+ sid: string;
95
+ sizeSystem: string;
96
+ clothType: ClothType;
97
+ filterByWhatFitsMe?: boolean;
98
+ personaHash?: string;
99
+ gender?: string;
100
+ style?: string;
101
+ color?: string;
102
+ page?: number;
103
+ perPage?: number;
104
+ similarityThreshold: number;
105
+ }
106
+ export interface GetComplementaryProductsByImageResponse {
107
+ baseProduct: ProductDto;
108
+ complementary: ProductDto[];
109
+ page: number;
110
+ perPage: number;
111
+ total: number;
112
+ }
@@ -0,0 +1,7 @@
1
+ export declare const ClothType: {
2
+ FULL_BODY: string;
3
+ BOTTOM: string;
4
+ TOP: string;
5
+ SHOE: string;
6
+ };
7
+ export type ClothType = (typeof ClothType)[keyof typeof ClothType];
@@ -1,4 +1,5 @@
1
1
  export * from './sdk.types';
2
2
  export * from './event.types';
3
3
  export * from './client.types';
4
+ export * from './clothType.type';
4
5
  export * from './ai-image-service.types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sizebay-core-sdk",
3
- "version": "1.4.1",
3
+ "version": "1.6.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",