perspectapi-ts-sdk 2.2.1 → 2.3.3

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
@@ -537,7 +537,29 @@ const session = await client.checkout.createCheckoutSession({
537
537
  priceId: 'price_1234567890',
538
538
  successUrl: 'https://myapp.com/success',
539
539
  cancelUrl: 'https://myapp.com/cancel',
540
- customerEmail: 'customer@example.com'
540
+ customerEmail: 'customer@example.com',
541
+ currency: 'usd',
542
+ shipping_amount: 500,
543
+ shipping_address: {
544
+ country: 'US',
545
+ state: 'CA',
546
+ postal_code: '94110'
547
+ },
548
+ billing_address: {
549
+ country: 'US',
550
+ state: 'CA',
551
+ postal_code: '94110'
552
+ },
553
+ tax: {
554
+ strategy: 'manual_rates',
555
+ customer_identifier: 'acct-123',
556
+ customer_display_name: 'Acme Corp',
557
+ customer_exemption: {
558
+ status: 'exempt',
559
+ tax_id: '99-1234567',
560
+ tax_id_type: 'ein'
561
+ }
562
+ }
541
563
  });
542
564
 
543
565
  // Redirect user to checkout
@@ -545,6 +567,7 @@ window.location.href = session.data.url;
545
567
 
546
568
  // Get checkout session status
547
569
  const sessionStatus = await client.checkout.getCheckoutSession('cs_test_123');
570
+ console.log(sessionStatus.data.tax?.amount); // Display assessed tax (if calculated)
548
571
  ```
549
572
 
550
573
  ### Contact Forms
package/dist/index.d.mts CHANGED
@@ -426,6 +426,14 @@ type CheckoutMetadataValue = string | number | boolean | null | CheckoutMetadata
426
426
  type CheckoutMetadata = Record<string, CheckoutMetadataValue>;
427
427
  type CheckoutTaxStrategy = 'disabled' | 'gateway_auto' | 'manual_rates' | 'external_service';
428
428
  type CheckoutTaxExemptionStatus = 'none' | 'exempt' | 'reverse_charge';
429
+ interface CheckoutAddress {
430
+ line1?: string;
431
+ line2?: string;
432
+ city?: string;
433
+ state?: string;
434
+ postal_code?: string;
435
+ country?: string;
436
+ }
429
437
  interface CheckoutTaxCustomerExemptionRequest {
430
438
  status?: CheckoutTaxExemptionStatus;
431
439
  reason?: string;
@@ -474,6 +482,7 @@ interface CreateCheckoutSessionRequest {
474
482
  cancelUrl?: string;
475
483
  customer_email?: string;
476
484
  customerEmail?: string;
485
+ currency?: string;
477
486
  metadata?: CheckoutMetadata;
478
487
  mode?: 'payment' | 'subscription' | 'setup';
479
488
  automatic_tax?: {
@@ -483,12 +492,35 @@ interface CreateCheckoutSessionRequest {
483
492
  allowed_countries: string[];
484
493
  };
485
494
  billing_address_collection?: 'auto' | 'required';
495
+ shipping_amount?: number;
496
+ shippingAmount?: number;
497
+ shipping_address?: CheckoutAddress;
498
+ shippingAddress?: CheckoutAddress;
499
+ billing_address?: CheckoutAddress;
500
+ billingAddress?: CheckoutAddress;
486
501
  tax?: CheckoutTaxRequest;
487
502
  }
503
+ interface CheckoutTaxBreakdownItem {
504
+ jurisdiction: string;
505
+ rate_percent: number;
506
+ tax_amount: number;
507
+ taxable_amount: number;
508
+ source: 'manual_map' | 'manual_percent' | 'gateway' | 'external';
509
+ }
510
+ interface CheckoutSessionTax {
511
+ amount: number;
512
+ currency: string;
513
+ strategy: CheckoutTaxStrategy;
514
+ exemption_applied: boolean;
515
+ exemption_status: CheckoutTaxExemptionStatus;
516
+ breakdown?: CheckoutTaxBreakdownItem[] | null;
517
+ }
488
518
  interface CheckoutSession {
489
519
  id: string;
490
520
  url: string;
491
521
  status: string;
522
+ payment_status?: string;
523
+ tax?: CheckoutSessionTax | null;
492
524
  }
493
525
  interface ContactSubmission {
494
526
  id: string;
@@ -2347,6 +2379,22 @@ interface CheckoutSessionOptions {
2347
2379
  logger?: LoaderLogger;
2348
2380
  fallbackProducts?: Product[];
2349
2381
  metadata?: CheckoutMetadata;
2382
+ /**
2383
+ * Optional currency override; defaults to the currency defined on each Stripe price.
2384
+ */
2385
+ currency?: string;
2386
+ /**
2387
+ * Optional shipping amount (in the smallest currency unit).
2388
+ */
2389
+ shippingAmount?: number;
2390
+ /**
2391
+ * Shipping address forwarded to the checkout API for tax estimation.
2392
+ */
2393
+ shippingAddress?: CheckoutAddress;
2394
+ /**
2395
+ * Billing address forwarded to the checkout API for tax estimation.
2396
+ */
2397
+ billingAddress?: CheckoutAddress;
2350
2398
  /**
2351
2399
  * Optional resolver to convert a product record into a Stripe price ID.
2352
2400
  */
@@ -2364,4 +2412,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
2364
2412
  error: string;
2365
2413
  }>;
2366
2414
 
2367
- export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
2415
+ export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
package/dist/index.d.ts CHANGED
@@ -426,6 +426,14 @@ type CheckoutMetadataValue = string | number | boolean | null | CheckoutMetadata
426
426
  type CheckoutMetadata = Record<string, CheckoutMetadataValue>;
427
427
  type CheckoutTaxStrategy = 'disabled' | 'gateway_auto' | 'manual_rates' | 'external_service';
428
428
  type CheckoutTaxExemptionStatus = 'none' | 'exempt' | 'reverse_charge';
429
+ interface CheckoutAddress {
430
+ line1?: string;
431
+ line2?: string;
432
+ city?: string;
433
+ state?: string;
434
+ postal_code?: string;
435
+ country?: string;
436
+ }
429
437
  interface CheckoutTaxCustomerExemptionRequest {
430
438
  status?: CheckoutTaxExemptionStatus;
431
439
  reason?: string;
@@ -474,6 +482,7 @@ interface CreateCheckoutSessionRequest {
474
482
  cancelUrl?: string;
475
483
  customer_email?: string;
476
484
  customerEmail?: string;
485
+ currency?: string;
477
486
  metadata?: CheckoutMetadata;
478
487
  mode?: 'payment' | 'subscription' | 'setup';
479
488
  automatic_tax?: {
@@ -483,12 +492,35 @@ interface CreateCheckoutSessionRequest {
483
492
  allowed_countries: string[];
484
493
  };
485
494
  billing_address_collection?: 'auto' | 'required';
495
+ shipping_amount?: number;
496
+ shippingAmount?: number;
497
+ shipping_address?: CheckoutAddress;
498
+ shippingAddress?: CheckoutAddress;
499
+ billing_address?: CheckoutAddress;
500
+ billingAddress?: CheckoutAddress;
486
501
  tax?: CheckoutTaxRequest;
487
502
  }
503
+ interface CheckoutTaxBreakdownItem {
504
+ jurisdiction: string;
505
+ rate_percent: number;
506
+ tax_amount: number;
507
+ taxable_amount: number;
508
+ source: 'manual_map' | 'manual_percent' | 'gateway' | 'external';
509
+ }
510
+ interface CheckoutSessionTax {
511
+ amount: number;
512
+ currency: string;
513
+ strategy: CheckoutTaxStrategy;
514
+ exemption_applied: boolean;
515
+ exemption_status: CheckoutTaxExemptionStatus;
516
+ breakdown?: CheckoutTaxBreakdownItem[] | null;
517
+ }
488
518
  interface CheckoutSession {
489
519
  id: string;
490
520
  url: string;
491
521
  status: string;
522
+ payment_status?: string;
523
+ tax?: CheckoutSessionTax | null;
492
524
  }
493
525
  interface ContactSubmission {
494
526
  id: string;
@@ -2347,6 +2379,22 @@ interface CheckoutSessionOptions {
2347
2379
  logger?: LoaderLogger;
2348
2380
  fallbackProducts?: Product[];
2349
2381
  metadata?: CheckoutMetadata;
2382
+ /**
2383
+ * Optional currency override; defaults to the currency defined on each Stripe price.
2384
+ */
2385
+ currency?: string;
2386
+ /**
2387
+ * Optional shipping amount (in the smallest currency unit).
2388
+ */
2389
+ shippingAmount?: number;
2390
+ /**
2391
+ * Shipping address forwarded to the checkout API for tax estimation.
2392
+ */
2393
+ shippingAddress?: CheckoutAddress;
2394
+ /**
2395
+ * Billing address forwarded to the checkout API for tax estimation.
2396
+ */
2397
+ billingAddress?: CheckoutAddress;
2350
2398
  /**
2351
2399
  * Optional resolver to convert a product record into a Stripe price ID.
2352
2400
  */
@@ -2364,4 +2412,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
2364
2412
  error: string;
2365
2413
  }>;
2366
2414
 
2367
- export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
2415
+ export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
package/dist/index.js CHANGED
@@ -106,13 +106,25 @@ var HttpClient = class {
106
106
  async request(endpoint, options = {}) {
107
107
  const url = this.buildUrl(endpoint, options.params);
108
108
  const requestOptions = this.buildRequestOptions(options);
109
- console.log(`[HTTP Client] Making ${options.method || "GET"} request to: ${url}`);
109
+ console.log(`[HTTP Client] ====== Request Details ======`);
110
+ console.log(`[HTTP Client] Method: ${options.method || "GET"}`);
110
111
  console.log(`[HTTP Client] Base URL: ${this.baseUrl}`);
111
112
  console.log(`[HTTP Client] Endpoint: ${endpoint}`);
112
113
  console.log(`[HTTP Client] Full URL: ${url}`);
113
114
  if (options.params) {
114
- console.log(`[HTTP Client] Query params:`, options.params);
115
+ console.log(`[HTTP Client] Query params:`, JSON.stringify(options.params, null, 2));
116
+ if (options.params.slug_prefix) {
117
+ console.log(`[HTTP Client] \u26A0\uFE0F slug_prefix detected: "${options.params.slug_prefix}"`);
118
+ }
119
+ }
120
+ const safeHeaders = { ...requestOptions.headers };
121
+ if (safeHeaders["Authorization"]) {
122
+ safeHeaders["Authorization"] = "Bearer [REDACTED]";
123
+ }
124
+ if (safeHeaders["X-API-Key"]) {
125
+ safeHeaders["X-API-Key"] = "[REDACTED]";
115
126
  }
127
+ console.log(`[HTTP Client] Headers:`, JSON.stringify(safeHeaders, null, 2));
116
128
  let lastError;
117
129
  for (let attempt = 0; attempt <= this.retries; attempt++) {
118
130
  try {
@@ -166,16 +178,26 @@ var HttpClient = class {
166
178
  */
167
179
  buildUrl(endpoint, params) {
168
180
  const url = `${this.baseUrl}${endpoint.startsWith("/") ? "" : "/"}${endpoint}`;
181
+ console.log(`[HTTP Client - URL Builder] Base URL: ${this.baseUrl}`);
182
+ console.log(`[HTTP Client - URL Builder] Endpoint: ${endpoint}`);
183
+ console.log(`[HTTP Client - URL Builder] Combined URL (before params): ${url}`);
169
184
  if (!params || Object.keys(params).length === 0) {
185
+ console.log(`[HTTP Client - URL Builder] No params, returning: ${url}`);
170
186
  return url;
171
187
  }
188
+ console.log(`[HTTP Client - URL Builder] Processing params:`, params);
172
189
  const searchParams = new URLSearchParams();
173
190
  Object.entries(params).forEach(([key, value]) => {
174
191
  if (value !== void 0 && value !== null) {
192
+ console.log(`[HTTP Client - URL Builder] Adding param: ${key}=${value}`);
175
193
  searchParams.append(key, String(value));
194
+ } else {
195
+ console.log(`[HTTP Client - URL Builder] Skipping null/undefined param: ${key}`);
176
196
  }
177
197
  });
178
- return `${url}?${searchParams.toString()}`;
198
+ const finalUrl = `${url}?${searchParams.toString()}`;
199
+ console.log(`[HTTP Client - URL Builder] Final URL: ${finalUrl}`);
200
+ return finalUrl;
179
201
  }
180
202
  /**
181
203
  * Build request options
@@ -223,27 +245,42 @@ var HttpClient = class {
223
245
  async handleResponse(response) {
224
246
  const contentType = response.headers.get("content-type");
225
247
  const isJson = contentType?.includes("application/json");
248
+ console.log(`[HTTP Client - Response] Status: ${response.status} ${response.statusText}`);
249
+ console.log(`[HTTP Client - Response] Content-Type: ${contentType}`);
226
250
  let data;
227
251
  try {
228
252
  data = isJson ? await response.json() : await response.text();
229
253
  } catch (error) {
254
+ console.error(`[HTTP Client - Response] Failed to parse response:`, error);
230
255
  data = null;
231
256
  }
257
+ const dataStr = JSON.stringify(data);
258
+ if (dataStr && dataStr.length > 1e3) {
259
+ console.log(`[HTTP Client - Response] Data (truncated):`, dataStr.substring(0, 1e3) + "...");
260
+ } else {
261
+ console.log(`[HTTP Client - Response] Data:`, data);
262
+ }
232
263
  if (!response.ok) {
264
+ console.error(`[HTTP Client - Response] Error response received`);
233
265
  const error = {
234
266
  message: data?.error || data?.message || `HTTP ${response.status}: ${response.statusText}`,
235
267
  status: response.status,
236
268
  code: data?.code,
237
269
  details: data
238
270
  };
271
+ console.error(`[HTTP Client - Response] Throwing error:`, error);
239
272
  throw error;
240
273
  }
241
274
  if (isJson && typeof data === "object") {
242
275
  if ("data" in data || "message" in data || "error" in data) {
243
- return data;
276
+ const apiResponse = data;
277
+ console.log(`[HTTP Client - Response] Returning API response with success=${apiResponse.success}, data length=${Array.isArray(apiResponse.data) ? apiResponse.data.length : "N/A"}`);
278
+ return apiResponse;
244
279
  }
280
+ console.log(`[HTTP Client - Response] Wrapping response in data property`);
245
281
  return { data, success: true };
246
282
  }
283
+ console.log(`[HTTP Client - Response] Returning text response`);
247
284
  return { data, success: true };
248
285
  }
249
286
  /**
@@ -778,6 +815,13 @@ var ContentClient = class extends BaseClient {
778
815
  const endpoint = this.siteScopedEndpoint(siteName);
779
816
  const path = this.buildPath(endpoint);
780
817
  const normalizedParams = params ? { ...params } : void 0;
818
+ console.log("[PerspectAPI Content] Starting content fetch:", {
819
+ siteName,
820
+ endpoint,
821
+ path,
822
+ originalParams: params,
823
+ normalizedParams
824
+ });
781
825
  if (normalizedParams) {
782
826
  const validatedLimit = validateOptionalLimit(
783
827
  normalizedParams.limit,
@@ -797,14 +841,52 @@ var ContentClient = class extends BaseClient {
797
841
  } else {
798
842
  delete normalizedParams.page_type;
799
843
  }
844
+ console.log("[PerspectAPI Content] Parameters after validation:", {
845
+ normalizedParams,
846
+ validatedLimit,
847
+ validatedPageType
848
+ });
800
849
  }
801
- return this.fetchWithCache(
850
+ console.log("[PerspectAPI Content] Cache details:", {
851
+ cacheEnabled: !!this.cache,
852
+ cachePolicy,
853
+ tags: this.buildContentTags(siteName)
854
+ });
855
+ const result = await this.fetchWithCache(
802
856
  endpoint,
803
857
  normalizedParams,
804
858
  this.buildContentTags(siteName),
805
859
  cachePolicy,
806
- () => this.http.get(path, normalizedParams)
860
+ async () => {
861
+ console.log("[PerspectAPI Content] Making HTTP request:", {
862
+ method: "GET",
863
+ url: path,
864
+ params: normalizedParams
865
+ });
866
+ const response = await this.http.get(path, normalizedParams);
867
+ console.log("[PerspectAPI Content] HTTP response received:", {
868
+ success: response.success,
869
+ dataLength: response.data?.length ?? 0,
870
+ pagination: response.pagination,
871
+ error: response.error,
872
+ message: response.message
873
+ });
874
+ if (response.data?.length === 0) {
875
+ console.warn("[PerspectAPI Content] WARNING: Received 0 results for query:", {
876
+ siteName,
877
+ params: normalizedParams,
878
+ fullResponse: response
879
+ });
880
+ }
881
+ return response;
882
+ }
807
883
  );
884
+ console.log("[PerspectAPI Content] Final result:", {
885
+ success: result.success,
886
+ dataLength: result.data?.length ?? 0,
887
+ pagination: result.pagination
888
+ });
889
+ return result;
808
890
  }
809
891
  /**
810
892
  * Get content by ID
@@ -2573,6 +2655,10 @@ async function createCheckoutSession(options) {
2573
2655
  logger = noopLogger,
2574
2656
  fallbackProducts,
2575
2657
  metadata,
2658
+ currency,
2659
+ shippingAmount,
2660
+ shippingAddress,
2661
+ billingAddress,
2576
2662
  priceIdResolver,
2577
2663
  tax
2578
2664
  } = options;
@@ -2628,6 +2714,21 @@ async function createCheckoutSession(options) {
2628
2714
  mode: mode === "test" ? "payment" : "payment",
2629
2715
  metadata
2630
2716
  };
2717
+ if (currency) {
2718
+ checkoutData.currency = currency;
2719
+ }
2720
+ if (typeof shippingAmount === "number") {
2721
+ checkoutData.shipping_amount = shippingAmount;
2722
+ checkoutData.shippingAmount = shippingAmount;
2723
+ }
2724
+ if (shippingAddress) {
2725
+ checkoutData.shipping_address = shippingAddress;
2726
+ checkoutData.shippingAddress = shippingAddress;
2727
+ }
2728
+ if (billingAddress) {
2729
+ checkoutData.billing_address = billingAddress;
2730
+ checkoutData.billingAddress = billingAddress;
2731
+ }
2631
2732
  if (resolvedTax) {
2632
2733
  checkoutData.tax = resolvedTax;
2633
2734
  }
package/dist/index.mjs CHANGED
@@ -45,13 +45,25 @@ var HttpClient = class {
45
45
  async request(endpoint, options = {}) {
46
46
  const url = this.buildUrl(endpoint, options.params);
47
47
  const requestOptions = this.buildRequestOptions(options);
48
- console.log(`[HTTP Client] Making ${options.method || "GET"} request to: ${url}`);
48
+ console.log(`[HTTP Client] ====== Request Details ======`);
49
+ console.log(`[HTTP Client] Method: ${options.method || "GET"}`);
49
50
  console.log(`[HTTP Client] Base URL: ${this.baseUrl}`);
50
51
  console.log(`[HTTP Client] Endpoint: ${endpoint}`);
51
52
  console.log(`[HTTP Client] Full URL: ${url}`);
52
53
  if (options.params) {
53
- console.log(`[HTTP Client] Query params:`, options.params);
54
+ console.log(`[HTTP Client] Query params:`, JSON.stringify(options.params, null, 2));
55
+ if (options.params.slug_prefix) {
56
+ console.log(`[HTTP Client] \u26A0\uFE0F slug_prefix detected: "${options.params.slug_prefix}"`);
57
+ }
58
+ }
59
+ const safeHeaders = { ...requestOptions.headers };
60
+ if (safeHeaders["Authorization"]) {
61
+ safeHeaders["Authorization"] = "Bearer [REDACTED]";
62
+ }
63
+ if (safeHeaders["X-API-Key"]) {
64
+ safeHeaders["X-API-Key"] = "[REDACTED]";
54
65
  }
66
+ console.log(`[HTTP Client] Headers:`, JSON.stringify(safeHeaders, null, 2));
55
67
  let lastError;
56
68
  for (let attempt = 0; attempt <= this.retries; attempt++) {
57
69
  try {
@@ -105,16 +117,26 @@ var HttpClient = class {
105
117
  */
106
118
  buildUrl(endpoint, params) {
107
119
  const url = `${this.baseUrl}${endpoint.startsWith("/") ? "" : "/"}${endpoint}`;
120
+ console.log(`[HTTP Client - URL Builder] Base URL: ${this.baseUrl}`);
121
+ console.log(`[HTTP Client - URL Builder] Endpoint: ${endpoint}`);
122
+ console.log(`[HTTP Client - URL Builder] Combined URL (before params): ${url}`);
108
123
  if (!params || Object.keys(params).length === 0) {
124
+ console.log(`[HTTP Client - URL Builder] No params, returning: ${url}`);
109
125
  return url;
110
126
  }
127
+ console.log(`[HTTP Client - URL Builder] Processing params:`, params);
111
128
  const searchParams = new URLSearchParams();
112
129
  Object.entries(params).forEach(([key, value]) => {
113
130
  if (value !== void 0 && value !== null) {
131
+ console.log(`[HTTP Client - URL Builder] Adding param: ${key}=${value}`);
114
132
  searchParams.append(key, String(value));
133
+ } else {
134
+ console.log(`[HTTP Client - URL Builder] Skipping null/undefined param: ${key}`);
115
135
  }
116
136
  });
117
- return `${url}?${searchParams.toString()}`;
137
+ const finalUrl = `${url}?${searchParams.toString()}`;
138
+ console.log(`[HTTP Client - URL Builder] Final URL: ${finalUrl}`);
139
+ return finalUrl;
118
140
  }
119
141
  /**
120
142
  * Build request options
@@ -162,27 +184,42 @@ var HttpClient = class {
162
184
  async handleResponse(response) {
163
185
  const contentType = response.headers.get("content-type");
164
186
  const isJson = contentType?.includes("application/json");
187
+ console.log(`[HTTP Client - Response] Status: ${response.status} ${response.statusText}`);
188
+ console.log(`[HTTP Client - Response] Content-Type: ${contentType}`);
165
189
  let data;
166
190
  try {
167
191
  data = isJson ? await response.json() : await response.text();
168
192
  } catch (error) {
193
+ console.error(`[HTTP Client - Response] Failed to parse response:`, error);
169
194
  data = null;
170
195
  }
196
+ const dataStr = JSON.stringify(data);
197
+ if (dataStr && dataStr.length > 1e3) {
198
+ console.log(`[HTTP Client - Response] Data (truncated):`, dataStr.substring(0, 1e3) + "...");
199
+ } else {
200
+ console.log(`[HTTP Client - Response] Data:`, data);
201
+ }
171
202
  if (!response.ok) {
203
+ console.error(`[HTTP Client - Response] Error response received`);
172
204
  const error = {
173
205
  message: data?.error || data?.message || `HTTP ${response.status}: ${response.statusText}`,
174
206
  status: response.status,
175
207
  code: data?.code,
176
208
  details: data
177
209
  };
210
+ console.error(`[HTTP Client - Response] Throwing error:`, error);
178
211
  throw error;
179
212
  }
180
213
  if (isJson && typeof data === "object") {
181
214
  if ("data" in data || "message" in data || "error" in data) {
182
- return data;
215
+ const apiResponse = data;
216
+ console.log(`[HTTP Client - Response] Returning API response with success=${apiResponse.success}, data length=${Array.isArray(apiResponse.data) ? apiResponse.data.length : "N/A"}`);
217
+ return apiResponse;
183
218
  }
219
+ console.log(`[HTTP Client - Response] Wrapping response in data property`);
184
220
  return { data, success: true };
185
221
  }
222
+ console.log(`[HTTP Client - Response] Returning text response`);
186
223
  return { data, success: true };
187
224
  }
188
225
  /**
@@ -717,6 +754,13 @@ var ContentClient = class extends BaseClient {
717
754
  const endpoint = this.siteScopedEndpoint(siteName);
718
755
  const path = this.buildPath(endpoint);
719
756
  const normalizedParams = params ? { ...params } : void 0;
757
+ console.log("[PerspectAPI Content] Starting content fetch:", {
758
+ siteName,
759
+ endpoint,
760
+ path,
761
+ originalParams: params,
762
+ normalizedParams
763
+ });
720
764
  if (normalizedParams) {
721
765
  const validatedLimit = validateOptionalLimit(
722
766
  normalizedParams.limit,
@@ -736,14 +780,52 @@ var ContentClient = class extends BaseClient {
736
780
  } else {
737
781
  delete normalizedParams.page_type;
738
782
  }
783
+ console.log("[PerspectAPI Content] Parameters after validation:", {
784
+ normalizedParams,
785
+ validatedLimit,
786
+ validatedPageType
787
+ });
739
788
  }
740
- return this.fetchWithCache(
789
+ console.log("[PerspectAPI Content] Cache details:", {
790
+ cacheEnabled: !!this.cache,
791
+ cachePolicy,
792
+ tags: this.buildContentTags(siteName)
793
+ });
794
+ const result = await this.fetchWithCache(
741
795
  endpoint,
742
796
  normalizedParams,
743
797
  this.buildContentTags(siteName),
744
798
  cachePolicy,
745
- () => this.http.get(path, normalizedParams)
799
+ async () => {
800
+ console.log("[PerspectAPI Content] Making HTTP request:", {
801
+ method: "GET",
802
+ url: path,
803
+ params: normalizedParams
804
+ });
805
+ const response = await this.http.get(path, normalizedParams);
806
+ console.log("[PerspectAPI Content] HTTP response received:", {
807
+ success: response.success,
808
+ dataLength: response.data?.length ?? 0,
809
+ pagination: response.pagination,
810
+ error: response.error,
811
+ message: response.message
812
+ });
813
+ if (response.data?.length === 0) {
814
+ console.warn("[PerspectAPI Content] WARNING: Received 0 results for query:", {
815
+ siteName,
816
+ params: normalizedParams,
817
+ fullResponse: response
818
+ });
819
+ }
820
+ return response;
821
+ }
746
822
  );
823
+ console.log("[PerspectAPI Content] Final result:", {
824
+ success: result.success,
825
+ dataLength: result.data?.length ?? 0,
826
+ pagination: result.pagination
827
+ });
828
+ return result;
747
829
  }
748
830
  /**
749
831
  * Get content by ID
@@ -2512,6 +2594,10 @@ async function createCheckoutSession(options) {
2512
2594
  logger = noopLogger,
2513
2595
  fallbackProducts,
2514
2596
  metadata,
2597
+ currency,
2598
+ shippingAmount,
2599
+ shippingAddress,
2600
+ billingAddress,
2515
2601
  priceIdResolver,
2516
2602
  tax
2517
2603
  } = options;
@@ -2567,6 +2653,21 @@ async function createCheckoutSession(options) {
2567
2653
  mode: mode === "test" ? "payment" : "payment",
2568
2654
  metadata
2569
2655
  };
2656
+ if (currency) {
2657
+ checkoutData.currency = currency;
2658
+ }
2659
+ if (typeof shippingAmount === "number") {
2660
+ checkoutData.shipping_amount = shippingAmount;
2661
+ checkoutData.shippingAmount = shippingAmount;
2662
+ }
2663
+ if (shippingAddress) {
2664
+ checkoutData.shipping_address = shippingAddress;
2665
+ checkoutData.shippingAddress = shippingAddress;
2666
+ }
2667
+ if (billingAddress) {
2668
+ checkoutData.billing_address = billingAddress;
2669
+ checkoutData.billingAddress = billingAddress;
2670
+ }
2570
2671
  if (resolvedTax) {
2571
2672
  checkoutData.tax = resolvedTax;
2572
2673
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perspectapi-ts-sdk",
3
- "version": "2.2.1",
3
+ "version": "2.3.3",
4
4
  "description": "TypeScript SDK for PerspectAPI - Cloudflare Workers compatible",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -34,6 +34,15 @@ export class ContentClient extends BaseClient {
34
34
  ? { ...params }
35
35
  : undefined;
36
36
 
37
+ // Log initial request parameters
38
+ console.log('[PerspectAPI Content] Starting content fetch:', {
39
+ siteName,
40
+ endpoint,
41
+ path,
42
+ originalParams: params,
43
+ normalizedParams
44
+ });
45
+
37
46
  if (normalizedParams) {
38
47
  const validatedLimit = validateOptionalLimit(
39
48
  normalizedParams.limit,
@@ -54,15 +63,64 @@ export class ContentClient extends BaseClient {
54
63
  } else {
55
64
  delete normalizedParams.page_type;
56
65
  }
66
+
67
+ // Log parameter validation results
68
+ console.log('[PerspectAPI Content] Parameters after validation:', {
69
+ normalizedParams,
70
+ validatedLimit,
71
+ validatedPageType
72
+ });
57
73
  }
58
74
 
59
- return this.fetchWithCache<PaginatedResponse<Content>>(
75
+ // Log cache information
76
+ console.log('[PerspectAPI Content] Cache details:', {
77
+ cacheEnabled: !!this.cache,
78
+ cachePolicy,
79
+ tags: this.buildContentTags(siteName)
80
+ });
81
+
82
+ const result = await this.fetchWithCache<PaginatedResponse<Content>>(
60
83
  endpoint,
61
84
  normalizedParams,
62
85
  this.buildContentTags(siteName),
63
86
  cachePolicy,
64
- () => this.http.get(path, normalizedParams) as Promise<PaginatedResponse<Content>>
87
+ async () => {
88
+ console.log('[PerspectAPI Content] Making HTTP request:', {
89
+ method: 'GET',
90
+ url: path,
91
+ params: normalizedParams
92
+ });
93
+
94
+ const response = await this.http.get(path, normalizedParams) as PaginatedResponse<Content>;
95
+
96
+ console.log('[PerspectAPI Content] HTTP response received:', {
97
+ success: response.success,
98
+ dataLength: response.data?.length ?? 0,
99
+ pagination: response.pagination,
100
+ error: response.error,
101
+ message: response.message
102
+ });
103
+
104
+ // Log more details if we got 0 results
105
+ if (response.data?.length === 0) {
106
+ console.warn('[PerspectAPI Content] WARNING: Received 0 results for query:', {
107
+ siteName,
108
+ params: normalizedParams,
109
+ fullResponse: response
110
+ });
111
+ }
112
+
113
+ return response;
114
+ }
65
115
  );
116
+
117
+ console.log('[PerspectAPI Content] Final result:', {
118
+ success: result.success,
119
+ dataLength: result.data?.length ?? 0,
120
+ pagination: result.pagination
121
+ });
122
+
123
+ return result;
66
124
  }
67
125
 
68
126
  /**
package/src/loaders.ts CHANGED
@@ -18,7 +18,8 @@ import type {
18
18
  CreateCheckoutSessionRequest,
19
19
  CheckoutSession,
20
20
  CheckoutMetadata,
21
- CheckoutTaxRequest
21
+ CheckoutTaxRequest,
22
+ CheckoutAddress
22
23
  } from './types';
23
24
  import {
24
25
  MAX_API_QUERY_LIMIT,
@@ -585,6 +586,22 @@ export interface CheckoutSessionOptions {
585
586
  logger?: LoaderLogger;
586
587
  fallbackProducts?: Product[];
587
588
  metadata?: CheckoutMetadata;
589
+ /**
590
+ * Optional currency override; defaults to the currency defined on each Stripe price.
591
+ */
592
+ currency?: string;
593
+ /**
594
+ * Optional shipping amount (in the smallest currency unit).
595
+ */
596
+ shippingAmount?: number;
597
+ /**
598
+ * Shipping address forwarded to the checkout API for tax estimation.
599
+ */
600
+ shippingAddress?: CheckoutAddress;
601
+ /**
602
+ * Billing address forwarded to the checkout API for tax estimation.
603
+ */
604
+ billingAddress?: CheckoutAddress;
588
605
  /**
589
606
  * Optional resolver to convert a product record into a Stripe price ID.
590
607
  */
@@ -613,6 +630,10 @@ export async function createCheckoutSession(
613
630
  logger = noopLogger,
614
631
  fallbackProducts,
615
632
  metadata,
633
+ currency,
634
+ shippingAmount,
635
+ shippingAddress,
636
+ billingAddress,
616
637
  priceIdResolver,
617
638
  tax
618
639
  } = options;
@@ -686,6 +707,25 @@ export async function createCheckoutSession(
686
707
  metadata,
687
708
  };
688
709
 
710
+ if (currency) {
711
+ checkoutData.currency = currency;
712
+ }
713
+
714
+ if (typeof shippingAmount === 'number') {
715
+ checkoutData.shipping_amount = shippingAmount;
716
+ checkoutData.shippingAmount = shippingAmount;
717
+ }
718
+
719
+ if (shippingAddress) {
720
+ checkoutData.shipping_address = shippingAddress;
721
+ checkoutData.shippingAddress = shippingAddress;
722
+ }
723
+
724
+ if (billingAddress) {
725
+ checkoutData.billing_address = billingAddress;
726
+ checkoutData.billingAddress = billingAddress;
727
+ }
728
+
689
729
  if (resolvedTax) {
690
730
  checkoutData.tax = resolvedTax;
691
731
  }
@@ -410,6 +410,15 @@ export type CheckoutTaxExemptionStatus =
410
410
  | 'exempt'
411
411
  | 'reverse_charge';
412
412
 
413
+ export interface CheckoutAddress {
414
+ line1?: string;
415
+ line2?: string;
416
+ city?: string;
417
+ state?: string;
418
+ postal_code?: string;
419
+ country?: string;
420
+ }
421
+
413
422
  export interface CheckoutTaxCustomerExemptionRequest {
414
423
  status?: CheckoutTaxExemptionStatus;
415
424
  reason?: string;
@@ -467,6 +476,7 @@ export interface CreateCheckoutSessionRequest {
467
476
  cancelUrl?: string; // Alternative naming
468
477
  customer_email?: string;
469
478
  customerEmail?: string; // Alternative naming
479
+ currency?: string;
470
480
  metadata?: CheckoutMetadata;
471
481
  mode?: 'payment' | 'subscription' | 'setup';
472
482
  automatic_tax?: {
@@ -476,13 +486,38 @@ export interface CreateCheckoutSessionRequest {
476
486
  allowed_countries: string[];
477
487
  };
478
488
  billing_address_collection?: 'auto' | 'required';
489
+ shipping_amount?: number;
490
+ shippingAmount?: number;
491
+ shipping_address?: CheckoutAddress;
492
+ shippingAddress?: CheckoutAddress;
493
+ billing_address?: CheckoutAddress;
494
+ billingAddress?: CheckoutAddress;
479
495
  tax?: CheckoutTaxRequest;
480
496
  }
481
497
 
498
+ export interface CheckoutTaxBreakdownItem {
499
+ jurisdiction: string;
500
+ rate_percent: number;
501
+ tax_amount: number;
502
+ taxable_amount: number;
503
+ source: 'manual_map' | 'manual_percent' | 'gateway' | 'external';
504
+ }
505
+
506
+ export interface CheckoutSessionTax {
507
+ amount: number;
508
+ currency: string;
509
+ strategy: CheckoutTaxStrategy;
510
+ exemption_applied: boolean;
511
+ exemption_status: CheckoutTaxExemptionStatus;
512
+ breakdown?: CheckoutTaxBreakdownItem[] | null;
513
+ }
514
+
482
515
  export interface CheckoutSession {
483
516
  id: string;
484
517
  url: string;
485
518
  status: string;
519
+ payment_status?: string;
520
+ tax?: CheckoutSessionTax | null;
486
521
  }
487
522
 
488
523
  // Contact Forms
@@ -68,14 +68,31 @@ export class HttpClient {
68
68
  const url = this.buildUrl(endpoint, options.params);
69
69
  const requestOptions = this.buildRequestOptions(options);
70
70
 
71
- // Log the full request details
72
- console.log(`[HTTP Client] Making ${options.method || 'GET'} request to: ${url}`);
71
+ // Enhanced logging for debugging
72
+ console.log(`[HTTP Client] ====== Request Details ======`);
73
+ console.log(`[HTTP Client] Method: ${options.method || 'GET'}`);
73
74
  console.log(`[HTTP Client] Base URL: ${this.baseUrl}`);
74
75
  console.log(`[HTTP Client] Endpoint: ${endpoint}`);
75
76
  console.log(`[HTTP Client] Full URL: ${url}`);
77
+
76
78
  if (options.params) {
77
- console.log(`[HTTP Client] Query params:`, options.params);
79
+ console.log(`[HTTP Client] Query params:`, JSON.stringify(options.params, null, 2));
80
+
81
+ // Specifically log slug_prefix if present
82
+ if (options.params.slug_prefix) {
83
+ console.log(`[HTTP Client] ⚠️ slug_prefix detected: "${options.params.slug_prefix}"`);
84
+ }
85
+ }
86
+
87
+ // Log headers (excluding sensitive data)
88
+ const safeHeaders: Record<string, any> = { ...requestOptions.headers };
89
+ if (safeHeaders['Authorization']) {
90
+ safeHeaders['Authorization'] = 'Bearer [REDACTED]';
91
+ }
92
+ if (safeHeaders['X-API-Key']) {
93
+ safeHeaders['X-API-Key'] = '[REDACTED]';
78
94
  }
95
+ console.log(`[HTTP Client] Headers:`, JSON.stringify(safeHeaders, null, 2));
79
96
 
80
97
  let lastError: Error;
81
98
 
@@ -146,18 +163,31 @@ export class HttpClient {
146
163
  private buildUrl(endpoint: string, params?: Record<string, any>): string {
147
164
  const url = `${this.baseUrl}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
148
165
 
166
+ console.log(`[HTTP Client - URL Builder] Base URL: ${this.baseUrl}`);
167
+ console.log(`[HTTP Client - URL Builder] Endpoint: ${endpoint}`);
168
+ console.log(`[HTTP Client - URL Builder] Combined URL (before params): ${url}`);
169
+
149
170
  if (!params || Object.keys(params).length === 0) {
171
+ console.log(`[HTTP Client - URL Builder] No params, returning: ${url}`);
150
172
  return url;
151
173
  }
152
174
 
175
+ console.log(`[HTTP Client - URL Builder] Processing params:`, params);
176
+
153
177
  const searchParams = new URLSearchParams();
154
178
  Object.entries(params).forEach(([key, value]) => {
155
179
  if (value !== undefined && value !== null) {
180
+ console.log(`[HTTP Client - URL Builder] Adding param: ${key}=${value}`);
156
181
  searchParams.append(key, String(value));
182
+ } else {
183
+ console.log(`[HTTP Client - URL Builder] Skipping null/undefined param: ${key}`);
157
184
  }
158
185
  });
159
186
 
160
- return `${url}?${searchParams.toString()}`;
187
+ const finalUrl = `${url}?${searchParams.toString()}`;
188
+ console.log(`[HTTP Client - URL Builder] Final URL: ${finalUrl}`);
189
+
190
+ return finalUrl;
161
191
  }
162
192
 
163
193
  /**
@@ -215,20 +245,34 @@ export class HttpClient {
215
245
  const contentType = response.headers.get('content-type');
216
246
  const isJson = contentType?.includes('application/json');
217
247
 
248
+ console.log(`[HTTP Client - Response] Status: ${response.status} ${response.statusText}`);
249
+ console.log(`[HTTP Client - Response] Content-Type: ${contentType}`);
250
+
218
251
  let data: any;
219
252
  try {
220
253
  data = isJson ? await response.json() : await response.text();
221
254
  } catch (error) {
255
+ console.error(`[HTTP Client - Response] Failed to parse response:`, error);
222
256
  data = null;
223
257
  }
224
258
 
259
+ // Log response data (truncate if too large)
260
+ const dataStr = JSON.stringify(data);
261
+ if (dataStr && dataStr.length > 1000) {
262
+ console.log(`[HTTP Client - Response] Data (truncated):`, dataStr.substring(0, 1000) + '...');
263
+ } else {
264
+ console.log(`[HTTP Client - Response] Data:`, data);
265
+ }
266
+
225
267
  if (!response.ok) {
268
+ console.error(`[HTTP Client - Response] Error response received`);
226
269
  const error: ApiError = {
227
270
  message: data?.error || data?.message || `HTTP ${response.status}: ${response.statusText}`,
228
271
  status: response.status,
229
272
  code: data?.code,
230
273
  details: data,
231
274
  };
275
+ console.error(`[HTTP Client - Response] Throwing error:`, error);
232
276
  throw error;
233
277
  }
234
278
 
@@ -236,12 +280,16 @@ export class HttpClient {
236
280
  if (isJson && typeof data === 'object') {
237
281
  // If response has data property, return as-is
238
282
  if ('data' in data || 'message' in data || 'error' in data) {
239
- return data as ApiResponse<T>;
283
+ const apiResponse = data as ApiResponse<T>;
284
+ console.log(`[HTTP Client - Response] Returning API response with success=${apiResponse.success}, data length=${Array.isArray(apiResponse.data) ? apiResponse.data.length : 'N/A'}`);
285
+ return apiResponse;
240
286
  }
241
287
  // Otherwise wrap in data property
288
+ console.log(`[HTTP Client - Response] Wrapping response in data property`);
242
289
  return { data: data as T, success: true };
243
290
  }
244
291
 
292
+ console.log(`[HTTP Client - Response] Returning text response`);
245
293
  return { data: data as T, success: true };
246
294
  }
247
295