@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 +144 -11
- package/dist/index.d.mts +54 -6
- package/dist/index.mjs +36 -5
- package/package.json +1 -1
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
96
|
+
```ts
|
|
44
97
|
caldik.cart.updateQuantity(cart.items[0].id, 3)
|
|
98
|
+
```
|
|
45
99
|
|
|
46
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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(
|
|
114
|
-
|
|
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",
|
|
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" });
|