@swell/apps-sdk 1.0.189 → 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.
- package/README.md +146 -247
- package/dist/backend.d.cts +81 -0
- package/dist/backend.d.ts +81 -0
- package/dist/backend.js +152 -0
- package/dist/browser-refusal.d.cts +1 -0
- package/dist/browser-refusal.d.ts +1 -0
- package/dist/browser-refusal.js +2 -0
- package/dist/context.d.cts +21 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.js +42 -0
- package/dist/error.d.cts +23 -0
- package/dist/error.d.ts +23 -0
- package/dist/error.js +30 -0
- package/dist/guard.d.cts +1 -0
- package/dist/guard.d.ts +1 -0
- package/dist/guard.js +4 -0
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +5 -20298
- package/dist/staff.d.cts +16 -0
- package/dist/staff.d.ts +16 -0
- package/dist/staff.js +33 -0
- package/dist/storefront.d.cts +28 -0
- package/dist/storefront.d.ts +28 -0
- package/dist/storefront.js +44 -0
- package/dist/version.d.cts +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/workflow.d.cts +1 -0
- package/dist/workflow.d.ts +1 -0
- package/dist/workflow.js +35 -0
- package/package.json +48 -63
- package/dist/index.cjs +0 -20546
- package/dist/index.cjs.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/index.mjs +0 -20403
- package/dist/index.mjs.map +0 -7
- package/dist/src/api.d.ts +0 -96
- package/dist/src/cache/cache.d.ts +0 -41
- package/dist/src/cache/cf-worker-kv-keyv-adapter.d.ts +0 -18
- package/dist/src/cache/constants.d.ts +0 -7
- package/dist/src/cache/content-cache.d.ts +0 -21
- package/dist/src/cache/html-cache/html-cache-backend.d.ts +0 -64
- package/dist/src/cache/html-cache/html-cache-factory.d.ts +0 -9
- package/dist/src/cache/html-cache/html-cache-kv.d.ts +0 -38
- package/dist/src/cache/html-cache/html-cache-worker.d.ts +0 -8
- package/dist/src/cache/html-cache/html-cache.d.ts +0 -120
- package/dist/src/cache/html-cache/index.d.ts +0 -4
- package/dist/src/cache/index.d.ts +0 -9
- package/dist/src/cache/kv-variety.d.ts +0 -10
- package/dist/src/cache/request-cache.d.ts +0 -4
- package/dist/src/cache/resource-cache.d.ts +0 -4
- package/dist/src/cache/theme-cache.d.ts +0 -4
- package/dist/src/cache/theme-file-cache.d.ts +0 -87
- package/dist/src/compatibility/drops/all_products.d.ts +0 -10
- package/dist/src/compatibility/drops/articles.d.ts +0 -10
- package/dist/src/compatibility/drops/blogs.d.ts +0 -10
- package/dist/src/compatibility/drops/collections.d.ts +0 -19
- package/dist/src/compatibility/drops/image-src.d.ts +0 -15
- package/dist/src/compatibility/drops/image.d.ts +0 -29
- package/dist/src/compatibility/drops/images.d.ts +0 -9
- package/dist/src/compatibility/drops/money.d.ts +0 -10
- package/dist/src/compatibility/drops/object-handles.d.ts +0 -6
- package/dist/src/compatibility/drops/pages.d.ts +0 -17
- package/dist/src/compatibility/drops/robots-rule.d.ts +0 -9
- package/dist/src/compatibility/drops/template.d.ts +0 -9
- package/dist/src/compatibility/shopify-configs.d.ts +0 -8
- package/dist/src/compatibility/shopify-fonts.d.ts +0 -1
- package/dist/src/compatibility/shopify-objects/address.d.ts +0 -7
- package/dist/src/compatibility/shopify-objects/article.d.ts +0 -7
- package/dist/src/compatibility/shopify-objects/blog.d.ts +0 -6
- package/dist/src/compatibility/shopify-objects/cart.d.ts +0 -6
- package/dist/src/compatibility/shopify-objects/collection.d.ts +0 -7
- package/dist/src/compatibility/shopify-objects/collections.d.ts +0 -6
- package/dist/src/compatibility/shopify-objects/content.d.ts +0 -12
- package/dist/src/compatibility/shopify-objects/currency.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/customer.d.ts +0 -6
- package/dist/src/compatibility/shopify-objects/filter.d.ts +0 -6
- package/dist/src/compatibility/shopify-objects/font.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/form.d.ts +0 -29
- package/dist/src/compatibility/shopify-objects/image.d.ts +0 -10
- package/dist/src/compatibility/shopify-objects/index.d.ts +0 -27
- package/dist/src/compatibility/shopify-objects/line_item.d.ts +0 -7
- package/dist/src/compatibility/shopify-objects/link.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/localization.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/media.d.ts +0 -9
- package/dist/src/compatibility/shopify-objects/money.d.ts +0 -3
- package/dist/src/compatibility/shopify-objects/order.d.ts +0 -11
- package/dist/src/compatibility/shopify-objects/page.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/paginate.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/predictive_search.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/product.d.ts +0 -9
- package/dist/src/compatibility/shopify-objects/recommendations.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/resource.d.ts +0 -27
- package/dist/src/compatibility/shopify-objects/search.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/shop.d.ts +0 -5
- package/dist/src/compatibility/shopify-objects/template.d.ts +0 -4
- package/dist/src/compatibility/shopify-objects/variant.d.ts +0 -6
- package/dist/src/compatibility/shopify.d.ts +0 -134
- package/dist/src/constants.d.ts +0 -598
- package/dist/src/content.d.ts +0 -8
- package/dist/src/easyblocks/config.d.ts +0 -152
- package/dist/src/easyblocks/index.d.ts +0 -2
- package/dist/src/easyblocks/utils.d.ts +0 -23
- package/dist/src/editor/resources.d.ts +0 -9
- package/dist/src/fonts.d.ts +0 -6
- package/dist/src/globals.d.ts +0 -7
- package/dist/src/index.d.ts +0 -16
- package/dist/src/liquid/color.d.ts +0 -33
- package/dist/src/liquid/drops/render.d.ts +0 -10
- package/dist/src/liquid/filters/asset_url.d.ts +0 -3
- package/dist/src/liquid/filters/brightness_difference.d.ts +0 -2
- package/dist/src/liquid/filters/color_brightness.d.ts +0 -2
- package/dist/src/liquid/filters/color_contrast.d.ts +0 -2
- package/dist/src/liquid/filters/color_darken.d.ts +0 -2
- package/dist/src/liquid/filters/color_desaturate.d.ts +0 -2
- package/dist/src/liquid/filters/color_difference.d.ts +0 -2
- package/dist/src/liquid/filters/color_extract.d.ts +0 -4
- package/dist/src/liquid/filters/color_lighten.d.ts +0 -2
- package/dist/src/liquid/filters/color_mix.d.ts +0 -2
- package/dist/src/liquid/filters/color_modify.d.ts +0 -3
- package/dist/src/liquid/filters/color_saturate.d.ts +0 -2
- package/dist/src/liquid/filters/color_to_hex.d.ts +0 -2
- package/dist/src/liquid/filters/color_to_hsl.d.ts +0 -2
- package/dist/src/liquid/filters/color_to_rgb.d.ts +0 -2
- package/dist/src/liquid/filters/date.d.ts +0 -7
- package/dist/src/liquid/filters/date_next_interval.d.ts +0 -3
- package/dist/src/liquid/filters/default_errors.d.ts +0 -3
- package/dist/src/liquid/filters/divided_by.d.ts +0 -2
- package/dist/src/liquid/filters/embedded_content.d.ts +0 -2
- package/dist/src/liquid/filters/escape.d.ts +0 -3
- package/dist/src/liquid/filters/font_face.d.ts +0 -2
- package/dist/src/liquid/filters/font_modify.d.ts +0 -3
- package/dist/src/liquid/filters/font_url.d.ts +0 -2
- package/dist/src/liquid/filters/format_address.d.ts +0 -6
- package/dist/src/liquid/filters/handleize.d.ts +0 -3
- package/dist/src/liquid/filters/image_tag.d.ts +0 -3
- package/dist/src/liquid/filters/image_url.d.ts +0 -8
- package/dist/src/liquid/filters/index.d.ts +0 -120
- package/dist/src/liquid/filters/inline_asset_content.d.ts +0 -2
- package/dist/src/liquid/filters/inline_editable.d.ts +0 -4
- package/dist/src/liquid/filters/json.d.ts +0 -3
- package/dist/src/liquid/filters/json_pretty.d.ts +0 -3
- package/dist/src/liquid/filters/locale_flag.d.ts +0 -2
- package/dist/src/liquid/filters/minus.d.ts +0 -2
- package/dist/src/liquid/filters/money.d.ts +0 -4
- package/dist/src/liquid/filters/money_with_currency.d.ts +0 -3
- package/dist/src/liquid/filters/money_without_currency.d.ts +0 -3
- package/dist/src/liquid/filters/money_without_trailing_zeros.d.ts +0 -3
- package/dist/src/liquid/filters/preload_tag.d.ts +0 -3
- package/dist/src/liquid/filters/script_tag.d.ts +0 -3
- package/dist/src/liquid/filters/shopify/asset_img_url.d.ts +0 -3
- package/dist/src/liquid/filters/shopify/default_pagination.d.ts +0 -3
- package/dist/src/liquid/filters/shopify/hex_to_rgba.d.ts +0 -2
- package/dist/src/liquid/filters/shopify/img_url.d.ts +0 -3
- package/dist/src/liquid/filters/shopify/item_count_for_variant.d.ts +0 -6
- package/dist/src/liquid/filters/shopify/payment_button.d.ts +0 -2
- package/dist/src/liquid/filters/shopify/payment_terms.d.ts +0 -2
- package/dist/src/liquid/filters/shopify/placeholder-svgs/index.d.ts +0 -5
- package/dist/src/liquid/filters/shopify/placeholder_svg_tag.d.ts +0 -3
- package/dist/src/liquid/filters/shopify/shopify_asset_url.d.ts +0 -3
- package/dist/src/liquid/filters/shopify/structured_data.d.ts +0 -3
- package/dist/src/liquid/filters/stylesheet_tag.d.ts +0 -3
- package/dist/src/liquid/filters/time_tag.d.ts +0 -2
- package/dist/src/liquid/filters/translate.d.ts +0 -3
- package/dist/src/liquid/filters/where.d.ts +0 -3
- package/dist/src/liquid/font.d.ts +0 -51
- package/dist/src/liquid/form.d.ts +0 -17
- package/dist/src/liquid/hash.d.ts +0 -5
- package/dist/src/liquid/index.d.ts +0 -52
- package/dist/src/liquid/operators.d.ts +0 -10
- package/dist/src/liquid/tags/assign.d.ts +0 -3
- package/dist/src/liquid/tags/case.d.ts +0 -3
- package/dist/src/liquid/tags/comment.d.ts +0 -3
- package/dist/src/liquid/tags/content_for.d.ts +0 -3
- package/dist/src/liquid/tags/doc.d.ts +0 -2
- package/dist/src/liquid/tags/for.d.ts +0 -3
- package/dist/src/liquid/tags/form.d.ts +0 -3
- package/dist/src/liquid/tags/if.d.ts +0 -4
- package/dist/src/liquid/tags/index.d.ts +0 -42
- package/dist/src/liquid/tags/inline_editable.d.ts +0 -3
- package/dist/src/liquid/tags/javascript.d.ts +0 -3
- package/dist/src/liquid/tags/layout.d.ts +0 -3
- package/dist/src/liquid/tags/paginate.d.ts +0 -3
- package/dist/src/liquid/tags/render.d.ts +0 -6
- package/dist/src/liquid/tags/section.d.ts +0 -3
- package/dist/src/liquid/tags/sections.d.ts +0 -3
- package/dist/src/liquid/tags/shopify/include.d.ts +0 -3
- package/dist/src/liquid/tags/shopify/schema.d.ts +0 -3
- package/dist/src/liquid/tags/style.d.ts +0 -3
- package/dist/src/liquid/tags/stylesheet.d.ts +0 -3
- package/dist/src/liquid/test-helpers.d.ts +0 -8
- package/dist/src/liquid/tokens/identifier-token.d.ts +0 -9
- package/dist/src/liquid/tokens/index.d.ts +0 -2
- package/dist/src/liquid/tokienizer.d.ts +0 -5
- package/dist/src/liquid/utils.d.ts +0 -45
- package/dist/src/menus.d.ts +0 -25
- package/dist/src/resources/account.d.ts +0 -6
- package/dist/src/resources/addresses.d.ts +0 -7
- package/dist/src/resources/blog.d.ts +0 -7
- package/dist/src/resources/blog_category.d.ts +0 -7
- package/dist/src/resources/cart.d.ts +0 -6
- package/dist/src/resources/categories.d.ts +0 -7
- package/dist/src/resources/category.d.ts +0 -7
- package/dist/src/resources/index.d.ts +0 -48
- package/dist/src/resources/order.d.ts +0 -7
- package/dist/src/resources/orders.d.ts +0 -7
- package/dist/src/resources/page.d.ts +0 -7
- package/dist/src/resources/predictive_search.d.ts +0 -6
- package/dist/src/resources/product.d.ts +0 -7
- package/dist/src/resources/product_helpers.d.ts +0 -21
- package/dist/src/resources/search.d.ts +0 -6
- package/dist/src/resources/subscription.d.ts +0 -7
- package/dist/src/resources/subscriptions.d.ts +0 -7
- package/dist/src/resources/swell_types.d.ts +0 -163
- package/dist/src/resources/variant.d.ts +0 -9
- package/dist/src/resources.d.ts +0 -113
- package/dist/src/theme/theme-loader.d.ts +0 -110
- package/dist/src/theme.d.ts +0 -204
- package/dist/src/utils/escape.d.ts +0 -1
- package/dist/src/utils/index.d.ts +0 -34
- package/dist/src/utils/kv-flavor.d.ts +0 -7
- package/dist/src/utils/logger.d.ts +0 -21
- package/dist/src/utils/md5.d.ts +0 -1
- package/dist/types/cloudflare.d.ts +0 -61
- package/dist/types/shopify.d.ts +0 -1035
- package/dist/types/swell.d.ts +0 -576
- package/types/index.d.ts +0 -4
- 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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
```
|
|
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
|
-
###
|
|
24
|
+
### Headers and app proxying
|
|
39
25
|
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
44
|
-
|
|
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
|
-
|
|
49
|
-
const products = await swell.backend.get('/products');
|
|
33
|
+
### Backend API calls
|
|
50
34
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```
|
|
35
|
+
```ts
|
|
36
|
+
import { SwellBackendAPI } from '@swell/apps-sdk';
|
|
54
37
|
|
|
55
|
-
|
|
38
|
+
// Use the credentials supplied to your Swell-hosted app.
|
|
39
|
+
const backend = new SwellBackendAPI({ headers: request.headers });
|
|
56
40
|
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47
|
+
```ts
|
|
48
|
+
const backend = new SwellBackendAPI({ storeId, secretKey, apiHost });
|
|
49
|
+
```
|
|
83
50
|
|
|
84
|
-
###
|
|
51
|
+
### Storefront API calls
|
|
85
52
|
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
57
|
+
```ts
|
|
58
|
+
import { getStorefrontConfig } from '@swell/apps-sdk';
|
|
59
|
+
import { createStorefrontClient } from '@swell/apps-sdk/storefront';
|
|
93
60
|
|
|
94
|
-
//
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
//
|
|
102
|
-
await
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
204
|
-
Resources are automatically cached in memory per worker instance:
|
|
93
|
+
### Staff identity
|
|
205
94
|
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
218
|
-
|
|
98
|
+
```ts
|
|
99
|
+
import { requireStaff } from '@swell/apps-sdk';
|
|
219
100
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
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
|
-
|
|
111
|
+
### Backend client
|
|
235
112
|
|
|
236
|
-
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
252
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
259
|
-
|
|
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
|
-
|
|
154
|
+
### Cookies and caching
|
|
265
155
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
272
|
-
|
|
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
|
-
|
|
275
|
-
|
|
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
|
-
|
|
278
|
-
npm test
|
|
279
|
-
```
|
|
169
|
+
For caching, replace `storefront.request` before first use. The SDK has no built-in cache.
|
|
280
170
|
|
|
281
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
297
|
-
|
|
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
|
-
##
|
|
201
|
+
## License
|
|
303
202
|
|
|
304
|
-
|
|
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
|
+
}
|