@caldik/client 0.1.4 → 0.1.6

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
@@ -59,14 +59,59 @@ const { products } = await caldik.products.list(20)
59
59
 
60
60
  ### Get Product
61
61
 
62
- Retrieve a specific product by its ID.
62
+ Retrieve a visible product by its ID or slug. Product IDs are unambiguous. The
63
+ same slug can be used in different categories, but must be unique within a
64
+ category. Uncategorized products have their own shared slug namespace.
63
65
 
64
66
  **Basic usage**
65
67
 
66
68
  ```ts
67
- const { product } = await caldik.products.get("product_123")
69
+ const { product } = await caldik.products.get("PRODUCT_...")
68
70
  ```
69
71
 
72
+ **Get a product by category and slug**
73
+
74
+ Pass a category ID or slug when the product slug is shared across categories.
75
+
76
+ ```ts
77
+ const { product: rustProduct } = await caldik.products.get("stealth", {
78
+ category: "test2",
79
+ })
80
+
81
+ const { product: testProduct } = await caldik.products.get("stealth", {
82
+ category: "test",
83
+ })
84
+ ```
85
+
86
+ **Get a product by a unique slug**
87
+
88
+ ```ts
89
+ const { product } = await caldik.products.get("unique-product")
90
+ ```
91
+
92
+ ### Get Store
93
+
94
+ **Get the store profile and statistics**
95
+
96
+ ```ts
97
+ const { store } = await caldik.store.get()
98
+
99
+ console.log(store.name)
100
+ console.log(store.averageRating) // e.g. 4.9; null when there are no reviews
101
+ console.log(store.orders) // integer count of all store order records
102
+ console.log(store.customers) // integer count of all customer records, including guests
103
+ ```
104
+
105
+ **Read the store's social links**
106
+
107
+ ```ts
108
+ const { store } = await caldik.store.get()
109
+
110
+ const { instagram, tiktok, x, youtube, discord, telegram } = store.socials
111
+ ```
112
+
113
+ Socials are included in the same response. Each unconfigured link is `null`.
114
+
70
115
  ### Get Category
71
116
 
72
117
  Retrieve a specific category by its ID.
@@ -218,6 +263,10 @@ a storefront API proxy). Cookies set only on a separate API hostname are not
218
263
  included in requests to the storefront server. A private store key does not
219
264
  replace a shopper's customer session.
220
265
 
266
+ Customer and cart cookies are scoped to the storefront origin. When you pass
267
+ `request`, the SDK forwards its `Origin` header, or the request URL's origin when
268
+ that header is absent, so server calls use the same session as the storefront.
269
+
221
270
  ### Checkout with Explicit Items
222
271
 
223
272
  Use `caldik.checkout.create()` to create an order from explicitly provided items.
package/dist/index.d.mts CHANGED
@@ -70,6 +70,25 @@ interface CategoryResponse {
70
70
  interface Store {
71
71
  name: string;
72
72
  description: string;
73
+ /** Average of all store reviews, rounded to one decimal; null without reviews. */
74
+ averageRating: number | null;
75
+ /** All store order records, including unpaid, failed and refunded orders. */
76
+ orders: number;
77
+ /** All store customer records, including guest customers. */
78
+ customers: number;
79
+ socials: StoreSocials;
80
+ }
81
+ interface StoreSocials {
82
+ instagram: string | null;
83
+ tiktok: string | null;
84
+ x: string | null;
85
+ youtube: string | null;
86
+ discord: string | null;
87
+ telegram: string | null;
88
+ }
89
+ interface ProductGetOptions {
90
+ /** Category ID or slug. Required for a slug used in multiple categories. */
91
+ category?: string;
73
92
  }
74
93
  interface StoreResponse {
75
94
  success: boolean;
@@ -99,6 +118,7 @@ interface Product {
99
118
  deliveryType: string;
100
119
  minimumQuantity: number | null;
101
120
  maximumQuantity: number | null;
121
+ images: ProductImage[];
102
122
  variants: ProductVariant[];
103
123
  tags: ProductTag[];
104
124
  customFields: ProductCustomField[];
@@ -110,6 +130,13 @@ interface ProductVariant {
110
130
  position: number;
111
131
  price: string;
112
132
  compareAtPrice: string | null;
133
+ images: ProductImage[];
134
+ }
135
+ interface ProductImage {
136
+ id: string;
137
+ url: string;
138
+ alt: string | null;
139
+ position: number;
113
140
  }
114
141
  interface ProductTag {
115
142
  label: string;
@@ -367,6 +394,7 @@ declare class CaldikHttpClient {
367
394
  private readonly storeId?;
368
395
  private readonly cookies;
369
396
  private readonly onSetCookie?;
397
+ private readonly storefrontOrigin?;
370
398
  private readonly authenticationListeners;
371
399
  constructor(options?: HttpClientOptions);
372
400
  storeContextId(): string | null;
@@ -393,7 +421,7 @@ declare class ProductsApi {
393
421
  private client;
394
422
  constructor(client: CaldikHttpClient);
395
423
  list(): Promise<ProductsResponse>;
396
- get(productIdOrSlug: string): Promise<ProductResponse>;
424
+ get(productIdOrSlug: string, options?: ProductGetOptions): Promise<ProductResponse>;
397
425
  }
398
426
  //#endregion
399
427
  //#region src/reviews.d.ts
@@ -559,4 +587,4 @@ declare class CaldikClient {
559
587
  constructor(options?: CaldikClientOptions);
560
588
  }
561
589
  //#endregion
562
- export { AppliedDiscount, CaldikClient, CaldikClientOptions, CartApi, CartCheckoutInput, CartDiscount, CartItem, CartSnapshot, CategoriesResponse, Category, CategoryDetails, CategoryInclude, CategoryListOptions, CategoryMetadata, CategoryProduct, CategoryResponse, CheckDiscountInput, CheckoutPayment, CheckoutPaymentMethod, CheckoutPaymentMethodsResponse, CheckoutPaymentProviderId, CheckoutSettings, CheckoutSettingsResponse, CommerceItem, CreateOrderInput, CreateSubscriptionInput, CustomerEmailLoginInput, CustomerLoginResponse, CustomerLoginSettings, CustomerLoginSettingsResponse, CustomerLoginVerifyResponse, CustomerPasswordInput, CustomerPasswordResetInput, CustomerPasswordResetResponse, CustomerPasswordResetVerifyResponse, CustomerPasswordResponse, CustomerProfileResponse, CustomerRegistrationInput, CustomerRegistrationResponse, CustomerSessionResponse, DiscountQuoteResponse, DiscountsApi, ManualCommerceItem, OrderResponse, PaymentProviderId, Product, ProductCommerceItem, ProductCustomField, ProductCustomFieldInputType, ProductCustomFieldOption, ProductMetadata, ProductResponse, ProductTag, ProductVariant, ProductsResponse, Review, ReviewsResponse, Store, StoreResponse, StoreWebhookEvent, StoreWebhookEventName, StorefrontMetadata, StorefrontOrder, SubscriptionPaymentProviderId, SubscriptionResponse, checkoutPaymentProviderIds, paymentProviderIds, storeWebhookEventNames, subscriptionPaymentProviderIds };
590
+ export { AppliedDiscount, CaldikClient, CaldikClientOptions, CartApi, CartCheckoutInput, CartDiscount, CartItem, CartSnapshot, CategoriesResponse, Category, CategoryDetails, CategoryInclude, CategoryListOptions, CategoryMetadata, CategoryProduct, CategoryResponse, CheckDiscountInput, CheckoutPayment, CheckoutPaymentMethod, CheckoutPaymentMethodsResponse, CheckoutPaymentProviderId, CheckoutSettings, CheckoutSettingsResponse, CommerceItem, CreateOrderInput, CreateSubscriptionInput, CustomerEmailLoginInput, CustomerLoginResponse, CustomerLoginSettings, CustomerLoginSettingsResponse, CustomerLoginVerifyResponse, CustomerPasswordInput, CustomerPasswordResetInput, CustomerPasswordResetResponse, CustomerPasswordResetVerifyResponse, CustomerPasswordResponse, CustomerProfileResponse, CustomerRegistrationInput, CustomerRegistrationResponse, CustomerSessionResponse, DiscountQuoteResponse, DiscountsApi, ManualCommerceItem, OrderResponse, PaymentProviderId, Product, ProductCommerceItem, ProductCustomField, ProductCustomFieldInputType, ProductCustomFieldOption, ProductGetOptions, ProductImage, ProductMetadata, ProductResponse, ProductTag, ProductVariant, ProductsResponse, Review, ReviewsResponse, Store, StoreResponse, StoreSocials, StoreWebhookEvent, StoreWebhookEventName, StorefrontMetadata, StorefrontOrder, SubscriptionPaymentProviderId, SubscriptionResponse, checkoutPaymentProviderIds, paymentProviderIds, storeWebhookEventNames, subscriptionPaymentProviderIds };
package/dist/index.mjs CHANGED
@@ -47,22 +47,19 @@ function browserRuntimeStoreId() {
47
47
  const buildStoreId = browserBuildStoreId();
48
48
  return buildStoreId && STORE_ID_PATTERN.test(buildStoreId) ? buildStoreId : null;
49
49
  }
50
- function isLocalBrowserRuntime() {
51
- if (!isBrowserRuntime() || typeof location === "undefined") return false;
52
- const hostname = location.hostname.toLowerCase();
53
- return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]";
54
- }
55
50
  var CaldikHttpClient = class {
56
51
  apiKey;
57
52
  apiUrl;
58
53
  storeId;
59
54
  cookies = /* @__PURE__ */ new Map();
60
55
  onSetCookie;
56
+ storefrontOrigin;
61
57
  authenticationListeners = /* @__PURE__ */ new Set();
62
58
  constructor(options = {}) {
63
59
  this.apiKey = options.apiKey?.trim() || void 0;
64
60
  this.apiUrl = options.apiUrl || defaultApiUrl(isBrowserRuntime());
65
61
  this.onSetCookie = options.onSetCookie;
62
+ if (options.request && !isBrowserRuntime()) this.storefrontOrigin = options.request.headers.get("Origin") || new URL(options.request.url).origin;
66
63
  if (!isBrowserRuntime()) for (const part of (options.request?.headers.get("Cookie") || "").split(";")) {
67
64
  const separator = part.indexOf("=");
68
65
  if (separator > 0) this.cookies.set(part.slice(0, separator).trim(), part.slice(separator + 1).trim());
@@ -77,7 +74,8 @@ var CaldikHttpClient = class {
77
74
  return this.storeId || boundRuntimeStoreId();
78
75
  }
79
76
  hasCartSession() {
80
- return this.cookies.has(`caldik_cart_session_${this.storeContextId()}`);
77
+ const prefix = `caldik_cart_session_${this.storeContextId()}`;
78
+ return [...this.cookies.keys()].some((name) => name === prefix || name.startsWith(`${prefix}_`));
81
79
  }
82
80
  onCustomerAuthentication(listener) {
83
81
  this.authenticationListeners.add(listener);
@@ -118,10 +116,11 @@ var CaldikHttpClient = class {
118
116
  const url = new URL(`${this.baseUrl()}${path}`);
119
117
  if (params) for (const [key, value] of Object.entries(params)) url.searchParams.set(key, String(value));
120
118
  const headers = { ...options?.headers };
119
+ if (!isBrowserRuntime() && this.storefrontOrigin) headers.Origin = this.storefrontOrigin;
121
120
  if (!isBrowserRuntime()) headers["User-Agent"] = "CaldikClient/0.0.2";
122
121
  if (!isBrowserRuntime() && options?.access === "public" && this.cookies.size) headers.Cookie = [...this.cookies].map(([name, value]) => `${name}=${value}`).join("; ");
123
122
  if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`;
124
- else if (options?.access === "public" && (!isBrowserRuntime() || isLocalBrowserRuntime())) headers["X-Caldik-Public-Request"] = "1";
123
+ else if (options?.access === "public") headers["X-Caldik-Public-Request"] = "1";
125
124
  if (input !== void 0) headers["Content-Type"] = "application/json";
126
125
  if (options?.edgeCache) headers["X-Cache-Policy"] = "public";
127
126
  const response = await fetch(url, {
@@ -173,8 +172,8 @@ var ProductsApi = class {
173
172
  list() {
174
173
  return this.client.get("/products", void 0, { access: "public" });
175
174
  }
176
- get(productIdOrSlug) {
177
- return this.client.get(`/products/${encodeURIComponent(productIdOrSlug)}`, void 0, { access: "public" });
175
+ get(productIdOrSlug, options) {
176
+ return this.client.get(`/products/${encodeURIComponent(productIdOrSlug)}`, options?.category === void 0 ? void 0 : { category: options.category }, { access: "public" });
178
177
  }
179
178
  };
180
179
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caldik/client",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",