@caldik/client 0.1.1 → 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
@@ -1,81 +1,339 @@
1
- # Caldik SDK
2
-
3
- ## Caldik-hosted storefront
4
-
5
- No credentials or store configuration are required:
6
-
7
- ```ts
8
- import { CaldikClient } from "@caldik/client"
9
-
10
- const caldik = new CaldikClient()
11
- const { products } = await caldik.products.list()
12
- ```
13
-
14
- ## External server
15
-
16
- External integrations explicitly provide the store ID and a private `sk_` API
17
- key:
18
-
19
- ```ts
20
- const caldik = new CaldikClient({
21
- storeId: "STORE_...",
22
- apiKey: process.env.CALDIK_PRIVATE_API_KEY,
23
- })
24
- ```
25
-
26
- ## Cart and discounts
27
-
28
-
29
- ```ts
30
- const cart = caldik.cart.add({
31
- productId: "PRODUCT_...",
32
- productVariantId: "PRODUCT_VARIANT_...",
33
- quantity: 1,
34
- })
35
-
36
- caldik.cart.updateQuantity(cart.items[0].id, 3)
37
- caldik.cart.remove(cart.items[0].id)
38
- ```
39
-
40
- ```ts
41
- await caldik.cart.applyDiscount("SAVE10")
42
-
43
- const result = await caldik.cart.checkout({
44
- paymentMethod: "stripe",
45
- items: [{ productId, productVariantId, quantity: 1 }],
46
- termsAccepted: acceptedTermsCheckbox,
47
- successUrl: "https://shop.example/success",
48
- cancelUrl: "https://shop.example/cart",
49
- })
50
- ```
51
-
52
- Use `caldik.discounts.check({ code, items })` when a cart should be managed by
53
- the application instead of the SDK.
54
-
55
-
56
- ## Customer Logins
57
-
58
- Magic Code
59
- ```ts
60
- await caldik.customer.login("customer@example.com")
61
- await caldik.customer.login.verify(code) // Six-digit code sent by email.
62
- ```
63
-
64
- Username / Email Password ( if password login is enabled )
65
- ```ts
66
- await caldik.customer.login({ username: "customer", password })
67
- ```
68
-
69
- if you are logged in using magic code you can just do
70
- - this to enroll the customers account into username / email password login ( password login needs to be enabled in the dashboard )
71
- ```ts
72
- await caldik.customer.setPassword({ username: "customer", password })
73
- ```
74
-
75
- ## Payment methods and Settings
76
-
77
- ```ts
78
- const { settings: loginSettings } = await caldik.customer.settings.get()
79
- const { settings: checkoutSettings } = await caldik.checkout.settings.get()
80
- const { paymentMethods } = await caldik.checkout.paymentmethods.list()
81
- ```
1
+ # Caldik SDK
2
+
3
+ The official Caldik SDK for interacting with Caldik storefronts, products, carts, checkouts, and customer accounts.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @caldik/client
9
+ ```
10
+
11
+ ## Getting Started
12
+
13
+ ### Caldik-hosted Storefront
14
+
15
+ No credentials or store configuration are required when running inside a Caldik-hosted storefront.
16
+
17
+ ```ts
18
+ import { CaldikClient } from "@caldik/client"
19
+
20
+ const caldik = new CaldikClient()
21
+
22
+ const { products } = await caldik.products.list()
23
+ ```
24
+
25
+ ### External Server
26
+
27
+ External integrations must explicitly provide a store ID and a private `sk_` API key.
28
+
29
+ ```ts
30
+ import { CaldikClient } from "@caldik/client"
31
+
32
+ const caldik = new CaldikClient({
33
+ storeId: "STORE_...",
34
+ apiKey: process.env.CALDIK_PRIVATE_API_KEY,
35
+ })
36
+ ```
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
+
78
+ ## Cart and Discounts
79
+
80
+ ### Cart Management
81
+
82
+ Add products to the cart, update quantities, or remove items.
83
+
84
+ **Add an item**
85
+
86
+ ```ts
87
+ const cart = caldik.cart.add({
88
+ productId: "PRODUCT_...",
89
+ productVariantId: "PRODUCT_VARIANT_...",
90
+ quantity: 1,
91
+ })
92
+ ```
93
+
94
+ **Update item quantity**
95
+
96
+ ```ts
97
+ caldik.cart.updateQuantity(cart.items[0].id, 3)
98
+ ```
99
+
100
+ **Remove an item**
101
+
102
+ ```ts
103
+ caldik.cart.remove(cart.items[0].id)
104
+ ```
105
+
106
+ ### Apply Discounts
107
+
108
+ Apply a discount code to the current cart.
109
+
110
+ ```ts
111
+ await caldik.cart.applyDiscount("SAVE10")
112
+ ```
113
+
114
+ ### Checkout
115
+
116
+ Create a checkout session using the current cart or explicitly provided items.
117
+
118
+ ```ts
119
+ const result = await caldik.cart.checkout({
120
+ paymentMethod: "stripe",
121
+ items: [
122
+ {
123
+ productId,
124
+ productVariantId,
125
+ quantity: 1,
126
+ },
127
+ ],
128
+ termsAccepted: acceptedTermsCheckbox,
129
+ successUrl: "https://shop.example/success",
130
+ cancelUrl: "https://shop.example/cart",
131
+ })
132
+ ```
133
+
134
+ ### Validate Discounts
135
+
136
+ If your application manages its own cart instead of using the SDK's built-in cart management, validate discount codes directly.
137
+
138
+ ```ts
139
+ const result = await caldik.discounts.check({
140
+ code,
141
+ items,
142
+ })
143
+ ```
144
+
145
+ ## Customer Authentication
146
+
147
+ Caldik supports email-based magic code authentication and optional password authentication.
148
+
149
+ Username authentication is available through the **Customer Usernames** plugin.
150
+
151
+ ### Magic Code Login
152
+
153
+ Customers can log in using a six-digit verification code sent to their email address.
154
+
155
+ **Send a verification code**
156
+
157
+ ```ts
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**
171
+
172
+ ```ts
173
+ await caldik.customer.login.verify(code)
174
+ ```
175
+
176
+ ### Email and Password Login
177
+
178
+ Email and password authentication requires password login to be enabled in the store dashboard.
179
+
180
+ ```ts
181
+ await caldik.customer.login({
182
+ email: "customer@example.com",
183
+ password,
184
+ rememberMe: true, // Optional, defaults to false
185
+ })
186
+ ```
187
+
188
+ ### Username and Password Login
189
+
190
+ Username authentication requires the **Customer Usernames** plugin to be installed and enabled.
191
+
192
+ Once installed, customers can authenticate using their username instead of their email address.
193
+
194
+ ```ts
195
+ await caldik.customer.login({
196
+ username: "customer",
197
+ password,
198
+ rememberMe: true, // Optional, defaults to false
199
+ })
200
+ ```
201
+
202
+ > **Note:** Username authentication requires both the Customer Usernames plugin and password authentication to be enabled.
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
+
250
+ ## Customer Registration
251
+
252
+ Customers can register using their email address, with optional password and username support.
253
+
254
+ All registrations require email verification before the account is activated.
255
+
256
+ Password registration must be enabled in the store dashboard.
257
+
258
+ ### Email Registration
259
+
260
+ Register a customer using their email address and password.
261
+
262
+ **Register a customer**
263
+
264
+ ```ts
265
+ await caldik.customer.register({
266
+ email: "customer@example.com",
267
+ password,
268
+ })
269
+ ```
270
+
271
+ **Verify the email address**
272
+
273
+ ```ts
274
+ await caldik.customer.register.verify(code)
275
+ ```
276
+
277
+ ### Email and Username Registration
278
+
279
+ To register customers with a username, install and enable the **Customer Usernames** plugin.
280
+
281
+ Once installed, the registration endpoint accepts an additional `username` field.
282
+
283
+ **Register a customer with a username**
284
+
285
+ ```ts
286
+ await caldik.customer.register({
287
+ email: "customer@example.com",
288
+ password,
289
+ username: "customer",
290
+ })
291
+ ```
292
+
293
+ **Verify the email address**
294
+
295
+ ```ts
296
+ await caldik.customer.register.verify(code)
297
+ ```
298
+
299
+ > **Note:** The `username` field is provided by the Customer Usernames plugin. Omit this field when the plugin is not installed.
300
+
301
+ ## Payment Methods and Settings
302
+
303
+ Retrieve customer authentication settings, checkout configuration, and available payment methods.
304
+
305
+ ### Customer Settings
306
+
307
+ Retrieve the store's customer authentication settings.
308
+
309
+ ```ts
310
+ const { settings: loginSettings } = await caldik.customer.settings.get()
311
+ ```
312
+
313
+ ### Checkout Settings
314
+
315
+ Retrieve the store's checkout configuration.
316
+
317
+ ```ts
318
+ const { settings: checkoutSettings } = await caldik.checkout.settings.get()
319
+ ```
320
+
321
+ ### Available Payment Methods
322
+
323
+ Retrieve the payment methods available for checkout.
324
+
325
+ ```ts
326
+ const { paymentMethods } = await caldik.checkout.paymentmethods.list()
327
+ ```
328
+
329
+ ### Combined Example
330
+
331
+ Retrieve customer settings, checkout settings, and available payment methods together.
332
+
333
+ ```ts
334
+ const { settings: loginSettings } = await caldik.customer.settings.get()
335
+
336
+ const { settings: checkoutSettings } = await caldik.checkout.settings.get()
337
+
338
+ const { paymentMethods } = await caldik.checkout.paymentmethods.list()
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;
@@ -139,16 +147,19 @@ interface ManualCommerceItem {
139
147
  unitAmount: string | number;
140
148
  }
141
149
  interface ProductCommerceItem {
150
+ customFields?: Record<string, string | number | boolean>;
142
151
  productId: string;
143
152
  productVariantId?: string;
144
153
  quantity?: number;
145
154
  }
146
155
  type CommerceItem = ManualCommerceItem | ProductCommerceItem;
147
156
  interface CreateOrderInput {
157
+ uiMode?: "hosted" | "elements";
158
+ returnUrl?: string;
148
159
  customerId?: string;
149
160
  email?: string;
150
161
  termsAccepted?: boolean;
151
- paymentMethod: CheckoutPaymentProviderId;
162
+ paymentMethod?: CheckoutPaymentProviderId;
152
163
  items: CommerceItem[];
153
164
  discountCode?: string;
154
165
  successUrl?: string;
@@ -157,10 +168,8 @@ interface CreateOrderInput {
157
168
  interface StorefrontOrder {
158
169
  id: string;
159
170
  shortId: string;
160
- displayId: string;
161
171
  customerId: string | null;
162
172
  paymentStatus: string;
163
- fulfillmentStatus: string;
164
173
  subtotal: string;
165
174
  amount: string;
166
175
  discount: {
@@ -171,6 +180,8 @@ interface StorefrontOrder {
171
180
  currency: string;
172
181
  }
173
182
  interface CheckoutPayment {
183
+ clientSecret?: string;
184
+ publishableKey?: string;
174
185
  type: CheckoutPaymentProviderId;
175
186
  checkoutUrl?: string | null;
176
187
  checkoutSessionId?: string | null;
@@ -223,23 +234,83 @@ interface StoreWebhookEvent<TObject extends Record<string, unknown> = Record<str
223
234
  }
224
235
  interface CustomerLoginResponse {
225
236
  success: boolean;
226
- message: string;
227
- loginId: string;
237
+ challengeId: string;
228
238
  }
229
239
  interface CustomerLoginVerifyResponse {
240
+ session?: {
241
+ token: string;
242
+ expiresAt: number;
243
+ };
230
244
  success: boolean;
245
+ }
246
+ interface CustomerPasswordResponse extends CustomerLoginVerifyResponse {
231
247
  customer: {
232
248
  id: string;
233
249
  shortId: string;
234
250
  displayId: string;
235
251
  email: string | null;
236
252
  status: string;
253
+ extensions?: Record<string, Record<string, string | number | boolean>>;
237
254
  };
238
255
  }
239
- interface CustomerPasswordInput {
256
+ type CustomerPasswordInput = ({
240
257
  username: string;
258
+ email?: never;
259
+ } | {
260
+ email: string;
261
+ username?: never;
262
+ }) & {
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;
241
286
  password: string;
242
287
  }
288
+ interface CustomerPasswordResetVerifyResponse {
289
+ success: boolean;
290
+ message: string;
291
+ }
292
+ interface CustomerRegistrationInput {
293
+ email: string;
294
+ password?: string;
295
+ /** Available when the store installs Customer Usernames. */
296
+ username?: string;
297
+ [pluginField: string]: string | number | boolean | undefined;
298
+ }
299
+ interface CustomerRegistrationResponse extends CustomerLoginResponse {
300
+ expiresAt: number;
301
+ }
302
+ interface CustomerProfileResponse {
303
+ success: boolean;
304
+ customer: {
305
+ id: string;
306
+ email: string | null;
307
+ extensions?: Record<string, Record<string, string | number | boolean>>;
308
+ };
309
+ balances: Array<{
310
+ currency: string;
311
+ amount: string;
312
+ }>;
313
+ }
243
314
  interface CustomerLoginSettings {
244
315
  passwordEnabled: boolean;
245
316
  }
@@ -248,6 +319,9 @@ interface CustomerLoginSettingsResponse {
248
319
  settings: CustomerLoginSettings;
249
320
  }
250
321
  interface CheckoutSettings {
322
+ termsUrl?: string | null;
323
+ refundPolicyUrl?: string | null;
324
+ embedStripeMode: "elements" | "hosted" | "popup";
251
325
  requireEmail: boolean;
252
326
  requireTermsAcceptance: boolean;
253
327
  }
@@ -299,7 +373,7 @@ declare class CaldikHttpClient {
299
373
  declare class CategoriesApi {
300
374
  private client;
301
375
  constructor(client: CaldikHttpClient);
302
- list(limit?: number): Promise<CategoriesResponse>;
376
+ list(options?: number | CategoryListOptions): Promise<CategoriesResponse>;
303
377
  get(categoryId: string): Promise<CategoryResponse>;
304
378
  }
305
379
  //#endregion
@@ -346,14 +420,29 @@ declare class CustomerApi {
346
420
  get: () => Promise<CustomerLoginSettingsResponse>;
347
421
  };
348
422
  readonly login: {
349
- (email: string): Promise<CustomerLoginResponse>;
350
- (input: CustomerPasswordInput): Promise<CustomerLoginVerifyResponse>;
423
+ (email: string, options?: {
424
+ rememberMe?: boolean;
425
+ }): Promise<CustomerLoginResponse>;
426
+ (input: CustomerEmailLoginInput): Promise<CustomerLoginResponse>;
427
+ (input: CustomerPasswordInput): Promise<CustomerPasswordResponse>;
428
+ } & {
429
+ /** Pass challengeId to resume a code request after reloading the page. */verify: (code: string, challengeId?: string | undefined) => Promise<CustomerLoginVerifyResponse>;
430
+ };
431
+ readonly register: {
432
+ (email: string): Promise<CustomerRegistrationResponse>;
433
+ (input: CustomerRegistrationInput): Promise<CustomerRegistrationResponse>;
351
434
  } & {
352
- /** Pass loginId to resume a code request after reloading the page. */verify: (code: string, loginId?: string | undefined) => Promise<CustomerLoginVerifyResponse>;
435
+ /** Verify the email and atomically activate the account. Supports resuming after a reload. */verify: (code: string, challengeId?: string | undefined) => Promise<CustomerPasswordResponse>;
436
+ };
437
+ readonly password: {
438
+ requestReset: (email: string) => Promise<CustomerPasswordResetResponse>;
439
+ reset: (input: CustomerPasswordResetInput) => Promise<CustomerPasswordResetVerifyResponse>;
353
440
  };
354
441
  constructor(client: CaldikHttpClient);
355
- /** Set or reset credentials after signing in with an email code. Requires a customer session. */
356
- setPassword(input: CustomerPasswordInput): Promise<CustomerLoginVerifyResponse>;
442
+ /** Check a store-scoped session without raising an error for signed-out customers. */
443
+ session(): Promise<CustomerSessionResponse>;
444
+ /** Read the signed-in customer and their balances. */
445
+ me(): Promise<CustomerProfileResponse>;
357
446
  }
358
447
  //#endregion
359
448
  //#region src/subscriptions.d.ts
@@ -446,4 +535,4 @@ declare class CaldikClient {
446
535
  constructor(options?: CaldikClientOptions);
447
536
  }
448
537
  //#endregion
449
- 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, 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" });
@@ -177,32 +181,78 @@ var CustomerApi = class {
177
181
  client;
178
182
  settings;
179
183
  login;
184
+ register;
185
+ password;
180
186
  constructor(client) {
181
187
  this.client = client;
182
188
  this.settings = { get: () => this.client.get("/customers/settings", void 0, { access: "public" }) };
183
- let pendingLoginId;
184
- async function login(input) {
185
- if (typeof input !== "string") return client.post("/customers/login/password", input, { access: "public" });
186
- const response = await client.post("/customers/login", { email: input }, { access: "public" });
187
- pendingLoginId = response.loginId;
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
+ };
208
+ let pendingChallengeId;
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" });
215
+ pendingChallengeId = response.challengeId;
188
216
  return response;
189
217
  }
190
218
  this.login = Object.assign(login, {
191
- /** Pass loginId to resume a code request after reloading the page. */
192
- verify: async (code, loginId = pendingLoginId) => {
219
+ /** Pass challengeId to resume a code request after reloading the page. */
220
+ verify: async (code, challengeId = pendingChallengeId) => {
193
221
  if (!/^\d{6}$/.test(code)) throw new Error("A six-digit login code is required");
194
- if (!loginId) throw new Error("Request a login code first or provide its loginId");
222
+ if (!challengeId) throw new Error("Request a login code first or provide its challengeId");
195
223
  const response = await client.post("/customers/login/verify", {
196
224
  code,
197
- loginId
225
+ challengeId
198
226
  }, { access: "public" });
199
- if (pendingLoginId === loginId) pendingLoginId = void 0;
227
+ if (pendingChallengeId === challengeId) pendingChallengeId = void 0;
200
228
  return response;
201
229
  } });
230
+ let pendingRegistrationId;
231
+ async function register(input) {
232
+ const response = await client.post("/customers/register", typeof input === "string" ? { email: input } : input, { access: "public" });
233
+ pendingRegistrationId = response.challengeId;
234
+ return response;
235
+ }
236
+ this.register = Object.assign(register, {
237
+ /** Verify the email and atomically activate the account. Supports resuming after a reload. */
238
+ verify: async (code, challengeId = pendingRegistrationId) => {
239
+ if (!/^\d{6}$/.test(code)) throw new Error("A six-digit registration code is required");
240
+ if (!challengeId) throw new Error("Request a registration code first or provide its challengeId");
241
+ const response = await client.post("/customers/register/verify", {
242
+ code,
243
+ challengeId
244
+ }, { access: "public" });
245
+ if (pendingRegistrationId === challengeId) pendingRegistrationId = void 0;
246
+ return response;
247
+ } });
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" });
202
252
  }
203
- /** Set or reset credentials after signing in with an email code. Requires a customer session. */
204
- setPassword(input) {
205
- return this.client.post("/customers/password", input, { access: "public" });
253
+ /** Read the signed-in customer and their balances. */
254
+ me() {
255
+ return this.client.get("/customers/me", void 0, { access: "public" });
206
256
  }
207
257
  };
208
258
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caldik/client",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",