@commercengine/storefront-sdk 0.14.5 → 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
@@ -611,6 +611,17 @@ var SessionStorefrontAPIClient = class extends StorefrontAPIClientBase {
611
611
  };
612
612
  }
613
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
+ /**
614
625
  * Resolve path parameters that require `customer_id`.
615
626
  *
616
627
  * @param pathParams - Path parameters with an optional `customer_id`
@@ -620,7 +631,7 @@ var SessionStorefrontAPIClient = class extends StorefrontAPIClientBase {
620
631
  async resolveCustomerPathParams(pathParams) {
621
632
  return {
622
633
  ...pathParams,
623
- customer_id: pathParams.customer_id ?? await this.config.sessionManager.ensureCustomerId()
634
+ customer_id: await this.resolveCurrentCustomerId(pathParams.customer_id)
624
635
  };
625
636
  }
626
637
  };
@@ -1232,6 +1243,35 @@ var PublicCatalogClient = class extends BaseCatalogClient {
1232
1243
  }
1233
1244
  };
1234
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
1235
1275
  //#region src/lib/catalog.ts
1236
1276
  /**
1237
1277
  * Client for interacting with catalog endpoints
@@ -1276,12 +1316,7 @@ var CatalogClient = class extends BaseCatalogClient {
1276
1316
  return this.executeRequest(() => this.client.POST("/catalog/products/{product_id}/reviews", {
1277
1317
  params: { path: pathParams },
1278
1318
  body: formData,
1279
- bodySerializer: (body) => {
1280
- const fd = new FormData();
1281
- 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);
1282
- else fd.append(key, String(value));
1283
- return fd;
1284
- }
1319
+ bodySerializer: (body) => toFormData(body)
1285
1320
  }));
1286
1321
  }
1287
1322
  };
@@ -2463,11 +2498,7 @@ var AuthClient = class extends SessionStorefrontAPIClient {
2463
2498
  return this.executeRequest(() => this.client.POST("/auth/user/{id}/profile-image", {
2464
2499
  params: { path: pathParams },
2465
2500
  body: formData,
2466
- bodySerializer: (body) => {
2467
- const fd = new FormData();
2468
- for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) fd.append(key, value);
2469
- return fd;
2470
- }
2501
+ bodySerializer: (body) => toFormData(body)
2471
2502
  }));
2472
2503
  }
2473
2504
  /**
@@ -2497,11 +2528,7 @@ var AuthClient = class extends SessionStorefrontAPIClient {
2497
2528
  return this.executeRequest(() => this.client.PUT("/auth/user/{id}/profile-image", {
2498
2529
  params: { path: pathParams },
2499
2530
  body: formData,
2500
- bodySerializer: (body) => {
2501
- const fd = new FormData();
2502
- for (const [key, value] of Object.entries(body)) if (value !== void 0 && value !== null) fd.append(key, value);
2503
- return fd;
2504
- }
2531
+ bodySerializer: (body) => toFormData(body)
2505
2532
  }));
2506
2533
  }
2507
2534
  /**
@@ -2767,6 +2794,44 @@ var OrderClient = class extends SessionStorefrontAPIClient {
2767
2794
  return this.executeRequest(() => this.client.GET("/orders", { params: { query: resolvedQueryParams } }));
2768
2795
  }
2769
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
+ /**
2770
2835
  * Get payment status for an order
2771
2836
  *
2772
2837
  * @param orderNumber - Order number
@@ -2988,6 +3053,184 @@ var OrderClient = class extends SessionStorefrontAPIClient {
2988
3053
  body
2989
3054
  }));
2990
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
+ }
2991
3234
  };
2992
3235
  //#endregion
2993
3236
  //#region src/lib/payments.ts
@@ -3460,6 +3703,16 @@ var CustomerClient = class extends SessionStorefrontAPIClient {
3460
3703
  query: resolvedQueryParams
3461
3704
  } }));
3462
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
+ }
3463
3716
  };
3464
3717
  //#endregion
3465
3718
  //#region src/lib/shared/store-config.ts