@swell/apps-sdk 1.0.190 → 2.0.0-alpha.0

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 (229) hide show
  1. package/README.md +146 -247
  2. package/dist/backend.d.cts +81 -0
  3. package/dist/backend.d.ts +81 -0
  4. package/dist/backend.js +152 -0
  5. package/dist/browser-refusal.d.cts +1 -0
  6. package/dist/browser-refusal.d.ts +1 -0
  7. package/dist/browser-refusal.js +2 -0
  8. package/dist/context.d.cts +21 -0
  9. package/dist/context.d.ts +21 -0
  10. package/dist/context.js +42 -0
  11. package/dist/error.d.cts +23 -0
  12. package/dist/error.d.ts +23 -0
  13. package/dist/error.js +30 -0
  14. package/dist/guard.d.cts +1 -0
  15. package/dist/guard.d.ts +1 -0
  16. package/dist/guard.js +4 -0
  17. package/dist/index.d.cts +9 -0
  18. package/dist/index.d.ts +9 -0
  19. package/dist/index.js +5 -20299
  20. package/dist/staff.d.cts +16 -0
  21. package/dist/staff.d.ts +16 -0
  22. package/dist/staff.js +33 -0
  23. package/dist/storefront.d.cts +28 -0
  24. package/dist/storefront.d.ts +28 -0
  25. package/dist/storefront.js +44 -0
  26. package/dist/version.d.cts +1 -0
  27. package/dist/version.d.ts +1 -0
  28. package/dist/version.js +2 -0
  29. package/dist/workflow.d.cts +1 -0
  30. package/dist/workflow.d.ts +1 -0
  31. package/dist/workflow.js +35 -0
  32. package/package.json +48 -63
  33. package/dist/index.cjs +0 -20547
  34. package/dist/index.cjs.map +0 -7
  35. package/dist/index.js.map +0 -7
  36. package/dist/index.mjs +0 -20404
  37. package/dist/index.mjs.map +0 -7
  38. package/dist/src/api.d.ts +0 -96
  39. package/dist/src/cache/cache.d.ts +0 -41
  40. package/dist/src/cache/cf-worker-kv-keyv-adapter.d.ts +0 -18
  41. package/dist/src/cache/constants.d.ts +0 -7
  42. package/dist/src/cache/content-cache.d.ts +0 -21
  43. package/dist/src/cache/html-cache/html-cache-backend.d.ts +0 -64
  44. package/dist/src/cache/html-cache/html-cache-factory.d.ts +0 -9
  45. package/dist/src/cache/html-cache/html-cache-kv.d.ts +0 -38
  46. package/dist/src/cache/html-cache/html-cache-worker.d.ts +0 -8
  47. package/dist/src/cache/html-cache/html-cache.d.ts +0 -120
  48. package/dist/src/cache/html-cache/index.d.ts +0 -4
  49. package/dist/src/cache/index.d.ts +0 -9
  50. package/dist/src/cache/kv-variety.d.ts +0 -10
  51. package/dist/src/cache/request-cache.d.ts +0 -4
  52. package/dist/src/cache/resource-cache.d.ts +0 -4
  53. package/dist/src/cache/theme-cache.d.ts +0 -4
  54. package/dist/src/cache/theme-file-cache.d.ts +0 -87
  55. package/dist/src/compatibility/drops/all_products.d.ts +0 -10
  56. package/dist/src/compatibility/drops/articles.d.ts +0 -10
  57. package/dist/src/compatibility/drops/blogs.d.ts +0 -10
  58. package/dist/src/compatibility/drops/collections.d.ts +0 -19
  59. package/dist/src/compatibility/drops/image-src.d.ts +0 -15
  60. package/dist/src/compatibility/drops/image.d.ts +0 -29
  61. package/dist/src/compatibility/drops/images.d.ts +0 -9
  62. package/dist/src/compatibility/drops/money.d.ts +0 -10
  63. package/dist/src/compatibility/drops/object-handles.d.ts +0 -6
  64. package/dist/src/compatibility/drops/pages.d.ts +0 -17
  65. package/dist/src/compatibility/drops/robots-rule.d.ts +0 -9
  66. package/dist/src/compatibility/drops/template.d.ts +0 -9
  67. package/dist/src/compatibility/shopify-configs.d.ts +0 -8
  68. package/dist/src/compatibility/shopify-fonts.d.ts +0 -1
  69. package/dist/src/compatibility/shopify-objects/address.d.ts +0 -7
  70. package/dist/src/compatibility/shopify-objects/article.d.ts +0 -7
  71. package/dist/src/compatibility/shopify-objects/blog.d.ts +0 -6
  72. package/dist/src/compatibility/shopify-objects/cart.d.ts +0 -6
  73. package/dist/src/compatibility/shopify-objects/collection.d.ts +0 -7
  74. package/dist/src/compatibility/shopify-objects/collections.d.ts +0 -6
  75. package/dist/src/compatibility/shopify-objects/content.d.ts +0 -12
  76. package/dist/src/compatibility/shopify-objects/currency.d.ts +0 -5
  77. package/dist/src/compatibility/shopify-objects/customer.d.ts +0 -6
  78. package/dist/src/compatibility/shopify-objects/filter.d.ts +0 -6
  79. package/dist/src/compatibility/shopify-objects/font.d.ts +0 -5
  80. package/dist/src/compatibility/shopify-objects/form.d.ts +0 -29
  81. package/dist/src/compatibility/shopify-objects/image.d.ts +0 -10
  82. package/dist/src/compatibility/shopify-objects/index.d.ts +0 -27
  83. package/dist/src/compatibility/shopify-objects/line_item.d.ts +0 -7
  84. package/dist/src/compatibility/shopify-objects/link.d.ts +0 -5
  85. package/dist/src/compatibility/shopify-objects/localization.d.ts +0 -5
  86. package/dist/src/compatibility/shopify-objects/media.d.ts +0 -9
  87. package/dist/src/compatibility/shopify-objects/money.d.ts +0 -3
  88. package/dist/src/compatibility/shopify-objects/order.d.ts +0 -11
  89. package/dist/src/compatibility/shopify-objects/page.d.ts +0 -5
  90. package/dist/src/compatibility/shopify-objects/paginate.d.ts +0 -5
  91. package/dist/src/compatibility/shopify-objects/predictive_search.d.ts +0 -5
  92. package/dist/src/compatibility/shopify-objects/product.d.ts +0 -9
  93. package/dist/src/compatibility/shopify-objects/recommendations.d.ts +0 -5
  94. package/dist/src/compatibility/shopify-objects/resource.d.ts +0 -27
  95. package/dist/src/compatibility/shopify-objects/search.d.ts +0 -5
  96. package/dist/src/compatibility/shopify-objects/shop.d.ts +0 -5
  97. package/dist/src/compatibility/shopify-objects/template.d.ts +0 -4
  98. package/dist/src/compatibility/shopify-objects/variant.d.ts +0 -6
  99. package/dist/src/compatibility/shopify.d.ts +0 -134
  100. package/dist/src/constants.d.ts +0 -598
  101. package/dist/src/content.d.ts +0 -8
  102. package/dist/src/easyblocks/config.d.ts +0 -152
  103. package/dist/src/easyblocks/index.d.ts +0 -2
  104. package/dist/src/easyblocks/utils.d.ts +0 -23
  105. package/dist/src/editor/resources.d.ts +0 -9
  106. package/dist/src/fonts.d.ts +0 -6
  107. package/dist/src/globals.d.ts +0 -7
  108. package/dist/src/index.d.ts +0 -16
  109. package/dist/src/liquid/color.d.ts +0 -33
  110. package/dist/src/liquid/drops/render.d.ts +0 -10
  111. package/dist/src/liquid/filters/asset_url.d.ts +0 -3
  112. package/dist/src/liquid/filters/brightness_difference.d.ts +0 -2
  113. package/dist/src/liquid/filters/color_brightness.d.ts +0 -2
  114. package/dist/src/liquid/filters/color_contrast.d.ts +0 -2
  115. package/dist/src/liquid/filters/color_darken.d.ts +0 -2
  116. package/dist/src/liquid/filters/color_desaturate.d.ts +0 -2
  117. package/dist/src/liquid/filters/color_difference.d.ts +0 -2
  118. package/dist/src/liquid/filters/color_extract.d.ts +0 -4
  119. package/dist/src/liquid/filters/color_lighten.d.ts +0 -2
  120. package/dist/src/liquid/filters/color_mix.d.ts +0 -2
  121. package/dist/src/liquid/filters/color_modify.d.ts +0 -3
  122. package/dist/src/liquid/filters/color_saturate.d.ts +0 -2
  123. package/dist/src/liquid/filters/color_to_hex.d.ts +0 -2
  124. package/dist/src/liquid/filters/color_to_hsl.d.ts +0 -2
  125. package/dist/src/liquid/filters/color_to_rgb.d.ts +0 -2
  126. package/dist/src/liquid/filters/date.d.ts +0 -7
  127. package/dist/src/liquid/filters/date_next_interval.d.ts +0 -3
  128. package/dist/src/liquid/filters/default_errors.d.ts +0 -3
  129. package/dist/src/liquid/filters/divided_by.d.ts +0 -2
  130. package/dist/src/liquid/filters/embedded_content.d.ts +0 -2
  131. package/dist/src/liquid/filters/escape.d.ts +0 -3
  132. package/dist/src/liquid/filters/font_face.d.ts +0 -2
  133. package/dist/src/liquid/filters/font_modify.d.ts +0 -3
  134. package/dist/src/liquid/filters/font_url.d.ts +0 -2
  135. package/dist/src/liquid/filters/format_address.d.ts +0 -6
  136. package/dist/src/liquid/filters/handleize.d.ts +0 -3
  137. package/dist/src/liquid/filters/image_tag.d.ts +0 -3
  138. package/dist/src/liquid/filters/image_url.d.ts +0 -8
  139. package/dist/src/liquid/filters/index.d.ts +0 -120
  140. package/dist/src/liquid/filters/inline_asset_content.d.ts +0 -2
  141. package/dist/src/liquid/filters/inline_editable.d.ts +0 -4
  142. package/dist/src/liquid/filters/json.d.ts +0 -3
  143. package/dist/src/liquid/filters/json_pretty.d.ts +0 -3
  144. package/dist/src/liquid/filters/locale_flag.d.ts +0 -2
  145. package/dist/src/liquid/filters/minus.d.ts +0 -2
  146. package/dist/src/liquid/filters/money.d.ts +0 -4
  147. package/dist/src/liquid/filters/money_with_currency.d.ts +0 -3
  148. package/dist/src/liquid/filters/money_without_currency.d.ts +0 -3
  149. package/dist/src/liquid/filters/money_without_trailing_zeros.d.ts +0 -3
  150. package/dist/src/liquid/filters/preload_tag.d.ts +0 -3
  151. package/dist/src/liquid/filters/script_tag.d.ts +0 -3
  152. package/dist/src/liquid/filters/shopify/asset_img_url.d.ts +0 -3
  153. package/dist/src/liquid/filters/shopify/default_pagination.d.ts +0 -3
  154. package/dist/src/liquid/filters/shopify/hex_to_rgba.d.ts +0 -2
  155. package/dist/src/liquid/filters/shopify/img_url.d.ts +0 -3
  156. package/dist/src/liquid/filters/shopify/item_count_for_variant.d.ts +0 -6
  157. package/dist/src/liquid/filters/shopify/payment_button.d.ts +0 -2
  158. package/dist/src/liquid/filters/shopify/payment_terms.d.ts +0 -2
  159. package/dist/src/liquid/filters/shopify/placeholder-svgs/index.d.ts +0 -5
  160. package/dist/src/liquid/filters/shopify/placeholder_svg_tag.d.ts +0 -3
  161. package/dist/src/liquid/filters/shopify/shopify_asset_url.d.ts +0 -3
  162. package/dist/src/liquid/filters/shopify/structured_data.d.ts +0 -3
  163. package/dist/src/liquid/filters/stylesheet_tag.d.ts +0 -3
  164. package/dist/src/liquid/filters/time_tag.d.ts +0 -2
  165. package/dist/src/liquid/filters/translate.d.ts +0 -3
  166. package/dist/src/liquid/filters/where.d.ts +0 -3
  167. package/dist/src/liquid/font.d.ts +0 -51
  168. package/dist/src/liquid/form.d.ts +0 -17
  169. package/dist/src/liquid/hash.d.ts +0 -5
  170. package/dist/src/liquid/index.d.ts +0 -52
  171. package/dist/src/liquid/operators.d.ts +0 -10
  172. package/dist/src/liquid/tags/assign.d.ts +0 -3
  173. package/dist/src/liquid/tags/case.d.ts +0 -3
  174. package/dist/src/liquid/tags/comment.d.ts +0 -3
  175. package/dist/src/liquid/tags/content_for.d.ts +0 -3
  176. package/dist/src/liquid/tags/doc.d.ts +0 -2
  177. package/dist/src/liquid/tags/for.d.ts +0 -3
  178. package/dist/src/liquid/tags/form.d.ts +0 -3
  179. package/dist/src/liquid/tags/if.d.ts +0 -4
  180. package/dist/src/liquid/tags/index.d.ts +0 -42
  181. package/dist/src/liquid/tags/inline_editable.d.ts +0 -3
  182. package/dist/src/liquid/tags/javascript.d.ts +0 -3
  183. package/dist/src/liquid/tags/layout.d.ts +0 -3
  184. package/dist/src/liquid/tags/paginate.d.ts +0 -3
  185. package/dist/src/liquid/tags/render.d.ts +0 -6
  186. package/dist/src/liquid/tags/section.d.ts +0 -3
  187. package/dist/src/liquid/tags/sections.d.ts +0 -3
  188. package/dist/src/liquid/tags/shopify/include.d.ts +0 -3
  189. package/dist/src/liquid/tags/shopify/schema.d.ts +0 -3
  190. package/dist/src/liquid/tags/style.d.ts +0 -3
  191. package/dist/src/liquid/tags/stylesheet.d.ts +0 -3
  192. package/dist/src/liquid/test-helpers.d.ts +0 -8
  193. package/dist/src/liquid/tokens/identifier-token.d.ts +0 -9
  194. package/dist/src/liquid/tokens/index.d.ts +0 -2
  195. package/dist/src/liquid/tokienizer.d.ts +0 -5
  196. package/dist/src/liquid/utils.d.ts +0 -45
  197. package/dist/src/menus.d.ts +0 -25
  198. package/dist/src/resources/account.d.ts +0 -6
  199. package/dist/src/resources/addresses.d.ts +0 -7
  200. package/dist/src/resources/blog.d.ts +0 -7
  201. package/dist/src/resources/blog_category.d.ts +0 -7
  202. package/dist/src/resources/cart.d.ts +0 -6
  203. package/dist/src/resources/categories.d.ts +0 -7
  204. package/dist/src/resources/category.d.ts +0 -7
  205. package/dist/src/resources/index.d.ts +0 -48
  206. package/dist/src/resources/order.d.ts +0 -7
  207. package/dist/src/resources/orders.d.ts +0 -7
  208. package/dist/src/resources/page.d.ts +0 -7
  209. package/dist/src/resources/predictive_search.d.ts +0 -6
  210. package/dist/src/resources/product.d.ts +0 -7
  211. package/dist/src/resources/product_helpers.d.ts +0 -21
  212. package/dist/src/resources/search.d.ts +0 -6
  213. package/dist/src/resources/subscription.d.ts +0 -7
  214. package/dist/src/resources/subscriptions.d.ts +0 -7
  215. package/dist/src/resources/swell_types.d.ts +0 -163
  216. package/dist/src/resources/variant.d.ts +0 -9
  217. package/dist/src/resources.d.ts +0 -113
  218. package/dist/src/theme/theme-loader.d.ts +0 -110
  219. package/dist/src/theme.d.ts +0 -204
  220. package/dist/src/utils/escape.d.ts +0 -1
  221. package/dist/src/utils/index.d.ts +0 -34
  222. package/dist/src/utils/kv-flavor.d.ts +0 -7
  223. package/dist/src/utils/logger.d.ts +0 -21
  224. package/dist/src/utils/md5.d.ts +0 -1
  225. package/dist/types/cloudflare.d.ts +0 -61
  226. package/dist/types/shopify.d.ts +0 -1035
  227. package/dist/types/swell.d.ts +0 -576
  228. package/types/index.d.ts +0 -4
  229. package/types/svg.d.ts +0 -4
package/README.md CHANGED
@@ -1,304 +1,203 @@
1
1
  # Swell Apps SDK
2
2
 
3
- The Swell Apps SDK is a TypeScript-based library designed to simplify the development of isomorphic Swell apps by providing streamlined API access, theme rendering capabilities, and comprehensive caching solutions.
4
-
5
- ## Features
6
-
7
- ### Core functionality
8
- - **Unified API access** - Seamless integration with both Swell Backend API and Storefront API
9
- - **Authentication handling** - Automatic scoped access token management based on app permissions
10
- - **Theme rendering** - Complete Shopify-compatible theme system with Liquid templating
11
- - **Resource management** - Deferred loading of storefront resources (products, categories, etc.)
12
- - **Caching system** - Multi-tier caching with Cloudflare KV integration
13
- - **Shopify compatibility** - Full compatibility layer for migrating Shopify themes and apps
14
-
15
- ### Theme capabilities
16
- - **Liquid templating** - Enhanced Liquid engine with Swell-specific objects and filters
17
- - **Section rendering** - Dynamic section management with schema support
18
- - **Settings resolution** - Automatic theme and section settings processing
19
- - **Layout system** - Flexible layout rendering with section groups
20
- - **Asset management** - Optimized asset loading and URL generation
21
- - **Localization** - Multi-language support with translation rendering
22
-
23
- ### Developer experience
24
- - **TypeScript support** - Full type safety with comprehensive type definitions
25
- - **Isomorphic design** - Works seamlessly in both browser and server environments
26
- - **Error handling** - Robust error management with detailed debugging information
27
- - **Performance optimized** - Built-in caching and resource optimization
28
- - **Extensible architecture** - Plugin system for custom resource types
3
+ The Swell Apps SDK is a TypeScript library for building server-side Swell apps. It
4
+ provides access to the Backend and Storefront APIs, along with helpers for app
5
+ configuration, customer sessions and staff identity.
6
+
7
+ Use it in Swell-hosted apps, Cloudflare Workers or Node.js servers. For browser
8
+ applications, use [`swell-js`](https://github.com/swellstores/swell-js).
29
9
 
30
10
  ## Installation
31
11
 
32
- ```bash
33
- npm install @swell/apps-sdk
12
+ ```sh
13
+ npm install @swell/apps-sdk@next swell-js@^5.9.1
34
14
  ```
35
15
 
16
+ Supports Node.js 22.22.2+ and Cloudflare Workers, with no Node compatibility flags
17
+ needed in Workers. Includes ES modules, CommonJS and TypeScript declarations.
18
+
19
+ Version 2 replaces the 1.x theme API. Existing theme applications should remain on
20
+ 1.x until migrated to `@swell/themes-sdk`.
21
+
36
22
  ## Getting started
37
23
 
38
- ### Basic setup
24
+ ### Headers and app proxying
39
25
 
40
- ```typescript
41
- import { Swell } from '@swell/apps-sdk';
26
+ When your app runs on Swell, the platform supplies request headers with API
27
+ credentials, store configuration and storefront context. Pass the request's headers
28
+ to the SDK to work with the current store. Create clients for each incoming request.
42
29
 
43
- // Initialize Swell instance in your app frontend
44
- const swell = new Swell({
45
- serverHeaders: context.request.headers, // Headers from worker environment
46
- });
30
+ Only use these headers when they come through Swell's trusted proxy. On other servers,
31
+ use explicit credentials as shown below.
47
32
 
48
- // Make backend API calls
49
- const products = await swell.backend.get('/products');
33
+ ### Backend API calls
50
34
 
51
- // Make storefront API calls
52
- const cart = await swell.storefront.get('/cart');
53
- ```
35
+ ```ts
36
+ import { SwellBackendAPI } from '@swell/apps-sdk';
54
37
 
55
- ### Headers and app proxying
38
+ // Use the credentials supplied to your Swell-hosted app.
39
+ const backend = new SwellBackendAPI({ headers: request.headers });
56
40
 
57
- When your Swell app is deployed, it runs behind Swell's proxy infrastructure. The proxy automatically injects essential headers that contain authentication tokens, store configuration, and storefront context. These headers are critical for the SDK to function properly:
58
-
59
- ```typescript
60
- // Headers passed from Swell's proxy contain:
61
- // - swell-store-id: The store identifier
62
- // - swell-public-key: Frontend API access key
63
- // - swell-access-token: Backend API access token (scoped to app permissions)
64
- // - swell-storefront-id: Current storefront instance
65
- // - swell-environment-id: Environment (development, staging, production)
66
- // - swell-theme-id: Active theme identifier
67
- // - swell-storefront-context: Preloaded cart/account data
68
-
69
- const swell = new Swell({
70
- serverHeaders: context.request.headers, // Contains all proxy-injected headers
71
- getCookie: (name) => getCookieValue(name),
72
- setCookie: (name, value, options) => setCookieValue(name, value, options),
73
- });
41
+ // Fetch products from the Backend API.
42
+ const products = await backend.get('/products', { limit: 10 });
74
43
  ```
75
44
 
76
- Without these headers, the SDK cannot:
77
- - Authenticate with Swell APIs
78
- - Determine which store and storefront to operate on
79
- - Access cached resources or maintain session state
80
- - Render themes with proper configuration
45
+ For an external server, read credentials from your server configuration:
81
46
 
82
- The `serverHeaders` parameter should always be passed the complete headers object from your app's request context to ensure full functionality.
47
+ ```ts
48
+ const backend = new SwellBackendAPI({ storeId, secretKey, apiHost });
49
+ ```
83
50
 
84
- ### Theme rendering
51
+ ### Storefront API calls
85
52
 
86
- ```typescript
87
- import { Swell, SwellTheme, SwellProduct } from '@swell/apps-sdk';
53
+ Use the Storefront API for customer-facing data and cart or account operations.
54
+ In this example, `cookies` is your framework's cookie jar. Its reads must include
55
+ pending writes and deletions.
88
56
 
89
- const swell = new Swell({
90
- serverHeaders: context.request.headers,
91
- ...options,
92
- });
57
+ ```ts
58
+ import { getStorefrontConfig } from '@swell/apps-sdk';
59
+ import { createStorefrontClient } from '@swell/apps-sdk/storefront';
93
60
 
94
- // Initialize theme with optional configuration
95
- const theme = new SwellTheme(swell, {
96
- forms: formConfigs,
97
- resources: customResources,
98
- globals: additionalGlobals,
61
+ // Build the storefront config from the platform headers.
62
+ const config = getStorefrontConfig(request.headers);
63
+ const storefront = createStorefrontClient(config, {
64
+ cookies: {
65
+ get: name => cookies.get(name)?.value,
66
+ set: (name, value, options) => { cookies.set(name, value, options); },
67
+ },
99
68
  });
100
69
 
101
- // Fetch settings and set global context
102
- await theme.initGlobals('product'); // page ID
103
-
104
- // Create page data with deferred resource loading
105
- const data = {
106
- product: new SwellProduct(swell, context.params.id),
107
- };
108
-
109
- // Render theme page
110
- const renderedPage = await theme.renderPage(data);
70
+ // Use the same methods available in swell-js.
71
+ const products = await storefront.products.list({ limit: 10 });
111
72
  ```
112
73
 
113
- ## API reference
74
+ External servers can supply `storeId`, `publicKey` and `swell-js` options such as
75
+ `url`, `locale` or `currency` directly as the config. Only the `/storefront` entry
76
+ loads the `swell-js` runtime.
114
77
 
115
- ### Swell class
116
-
117
- The main entry point for SDK functionality:
118
-
119
- ```typescript
120
- class Swell {
121
- // API access
122
- backend: SwellBackendAPI;
123
- storefront: typeof SwellJS;
124
-
125
- // Configuration
126
- config: SwellAppConfig;
127
- url: URL;
128
- headers: Record<string, string>;
129
- queryParams: ParsedQs;
130
-
131
- // State
132
- isEditor: boolean;
133
- isPreview: boolean;
134
- storefrontContext: SwellData;
135
-
136
- // Methods
137
- get<T>(url: string, query?: SwellData): Promise<T>;
138
- post<T>(url: string, data: SwellData): Promise<T>;
139
- put<T>(url: string, data: SwellData): Promise<T>;
140
- delete<T>(url: string, data?: SwellData): Promise<T>;
141
- getCachedResource<T>(key: string, args: unknown[], handler: () => T, isCacheble = true): Promise<T>;
142
- }
143
- ```
78
+ ### Browser configuration
144
79
 
145
- ### SwellTheme class
146
-
147
- Handles theme rendering and management:
148
-
149
- ```typescript
150
- class SwellTheme {
151
- // Core properties
152
- swell: Swell;
153
- globals: ThemeGlobals;
154
- liquidSwell: LiquidSwell;
155
-
156
- // Methods
157
- initGlobals(pageId: string, altTemplate?: string): Promise<void>;
158
- renderPage(pageData?: SwellData, altTemplate?: string): Promise<string>;
159
- renderSection(sectionId: string, pageData?: SwellData): Promise<string>;
160
- renderLayout(layoutName?: string, data?: SwellData): Promise<string>;
161
- getSectionSchema(sectionName: string): Promise<ThemeSectionSchema>;
162
- setGlobals(globals: Partial<ThemeGlobals>): void;
163
- }
164
- ```
80
+ Send the public config from `getStorefrontConfig` to your browser app through a
81
+ loader or endpoint with `Cache-Control: private, no-store`. Then initialize swell-js:
165
82
 
166
- ### Resource classes
167
-
168
- Built-in storefront resource classes for deferred loading:
169
-
170
- #### Standard resources
171
- - `SwellAccount` - Customer account management
172
- - `SwellBlog` - Blog post content
173
- - `SwellBlogCategory` - Blog categorization
174
- - `SwellCart` - Shopping cart state
175
- - `SwellCategory` - Product categories
176
- - `SwellOrder` - Order information
177
- - `SwellPage` - Static pages
178
- - `SwellProduct` - Product details
179
- - `SwellVariant` - Product variants
180
-
181
- #### Primitive resources
182
- - `SwellStorefrontCollection` - Collection results with pagination
183
- - `SwellStorefrontRecord` - Individual records
184
- - `SwellStorefrontSingleton` - Unique resources (cart, account)
185
-
186
- ```typescript
187
- // Create custom resource class
188
- class MyAppCollection extends SwellStorefrontCollection {
189
- constructor(swell: Swell, query: SwellData = {}) {
190
- super(swell, 'my-app-collection', query);
191
- return this._getProxy();
192
- }
193
- }
194
-
195
- // Usage in theme data
196
- const data = {
197
- myCollection: new MyAppCollection(swell, { limit: 20 }),
198
- };
83
+ ```ts
84
+ import swell from 'swell-js';
85
+
86
+ swell.init(config.storeId, config.publicKey, config);
199
87
  ```
200
88
 
201
- ## Caching
89
+ This config excludes backend credentials. For server-side metadata, use
90
+ `parseSwellHeaders(headers)`. It reads headers without verifying their signature;
91
+ keep its result on the server because it includes the backend token.
202
92
 
203
- ### Memory caching
204
- Resources are automatically cached in memory per worker instance:
93
+ ### Staff identity
205
94
 
206
- ```typescript
207
- // Cached resource with custom handler
208
- const cachedData = await swell.getCachedResource(
209
- 'expensive-operation',
210
- [param1, param2],
211
- async () => {
212
- return await performExpensiveOperation(param1, param2);
213
- }
214
- );
215
- ```
95
+ Use `requireStaff` to check that a request belongs to a staff member of the current
96
+ store before applying your application's permission checks:
216
97
 
217
- ### Cloudflare KV caching
218
- For production scalability, enable KV caching:
98
+ ```ts
99
+ import { requireStaff } from '@swell/apps-sdk';
219
100
 
220
- ```typescript
221
- const swell = new Swell({
222
- serverHeaders: context.request.headers,
223
- workerEnv: context.locals.runtime.env, // Contains THEME KV binding
224
- workerCtx: context.locals.runtime.ctx, // Worker context
101
+ const staff = await requireStaff({
102
+ headers: request.headers,
103
+ method: request.method,
104
+ origin: appOrigin, // Your configured app origin.
105
+ cookies: { get: name => cookies.get(name)?.value },
225
106
  });
226
107
  ```
227
108
 
228
- ### Cache invalidation
229
- Caches are automatically invalidated based on:
230
- - Session cookies (for cart/account data)
231
- - Theme configuration versions
232
- - Storefront environment changes
109
+ ## API reference
233
110
 
234
- ## Shopify compatibility
111
+ ### Backend client
235
112
 
236
- The SDK includes comprehensive Shopify compatibility for theme migration.
113
+ `apiHost` is a required absolute HTTP(S) URL. Use either `secretKey` or `accessToken`;
114
+ do not mix explicit credentials with `headers`. Invalid constructor options throw
115
+ immediately. All backend methods return promises and reject on failure.
237
116
 
238
- ### Supported Shopify features
239
- - **Template mapping** - Direct file path compatibility
240
- - **Liquid objects** - Full object structure compatibility
241
- - **Form handling** - Compatible form endpoints and validation
242
- - **Section schemas** - Shopify section configuration format
243
- - **Settings data** - `settings_data.json` and `settings_schema.json`
117
+ | Method | Result |
118
+ | --- | --- |
119
+ | `get(path, query?)` | Response data |
120
+ | `post(path, data?)`, `put(path, data?)`, `delete(path, data?)` | Response data |
121
+ | `settings(appId?)` | Installed-app settings; defaults to the configured app ID |
122
+ | `workflows.create(name, params?)` | Created workflow instance |
123
+ | `transaction(ops, options?)` | Operation results in input order |
124
+ | `functions.call(appId, name, data?, options?)` | Function response payload |
244
125
 
245
- ## Liquid templating
126
+ Response generics describe expected data without validating it. `SwellCollection<T>`
127
+ is for ordinary paginated lists; aggregations and `page: false` return other shapes.
246
128
 
247
- Enhanced Liquid templating with Swell-specific features. See [Swell Liquid documentation](https://developers.swell.is/storefronts/swell-liquid-reference) for details.
129
+ Requests stay on the configured host; redirects are refused. Use endpoint paths,
130
+ not absolute URLs. Request IDs are forwarded when supplied. GET queries use bracket
131
+ notation, omit undefined values, encode Dates as ISO strings, and preserve native
132
+ null separately from the string `'null'`. Other methods send JSON.
248
133
 
249
- ## Performance optimization
134
+ **Workflows:** supplied parameters must be JSON-safe and at most 128 KiB of serialized
135
+ UTF-8 JSON. Omitted parameters are not sent. Invalid or oversized parameters reject
136
+ with `workflow_params_unserializable` or `workflow_params_too_large`.
250
137
 
251
- ### Lazy loading
252
- Resources are loaded only when accessed in templates:
138
+ **Transactions:** each operation contains `method`, `url` and optional `data`.
139
+ Retries are off by default. Set `retry: true` or
140
+ `retry: { limit: 3, base: 100, max: 5000, jitter: true }` to enable them. These are the
141
+ defaults: `limit` counts additional attempts, and delays are in milliseconds. Only
142
+ `transaction_conflict` and `transaction_throttled` retry. Ordinary requests and network
143
+ failures are not retried.
253
144
 
254
- ```liquid
255
- <!-- Product data is fetched only when this line executes -->
256
- {{ product.name }}
145
+ **Private functions:** use the app slug from `Swell-App-Id` and authorize the caller
146
+ first. `options.method` defaults to `post`; `get`, `put` and `delete` are also supported.
147
+ GET data must contain only flat string, number or boolean values. Caller headers are
148
+ not forwarded; response status and headers are not returned. Function errors and
149
+ non-2xx statuses reject with `SwellError`.
257
150
 
258
- <!-- Collection is fetched only when iteration begins -->
259
- {% for item in collection.products %}
260
- {{ item.name }}
261
- {% endfor %}
262
- ```
151
+ Private-app calls require platform support for app-slug lookup and fail on deployments
152
+ without it. Function execution and `req.swell` remain managed by the CLI and platform.
263
153
 
264
- ## Development
154
+ ### Cookies and caching
265
155
 
266
- ### Building the SDK
267
- ```bash
268
- # Install dependencies
269
- npm install
156
+ Cookie adapters exchange decoded values and own the current state. If your framework
157
+ reads only incoming cookies, track pending writes and deletions in request-local state.
158
+ The SDK keeps no cookie cache.
270
159
 
271
- # Build for production
272
- npm run build
160
+ Native cookie names and defaults apply: path `/`, one week, `sameSite: 'lax'`.
161
+ `cookieOptions` replaces these defaults; `{}` delegates attributes to the adapter.
162
+ Per-write attributes take precedence.
273
163
 
274
- # Watch for changes
275
- npm run watch
164
+ Omit `cookies.set` for read-only access. Attempted writes then throw, including session
165
+ rotation during GET requests. A supplied writer may throw or skip a write; after a skip,
166
+ its reader must still report the actual state. Writer return values are ignored.
167
+ Persist cookies in writable route handlers or actions.
276
168
 
277
- # Run tests
278
- npm test
279
- ```
169
+ For caching, replace `storefront.request` before first use. The SDK has no built-in cache.
280
170
 
281
- ### Project structure
282
- ```
283
- src/
284
- ├── api.ts # Core Swell class and API handling
285
- ├── theme.ts # SwellTheme class and rendering
286
- ├── resources.ts # Storefront resource classes
287
- ├── liquid/ # Liquid templating engine
288
- ├── compatibility/ # Shopify compatibility layer
289
- ├── cache/ # Caching implementations
290
- ├── utils/ # Utility functions
291
- └── index.ts # Main exports
292
- ```
171
+ ### Staff verification
293
172
 
294
- ## Resources
173
+ `requireStaff` verifies `_swell_admin_session` against the current store and returns
174
+ `{ userId, storeId }`. Use a trusted `appOrigin`: every non-GET request requires a
175
+ matching `Origin` and, when present, `Sec-Fetch-Site: same-origin`. Failures reject.
176
+ The helper checks identity and request origin; your application enforces permissions.
177
+
178
+ ### Errors
179
+
180
+ Import `SwellError` from the root package. Use `status` and optional `code`/`body` for
181
+ error handling; `message` is for people and may change.
182
+
183
+ - Structured backend errors retain their body; string errors have no body.
184
+ - HTTP-200 non-GET validation failures use status 400 and the `errors` field map as
185
+ `body`. Successful GET responses containing `errors` are returned as data.
186
+ - Function invocation failures retain the response payload, or the invocation envelope
187
+ when the payload is null or absent, in `body`.
188
+ - Network errors remain native. Local configuration errors may be ordinary `Error`
189
+ instances; not every failure is a `SwellError`.
190
+
191
+ ## Development
192
+
193
+ ```sh
194
+ npm ci
195
+ npm run verify
196
+ ```
295
197
 
296
- - [Swell Documentation](https://developers.swell.is/)
297
- - [Apps Development Guide](https://developers.swell.is/apps/overview)
298
- - [Proxima Example App](https://developers.swell.is/storefronts/proxima)
299
- - [Swell Liquid Reference](https://developers.swell.is/storefronts/swell-liquid-reference)
300
- - [GitHub Repository](https://github.com/swellstores/swell-apps-sdk)
198
+ `verify` builds the SDK, runs unit tests and typechecks, then checks the packed package,
199
+ browser/Worker boundaries and workerd execution.
301
200
 
302
- ## 📄 License
201
+ ## License
303
202
 
304
- See the [LICENSE](LICENSE) file for details.
203
+ [MIT](LICENSE)
@@ -0,0 +1,81 @@
1
+ import type { HeaderReader } from './context.cjs';
2
+ export type SwellData = Record<string, any>;
3
+ export type BackendOptions = {
4
+ headers: HeaderReader;
5
+ storeId?: never;
6
+ apiHost?: never;
7
+ accessToken?: never;
8
+ secretKey?: never;
9
+ appId?: never;
10
+ requestId?: never;
11
+ } | ({
12
+ headers?: never;
13
+ storeId: string;
14
+ apiHost: string;
15
+ appId?: string;
16
+ requestId?: string;
17
+ } & ({
18
+ accessToken: string;
19
+ secretKey?: never;
20
+ } | {
21
+ secretKey: string;
22
+ accessToken?: never;
23
+ }));
24
+ /** Envelope of an ordinary paginated backend list. `page: false` and aggregations return other shapes. */
25
+ export interface SwellCollection<T = SwellData> {
26
+ results: T[];
27
+ count: number;
28
+ page: number;
29
+ page_count: number;
30
+ limit: number;
31
+ pages?: Record<string, {
32
+ start: number;
33
+ end: number;
34
+ }>;
35
+ }
36
+ export interface TransactionOperation {
37
+ method: string;
38
+ url: string;
39
+ data?: any;
40
+ }
41
+ export interface TransactionOptions {
42
+ /** Opt in to retries: limit counts additional attempts (default 3); base/max are ms (100/5000); jitter defaults to true. */
43
+ retry?: true | {
44
+ limit?: number;
45
+ base?: number;
46
+ max?: number;
47
+ jitter?: boolean;
48
+ };
49
+ }
50
+ /** Per-request backend client. Use explicit credentials outside trusted platform ingress. */
51
+ export declare class SwellBackendAPI {
52
+ #private;
53
+ protected get userAgent(): string;
54
+ readonly workflows: {
55
+ /** Creates a workflow instance. Optional params must be JSON-safe and at most 128 KiB of UTF-8 JSON; invalid params reject. */
56
+ create: (name: string, params?: unknown) => Promise<SwellData>;
57
+ };
58
+ readonly functions: {
59
+ /**
60
+ * Invokes an app's private function from server code and resolves to its response payload,
61
+ * without the envelope's status or headers.
62
+ * `appId` is the app identifier from `Swell-App-Id` (`parseSwellHeaders(headers).appId`).
63
+ * `method` (default `post`) selects the function's handler. GET data reaches the function
64
+ * as query parameters, so its values must be flat strings, numbers or booleans.
65
+ * Throws `SwellError` when the function reports a non-2xx status or an error.
66
+ * Callers authorize the operation first; no caller headers are forwarded.
67
+ */
68
+ call: <T = SwellData>(appId: string, name: string, data?: SwellData, { method }?: {
69
+ method?: "get" | "post" | "put" | "delete";
70
+ }) => Promise<T>;
71
+ };
72
+ constructor(options: BackendOptions);
73
+ get<T = SwellData>(path: string, query?: SwellData): Promise<T>;
74
+ put<T = SwellData>(path: string, data?: any): Promise<T>;
75
+ post<T = SwellData>(path: string, data?: any): Promise<T>;
76
+ delete<T = SwellData>(path: string, data?: any): Promise<T>;
77
+ /** Reads installed-app settings; defaults to the configured app ID and rejects when neither ID is supplied. */
78
+ settings<T = SwellData>(appId?: string | undefined): Promise<T>;
79
+ /** Atomic operations returning results in operation order; only conflicts and throttling retry, and only when requested. */
80
+ transaction(ops: TransactionOperation[], options?: TransactionOptions): Promise<any[]>;
81
+ }
@@ -0,0 +1,81 @@
1
+ import type { HeaderReader } from './context.js';
2
+ export type SwellData = Record<string, any>;
3
+ export type BackendOptions = {
4
+ headers: HeaderReader;
5
+ storeId?: never;
6
+ apiHost?: never;
7
+ accessToken?: never;
8
+ secretKey?: never;
9
+ appId?: never;
10
+ requestId?: never;
11
+ } | ({
12
+ headers?: never;
13
+ storeId: string;
14
+ apiHost: string;
15
+ appId?: string;
16
+ requestId?: string;
17
+ } & ({
18
+ accessToken: string;
19
+ secretKey?: never;
20
+ } | {
21
+ secretKey: string;
22
+ accessToken?: never;
23
+ }));
24
+ /** Envelope of an ordinary paginated backend list. `page: false` and aggregations return other shapes. */
25
+ export interface SwellCollection<T = SwellData> {
26
+ results: T[];
27
+ count: number;
28
+ page: number;
29
+ page_count: number;
30
+ limit: number;
31
+ pages?: Record<string, {
32
+ start: number;
33
+ end: number;
34
+ }>;
35
+ }
36
+ export interface TransactionOperation {
37
+ method: string;
38
+ url: string;
39
+ data?: any;
40
+ }
41
+ export interface TransactionOptions {
42
+ /** Opt in to retries: limit counts additional attempts (default 3); base/max are ms (100/5000); jitter defaults to true. */
43
+ retry?: true | {
44
+ limit?: number;
45
+ base?: number;
46
+ max?: number;
47
+ jitter?: boolean;
48
+ };
49
+ }
50
+ /** Per-request backend client. Use explicit credentials outside trusted platform ingress. */
51
+ export declare class SwellBackendAPI {
52
+ #private;
53
+ protected get userAgent(): string;
54
+ readonly workflows: {
55
+ /** Creates a workflow instance. Optional params must be JSON-safe and at most 128 KiB of UTF-8 JSON; invalid params reject. */
56
+ create: (name: string, params?: unknown) => Promise<SwellData>;
57
+ };
58
+ readonly functions: {
59
+ /**
60
+ * Invokes an app's private function from server code and resolves to its response payload,
61
+ * without the envelope's status or headers.
62
+ * `appId` is the app identifier from `Swell-App-Id` (`parseSwellHeaders(headers).appId`).
63
+ * `method` (default `post`) selects the function's handler. GET data reaches the function
64
+ * as query parameters, so its values must be flat strings, numbers or booleans.
65
+ * Throws `SwellError` when the function reports a non-2xx status or an error.
66
+ * Callers authorize the operation first; no caller headers are forwarded.
67
+ */
68
+ call: <T = SwellData>(appId: string, name: string, data?: SwellData, { method }?: {
69
+ method?: "get" | "post" | "put" | "delete";
70
+ }) => Promise<T>;
71
+ };
72
+ constructor(options: BackendOptions);
73
+ get<T = SwellData>(path: string, query?: SwellData): Promise<T>;
74
+ put<T = SwellData>(path: string, data?: any): Promise<T>;
75
+ post<T = SwellData>(path: string, data?: any): Promise<T>;
76
+ delete<T = SwellData>(path: string, data?: any): Promise<T>;
77
+ /** Reads installed-app settings; defaults to the configured app ID and rejects when neither ID is supplied. */
78
+ settings<T = SwellData>(appId?: string | undefined): Promise<T>;
79
+ /** Atomic operations returning results in operation order; only conflicts and throttling retry, and only when requested. */
80
+ transaction(ops: TransactionOperation[], options?: TransactionOptions): Promise<any[]>;
81
+ }