arky-sdk 0.9.6 → 0.9.12

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.
Files changed (45) hide show
  1. package/README.md +113 -194
  2. package/dist/admin-D8HiRDCl.d.cts +1536 -0
  3. package/dist/admin-Dnnv18wN.d.ts +1536 -0
  4. package/dist/admin.cjs +832 -375
  5. package/dist/admin.cjs.map +1 -1
  6. package/dist/admin.d.cts +3 -3
  7. package/dist/admin.d.ts +3 -3
  8. package/dist/admin.js +832 -375
  9. package/dist/admin.js.map +1 -1
  10. package/dist/api-D4lMmvF0.d.cts +4337 -0
  11. package/dist/api-D4lMmvF0.d.ts +4337 -0
  12. package/dist/{index-nCF3Z6Af.d.cts → index-BS2x278C.d.cts} +1 -1
  13. package/dist/{index-CZxubTDA.d.ts → index-Be8suRwP.d.ts} +1 -1
  14. package/dist/index.cjs +934 -460
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -3
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +934 -460
  19. package/dist/index.js.map +1 -1
  20. package/dist/storefront.cjs +501 -300
  21. package/dist/storefront.cjs.map +1 -1
  22. package/dist/storefront.d.cts +174 -89
  23. package/dist/storefront.d.ts +174 -89
  24. package/dist/storefront.js +499 -299
  25. package/dist/storefront.js.map +1 -1
  26. package/dist/types.cjs.map +1 -1
  27. package/dist/types.d.cts +1 -1
  28. package/dist/types.d.ts +1 -1
  29. package/dist/types.js.map +1 -1
  30. package/dist/utils.d.cts +2 -2
  31. package/dist/utils.d.ts +2 -2
  32. package/package.json +7 -10
  33. package/scripts/contract-admin.mjs +137 -0
  34. package/scripts/contract-storefront.mjs +296 -0
  35. package/dist/admin-DjYydKeB.d.ts +0 -1389
  36. package/dist/admin-DlL8mCxL.d.cts +0 -1389
  37. package/dist/api-BbBHcd4p.d.cts +0 -3289
  38. package/dist/api-BbBHcd4p.d.ts +0 -3289
  39. package/dist/storefront-store.cjs +0 -2809
  40. package/dist/storefront-store.cjs.map +0 -1
  41. package/dist/storefront-store.d.cts +0 -5
  42. package/dist/storefront-store.d.ts +0 -5
  43. package/dist/storefront-store.js +0 -2807
  44. package/dist/storefront-store.js.map +0 -1
  45. package/scripts/smoke-store.mjs +0 -41
package/README.md CHANGED
@@ -1,28 +1,8 @@
1
1
  # arky-sdk
2
2
 
3
- Official TypeScript SDK for [Arky](https://arky.io) Build online stores with headless CMS, e-commerce, and service scheduling.
3
+ Official TypeScript SDK for [Arky](https://arky.io), the website backend and client Admin for custom frontends.
4
4
 
5
- ## What is Arky?
6
-
7
- Arky is an **all-in-one platform** that gives you everything you need to run an online store:
8
-
9
- - 📝 **Headless CMS** - Manage content with flexible blocks, multilingual support, and AI-powered content generation
10
- - 🛒 **E-commerce** - Sell products with multi-currency pricing, inventory, orders, and Stripe payments
11
- - 📅 **Service Scheduling** - Sell scheduled services with providers and availability calendars
12
- - 📧 **Campaigns** - Send template-backed newsletters, broadcasts, and outreach emails through tenant mailboxes
13
- - 👥 **User Management** - Authentication, roles, permissions, and user profiles
14
- - 💳 **Payments** - Integrated Stripe checkout and promo codes
15
-
16
- **Build any online store:** SaaS products, e-commerce shops, service businesses, content sites, newsletters, or multi-tenant marketplaces.
17
-
18
- ## Why Use This SDK?
19
-
20
- Instead of manually calling REST APIs, use this TypeScript SDK to:
21
-
22
- ✅ **Type-safe** - Full TypeScript support with IntelliSense
23
- ✅ **Auto-authentication** - Handles tokens, refresh, and guest sessions automatically
24
- ✅ **Utility helpers** - Extract block values, format prices, slugify text, validate phones
25
- ✅ **Framework-agnostic** - Works in React, Vue, Svelte, Node.js, or any JS environment
5
+ Arky lets you keep frontend control while using one backend for CMS, commerce, bookings, forms, profiles, action, experiments, support, workflows, API, and SDK.
26
6
 
27
7
  ## Installation
28
8
 
@@ -30,244 +10,183 @@ Instead of manually calling REST APIs, use this TypeScript SDK to:
30
10
  npm install arky-sdk
31
11
  ```
32
12
 
33
- ## Quick Start
13
+ ## Storefront Quick Start
34
14
 
35
- ### 1. Install & Initialize
15
+ Use `initialize` from `arky-sdk/storefront` for normal custom frontends. It creates the Arky storefront object, keeps store/locale/market context, and exposes the backend modules the frontend needs.
36
16
 
37
17
  ```typescript
38
- import { createArkyStore } from 'arky-sdk/storefront-store'
39
-
40
- const arkyStore = createArkyStore({
41
- baseUrl: 'https://api.arky.io',
42
- storeId: 'your-store-id',
43
- market: 'us',
44
- locale: 'en',
45
- marketForLocale: (locale) => locale === 'it' ? 'ita' : 'us',
46
- })
47
-
48
- const { cart } = await arkyStore.setup({
49
- locale: 'en',
50
- hydrateCart: true,
51
- })
52
-
53
- const websiteNode = await arkyStore.cms.node.get({
54
- key: 'website',
55
- locale: 'en',
56
- })
57
- ```
18
+ import { initialize } from "arky-sdk/storefront";
19
+
20
+ const arky = initialize({
21
+ baseUrl: "https://api.arky.io",
22
+ storeId: "your-store-id",
23
+ market: "us",
24
+ locale: "en",
25
+ marketForLocale: (locale) => (locale === "it" ? "ita" : "us"),
26
+ });
58
27
 
59
- ### 2. Browse Products
28
+ const homepage = await arky.cms.entry.get({
29
+ collection_id: "pages",
30
+ key: "homepage",
31
+ locale: "en",
32
+ });
60
33
 
61
- ```typescript
62
- // List products (like on arky.io/products)
63
- const { items: products } = await arkyStore.eshop.product.list({
64
- limit: 20
34
+ await arky.action.track({
35
+ key: "page.view",
36
+ payload: { path: location.pathname },
65
37
  });
38
+ ```
66
39
 
67
- // Get product details (like arky.io/products/guitar)
68
- const product = await arkyStore.eshop.product.loadDetail({ id: 'prod_123' });
40
+ `initialize` is the public storefront factory. Use the Arky domain noun `Store` for tenant/business concepts, not for naming the SDK factory.
69
41
 
70
- // Format price (uses currency from price object)
71
- const formatted = arkyStore.utils.formatPrice(product.variants[0].prices); // "$29.99"
72
- ```
42
+ ## Storefront Modules
73
43
 
74
- ### 3. Shop & Checkout
44
+ The storefront module API is the preferred surface for websites:
75
45
 
76
46
  ```typescript
77
- const product = await arkyStore.eshop.product.loadDetail({ id: 'prod_123' })
78
- const variant = product.variants[0]
47
+ await arky.cart.load();
79
48
 
80
- await arkyStore.eshop.cart.addProduct(product, variant, 2)
49
+ await arky.cms.entry.get({
50
+ collection_id: "pages",
51
+ key: "homepage",
52
+ locale: "en",
53
+ });
54
+ await arky.cms.form.submitByKey({ key: "contact", entries: [] });
81
55
 
82
- const quote = await arkyStore.eshop.cart.quote()
56
+ const { items: products } = await arky.eshop.product.list({ limit: 20 });
57
+ await arky.cart.addProduct(products[0], products[0].variants[0], 1);
58
+ await arky.cart.quote();
59
+ await arky.cart.checkout({ payment_method_id: "cash" });
83
60
 
84
- const order = await arkyStore.eshop.cart.checkout({
85
- payment_method_id: 'credit_card',
86
- })
87
- ```
61
+ const { items: services } = await arky.eshop.service.list({ limit: 20 });
62
+ await arky.eshop.service.initialize();
88
63
 
89
- ### Framework-Agnostic Store
64
+ await arky.action.track({
65
+ key: "project.inquiry.started",
66
+ payload: { placement: "homepage" },
67
+ });
68
+ ```
90
69
 
91
- The storefront store is framework-agnostic and built on Nano Stores. UI frameworks can subscribe to atoms directly, while app code calls direct store methods:
70
+ UI frameworks can subscribe to Nano Stores exposed by the modules:
92
71
 
93
72
  ```typescript
94
- await arkyStore.setup({
95
- locale: 'en',
96
- hydrateCart: true,
97
- track: {
98
- type: 'page_view',
99
- payload: { url: location.pathname },
100
- },
101
- })
102
-
103
- const unsubscribe = arkyStore.eshop.cart.snapshot.subscribe((snapshot) => {
104
- console.log(snapshot.item_count, snapshot.cart?.id)
73
+ const unsubscribe = arky.eshop.cart.snapshot.subscribe((snapshot) => {
74
+ console.log(snapshot.item_count, snapshot.cart?.id);
105
75
  });
106
76
 
107
- await arkyStore.eshop.cart.ensure();
108
- await arkyStore.eshop.cart.clear();
109
-
77
+ await arky.eshop.cart.load();
110
78
  unsubscribe();
111
79
  ```
112
80
 
113
- For content-heavy pages, a website node load can be a single context-aware call:
114
-
115
- ```typescript
116
- const website = await arkyStore.cms.node.get({ key: "website", locale: 'en' })
117
- const info = website.blocks.find((block) => block.key === 'info')
118
- ```
81
+ ## Read Content And Submit Forms
119
82
 
120
- The low-level SDK client is still available as `arkyStore.client` for unusual cases, but normal storefronts should use the store-shaped modules: `cms`, `eshop`, `crm`, `activity`, `automation`, `store`, and `utils`.
121
-
122
- ### 4. Sell Scheduled Services
83
+ The server storefront entry route uses collection entries. Key-based content loads must include `collection_id`.
123
84
 
124
85
  ```typescript
125
- // Browse services (like arky.io/services)
126
- const { items: services } = await arkyStore.eshop.service.list({});
127
- const service = services[0];
128
-
129
- await arkyStore.eshop.service.initialize();
130
- await arkyStore.eshop.service.select(service);
131
- arkyStore.eshop.service.findFirstAvailable();
132
-
133
- const state = arkyStore.eshop.service.state.get();
134
- if (state.slots[0]) {
135
- arkyStore.eshop.service.selectTimeSlot(state.slots[0]);
136
- arkyStore.eshop.service.nextStep();
137
- await arkyStore.eshop.service.addToCart();
138
- }
139
-
140
- const order = await arkyStore.eshop.cart.checkout({
141
- payment_method_id: 'cash',
86
+ const page = await arky.cms.entry.get({
87
+ collection_id: "pages",
88
+ key: "homepage",
89
+ locale: "en",
142
90
  });
143
- ```
144
-
145
- ### 5. Read Content And Submit Forms
146
91
 
147
- ```typescript
148
- const website = await arkyStore.cms.node.get({ key: "website", locale: 'en' })
149
- const titleBlock = website.blocks.find((block) => block.key === 'title')
150
- const title = arkyStore.utils.getBlockTextValue(titleBlock, 'en')
92
+ const titleBlock = page.blocks.find((block) => block.key === "title");
93
+ const title = arky.utils.getBlockTextValue(titleBlock, "en");
151
94
 
152
- await arkyStore.cms.form.submitByKey({
153
- key: 'contact',
95
+ await arky.cms.form.submitByKey({
96
+ key: "contact",
154
97
  entries: [
155
- { key: 'email', value: 'profile@example.com' },
156
- { key: 'message', value: 'Hello from the storefront' },
98
+ { key: "email", value: "profile@example.com" },
99
+ { key: "message", value: "Hello from the storefront" },
157
100
  ],
158
- })
101
+ });
159
102
  ```
160
103
 
161
- ## Storefront Modules
162
-
163
- The store-shaped API is the preferred surface for websites:
104
+ ## Browse Products And Checkout
164
105
 
165
106
  ```typescript
166
- await arkyStore.setup({ hydrateCart: true })
167
-
168
- await arkyStore.cms.node.get({ key: "website", locale: 'en' })
169
- await arkyStore.cms.form.submitByKey({ key: 'contact', entries: [] })
107
+ const { items: products } = await arky.eshop.product.list({ limit: 20 });
108
+ const product = await arky.eshop.product.loadDetail({ id: products[0].id });
109
+ const variant = product.variants[0];
170
110
 
171
- await arkyStore.eshop.product.list({ limit: 20 })
172
- await arkyStore.eshop.cart.ensure()
173
- await arkyStore.eshop.cart.quote()
174
- await arkyStore.eshop.cart.checkout({ payment_method_id: 'cash' })
111
+ await arky.eshop.cart.addProduct(product, variant, 2);
175
112
 
176
- await arkyStore.eshop.service.list({ limit: 20 })
177
- await arkyStore.eshop.service.initialize()
113
+ const quote = await arky.eshop.cart.quote();
178
114
 
179
- await arkyStore.activity.pageView({ path: location.pathname })
115
+ const order = await arky.eshop.cart.checkout({
116
+ payment_method_id: "credit_card",
117
+ });
180
118
  ```
181
119
 
182
- ## Low-Level Client
183
-
184
- The underlying SDK remains available for admin tools or uncommon integrations:
120
+ ## Sell Scheduled Services
185
121
 
186
122
  ```typescript
187
- const sdk = arkyStore.client
123
+ const { items: services } = await arky.eshop.service.list({ limit: 20 });
124
+
125
+ await arky.eshop.service.initialize();
126
+ await arky.eshop.service.select(services[0]);
127
+ arky.eshop.service.findFirstAvailable();
128
+
129
+ const state = arky.eshop.service.state.get();
130
+ if (state.slots[0]) {
131
+ arky.eshop.service.selectTimeSlot(state.slots[0]);
132
+ arky.eshop.service.nextStep();
133
+ await arky.eshop.service.addToCart();
134
+ }
188
135
 
189
- await sdk.eshop.product.find({ limit: 20 })
190
- await sdk.eshop.cart.current({ market: arkyStore.getMarket() })
191
- await sdk.eshop.order.find({})
192
- await sdk.cms.node.get({ key: 'website' })
136
+ await arky.eshop.cart.checkout({
137
+ payment_method_id: "cash",
138
+ });
193
139
  ```
194
140
 
195
- ## Utility Functions
141
+ ## Low-Level Client
196
142
 
197
- The SDK includes helpful utilities accessible through `arkyStore.utils`:
143
+ The lower-level SDK client remains available as `arky.client` for admin tools and advanced frontend utilities. Normal storefronts should use the module API first.
198
144
 
199
145
  ```typescript
200
- const title = arkyStore.utils.getBlockTextValue(block, 'en')
201
- const imageUrl = arkyStore.utils.getImageUrl(imageBlock)
202
- const price = arkyStore.utils.formatPrice(prices)
203
- const payment = arkyStore.utils.formatPayment(paymentObject)
204
- const slug = arkyStore.utils.slugify('Hello World')
205
- const date = arkyStore.utils.formatDate(Date.now(), 'en')
206
- const phone = arkyStore.utils.validatePhoneNumber('+1234567890')
146
+ const sdk = arky.client;
147
+
148
+ await sdk.eshop.product.find({ limit: 20 });
149
+ await sdk.eshop.cart.current({ market: arky.getMarket() });
150
+ await sdk.eshop.order.find({});
151
+ await sdk.cms.entry.find({
152
+ collection_id: "pages",
153
+ key: "homepage",
154
+ limit: 1,
155
+ });
207
156
  ```
208
157
 
209
- ## What Can You Build?
210
-
211
- - 🏪 **E-commerce shops** - Product catalogs, shopping carts, checkout
212
- - 📰 **Content websites** - Blogs, documentation, marketing sites
213
- - 📅 **Service businesses** - Appointment scheduling, service scheduling
214
- - 📬 **Newsletter platforms** - Subscriber management, email campaigns
215
- - 🏢 **SaaS products** - Multi-tenant apps with user auth and billing
216
- - 🛍️ **Marketplaces** - Multi-vendor platforms with payments
217
-
218
158
  ## Configuration Options
219
159
 
220
160
  ```typescript
221
- createArkyStore({
161
+ initialize({
222
162
  // Required
223
- baseUrl: string, // API URL
224
- storeId: string, // Your store ID
163
+ baseUrl: string,
164
+ storeId: string,
225
165
 
226
166
  // Optional
227
- market?: string, // Market key (e.g., 'us', 'eu')
228
- locale?: string, // Storefront locale (default: SDK/client locale)
229
- apiToken?: string, // Trusted server-side API token
167
+ market?: string,
168
+ locale?: string,
169
+ apiToken?: string,
230
170
  marketForLocale?: (locale: string) => string | null,
231
171
  navigate?: (path: string) => void,
232
172
  loginFallbackPath?: string,
233
- })
173
+ });
234
174
  ```
235
175
 
236
176
  ## TypeScript Support
237
177
 
238
- The SDK is written in TypeScript and provides full type definitions:
239
-
240
178
  ```typescript
241
- import type {
242
- HttpClientConfig,
243
- ApiResponse,
244
- Block,
245
- Store,
246
- Price,
247
- // ... and many more
248
- } from 'arky-sdk'
179
+ import { initialize, type ArkyStore } from "arky-sdk/storefront";
180
+ import type { Block, Cart, Order, Price, Product, Service, Store } from "arky-sdk";
249
181
  ```
250
182
 
251
- ## Adding a new endpoint
183
+ ## Adding A New Endpoint
252
184
 
253
185
  When adding a new SDK method, follow this checklist so the API surface stays typed end-to-end and request shapes stay aligned with the Rust DTOs on the server:
254
186
 
255
- 1. **Define the entity** in `src/types/index.ts` if it does not already exist. Mirror the Rust response struct field-for-field.
256
- 2. **Define the request params** in `src/types/api.ts`. Mirror the Rust DTO in `server/core/src/{module}/types/commands.rs` field-for-field. Two exceptions: `store_id?: string` and `market?: string` are optional in TS (the SDK auto-fills both from `apiConfig.storeId` and `apiConfig.market`). Do **not** use `[key: string]: any` index signatures.
257
- 3. **Annotate the SDK method's return type** using the matching entity from `src/types/index.ts`.
258
- 4. **Pass the response generic to the HTTP call**: `apiConfig.httpClient.post<EntityType>(...)`, `apiConfig.httpClient.get<PaginatedResponse<EntityType>>(...)`, etc. Never rely on inference.
259
- 5. **Inject `market` from `apiConfig`**: when a body needs a `market` field, write `{ market: apiConfig.market, ...payload }`. Never hardcode `"default"`, `"eshop"`, or any other market string in `src/api/*.ts`.
260
- 6. **Re-export the entity** from `src/index.ts` if consumers (admin, storefront) will import it.
261
- 7. **Bump `SDK_VERSION`** in `src/index.ts` and the `version` in `package.json`. Patch only.
262
-
263
- A guardrail script (`scripts/check-no-any.mjs`) runs on `npm run build` (via `prebuild`) and fails red if `: any`, `as any`, or hardcoded `market: "..."` literals show up in `src/api/*.ts`.
264
-
265
- ## License
266
-
267
- MIT
268
-
269
- ## Links
270
-
271
- - [Documentation](https://docs.arky.io)
272
- - [GitHub](https://github.com/0xDjole/arky-sdk)
273
- - [npm](https://www.npmjs.com/package/arky-sdk)
187
+ 1. Define the entity in `src/types/index.ts` if it does not already exist. Mirror the Rust response struct field-for-field.
188
+ 2. Define the request params in `src/types/api.ts`. Mirror the Rust DTO in `server/core/src/{module}/types/commands.rs` field-for-field. Two exceptions: `store_id?: string` and `market?: string` are optional in TS because the SDK auto-fills both from `apiConfig.storeId` and `apiConfig.market`. Do not use `[key: string]: any` index signatures.
189
+ 3. Annotate the SDK method's return type using the matching entity from `src/types/index.ts`.
190
+ 4. Pass the response generic to the HTTP call: `apiConfig.httpClient.post<EntityType>(...)`, `apiConfig.httpClient.get<PaginatedResponse<EntityType>>(...)`, etc. Never rely on inference.
191
+ 5. Inject `market` from `apiConfig`: when a body needs a `market` field, write `{ market: apiConfig.market, ...payload }`. Never hardcode `"default"`, `"eshop"`, or any other market string in `src/api/*.ts`.
192
+ 6. Re-export the entity from `src/index.ts` if consumers will import it.