@caldik/client 0.1.1 → 0.1.2

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,206 @@
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
+ ## Caldik-hosted Storefront
6
+
7
+ No credentials or store configuration are required when running inside a Caldik-hosted storefront.
8
+
9
+ ```ts
10
+ import { CaldikClient } from "@caldik/client"
11
+
12
+ const caldik = new CaldikClient()
13
+
14
+ const { products } = await caldik.products.list()
15
+ ```
16
+
17
+ ## External Server
18
+
19
+ External integrations must explicitly provide a store ID and a private `sk_` API key.
20
+
21
+ ```ts
22
+ import { CaldikClient } from "@caldik/client"
23
+
24
+ const caldik = new CaldikClient({
25
+ storeId: "STORE_...",
26
+ apiKey: process.env.CALDIK_PRIVATE_API_KEY,
27
+ })
28
+ ```
29
+
30
+ ## Cart and Discounts
31
+
32
+ ### Cart Management
33
+
34
+ Add products to the cart, update quantities, or remove items.
35
+
36
+ ```ts
37
+ const cart = caldik.cart.add({
38
+ productId: "PRODUCT_...",
39
+ productVariantId: "PRODUCT_VARIANT_...",
40
+ quantity: 1,
41
+ })
42
+
43
+ // Update item quantity
44
+ caldik.cart.updateQuantity(cart.items[0].id, 3)
45
+
46
+ // Remove an item
47
+ caldik.cart.remove(cart.items[0].id)
48
+ ```
49
+
50
+ ### Apply Discounts
51
+
52
+ Apply a discount code to the current cart.
53
+
54
+ ```ts
55
+ await caldik.cart.applyDiscount("SAVE10")
56
+ ```
57
+
58
+ ### Checkout
59
+
60
+ Create a checkout session using the current cart or explicitly provided items.
61
+
62
+ ```ts
63
+ const result = await caldik.cart.checkout({
64
+ paymentMethod: "stripe",
65
+ items: [
66
+ {
67
+ productId,
68
+ productVariantId,
69
+ quantity: 1,
70
+ },
71
+ ],
72
+ termsAccepted: acceptedTermsCheckbox,
73
+ successUrl: "https://shop.example/success",
74
+ cancelUrl: "https://shop.example/cart",
75
+ })
76
+ ```
77
+
78
+ ### Validate Discounts
79
+
80
+ If your application manages its own cart instead of using the SDK's built-in cart management, validate discount codes directly.
81
+
82
+ ```ts
83
+ const result = await caldik.discounts.check({
84
+ code,
85
+ items,
86
+ })
87
+ ```
88
+
89
+ ## Customer Authentication
90
+
91
+ Caldik supports email-based magic code authentication and optional password authentication.
92
+
93
+ Username authentication is available through the **Customer Usernames** plugin.
94
+
95
+ ### Magic Code Login
96
+
97
+ Customers can log in using a six-digit verification code sent to their email address.
98
+
99
+ ```ts
100
+ // Send a six-digit verification code
101
+ await caldik.customer.login("customer@example.com")
102
+
103
+ // Verify the code
104
+ await caldik.customer.login.verify(code)
105
+ ```
106
+
107
+ ### Email and Password Login
108
+
109
+ Email and password authentication requires password login to be enabled in the store dashboard.
110
+
111
+ ```ts
112
+ await caldik.customer.login({
113
+ email: "customer@example.com",
114
+ password,
115
+ })
116
+ ```
117
+
118
+ ### Username and Password Login
119
+
120
+ Username authentication requires the **Customer Usernames** plugin to be installed and enabled.
121
+
122
+ Once installed, customers can authenticate using their username instead of their email address.
123
+
124
+ ```ts
125
+ await caldik.customer.login({
126
+ username: "customer",
127
+ password,
128
+ })
129
+ ```
130
+
131
+ > **Note:** Username authentication requires both the Customer Usernames plugin and password authentication to be enabled.
132
+
133
+ ## Customer Registration
134
+
135
+ Customers can register using their email address, with optional password and username support.
136
+
137
+ All registrations require email verification before the account is activated.
138
+
139
+ Password registration must be enabled in the store dashboard.
140
+
141
+ ### Email Registration
142
+
143
+ Register a customer using their email address and password.
144
+
145
+ ```ts
146
+ // Register a new customer
147
+ await caldik.customer.register({
148
+ email: "customer@example.com",
149
+ password,
150
+ })
151
+
152
+ // Verify the email using the six-digit code
153
+ await caldik.customer.register.verify(code)
154
+ ```
155
+
156
+ ### Email and Username Registration
157
+
158
+ To register customers with a username, install and enable the **Customer Usernames** plugin.
159
+
160
+ Once installed, the registration endpoint accepts an additional `username` field.
161
+
162
+ ```ts
163
+ // Register a new customer with a username
164
+ await caldik.customer.register({
165
+ email: "customer@example.com",
166
+ password,
167
+ username: "customer",
168
+ })
169
+
170
+ // Verify the email using the six-digit code
171
+ await caldik.customer.register.verify(code)
172
+ ```
173
+
174
+ > **Note:** The `username` field is provided by the Customer Usernames plugin. Omit this field when the plugin is not installed.
175
+
176
+ ## Payment Methods and Settings
177
+
178
+ Retrieve customer authentication settings, checkout configuration, and available payment methods.
179
+
180
+ ### Customer Settings
181
+
182
+ ```ts
183
+ const { settings: loginSettings } = await caldik.customer.settings.get()
184
+ ```
185
+
186
+ ### Checkout Settings
187
+
188
+ ```ts
189
+ const { settings: checkoutSettings } = await caldik.checkout.settings.get()
190
+ ```
191
+
192
+ ### Available Payment Methods
193
+
194
+ ```ts
195
+ const { paymentMethods } = await caldik.checkout.paymentmethods.list()
196
+ ```
197
+
198
+ ### Combined Example
199
+
200
+ ```ts
201
+ const { settings: loginSettings } = await caldik.customer.settings.get()
202
+
203
+ const { settings: checkoutSettings } = await caldik.checkout.settings.get()
204
+
205
+ const { paymentMethods } = await caldik.checkout.paymentmethods.list()
206
+ ```
package/dist/index.d.mts CHANGED
@@ -139,16 +139,19 @@ interface ManualCommerceItem {
139
139
  unitAmount: string | number;
140
140
  }
141
141
  interface ProductCommerceItem {
142
+ customFields?: Record<string, string | number | boolean>;
142
143
  productId: string;
143
144
  productVariantId?: string;
144
145
  quantity?: number;
145
146
  }
146
147
  type CommerceItem = ManualCommerceItem | ProductCommerceItem;
147
148
  interface CreateOrderInput {
149
+ uiMode?: "hosted" | "elements";
150
+ returnUrl?: string;
148
151
  customerId?: string;
149
152
  email?: string;
150
153
  termsAccepted?: boolean;
151
- paymentMethod: CheckoutPaymentProviderId;
154
+ paymentMethod?: CheckoutPaymentProviderId;
152
155
  items: CommerceItem[];
153
156
  discountCode?: string;
154
157
  successUrl?: string;
@@ -157,10 +160,8 @@ interface CreateOrderInput {
157
160
  interface StorefrontOrder {
158
161
  id: string;
159
162
  shortId: string;
160
- displayId: string;
161
163
  customerId: string | null;
162
164
  paymentStatus: string;
163
- fulfillmentStatus: string;
164
165
  subtotal: string;
165
166
  amount: string;
166
167
  discount: {
@@ -171,6 +172,8 @@ interface StorefrontOrder {
171
172
  currency: string;
172
173
  }
173
174
  interface CheckoutPayment {
175
+ clientSecret?: string;
176
+ publishableKey?: string;
174
177
  type: CheckoutPaymentProviderId;
175
178
  checkoutUrl?: string | null;
176
179
  checkoutSessionId?: string | null;
@@ -223,23 +226,52 @@ interface StoreWebhookEvent<TObject extends Record<string, unknown> = Record<str
223
226
  }
224
227
  interface CustomerLoginResponse {
225
228
  success: boolean;
226
- message: string;
227
- loginId: string;
229
+ challengeId: string;
228
230
  }
229
231
  interface CustomerLoginVerifyResponse {
232
+ session?: {
233
+ token: string;
234
+ expiresAt: number;
235
+ };
230
236
  success: boolean;
237
+ }
238
+ interface CustomerPasswordResponse extends CustomerLoginVerifyResponse {
231
239
  customer: {
232
240
  id: string;
233
241
  shortId: string;
234
242
  displayId: string;
235
243
  email: string | null;
236
244
  status: string;
245
+ extensions?: Record<string, Record<string, string | number | boolean>>;
237
246
  };
238
247
  }
239
248
  interface CustomerPasswordInput {
249
+ /** A username from an installed identity plugin, or the customer's email. */
240
250
  username: string;
241
251
  password: string;
242
252
  }
253
+ interface CustomerRegistrationInput {
254
+ email: string;
255
+ password?: string;
256
+ /** Available when the store installs Customer Usernames. */
257
+ username?: string;
258
+ [pluginField: string]: string | number | boolean | undefined;
259
+ }
260
+ interface CustomerRegistrationResponse extends CustomerLoginResponse {
261
+ expiresAt: number;
262
+ }
263
+ interface CustomerProfileResponse {
264
+ success: boolean;
265
+ customer: {
266
+ id: string;
267
+ email: string | null;
268
+ extensions?: Record<string, Record<string, string | number | boolean>>;
269
+ };
270
+ balances: Array<{
271
+ currency: string;
272
+ amount: string;
273
+ }>;
274
+ }
243
275
  interface CustomerLoginSettings {
244
276
  passwordEnabled: boolean;
245
277
  }
@@ -248,6 +280,9 @@ interface CustomerLoginSettingsResponse {
248
280
  settings: CustomerLoginSettings;
249
281
  }
250
282
  interface CheckoutSettings {
283
+ termsUrl?: string | null;
284
+ refundPolicyUrl?: string | null;
285
+ embedStripeMode: "elements" | "hosted" | "popup";
251
286
  requireEmail: boolean;
252
287
  requireTermsAcceptance: boolean;
253
288
  }
@@ -347,13 +382,19 @@ declare class CustomerApi {
347
382
  };
348
383
  readonly login: {
349
384
  (email: string): Promise<CustomerLoginResponse>;
350
- (input: CustomerPasswordInput): Promise<CustomerLoginVerifyResponse>;
385
+ (input: CustomerPasswordInput): Promise<CustomerPasswordResponse>;
386
+ } & {
387
+ /** Pass challengeId to resume a code request after reloading the page. */verify: (code: string, challengeId?: string | undefined) => Promise<CustomerLoginVerifyResponse>;
388
+ };
389
+ readonly register: {
390
+ (email: string): Promise<CustomerRegistrationResponse>;
391
+ (input: CustomerRegistrationInput): Promise<CustomerRegistrationResponse>;
351
392
  } & {
352
- /** Pass loginId to resume a code request after reloading the page. */verify: (code: string, loginId?: string | undefined) => Promise<CustomerLoginVerifyResponse>;
393
+ /** Verify the email and atomically activate the account. Supports resuming after a reload. */verify: (code: string, challengeId?: string | undefined) => Promise<CustomerPasswordResponse>;
353
394
  };
354
395
  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>;
396
+ /** Read the signed-in customer and their balances. */
397
+ me(): Promise<CustomerProfileResponse>;
357
398
  }
358
399
  //#endregion
359
400
  //#region src/subscriptions.d.ts
@@ -446,4 +487,4 @@ declare class CaldikClient {
446
487
  constructor(options?: CaldikClientOptions);
447
488
  }
448
489
  //#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 };
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 };
package/dist/index.mjs CHANGED
@@ -177,32 +177,51 @@ var CustomerApi = class {
177
177
  client;
178
178
  settings;
179
179
  login;
180
+ register;
180
181
  constructor(client) {
181
182
  this.client = client;
182
183
  this.settings = { get: () => this.client.get("/customers/settings", void 0, { access: "public" }) };
183
- let pendingLoginId;
184
+ let pendingChallengeId;
184
185
  async function login(input) {
185
186
  if (typeof input !== "string") return client.post("/customers/login/password", input, { access: "public" });
186
187
  const response = await client.post("/customers/login", { email: input }, { access: "public" });
187
- pendingLoginId = response.loginId;
188
+ pendingChallengeId = response.challengeId;
188
189
  return response;
189
190
  }
190
191
  this.login = Object.assign(login, {
191
- /** Pass loginId to resume a code request after reloading the page. */
192
- verify: async (code, loginId = pendingLoginId) => {
192
+ /** Pass challengeId to resume a code request after reloading the page. */
193
+ verify: async (code, challengeId = pendingChallengeId) => {
193
194
  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");
195
+ if (!challengeId) throw new Error("Request a login code first or provide its challengeId");
195
196
  const response = await client.post("/customers/login/verify", {
196
197
  code,
197
- loginId
198
+ challengeId
198
199
  }, { access: "public" });
199
- if (pendingLoginId === loginId) pendingLoginId = void 0;
200
+ if (pendingChallengeId === challengeId) pendingChallengeId = void 0;
201
+ return response;
202
+ } });
203
+ let pendingRegistrationId;
204
+ async function register(input) {
205
+ const response = await client.post("/customers/register", typeof input === "string" ? { email: input } : input, { access: "public" });
206
+ pendingRegistrationId = response.challengeId;
207
+ return response;
208
+ }
209
+ this.register = Object.assign(register, {
210
+ /** Verify the email and atomically activate the account. Supports resuming after a reload. */
211
+ verify: async (code, challengeId = pendingRegistrationId) => {
212
+ if (!/^\d{6}$/.test(code)) throw new Error("A six-digit registration code is required");
213
+ if (!challengeId) throw new Error("Request a registration code first or provide its challengeId");
214
+ const response = await client.post("/customers/register/verify", {
215
+ code,
216
+ challengeId
217
+ }, { access: "public" });
218
+ if (pendingRegistrationId === challengeId) pendingRegistrationId = void 0;
200
219
  return response;
201
220
  } });
202
221
  }
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" });
222
+ /** Read the signed-in customer and their balances. */
223
+ me() {
224
+ return this.client.get("/customers/me", void 0, { access: "public" });
206
225
  }
207
226
  };
208
227
  //#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.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",