@caldik/client 0.1.2 → 0.1.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
@@ -2,7 +2,15 @@
2
2
 
3
3
  The official Caldik SDK for interacting with Caldik storefronts, products, carts, checkouts, and customer accounts.
4
4
 
5
- ## Caldik-hosted Storefront
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @caldik/client
9
+ ```
10
+
11
+ ## Getting Started
12
+
13
+ ### Caldik-hosted Storefront
6
14
 
7
15
  No credentials or store configuration are required when running inside a Caldik-hosted storefront.
8
16
 
@@ -14,7 +22,7 @@ const caldik = new CaldikClient()
14
22
  const { products } = await caldik.products.list()
15
23
  ```
16
24
 
17
- ## External Server
25
+ ### External Server
18
26
 
19
27
  External integrations must explicitly provide a store ID and a private `sk_` API key.
20
28
 
@@ -27,23 +35,71 @@ const caldik = new CaldikClient({
27
35
  })
28
36
  ```
29
37
 
38
+ > **Security:** Private API keys must only be used in trusted server-side environments. Never expose `sk_` keys in client-side code.
39
+
40
+ ## Orders and Items
41
+
42
+ ### Categories
43
+
44
+ Retrieve categories associated with the current store.
45
+
46
+ **Basic usage**
47
+
48
+ ```ts
49
+ const { categories } = await caldik.categories.list()
50
+ ```
51
+
52
+ **Limit results**
53
+
54
+ Pass a number to limit the number of categories returned.
55
+
56
+ ```ts
57
+ const { categories } = await caldik.categories.list(20)
58
+ ```
59
+
60
+ **Advanced usage**
61
+
62
+ Use an options object to configure the limit and request additional fields.
63
+
64
+ ```ts
65
+ const { categories } = await caldik.categories.list({
66
+ limit: 20,
67
+ include: ["productCount", "startingPrice"],
68
+ })
69
+ ```
70
+
71
+ The following fields are omitted by default unless explicitly requested using `include`:
72
+
73
+ | Field | Description |
74
+ |---|---|
75
+ | `productCount` | Number of products associated with the category. |
76
+ | `startingPrice` | Lowest available product price in the category, in cents. |
77
+
30
78
  ## Cart and Discounts
31
79
 
32
80
  ### Cart Management
33
81
 
34
82
  Add products to the cart, update quantities, or remove items.
35
83
 
84
+ **Add an item**
85
+
36
86
  ```ts
37
87
  const cart = caldik.cart.add({
38
88
  productId: "PRODUCT_...",
39
89
  productVariantId: "PRODUCT_VARIANT_...",
40
90
  quantity: 1,
41
91
  })
92
+ ```
93
+
94
+ **Update item quantity**
42
95
 
43
- // Update item quantity
96
+ ```ts
44
97
  caldik.cart.updateQuantity(cart.items[0].id, 3)
98
+ ```
45
99
 
46
- // Remove an item
100
+ **Remove an item**
101
+
102
+ ```ts
47
103
  caldik.cart.remove(cart.items[0].id)
48
104
  ```
49
105
 
@@ -96,11 +152,24 @@ Username authentication is available through the **Customer Usernames** plugin.
96
152
 
97
153
  Customers can log in using a six-digit verification code sent to their email address.
98
154
 
155
+ **Send a verification code**
156
+
99
157
  ```ts
100
- // Send a six-digit verification code
101
158
  await caldik.customer.login("customer@example.com")
159
+ ```
160
+
161
+ Alternatively, use an options object to configure the session.
162
+
163
+ ```ts
164
+ await caldik.customer.login({
165
+ email: "customer@example.com",
166
+ rememberMe: true, // Optional, defaults to false
167
+ })
168
+ ```
169
+
170
+ **Verify the code**
102
171
 
103
- // Verify the code
172
+ ```ts
104
173
  await caldik.customer.login.verify(code)
105
174
  ```
106
175
 
@@ -112,6 +181,7 @@ Email and password authentication requires password login to be enabled in the s
112
181
  await caldik.customer.login({
113
182
  email: "customer@example.com",
114
183
  password,
184
+ rememberMe: true, // Optional, defaults to false
115
185
  })
116
186
  ```
117
187
 
@@ -125,11 +195,58 @@ Once installed, customers can authenticate using their username instead of their
125
195
  await caldik.customer.login({
126
196
  username: "customer",
127
197
  password,
198
+ rememberMe: true, // Optional, defaults to false
128
199
  })
129
200
  ```
130
201
 
131
202
  > **Note:** Username authentication requires both the Customer Usernames plugin and password authentication to be enabled.
132
203
 
204
+ ### Session Duration
205
+
206
+ All customer authentication methods support the optional `rememberMe` parameter.
207
+
208
+ | `rememberMe` | Session Duration |
209
+ |---|---|
210
+ | `false` (default) | 24 hours |
211
+ | `true` | 30 days |
212
+
213
+ Omit `rememberMe` to use the default session duration.
214
+
215
+ ### Session Check
216
+
217
+ Retrieve the current customer's authentication status, account details, and session expiration.
218
+
219
+ ```ts
220
+ const {
221
+ authenticated,
222
+ customer,
223
+ expiresAt,
224
+ } = await caldik.customer.session()
225
+ ```
226
+
227
+ ### Password Reset
228
+
229
+ Customers can reset their passwords using a verification code sent to their email address.
230
+
231
+ **Request a password reset**
232
+
233
+ ```ts
234
+ const { challengeId } =
235
+ await caldik.customer.password.requestReset(email)
236
+ ```
237
+
238
+ Password reset codes expire after **10 minutes**.
239
+
240
+ **Reset the password**
241
+
242
+ ```ts
243
+ await caldik.customer.password.reset({
244
+ challengeId,
245
+ code,
246
+ password: newPassword,
247
+ })
248
+ ```
249
+
133
250
  ## Customer Registration
134
251
 
135
252
  Customers can register using their email address, with optional password and username support.
@@ -142,14 +259,18 @@ Password registration must be enabled in the store dashboard.
142
259
 
143
260
  Register a customer using their email address and password.
144
261
 
262
+ **Register a customer**
263
+
145
264
  ```ts
146
- // Register a new customer
147
265
  await caldik.customer.register({
148
266
  email: "customer@example.com",
149
267
  password,
150
268
  })
269
+ ```
151
270
 
152
- // Verify the email using the six-digit code
271
+ **Verify the email address**
272
+
273
+ ```ts
153
274
  await caldik.customer.register.verify(code)
154
275
  ```
155
276
 
@@ -159,15 +280,19 @@ To register customers with a username, install and enable the **Customer Usernam
159
280
 
160
281
  Once installed, the registration endpoint accepts an additional `username` field.
161
282
 
283
+ **Register a customer with a username**
284
+
162
285
  ```ts
163
- // Register a new customer with a username
164
286
  await caldik.customer.register({
165
287
  email: "customer@example.com",
166
288
  password,
167
289
  username: "customer",
168
290
  })
291
+ ```
292
+
293
+ **Verify the email address**
169
294
 
170
- // Verify the email using the six-digit code
295
+ ```ts
171
296
  await caldik.customer.register.verify(code)
172
297
  ```
173
298
 
@@ -179,28 +304,36 @@ Retrieve customer authentication settings, checkout configuration, and available
179
304
 
180
305
  ### Customer Settings
181
306
 
307
+ Retrieve the store's customer authentication settings.
308
+
182
309
  ```ts
183
310
  const { settings: loginSettings } = await caldik.customer.settings.get()
184
311
  ```
185
312
 
186
313
  ### Checkout Settings
187
314
 
315
+ Retrieve the store's checkout configuration.
316
+
188
317
  ```ts
189
318
  const { settings: checkoutSettings } = await caldik.checkout.settings.get()
190
319
  ```
191
320
 
192
321
  ### Available Payment Methods
193
322
 
323
+ Retrieve the payment methods available for checkout.
324
+
194
325
  ```ts
195
326
  const { paymentMethods } = await caldik.checkout.paymentmethods.list()
196
327
  ```
197
328
 
198
329
  ### Combined Example
199
330
 
331
+ Retrieve customer settings, checkout settings, and available payment methods together.
332
+
200
333
  ```ts
201
334
  const { settings: loginSettings } = await caldik.customer.settings.get()
202
335
 
203
336
  const { settings: checkoutSettings } = await caldik.checkout.settings.get()
204
337
 
205
338
  const { paymentMethods } = await caldik.checkout.paymentmethods.list()
206
- ```
339
+ ```
package/dist/index.d.mts CHANGED
@@ -24,7 +24,10 @@ interface Category {
24
24
  name: string;
25
25
  slug: string;
26
26
  description: string;
27
- price: string;
27
+ /** Present when startingPrice is included. Prefer startingPrice. */
28
+ price?: string;
29
+ productCount?: number;
30
+ startingPrice?: string | null;
28
31
  logo: string | null;
29
32
  banner: string | null;
30
33
  metadata: CategoryMetadata[];
@@ -33,6 +36,11 @@ interface CategoriesResponse {
33
36
  success: boolean;
34
37
  categories: Category[];
35
38
  }
39
+ type CategoryInclude = "productCount" | "startingPrice" | "product count" | "starting price";
40
+ interface CategoryListOptions {
41
+ limit?: number;
42
+ include?: readonly CategoryInclude[];
43
+ }
36
44
  interface CategoryProduct {
37
45
  id: string;
38
46
  name: string;
@@ -245,10 +253,41 @@ interface CustomerPasswordResponse extends CustomerLoginVerifyResponse {
245
253
  extensions?: Record<string, Record<string, string | number | boolean>>;
246
254
  };
247
255
  }
248
- interface CustomerPasswordInput {
249
- /** A username from an installed identity plugin, or the customer's email. */
256
+ type CustomerPasswordInput = ({
250
257
  username: string;
258
+ email?: never;
259
+ } | {
260
+ email: string;
261
+ username?: never;
262
+ }) & {
251
263
  password: string;
264
+ rememberMe?: boolean;
265
+ };
266
+ interface CustomerEmailLoginInput {
267
+ email: string;
268
+ rememberMe?: boolean;
269
+ }
270
+ interface CustomerSessionResponse {
271
+ success: boolean;
272
+ authenticated: boolean;
273
+ customer: {
274
+ id: string;
275
+ email: string | null;
276
+ } | null;
277
+ expiresAt: number | null;
278
+ }
279
+ interface CustomerPasswordResetResponse extends CustomerLoginResponse {
280
+ expiresAt: number;
281
+ message: string;
282
+ }
283
+ interface CustomerPasswordResetInput {
284
+ challengeId?: string;
285
+ code: string;
286
+ password: string;
287
+ }
288
+ interface CustomerPasswordResetVerifyResponse {
289
+ success: boolean;
290
+ message: string;
252
291
  }
253
292
  interface CustomerRegistrationInput {
254
293
  email: string;
@@ -334,7 +373,7 @@ declare class CaldikHttpClient {
334
373
  declare class CategoriesApi {
335
374
  private client;
336
375
  constructor(client: CaldikHttpClient);
337
- list(limit?: number): Promise<CategoriesResponse>;
376
+ list(options?: number | CategoryListOptions): Promise<CategoriesResponse>;
338
377
  get(categoryId: string): Promise<CategoryResponse>;
339
378
  }
340
379
  //#endregion
@@ -381,7 +420,10 @@ declare class CustomerApi {
381
420
  get: () => Promise<CustomerLoginSettingsResponse>;
382
421
  };
383
422
  readonly login: {
384
- (email: string): Promise<CustomerLoginResponse>;
423
+ (email: string, options?: {
424
+ rememberMe?: boolean;
425
+ }): Promise<CustomerLoginResponse>;
426
+ (input: CustomerEmailLoginInput): Promise<CustomerLoginResponse>;
385
427
  (input: CustomerPasswordInput): Promise<CustomerPasswordResponse>;
386
428
  } & {
387
429
  /** Pass challengeId to resume a code request after reloading the page. */verify: (code: string, challengeId?: string | undefined) => Promise<CustomerLoginVerifyResponse>;
@@ -392,7 +434,13 @@ declare class CustomerApi {
392
434
  } & {
393
435
  /** Verify the email and atomically activate the account. Supports resuming after a reload. */verify: (code: string, challengeId?: string | undefined) => Promise<CustomerPasswordResponse>;
394
436
  };
437
+ readonly password: {
438
+ requestReset: (email: string) => Promise<CustomerPasswordResetResponse>;
439
+ reset: (input: CustomerPasswordResetInput) => Promise<CustomerPasswordResetVerifyResponse>;
440
+ };
395
441
  constructor(client: CaldikHttpClient);
442
+ /** Check a store-scoped session without raising an error for signed-out customers. */
443
+ session(): Promise<CustomerSessionResponse>;
396
444
  /** Read the signed-in customer and their balances. */
397
445
  me(): Promise<CustomerProfileResponse>;
398
446
  }
@@ -487,4 +535,4 @@ declare class CaldikClient {
487
535
  constructor(options?: CaldikClientOptions);
488
536
  }
489
537
  //#endregion
490
- export { AppliedDiscount, CaldikClient, CaldikClientOptions, CartApi, CartCheckoutInput, CartDiscount, CartItem, CartSnapshot, CategoriesResponse, Category, CategoryDetails, CategoryMetadata, CategoryProduct, CategoryResponse, CheckDiscountInput, CheckoutPayment, CheckoutPaymentMethod, CheckoutPaymentMethodsResponse, CheckoutPaymentProviderId, CheckoutSettings, CheckoutSettingsResponse, CommerceItem, CreateOrderInput, CreateSubscriptionInput, CustomerLoginResponse, CustomerLoginSettings, CustomerLoginSettingsResponse, CustomerLoginVerifyResponse, CustomerPasswordInput, CustomerPasswordResponse, CustomerProfileResponse, CustomerRegistrationInput, CustomerRegistrationResponse, 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 };
538
+ 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 };
package/dist/index.mjs CHANGED
@@ -110,8 +110,12 @@ var CategoriesApi = class {
110
110
  constructor(client) {
111
111
  this.client = client;
112
112
  }
113
- list(limit) {
114
- return this.client.get("/categories", limit ? { limit } : void 0, { access: "public" });
113
+ list(options) {
114
+ const { limit, include } = typeof options === "number" ? { limit: options } : options ?? {};
115
+ return this.client.get("/categories", {
116
+ ...limit !== void 0 ? { limit } : {},
117
+ ...include?.length ? { include: include.join(",") } : {}
118
+ }, { access: "public" });
115
119
  }
116
120
  get(categoryId) {
117
121
  return this.client.get(`/categories/${categoryId}`, void 0, { access: "public" });
@@ -178,13 +182,36 @@ var CustomerApi = class {
178
182
  settings;
179
183
  login;
180
184
  register;
185
+ password;
181
186
  constructor(client) {
182
187
  this.client = client;
183
188
  this.settings = { get: () => this.client.get("/customers/settings", void 0, { access: "public" }) };
189
+ let pendingResetId;
190
+ this.password = {
191
+ requestReset: async (email) => {
192
+ const response = await client.post("/customers/password/reset", { email }, { access: "public" });
193
+ pendingResetId = response.challengeId;
194
+ return response;
195
+ },
196
+ reset: async (input) => {
197
+ const challengeId = input.challengeId ?? pendingResetId;
198
+ if (!challengeId) throw new Error("Request a password reset first or provide its challengeId");
199
+ if (!/^\d{6}$/.test(input.code)) throw new Error("A six-digit reset code is required");
200
+ const response = await client.post("/customers/password/reset/verify", {
201
+ ...input,
202
+ challengeId
203
+ }, { access: "public" });
204
+ if (pendingResetId === challengeId) pendingResetId = void 0;
205
+ return response;
206
+ }
207
+ };
184
208
  let pendingChallengeId;
185
- async function login(input) {
186
- if (typeof input !== "string") return client.post("/customers/login/password", input, { access: "public" });
187
- const response = await client.post("/customers/login", { email: input }, { access: "public" });
209
+ async function login(input, options) {
210
+ if (typeof input !== "string" && "password" in input) return client.post("/customers/login/password", input, { access: "public" });
211
+ const response = await client.post("/customers/login", typeof input === "string" ? {
212
+ email: input,
213
+ ...options
214
+ } : input, { access: "public" });
188
215
  pendingChallengeId = response.challengeId;
189
216
  return response;
190
217
  }
@@ -219,6 +246,10 @@ verify: async (code, challengeId = pendingRegistrationId) => {
219
246
  return response;
220
247
  } });
221
248
  }
249
+ /** Check a store-scoped session without raising an error for signed-out customers. */
250
+ session() {
251
+ return this.client.get("/customers/session", void 0, { access: "public" });
252
+ }
222
253
  /** Read the signed-in customer and their balances. */
223
254
  me() {
224
255
  return this.client.get("/customers/me", void 0, { access: "public" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caldik/client",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",