@commercengine/storefront-sdk 0.14.4 → 0.15.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/dist/index.mjs CHANGED
@@ -450,9 +450,8 @@ let Environment = /* @__PURE__ */ function(Environment) {
450
450
  */
451
451
  function buildStorefrontURL(config) {
452
452
  if (config.baseUrl) return config.baseUrl;
453
- switch (config.environment || Environment.Production) {
454
- case Environment.Staging: return `https://staging.api.commercengine.io/api/v1/${config.storeId}/storefront`;
455
- case Environment.Production:
453
+ switch (config.environment || "production") {
454
+ case "staging": return `https://staging.api.commercengine.io/api/v1/${config.storeId}/storefront`;
456
455
  default: return `https://prod.api.commercengine.io/api/v1/${config.storeId}/storefront`;
457
456
  }
458
457
  }
@@ -612,6 +611,17 @@ var SessionStorefrontAPIClient = class extends StorefrontAPIClientBase {
612
611
  };
613
612
  }
614
613
  /**
614
+ * Resolve the current customer ID from explicit parameters or the active session.
615
+ *
616
+ * @param explicitCustomerId - Optional customer ID supplied by the caller
617
+ * @returns The resolved customer ID
618
+ * @throws When the user is anonymous or no session can be established
619
+ */
620
+ async resolveCurrentCustomerId(explicitCustomerId) {
621
+ if (explicitCustomerId) return explicitCustomerId;
622
+ return this.config.sessionManager.ensureCustomerId();
623
+ }
624
+ /**
615
625
  * Resolve path parameters that require `customer_id`.
616
626
  *
617
627
  * @param pathParams - Path parameters with an optional `customer_id`
@@ -621,7 +631,7 @@ var SessionStorefrontAPIClient = class extends StorefrontAPIClientBase {
621
631
  async resolveCustomerPathParams(pathParams) {
622
632
  return {
623
633
  ...pathParams,
624
- customer_id: pathParams.customer_id ?? await this.config.sessionManager.ensureCustomerId()
634
+ customer_id: await this.resolveCurrentCustomerId(pathParams.customer_id)
625
635
  };
626
636
  }
627
637
  };
@@ -1233,6 +1243,35 @@ var PublicCatalogClient = class extends BaseCatalogClient {
1233
1243
  }
1234
1244
  };
1235
1245
  //#endregion
1246
+ //#region src/lib/shared/form-data-utils.ts
1247
+ /**
1248
+ * Multipart form-data helpers for the Storefront SDK
1249
+ */
1250
+ /**
1251
+ * Serialize a request body object into a `FormData` instance.
1252
+ *
1253
+ * Binary fields are generated as `string` (OpenAPI `format: binary`), so callers pass
1254
+ * `File`/`Blob` values. Array fields are appended once per entry under the same key,
1255
+ * which is what the API expects for repeated uploads such as `images` and `videos`.
1256
+ * Everything else is coerced with `String()`.
1257
+ *
1258
+ * @param body - Request body object to serialize
1259
+ * @returns A `FormData` instance ready to be sent as `multipart/form-data`
1260
+ */
1261
+ function toFormData(body) {
1262
+ const formData = new FormData();
1263
+ if (body === void 0 || body === null) return formData;
1264
+ for (const [key, value] of Object.entries(body)) {
1265
+ if (value === void 0 || value === null) continue;
1266
+ const entries = Array.isArray(value) ? value : [value];
1267
+ for (const entry of entries) {
1268
+ if (entry === void 0 || entry === null) continue;
1269
+ formData.append(key, entry instanceof Blob ? entry : String(entry));
1270
+ }
1271
+ }
1272
+ return formData;
1273
+ }
1274
+ //#endregion
1236
1275
  //#region src/lib/catalog.ts
1237
1276
  /**
1238
1277
  * Client for interacting with catalog endpoints
@@ -1277,12 +1316,7 @@ var CatalogClient = class extends BaseCatalogClient {
1277
1316
  return this.executeRequest(() => this.client.POST("/catalog/products/{product_id}/reviews", {
1278
1317
  params: { path: pathParams },
1279
1318
  body: formData,
1280
- bodySerializer: (body) => {
1281
- const fd = new FormData();
1282
- for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) if (value instanceof File || value instanceof Blob) fd.append(key, value);
1283
- else fd.append(key, String(value));
1284
- return fd;
1285
- }
1319
+ bodySerializer: (body) => toFormData(body)
1286
1320
  }));
1287
1321
  }
1288
1322
  };
@@ -2464,11 +2498,7 @@ var AuthClient = class extends SessionStorefrontAPIClient {
2464
2498
  return this.executeRequest(() => this.client.POST("/auth/user/{id}/profile-image", {
2465
2499
  params: { path: pathParams },
2466
2500
  body: formData,
2467
- bodySerializer: (body) => {
2468
- const fd = new FormData();
2469
- for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) fd.append(key, value);
2470
- return fd;
2471
- }
2501
+ bodySerializer: (body) => toFormData(body)
2472
2502
  }));
2473
2503
  }
2474
2504
  /**
@@ -2498,11 +2528,7 @@ var AuthClient = class extends SessionStorefrontAPIClient {
2498
2528
  return this.executeRequest(() => this.client.PUT("/auth/user/{id}/profile-image", {
2499
2529
  params: { path: pathParams },
2500
2530
  body: formData,
2501
- bodySerializer: (body) => {
2502
- const fd = new FormData();
2503
- for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) fd.append(key, value);
2504
- return fd;
2505
- }
2531
+ bodySerializer: (body) => toFormData(body)
2506
2532
  }));
2507
2533
  }
2508
2534
  /**
@@ -2768,6 +2794,44 @@ var OrderClient = class extends SessionStorefrontAPIClient {
2768
2794
  return this.executeRequest(() => this.client.GET("/orders", { params: { query: resolvedQueryParams } }));
2769
2795
  }
2770
2796
  /**
2797
+ * List previously purchased items for the authenticated user
2798
+ *
2799
+ * @description Lists items previously purchased across paid orders (orders with a `payment_status`
2800
+ * of `pending` or `failed` are excluded). Results are deduplicated by `product_id`, returning the
2801
+ * most recent purchase for each product. Use this to power a "Buy it again" carousel.
2802
+ *
2803
+ * @param queryParams - Optional query parameters for pagination and seller filtering
2804
+ * @returns Promise with previously purchased items
2805
+ * @example
2806
+ * ```typescript
2807
+ * // Basic usage
2808
+ * const { data, error } = await sdk.order.listBuyItAgainItems();
2809
+ *
2810
+ * // With pagination and marketplace seller filtering
2811
+ * const { data, error } = await sdk.order.listBuyItAgainItems({
2812
+ * page: 1,
2813
+ * limit: 20,
2814
+ * seller_id: "seller_a,seller_b"
2815
+ * });
2816
+ *
2817
+ * if (error) {
2818
+ * console.error("Failed to list buy-it-again items:", error.message);
2819
+ * } else {
2820
+ * console.log("Items found:", data.items.length);
2821
+ * console.log("Pagination:", data.pagination);
2822
+ *
2823
+ * data.items.forEach(item => {
2824
+ * console.log(`${item.product_name} (${item.product_id})`);
2825
+ * console.log("Variant:", item.variant_name);
2826
+ * console.log("Selling price:", item.selling_price);
2827
+ * });
2828
+ * }
2829
+ * ```
2830
+ */
2831
+ async listBuyItAgainItems(queryParams) {
2832
+ return this.executeRequest(() => this.client.GET("/orders/buy-it-again", { params: { query: queryParams } }));
2833
+ }
2834
+ /**
2771
2835
  * Get payment status for an order
2772
2836
  *
2773
2837
  * @param orderNumber - Order number
@@ -2989,6 +3053,184 @@ var OrderClient = class extends SessionStorefrontAPIClient {
2989
3053
  body
2990
3054
  }));
2991
3055
  }
3056
+ /**
3057
+ * List all return requests for an order
3058
+ *
3059
+ * @param pathParams - Order number path parameters
3060
+ * @returns Promise with return requests
3061
+ * @example
3062
+ * ```typescript
3063
+ * const { data, error } = await sdk.order.listOrderReturns({
3064
+ * order_number: "ORD-2024-001"
3065
+ * });
3066
+ *
3067
+ * if (error) {
3068
+ * console.error("Failed to list order returns:", error.message);
3069
+ * } else {
3070
+ * console.log("Returns found:", data.returns?.length || 0);
3071
+ *
3072
+ * data.returns?.forEach(orderReturn => {
3073
+ * console.log(`Return ${orderReturn.request_number}: ${orderReturn.status}`);
3074
+ * console.log("Created at:", orderReturn.created_at);
3075
+ * console.log("Items:", orderReturn.items?.length || 0);
3076
+ * });
3077
+ * }
3078
+ * ```
3079
+ */
3080
+ async listOrderReturns(pathParams) {
3081
+ return this.executeRequest(() => this.client.GET("/orders/{order_number}/returns", { params: { path: pathParams } }));
3082
+ }
3083
+ /**
3084
+ * Create a return request for delivered items in an order
3085
+ *
3086
+ * @description Specify how the return should be settled via `requested_settlement` and list the
3087
+ * delivered line items to return. Each item is keyed by its shipment (`shipment_number`) and
3088
+ * product. Only shipments with `is_return_allowed` set to `true` can be returned.
3089
+ *
3090
+ * @param pathParams - Order number path parameters
3091
+ * @param body - Return request body
3092
+ * @returns Promise with the created return request
3093
+ * @example
3094
+ * ```typescript
3095
+ * const { data, error } = await sdk.order.createOrderReturn(
3096
+ * { order_number: "ORD-2024-001" },
3097
+ * {
3098
+ * requested_settlement: "refund",
3099
+ * items: [
3100
+ * {
3101
+ * shipment_number: "SHIP-2024-001",
3102
+ * product_id: "prod_01H9XYZ12345",
3103
+ * variant_id: "var_01H9XYZ12345",
3104
+ * quantity: 1,
3105
+ * return_reason: "Product arrived damaged"
3106
+ * }
3107
+ * ]
3108
+ * }
3109
+ * );
3110
+ *
3111
+ * // Request a replacement instead of a refund
3112
+ * const { data: replacement } = await sdk.order.createOrderReturn(
3113
+ * { order_number: "ORD-2024-001" },
3114
+ * {
3115
+ * requested_settlement: "replacement",
3116
+ * items: [
3117
+ * {
3118
+ * shipment_number: "SHIP-2024-001",
3119
+ * product_id: "prod_01H9XYZ12345",
3120
+ * variant_id: null,
3121
+ * quantity: 2,
3122
+ * return_reason: "Wrong size delivered"
3123
+ * }
3124
+ * ]
3125
+ * }
3126
+ * );
3127
+ *
3128
+ * if (error) {
3129
+ * console.error("Failed to create return:", error.message);
3130
+ * } else {
3131
+ * console.log("Return created:", data.order_return?.request_number);
3132
+ * console.log("Return status:", data.order_return?.status);
3133
+ * }
3134
+ * ```
3135
+ */
3136
+ async createOrderReturn(pathParams, body) {
3137
+ return this.executeRequest(() => this.client.POST("/orders/{order_number}/returns", {
3138
+ params: { path: pathParams },
3139
+ body
3140
+ }));
3141
+ }
3142
+ /**
3143
+ * Get the full detail of a return request
3144
+ *
3145
+ * @description Returns the return request along with its linked return order, replacement order,
3146
+ * refunds, and signed URLs for any uploaded attachments.
3147
+ *
3148
+ * @param pathParams - Order number and return number path parameters
3149
+ * @returns Promise with return request details
3150
+ * @example
3151
+ * ```typescript
3152
+ * const { data, error } = await sdk.order.getOrderReturnDetails({
3153
+ * order_number: "ORD-2024-001",
3154
+ * return_number: "RET-2024-001"
3155
+ * });
3156
+ *
3157
+ * if (error) {
3158
+ * console.error("Failed to get return details:", error.message);
3159
+ * } else {
3160
+ * const orderReturn = data.order_return;
3161
+ * console.log("Return status:", orderReturn?.status);
3162
+ * console.log("Return order:", orderReturn?.return_order?.order_number);
3163
+ * console.log("Replacement order:", orderReturn?.replacement_order?.order_number);
3164
+ * console.log("Refunds:", orderReturn?.refund?.length || 0);
3165
+ * console.log("Attachment images:", orderReturn?.attachments?.images);
3166
+ * }
3167
+ * ```
3168
+ */
3169
+ async getOrderReturnDetails(pathParams) {
3170
+ return this.executeRequest(() => this.client.GET("/orders/{order_number}/returns/{return_number}", { params: { path: pathParams } }));
3171
+ }
3172
+ /**
3173
+ * Upload supporting attachments for a return request
3174
+ *
3175
+ * @description Uploads images and videos that evidence the condition of the returned items.
3176
+ *
3177
+ * @param pathParams - Order number and return number path parameters
3178
+ * @param formData - Form data containing image and video files
3179
+ * @returns Promise with upload confirmation
3180
+ * @example
3181
+ * ```typescript
3182
+ * const imageFiles = Array.from(document.getElementById('image-input').files);
3183
+ *
3184
+ * const { data, error } = await sdk.order.uploadOrderReturnAttachments(
3185
+ * { order_number: "ORD-2024-001", return_number: "RET-2024-001" },
3186
+ * {
3187
+ * images: imageFiles,
3188
+ * videos: [new File(["video data"], "damage.mp4", { type: "video/mp4" })]
3189
+ * }
3190
+ * );
3191
+ *
3192
+ * if (error) {
3193
+ * console.error("Failed to upload attachments:", error.message);
3194
+ * } else {
3195
+ * console.log("Attachments uploaded:", data.success);
3196
+ * console.log("Message:", data.message);
3197
+ * }
3198
+ * ```
3199
+ */
3200
+ async uploadOrderReturnAttachments(pathParams, formData) {
3201
+ return this.executeRequest(() => this.client.POST("/orders/{order_number}/returns/{return_number}/attachments", {
3202
+ params: { path: pathParams },
3203
+ body: formData,
3204
+ bodySerializer: (body) => toFormData(body)
3205
+ }));
3206
+ }
3207
+ /**
3208
+ * Cancel a return request
3209
+ *
3210
+ * @param pathParams - Order number and return number path parameters
3211
+ * @param body - Cancellation request body
3212
+ * @returns Promise with the updated return request
3213
+ * @example
3214
+ * ```typescript
3215
+ * const { data, error } = await sdk.order.cancelOrderReturn(
3216
+ * { order_number: "ORD-2024-001", return_number: "RET-2024-001" },
3217
+ * { reason: "Decided to keep the product" }
3218
+ * );
3219
+ *
3220
+ * if (error) {
3221
+ * console.error("Failed to cancel return:", error.message);
3222
+ * } else {
3223
+ * console.log("Return cancelled");
3224
+ * console.log("Updated status:", data.order_return?.status);
3225
+ * }
3226
+ * ```
3227
+ */
3228
+ async cancelOrderReturn(pathParams, body) {
3229
+ return this.executeRequest(() => this.client.POST("/orders/{order_number}/returns/{return_number}/cancel", {
3230
+ params: { path: pathParams },
3231
+ body
3232
+ }));
3233
+ }
2992
3234
  };
2993
3235
  //#endregion
2994
3236
  //#region src/lib/payments.ts
@@ -3135,6 +3377,33 @@ var PaymentsClient = class extends SessionStorefrontAPIClient {
3135
3377
  async resendDirectOtp(body) {
3136
3378
  return this.executeRequest(() => this.client.POST("/payments/resend-direct-otp", { body }));
3137
3379
  }
3380
+ /**
3381
+ * Verify an IFSC code and resolve its bank branch details
3382
+ *
3383
+ * @description Resolves an 11-character Indian Financial System Code (IFSC) to bank,
3384
+ * branch, and supported payment rail details. Useful for validating user-entered IFSC
3385
+ * codes before creating bank accounts or mandates.
3386
+ *
3387
+ * @param pathParams - Path parameters containing the IFSC code
3388
+ * @returns Promise with IFSC details
3389
+ * @example
3390
+ * ```typescript
3391
+ * const { data, error } = await sdk.payments.verifyIfscCode({
3392
+ * ifsc_code: "HDFC0001234"
3393
+ * });
3394
+ *
3395
+ * if (error) {
3396
+ * console.error("Failed to verify IFSC:", error.message);
3397
+ * } else {
3398
+ * console.log("Bank:", data.ifsc.bank);
3399
+ * console.log("Branch:", data.ifsc.branch);
3400
+ * console.log("Supports UPI:", data.ifsc.upi);
3401
+ * }
3402
+ * ```
3403
+ */
3404
+ async verifyIfscCode(pathParams) {
3405
+ return this.executeRequest(() => this.client.GET("/payments/ifsc-lookup/{ifsc_code}", { params: { path: pathParams } }));
3406
+ }
3138
3407
  };
3139
3408
  //#endregion
3140
3409
  //#region src/lib/shared/helper.ts
@@ -3340,6 +3609,110 @@ var CustomerClient = class extends SessionStorefrontAPIClient {
3340
3609
  const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3341
3610
  return this.executeRequest(() => this.client.GET("/customers/{customer_id}/cards", { params: { path: resolvedPathParams } }));
3342
3611
  }
3612
+ async listBankAccounts(pathParamsOrQuery, queryParams) {
3613
+ const hasPathParams = queryParams !== void 0 || !!pathParamsOrQuery && typeof pathParamsOrQuery === "object" && "customer_id" in pathParamsOrQuery;
3614
+ const pathParams = hasPathParams ? pathParamsOrQuery : {};
3615
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3616
+ const resolvedQueryParams = hasPathParams ? queryParams : pathParamsOrQuery;
3617
+ return this.executeRequest(() => this.client.GET("/customers/{customer_id}/bank-accounts", { params: {
3618
+ path: resolvedPathParams,
3619
+ query: resolvedQueryParams
3620
+ } }));
3621
+ }
3622
+ async createBankAccount(pathParamsOrBody, maybeBody) {
3623
+ const pathParams = maybeBody ? pathParamsOrBody : {};
3624
+ const body = maybeBody ?? pathParamsOrBody;
3625
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3626
+ return this.executeRequest(() => this.client.POST("/customers/{customer_id}/bank-accounts", {
3627
+ params: { path: resolvedPathParams },
3628
+ body
3629
+ }));
3630
+ }
3631
+ async getBankAccount(pathParams) {
3632
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3633
+ return this.executeRequest(() => this.client.GET("/customers/{customer_id}/bank-accounts/{account_id}", { params: { path: resolvedPathParams } }));
3634
+ }
3635
+ async updateBankAccount(pathParams, body) {
3636
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3637
+ return this.executeRequest(() => this.client.PUT("/customers/{customer_id}/bank-accounts/{account_id}", {
3638
+ params: { path: resolvedPathParams },
3639
+ body
3640
+ }));
3641
+ }
3642
+ async deleteBankAccount(pathParams) {
3643
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3644
+ return this.executeRequest(() => this.client.DELETE("/customers/{customer_id}/bank-accounts/{account_id}", { params: { path: resolvedPathParams } }));
3645
+ }
3646
+ async verifyBankAccount(pathParams, body) {
3647
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3648
+ return this.executeRequest(() => this.client.POST("/customers/{customer_id}/bank-accounts/{account_id}/verify", {
3649
+ params: { path: resolvedPathParams },
3650
+ body
3651
+ }));
3652
+ }
3653
+ async getCreditLineBalance(pathParams = {}) {
3654
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3655
+ return this.executeRequest(() => this.client.GET("/customers/{customer_id}/credit-line-balance", { params: { path: resolvedPathParams } }));
3656
+ }
3657
+ async listMandates(pathParams = {}) {
3658
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3659
+ return this.executeRequest(() => this.client.GET("/customers/{customer_id}/mandates", { params: { path: resolvedPathParams } }));
3660
+ }
3661
+ async createMandate(pathParamsOrBody, maybeBody) {
3662
+ const pathParams = maybeBody ? pathParamsOrBody : {};
3663
+ const body = maybeBody ?? pathParamsOrBody;
3664
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3665
+ return this.executeRequest(() => this.client.POST("/customers/{customer_id}/mandates", {
3666
+ params: { path: resolvedPathParams },
3667
+ body
3668
+ }));
3669
+ }
3670
+ async getMandate(pathParams, queryParams) {
3671
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3672
+ return this.executeRequest(() => this.client.GET("/customers/{customer_id}/mandates/{mandate_id}", { params: {
3673
+ path: resolvedPathParams,
3674
+ query: queryParams
3675
+ } }));
3676
+ }
3677
+ async updateMandate(pathParams, body) {
3678
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3679
+ return this.executeRequest(() => this.client.PUT("/customers/{customer_id}/mandates/{mandate_id}", {
3680
+ params: { path: resolvedPathParams },
3681
+ body
3682
+ }));
3683
+ }
3684
+ async pauseMandate(pathParams) {
3685
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3686
+ return this.executeRequest(() => this.client.POST("/customers/{customer_id}/mandates/{mandate_id}/pause", { params: { path: resolvedPathParams } }));
3687
+ }
3688
+ async resumeMandate(pathParams) {
3689
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3690
+ return this.executeRequest(() => this.client.POST("/customers/{customer_id}/mandates/{mandate_id}/resume", { params: { path: resolvedPathParams } }));
3691
+ }
3692
+ async revokeMandate(pathParams) {
3693
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3694
+ return this.executeRequest(() => this.client.POST("/customers/{customer_id}/mandates/{mandate_id}/revoke", { params: { path: resolvedPathParams } }));
3695
+ }
3696
+ async listMandateDebitSchedules(pathParamsOrQuery, queryParams) {
3697
+ const hasPathParams = queryParams !== void 0 || !!pathParamsOrQuery && typeof pathParamsOrQuery === "object" && "customer_id" in pathParamsOrQuery;
3698
+ const pathParams = hasPathParams ? pathParamsOrQuery : {};
3699
+ const resolvedPathParams = await this.resolveCustomerPathParams(pathParams);
3700
+ const resolvedQueryParams = hasPathParams ? queryParams : pathParamsOrQuery;
3701
+ return this.executeRequest(() => this.client.GET("/customers/{customer_id}/mandate-debit-schedules", { params: {
3702
+ path: resolvedPathParams,
3703
+ query: resolvedQueryParams
3704
+ } }));
3705
+ }
3706
+ async listAuthorizedSellers(pathParamsOrQuery, queryParams) {
3707
+ const hasPathParams = queryParams !== void 0 || !!pathParamsOrQuery && typeof pathParamsOrQuery === "object" && "id" in pathParamsOrQuery;
3708
+ const pathParams = hasPathParams ? pathParamsOrQuery : {};
3709
+ const resolvedPathParams = { id: await this.resolveCurrentCustomerId(pathParams.id) };
3710
+ const resolvedQueryParams = hasPathParams ? queryParams : pathParamsOrQuery;
3711
+ return this.executeRequest(() => this.client.GET("/customers/{id}/authorized-sellers", { params: {
3712
+ path: resolvedPathParams,
3713
+ query: resolvedQueryParams
3714
+ } }));
3715
+ }
3343
3716
  };
3344
3717
  //#endregion
3345
3718
  //#region src/lib/shared/store-config.ts