@tiledev/sdk-shopify 0.2.5
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/LICENSE +21 -0
- package/README.md +269 -0
- package/dist/blogs.d.ts +3 -0
- package/dist/blogs.d.ts.map +1 -0
- package/dist/blogs.js +72 -0
- package/dist/blogs.js.map +1 -0
- package/dist/cart.d.ts +3 -0
- package/dist/cart.d.ts.map +1 -0
- package/dist/cart.js +96 -0
- package/dist/cart.js.map +1 -0
- package/dist/cartPolicy.d.ts +15 -0
- package/dist/cartPolicy.d.ts.map +1 -0
- package/dist/cartPolicy.js +74 -0
- package/dist/cartPolicy.js.map +1 -0
- package/dist/client.d.ts +15 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +130 -0
- package/dist/client.js.map +1 -0
- package/dist/collections.d.ts +3 -0
- package/dist/collections.d.ts.map +1 -0
- package/dist/collections.js +44 -0
- package/dist/collections.js.map +1 -0
- package/dist/customer.d.ts +3 -0
- package/dist/customer.d.ts.map +1 -0
- package/dist/customer.js +124 -0
- package/dist/customer.js.map +1 -0
- package/dist/errors.d.ts +19 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +63 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +24 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +81 -0
- package/dist/messages.js.map +1 -0
- package/dist/money.d.ts +18 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +93 -0
- package/dist/money.js.map +1 -0
- package/dist/products.d.ts +6 -0
- package/dist/products.d.ts.map +1 -0
- package/dist/products.js +193 -0
- package/dist/products.js.map +1 -0
- package/dist/queries.d.ts +55 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +582 -0
- package/dist/queries.js.map +1 -0
- package/dist/react/ShopifyProvider.d.ts +181 -0
- package/dist/react/ShopifyProvider.d.ts.map +1 -0
- package/dist/react/ShopifyProvider.js +785 -0
- package/dist/react/ShopifyProvider.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +14 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/useTileCredit.d.ts +34 -0
- package/dist/react/useTileCredit.d.ts.map +1 -0
- package/dist/react/useTileCredit.js +96 -0
- package/dist/react/useTileCredit.js.map +1 -0
- package/dist/shopify.d.ts +3 -0
- package/dist/shopify.d.ts.map +1 -0
- package/dist/shopify.js +54 -0
- package/dist/shopify.js.map +1 -0
- package/dist/tileCredit.d.ts +64 -0
- package/dist/tileCredit.d.ts.map +1 -0
- package/dist/tileCredit.js +274 -0
- package/dist/tileCredit.js.map +1 -0
- package/dist/types.d.ts +785 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/dist/variants.d.ts +3 -0
- package/dist/variants.d.ts.map +1 -0
- package/dist/variants.js +67 -0
- package/dist/variants.js.map +1 -0
- package/dist/wishlist.d.ts +4 -0
- package/dist/wishlist.d.ts.map +1 -0
- package/dist/wishlist.js +232 -0
- package/dist/wishlist.js.map +1 -0
- package/package.json +63 -0
- package/react/package.json +6 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Apptile
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# @apptile/sdk-shopify
|
|
2
|
+
|
|
3
|
+
Type-safe Shopify Storefront API client. Zero deps beyond `fetch`.
|
|
4
|
+
|
|
5
|
+
Works in any JavaScript runtime — Node, browsers, React Native, Cloudflare Workers, Deno, Bun.
|
|
6
|
+
|
|
7
|
+
Optional React helpers (provider + hooks) ship under a subpath so you only pay for `react` if you use them.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @apptile/sdk-shopify
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Pure SDK (framework-agnostic)
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { shopify } from '@apptile/sdk-shopify';
|
|
17
|
+
|
|
18
|
+
await shopify.init({
|
|
19
|
+
storeDomain: 'my-store.myshopify.com',
|
|
20
|
+
storefrontAccessToken: '...',
|
|
21
|
+
apiVersion: '2024-10',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const { nodes: products } = await shopify.products.list({ first: 20 });
|
|
25
|
+
const cart = await shopify.cart.create({ lines: [{ merchandiseId: 'gid://…', quantity: 1 }] });
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Surface
|
|
29
|
+
|
|
30
|
+
| API | Methods |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `shopify.products` | `list`, `byHandle`, `byId`, `search`, `recommended` |
|
|
33
|
+
| `shopify.collections` | `list`, `byHandle`, `products` |
|
|
34
|
+
| `shopify.cart` | `create`, `get`, `addLines`, `updateLines`, `removeLines`, `applyDiscountCodes`, `setBuyerIdentity`, `updateNote` |
|
|
35
|
+
| `shopify.customer` | `signup`, `login`, `logout`, `profile`, `updateProfile`, `recoverPassword`, `orders`, `orderById` |
|
|
36
|
+
| `shopify.blogs` | `list`, `byHandle`, `articles`, `articleByHandle` |
|
|
37
|
+
| `shopify.wishlist` | `init`, `add`, `remove`, `toggle`, `has`, `list`, `count`, `clear`, `refresh`, `onChange` |
|
|
38
|
+
| `shopify.alerts` | `message`, `setMessages`, `patchMessages`, `setPolicy` — see [Alerts & Toasts](#alerts--toasts) |
|
|
39
|
+
|
|
40
|
+
### Cart note
|
|
41
|
+
|
|
42
|
+
The shopper's order note — the free-text box on the cart, which the merchant reads beside the order. Distinct from cart *attributes*: attributes are the app's own bookkeeping, the note is content the shopper wrote.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const cart = await shopify.cart.updateNote(cartId, 'Leave at the back door');
|
|
46
|
+
cart.note; // 'Leave at the back door'
|
|
47
|
+
(await shopify.cart.updateNote(cartId, null)).note; // null — cleared
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`cart.note` is `string | null` and never `''`. Shopify reports "no note" as an empty string, normalized here so there is one falsy value to test rather than two. Passing `null` clears it — on the wire that is `''`, because Shopify's `note` argument is `String!` and declaring the variable nullable is rejected outright.
|
|
51
|
+
|
|
52
|
+
`cart.create()` takes no note; set it in a follow-up call once the cart exists.
|
|
53
|
+
|
|
54
|
+
From React:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
const { cart, updateNote } = useCart();
|
|
58
|
+
<TextInput
|
|
59
|
+
defaultValue={cart?.note ?? ''}
|
|
60
|
+
onBlur={e => updateNote(e.nativeEvent.text || null)}
|
|
61
|
+
/>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The hook's `updateNote` is **not** debounced — a note is typed and then committed, so write it on blur or a Save, not per keystroke. It is serialized against the line writes (a note landing mid-`addLine` would be applied to a cart the provider is about to replace, and would vanish), no-ops when there is no cart yet, and emits no alert event.
|
|
65
|
+
|
|
66
|
+
### Wishlist — local-storage backed
|
|
67
|
+
|
|
68
|
+
Stores a lightweight snapshot per product to whatever storage you give it (browser: `localStorage` by default; RN: pass AsyncStorage; server: pass any in-memory shim). Hydrates the full `Product` via a batched Storefront `nodes(ids:)` query on init and on demand, chunking arbitrarily large lists.
|
|
69
|
+
|
|
70
|
+
Deleted products (Storefront returns `null`) are pruned automatically. Pass `refresh({ keepDeleted: true })` to keep them with `product: null` for a "no longer available" UI.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
await shopify.wishlist.init(); // rehydrates from storage, background-refreshes from API
|
|
74
|
+
await shopify.wishlist.add(product);
|
|
75
|
+
shopify.wishlist.has(product.id); // O(1)
|
|
76
|
+
await shopify.wishlist.toggle(product);
|
|
77
|
+
shopify.wishlist.onChange(items => …); // subscribe
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Optional React helper
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { ShopifyProvider, useShopify, useCart, useWishlist } from '@apptile/sdk-shopify/react';
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Wrap your app once — one provider gives you SDK readiness + cart state + wishlist state:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<ShopifyProvider config={{ storeDomain, storefrontAccessToken }}>
|
|
90
|
+
<App />
|
|
91
|
+
</ShopifyProvider>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Storage is passed at the provider:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// Web: defaults to window.localStorage — nothing to configure
|
|
98
|
+
<ShopifyProvider config={...}>...</ShopifyProvider>
|
|
99
|
+
|
|
100
|
+
// React Native / Node / anywhere without localStorage:
|
|
101
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
102
|
+
<ShopifyProvider config={...} storage={AsyncStorage}>...</ShopifyProvider>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then read from the context:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
const { ready, error, cart, wishlist, customer, checkout } = useShopify();
|
|
109
|
+
const { addLine, itemCount, cart } = useCart();
|
|
110
|
+
const { items, count, toggle, has } = useWishlist();
|
|
111
|
+
const { loggedIn, login, logout } = useCustomer();
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`react` is an **optional** peer dep — install it only if you use the `/react` subpath.
|
|
115
|
+
|
|
116
|
+
## Alerts & Toasts
|
|
117
|
+
|
|
118
|
+
The editor's Settings panel configures the copy for 13 shopper-facing alerts. The
|
|
119
|
+
SDK never renders anything — it resolves the right string and hands it to you on
|
|
120
|
+
an event, so a screen can toast without keeping its own copy table or mapping
|
|
121
|
+
Shopify error shapes to sentences.
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
<ShopifyProvider
|
|
125
|
+
config={{ storeDomain, storefrontAccessToken }}
|
|
126
|
+
cartPolicy={{ maxLineItems: 25 }}
|
|
127
|
+
messages={{ 'cart.added': 'Added to bag' }} // ← what the Settings panel writes
|
|
128
|
+
translate={(key, fallback) => i18n.t(key, fallback)}
|
|
129
|
+
onEvent={(e) => toast.show(e.message, { type: e.severity })}
|
|
130
|
+
>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Every event carries the resolved copy, so that one-liner is the whole integration:
|
|
134
|
+
|
|
135
|
+
| Event | Message key | Panel group |
|
|
136
|
+
| --- | --- | --- |
|
|
137
|
+
| `cart:add` | `cart.added` | Cart |
|
|
138
|
+
| `cart:remove` | `cart.removed` | Cart |
|
|
139
|
+
| `cart:limitExceeded` | `cart.limitExceeded` | Cart |
|
|
140
|
+
| `cart:outOfStock` | `cart.outOfStock` | Checkout |
|
|
141
|
+
| `wishlist:add` / `wishlist:remove` | `wishlist.added` / `wishlist.removed` | Wishlist |
|
|
142
|
+
| `auth:loginSuccess` / `auth:loginFailed` | `auth.loginSuccess` / `auth.loginFailed` | Login |
|
|
143
|
+
| `auth:logout` / `auth:recoverSent` | `auth.loggedOut` / `auth.resetLinkSent` | Login |
|
|
144
|
+
| `checkout:orderPlaced` / `checkout:paymentFailed` | `checkout.orderPlaced` / `checkout.paymentFailed` | Checkout |
|
|
145
|
+
|
|
146
|
+
`cart:update` and `cart:buyerIdentity` are state signals and carry no message.
|
|
147
|
+
`wishlist.empty` has no event — read it directly for a placeholder:
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
const message = useShopifyMessage();
|
|
151
|
+
{count === 0 && <Text>{message('wishlist.empty')}</Text>}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Resolution order per key: `messages` prop → `config.messages` → `translate(key)`
|
|
155
|
+
→ built-in default. A cleared panel field (empty string) falls through rather than
|
|
156
|
+
rendering blank. `translate` is called with the i18n key where one exists
|
|
157
|
+
(`cart.added` → `toast.added_to_cart`), otherwise the message key itself.
|
|
158
|
+
|
|
159
|
+
### Cart line limit
|
|
160
|
+
|
|
161
|
+
`cartPolicy.maxLineItems` is the panel's "Cart Line Item Maximum Limit". It counts
|
|
162
|
+
**distinct lines, not units** — quantity 30 of one variant is one line — and is
|
|
163
|
+
checked before the mutation, so a refusal costs no round trip:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
const result = await cart.addLine({ merchandiseId, quantity: 1 });
|
|
167
|
+
if (!result.ok && result.reason === 'limit') { /* result.message is ready to show */ }
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`reason` is `'guard'` (a `cartGuard` veto), `'limit'`, or `'no-cart'`. An
|
|
171
|
+
unsellable line still throws — `cart:outOfStock` fires on the way out.
|
|
172
|
+
|
|
173
|
+
> **Breaking from 0.1.x:** `addLine` used to return `boolean`. An object is always
|
|
174
|
+
> truthy, so `if (await addLine(...))` no longer detects a refusal — read `.ok`.
|
|
175
|
+
|
|
176
|
+
### Customer session
|
|
177
|
+
|
|
178
|
+
`useCustomer()` owns the token so the Login alerts have somewhere to originate. It
|
|
179
|
+
persists to the same storage as the cart and restores on mount; an expired token
|
|
180
|
+
is dropped silently, because reopening the app is not a failed login.
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
const { loggedIn, customer, login, logout, recoverPassword, restoring } = useCustomer();
|
|
184
|
+
// `login` resolves false on bad credentials (and emits auth:loginFailed).
|
|
185
|
+
// Anything else — network, store down — throws.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Checkout
|
|
189
|
+
|
|
190
|
+
Checkout is Shopify-hosted, so the SDK cannot see the outcome. Report it from the
|
|
191
|
+
webview and the configured copy comes back on the event:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
const { reportOrderPlaced, reportPaymentFailed } = useCheckout();
|
|
195
|
+
// reportOrderPlaced also resets the cart — the old one is spent.
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> A `checkout.observe(url)` helper that classifies the return URL itself is the
|
|
199
|
+
> next piece of work; this is the seam it will emit through.
|
|
200
|
+
|
|
201
|
+
## Tile Credit
|
|
202
|
+
|
|
203
|
+
Customer wallet + gift-card mint + one-shot apply to a Shopify cart.
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import {shopify, centsToMoney} from '@apptile/sdk-shopify';
|
|
207
|
+
|
|
208
|
+
// Configure once per signed-in customer (rebuild on logout / new customer).
|
|
209
|
+
shopify.tileCredit.configure({
|
|
210
|
+
baseUrl: 'https://tile-credit-1097788179850.us-central1.run.app',
|
|
211
|
+
customerAccessToken, // shcat_… or classic Storefront customer token
|
|
212
|
+
shopDomain: 'yourshop.myshopify.com',
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const client = shopify.tileCredit.client()!;
|
|
216
|
+
const wallet = await client.getWallet();
|
|
217
|
+
console.log('balance:', centsToMoney(wallet.balanceCents));
|
|
218
|
+
|
|
219
|
+
// Redeem 15.00 AND apply the minted gift card to the current cart in one call.
|
|
220
|
+
const {redeemed, cart} = await shopify.tileCredit.redeemAndApplyToCart({
|
|
221
|
+
cartId,
|
|
222
|
+
amountCents: 1500,
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
React hook:
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
import {useTileCredit} from '@apptile/sdk-shopify/react';
|
|
230
|
+
|
|
231
|
+
function WalletScreen() {
|
|
232
|
+
const {wallet, config, redeemAndApply, refresh, loading, error} = useTileCredit({
|
|
233
|
+
baseUrl: TILE_CREDIT_URL,
|
|
234
|
+
customerAccessToken: session.token,
|
|
235
|
+
shopDomain: SHOP_DOMAIN,
|
|
236
|
+
});
|
|
237
|
+
// …
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Full integration guide (idempotency, error taxonomy, recovery playbook)
|
|
242
|
+
lives in the mobile app repo alongside the wallet screen — this SDK ships
|
|
243
|
+
the client + types only. Every method rejects with a `TileCreditError`
|
|
244
|
+
(`.code`: `'unauthorized' | 'insufficient_balance' | 'shopify_upstream'
|
|
245
|
+
| 'network' | …`). Branch on `.code`, not `.message`.
|
|
246
|
+
|
|
247
|
+
## Types
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
import type {
|
|
251
|
+
Product, ProductVariant, ProductOption,
|
|
252
|
+
Cart, CartLine, CartLineInput, CartLineUpdateInput,
|
|
253
|
+
Collection, Customer, Order, Blog, Article,
|
|
254
|
+
WishlistItem, WishlistStorageAdapter,
|
|
255
|
+
ShopifyConfig, ShopifyIntegration,
|
|
256
|
+
ShopifyError,
|
|
257
|
+
// Tile Credit
|
|
258
|
+
TileCreditConfig, TileCreditAPI,
|
|
259
|
+
TileCreditWallet, TileCreditLedgerEntry, TileCreditLedgerPage,
|
|
260
|
+
TileCreditIssuedGiftCard, TileCreditPublicConfig,
|
|
261
|
+
TileCreditRedeemInput, TileCreditRedeemResult,
|
|
262
|
+
TileCreditError, TileCreditErrorCode,
|
|
263
|
+
AppliedGiftCard,
|
|
264
|
+
} from '@apptile/sdk-shopify';
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
MIT
|
package/dist/blogs.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blogs.d.ts","sourceRoot":"","sources":["../src/blogs.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAMV,eAAe,EAChB,MAAM,SAAS,CAAC;AAsCjB,eAAO,MAAM,KAAK,EAAE,eA0CnB,CAAC"}
|
package/dist/blogs.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.blogs = void 0;
|
|
4
|
+
const client_1 = require("./client");
|
|
5
|
+
const queries_1 = require("./queries");
|
|
6
|
+
function normalizeArticle(a) {
|
|
7
|
+
var _a, _b, _c, _d, _e, _f;
|
|
8
|
+
return {
|
|
9
|
+
id: a.id,
|
|
10
|
+
handle: a.handle,
|
|
11
|
+
title: a.title,
|
|
12
|
+
content: a.content,
|
|
13
|
+
contentHtml: a.contentHtml,
|
|
14
|
+
excerpt: (_a = a.excerpt) !== null && _a !== void 0 ? _a : null,
|
|
15
|
+
excerptHtml: (_b = a.excerptHtml) !== null && _b !== void 0 ? _b : null,
|
|
16
|
+
publishedAt: a.publishedAt,
|
|
17
|
+
tags: (_c = a.tags) !== null && _c !== void 0 ? _c : [],
|
|
18
|
+
image: (_d = a.image) !== null && _d !== void 0 ? _d : null,
|
|
19
|
+
author: a.authorV2
|
|
20
|
+
? {
|
|
21
|
+
name: a.authorV2.name,
|
|
22
|
+
email: (_e = a.authorV2.email) !== null && _e !== void 0 ? _e : null,
|
|
23
|
+
bio: (_f = a.authorV2.bio) !== null && _f !== void 0 ? _f : null,
|
|
24
|
+
}
|
|
25
|
+
: null,
|
|
26
|
+
blog: a.blog,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
exports.blogs = {
|
|
30
|
+
async list(opts) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const data = await (0, client_1.request)(queries_1.BLOGS_LIST_QUERY, {
|
|
33
|
+
first: (_a = opts === null || opts === void 0 ? void 0 : opts.first) !== null && _a !== void 0 ? _a : 20,
|
|
34
|
+
after: opts === null || opts === void 0 ? void 0 : opts.after,
|
|
35
|
+
query: opts === null || opts === void 0 ? void 0 : opts.query,
|
|
36
|
+
sortKey: opts === null || opts === void 0 ? void 0 : opts.sortKey,
|
|
37
|
+
reverse: (_b = opts === null || opts === void 0 ? void 0 : opts.reverse) !== null && _b !== void 0 ? _b : false,
|
|
38
|
+
});
|
|
39
|
+
return data.blogs;
|
|
40
|
+
},
|
|
41
|
+
async byHandle(handle) {
|
|
42
|
+
const data = await (0, client_1.request)(queries_1.BLOG_BY_HANDLE_QUERY, { handle });
|
|
43
|
+
return data.blog;
|
|
44
|
+
},
|
|
45
|
+
async articles(blogHandle, opts) {
|
|
46
|
+
var _a, _b;
|
|
47
|
+
const data = await (0, client_1.request)(queries_1.BLOG_ARTICLES_QUERY, {
|
|
48
|
+
handle: blogHandle,
|
|
49
|
+
first: (_a = opts === null || opts === void 0 ? void 0 : opts.first) !== null && _a !== void 0 ? _a : 20,
|
|
50
|
+
after: opts === null || opts === void 0 ? void 0 : opts.after,
|
|
51
|
+
sortKey: opts === null || opts === void 0 ? void 0 : opts.sortKey,
|
|
52
|
+
reverse: (_b = opts === null || opts === void 0 ? void 0 : opts.reverse) !== null && _b !== void 0 ? _b : false,
|
|
53
|
+
});
|
|
54
|
+
if (!data.blog) {
|
|
55
|
+
return { nodes: [], pageInfo: { hasNextPage: false, hasPreviousPage: false, startCursor: null, endCursor: null } };
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
nodes: data.blog.articles.nodes.map(normalizeArticle),
|
|
59
|
+
pageInfo: data.blog.articles.pageInfo,
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
async articleByHandle(blogHandle, articleHandle) {
|
|
63
|
+
const data = await (0, client_1.request)(queries_1.BLOG_ARTICLE_BY_HANDLE_QUERY, {
|
|
64
|
+
blogHandle,
|
|
65
|
+
articleHandle,
|
|
66
|
+
});
|
|
67
|
+
if (!data.blog || !data.blog.articleByHandle)
|
|
68
|
+
return null;
|
|
69
|
+
return normalizeArticle(data.blog.articleByHandle);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=blogs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blogs.js","sourceRoot":"","sources":["../src/blogs.ts"],"names":[],"mappings":"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"}
|
package/dist/cart.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart.d.ts","sourceRoot":"","sources":["../src/cart.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAIV,cAAc,EAEf,MAAM,SAAS,CAAC;AAiCjB,eAAO,MAAM,IAAI,EAAE,cAyElB,CAAC"}
|
package/dist/cart.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cart = void 0;
|
|
4
|
+
const client_1 = require("./client");
|
|
5
|
+
const queries_1 = require("./queries");
|
|
6
|
+
function normalize(c) {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
return {
|
|
9
|
+
id: c.id,
|
|
10
|
+
checkoutUrl: c.checkoutUrl,
|
|
11
|
+
totalQuantity: c.totalQuantity,
|
|
12
|
+
lines: ((_b = (_a = c.lines) === null || _a === void 0 ? void 0 : _a.nodes) !== null && _b !== void 0 ? _b : []).map((line) => {
|
|
13
|
+
var _a, _b, _c;
|
|
14
|
+
return ({
|
|
15
|
+
id: line.id,
|
|
16
|
+
quantity: line.quantity,
|
|
17
|
+
attributes: (_a = line.attributes) !== null && _a !== void 0 ? _a : [],
|
|
18
|
+
merchandise: line.merchandise,
|
|
19
|
+
product: (_c = (_b = line.merchandise) === null || _b === void 0 ? void 0 : _b.product) !== null && _c !== void 0 ? _c : null,
|
|
20
|
+
cost: line.cost,
|
|
21
|
+
});
|
|
22
|
+
}),
|
|
23
|
+
cost: c.cost,
|
|
24
|
+
discountCodes: (_c = c.discountCodes) !== null && _c !== void 0 ? _c : [],
|
|
25
|
+
appliedGiftCards: (_d = c.appliedGiftCards) !== null && _d !== void 0 ? _d : [],
|
|
26
|
+
createdAt: c.createdAt,
|
|
27
|
+
updatedAt: c.updatedAt,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
exports.cart = {
|
|
31
|
+
async create(input) {
|
|
32
|
+
const payload = {
|
|
33
|
+
lines: input === null || input === void 0 ? void 0 : input.lines,
|
|
34
|
+
discountCodes: input === null || input === void 0 ? void 0 : input.discountCodes,
|
|
35
|
+
};
|
|
36
|
+
const data = await (0, client_1.request)(queries_1.CART_CREATE_MUTATION, { input: payload });
|
|
37
|
+
(0, client_1.assertNoUserErrors)('cartCreate', data.cartCreate.userErrors);
|
|
38
|
+
return normalize(data.cartCreate.cart);
|
|
39
|
+
},
|
|
40
|
+
async get(cartId) {
|
|
41
|
+
const data = await (0, client_1.request)(queries_1.CART_GET_QUERY, { id: cartId });
|
|
42
|
+
return data.cart ? normalize(data.cart) : null;
|
|
43
|
+
},
|
|
44
|
+
async addLines(cartId, lines) {
|
|
45
|
+
const data = await (0, client_1.request)(queries_1.CART_LINES_ADD_MUTATION, { cartId, lines });
|
|
46
|
+
(0, client_1.assertNoUserErrors)('cartLinesAdd', data.cartLinesAdd.userErrors);
|
|
47
|
+
return normalize(data.cartLinesAdd.cart);
|
|
48
|
+
},
|
|
49
|
+
async updateLines(cartId, lines) {
|
|
50
|
+
const data = await (0, client_1.request)(queries_1.CART_LINES_UPDATE_MUTATION, { cartId, lines });
|
|
51
|
+
(0, client_1.assertNoUserErrors)('cartLinesUpdate', data.cartLinesUpdate.userErrors);
|
|
52
|
+
return normalize(data.cartLinesUpdate.cart);
|
|
53
|
+
},
|
|
54
|
+
async removeLines(cartId, lineIds) {
|
|
55
|
+
const data = await (0, client_1.request)(queries_1.CART_LINES_REMOVE_MUTATION, { cartId, lineIds });
|
|
56
|
+
(0, client_1.assertNoUserErrors)('cartLinesRemove', data.cartLinesRemove.userErrors);
|
|
57
|
+
return normalize(data.cartLinesRemove.cart);
|
|
58
|
+
},
|
|
59
|
+
async applyDiscountCodes(cartId, codes) {
|
|
60
|
+
const data = await (0, client_1.request)(queries_1.CART_DISCOUNT_CODES_UPDATE_MUTATION, {
|
|
61
|
+
cartId,
|
|
62
|
+
discountCodes: codes,
|
|
63
|
+
});
|
|
64
|
+
(0, client_1.assertNoUserErrors)('cartDiscountCodesUpdate', data.cartDiscountCodesUpdate.userErrors);
|
|
65
|
+
return normalize(data.cartDiscountCodesUpdate.cart);
|
|
66
|
+
},
|
|
67
|
+
async setBuyerIdentity(cartId, identity) {
|
|
68
|
+
const data = await (0, client_1.request)(queries_1.CART_BUYER_IDENTITY_UPDATE_MUTATION, {
|
|
69
|
+
cartId,
|
|
70
|
+
buyerIdentity: {
|
|
71
|
+
email: identity.email,
|
|
72
|
+
countryCode: identity.countryCode,
|
|
73
|
+
customerAccessToken: identity.customerAccessToken,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
(0, client_1.assertNoUserErrors)('cartBuyerIdentityUpdate', data.cartBuyerIdentityUpdate.userErrors);
|
|
77
|
+
return normalize(data.cartBuyerIdentityUpdate.cart);
|
|
78
|
+
},
|
|
79
|
+
async applyGiftCardCodes(cartId, codes) {
|
|
80
|
+
const data = await (0, client_1.request)(queries_1.CART_GIFT_CARD_CODES_UPDATE_MUTATION, {
|
|
81
|
+
cartId,
|
|
82
|
+
giftCardCodes: codes,
|
|
83
|
+
});
|
|
84
|
+
(0, client_1.assertNoUserErrors)('cartGiftCardCodesUpdate', data.cartGiftCardCodesUpdate.userErrors);
|
|
85
|
+
return normalize(data.cartGiftCardCodesUpdate.cart);
|
|
86
|
+
},
|
|
87
|
+
async removeGiftCardCodes(cartId, appliedGiftCardIds) {
|
|
88
|
+
const data = await (0, client_1.request)(queries_1.CART_GIFT_CARD_CODES_REMOVE_MUTATION, {
|
|
89
|
+
cartId,
|
|
90
|
+
appliedGiftCardIds,
|
|
91
|
+
});
|
|
92
|
+
(0, client_1.assertNoUserErrors)('cartGiftCardCodesRemove', data.cartGiftCardCodesRemove.userErrors);
|
|
93
|
+
return normalize(data.cartGiftCardCodesRemove.cart);
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=cart.js.map
|
package/dist/cart.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cart.js","sourceRoot":"","sources":["../src/cart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Cart, CartLineInput, CartPolicy } from './types';
|
|
2
|
+
export declare function setCartPolicy(policy?: CartPolicy | null): void;
|
|
3
|
+
export declare function getCartPolicy(): CartPolicy;
|
|
4
|
+
/** Normalised limit, or `null` for "no limit" — including a garbage config
|
|
5
|
+
* value, which must not silently block every add. */
|
|
6
|
+
export declare function maxLineItems(): number | null;
|
|
7
|
+
/** How many distinct lines the cart would hold once `inputs` are added. */
|
|
8
|
+
export declare function projectedLineCount(cart: Cart | null, inputs: CartLineInput[]): number;
|
|
9
|
+
/**
|
|
10
|
+
* True when adding `inputs` would push the cart past `maxLineItems`. Checked
|
|
11
|
+
* before the mutation so a refusal costs no round trip — and so the shopper
|
|
12
|
+
* sees the configured message instead of a Shopify error.
|
|
13
|
+
*/
|
|
14
|
+
export declare function wouldExceedLineLimit(cart: Cart | null, inputs: CartLineInput[]): boolean;
|
|
15
|
+
//# sourceMappingURL=cartPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cartPolicy.d.ts","sourceRoot":"","sources":["../src/cartPolicy.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAQ/D,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE9D;AAED,wBAAgB,aAAa,IAAI,UAAU,CAE1C;AAED;sDACsD;AACtD,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAI5C;AAqBD,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAarF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAIxF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setCartPolicy = setCartPolicy;
|
|
4
|
+
exports.getCartPolicy = getCartPolicy;
|
|
5
|
+
exports.maxLineItems = maxLineItems;
|
|
6
|
+
exports.projectedLineCount = projectedLineCount;
|
|
7
|
+
exports.wouldExceedLineLimit = wouldExceedLineLimit;
|
|
8
|
+
const state = { policy: {} };
|
|
9
|
+
function setCartPolicy(policy) {
|
|
10
|
+
state.policy = policy ? { ...policy } : {};
|
|
11
|
+
}
|
|
12
|
+
function getCartPolicy() {
|
|
13
|
+
return { ...state.policy };
|
|
14
|
+
}
|
|
15
|
+
/** Normalised limit, or `null` for "no limit" — including a garbage config
|
|
16
|
+
* value, which must not silently block every add. */
|
|
17
|
+
function maxLineItems() {
|
|
18
|
+
const max = state.policy.maxLineItems;
|
|
19
|
+
if (typeof max !== 'number' || !Number.isFinite(max) || max <= 0)
|
|
20
|
+
return null;
|
|
21
|
+
return Math.floor(max);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The line an input would land on, if the cart already holds one.
|
|
25
|
+
*
|
|
26
|
+
* Shopify merges an add into an existing line only when the merchandise AND the
|
|
27
|
+
* line attributes match, so a per-add attribute opens a new line. Selling plans
|
|
28
|
+
* split lines too, but `CartLine` carries no `sellingPlanAllocation` today, so a
|
|
29
|
+
* subscription add can look like a merge into the one-off line — which counts
|
|
30
|
+
* one line low and makes the limit slightly lenient rather than falsely
|
|
31
|
+
* blocking a shopper.
|
|
32
|
+
*/
|
|
33
|
+
function mergesInto(cart, input) {
|
|
34
|
+
var _a;
|
|
35
|
+
const attrs = (_a = input.attributes) !== null && _a !== void 0 ? _a : [];
|
|
36
|
+
return cart.lines.some((line) => {
|
|
37
|
+
var _a;
|
|
38
|
+
if (((_a = line.merchandise) === null || _a === void 0 ? void 0 : _a.id) !== input.merchandiseId)
|
|
39
|
+
return false;
|
|
40
|
+
if (attrs.length !== line.attributes.length)
|
|
41
|
+
return false;
|
|
42
|
+
return attrs.every((a) => line.attributes.some((b) => b.key === a.key && b.value === a.value));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** How many distinct lines the cart would hold once `inputs` are added. */
|
|
46
|
+
function projectedLineCount(cart, inputs) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
let count = (_a = cart === null || cart === void 0 ? void 0 : cart.lines.length) !== null && _a !== void 0 ? _a : 0;
|
|
49
|
+
// Two inputs for the same new variant open one line between them, so track
|
|
50
|
+
// what this batch has already accounted for.
|
|
51
|
+
const opened = new Set();
|
|
52
|
+
for (const input of inputs) {
|
|
53
|
+
if (cart && mergesInto(cart, input))
|
|
54
|
+
continue;
|
|
55
|
+
const key = `${input.merchandiseId}|${JSON.stringify((_b = input.attributes) !== null && _b !== void 0 ? _b : [])}`;
|
|
56
|
+
if (opened.has(key))
|
|
57
|
+
continue;
|
|
58
|
+
opened.add(key);
|
|
59
|
+
count += 1;
|
|
60
|
+
}
|
|
61
|
+
return count;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* True when adding `inputs` would push the cart past `maxLineItems`. Checked
|
|
65
|
+
* before the mutation so a refusal costs no round trip — and so the shopper
|
|
66
|
+
* sees the configured message instead of a Shopify error.
|
|
67
|
+
*/
|
|
68
|
+
function wouldExceedLineLimit(cart, inputs) {
|
|
69
|
+
const max = maxLineItems();
|
|
70
|
+
if (max === null)
|
|
71
|
+
return false;
|
|
72
|
+
return projectedLineCount(cart, inputs) > max;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=cartPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cartPolicy.js","sourceRoot":"","sources":["../src/cartPolicy.ts"],"names":[],"mappings":";;AAeA,sCAEC;AAED,sCAEC;AAID,oCAIC;AAsBD,gDAaC;AAOD,oDAIC;AA9DD,MAAM,KAAK,GAAgB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAE1C,SAAgB,aAAa,CAAC,MAA0B;IACtD,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7C,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED;sDACsD;AACtD,SAAgB,YAAY;IAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC;IACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9E,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,UAAU,CAAC,IAAU,EAAE,KAAoB;;IAClD,MAAM,KAAK,GAAG,MAAA,KAAK,CAAC,UAAU,mCAAI,EAAE,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;;QAC9B,IAAI,CAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,EAAE,MAAK,KAAK,CAAC,aAAa;YAAE,OAAO,KAAK,CAAC;QAC/D,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1D,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,SAAgB,kBAAkB,CAAC,IAAiB,EAAE,MAAuB;;IAC3E,IAAI,KAAK,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,CAAC,MAAM,mCAAI,CAAC,CAAC;IACpC,2EAA2E;IAC3E,6CAA6C;IAC7C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC;YAAE,SAAS;QAC9C,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,CAAC,MAAA,KAAK,CAAC,UAAU,mCAAI,EAAE,CAAC,EAAE,CAAC;QAC/E,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,IAAiB,EAAE,MAAuB;IAC7E,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC;AAChD,CAAC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ShopifyConfig, UserError } from './types';
|
|
2
|
+
export declare function setShopInfo(info: {
|
|
3
|
+
moneyFormat?: string | null;
|
|
4
|
+
currencyCode?: string | null;
|
|
5
|
+
}): void;
|
|
6
|
+
/** Null until the shop query resolves. */
|
|
7
|
+
export declare function getMoneyFormat(): string | null;
|
|
8
|
+
export declare function getCurrencyCode(): string | null;
|
|
9
|
+
export declare function setConfig(config: ShopifyConfig): void;
|
|
10
|
+
export declare function getConfig(): ShopifyConfig;
|
|
11
|
+
export declare function isConfigured(): boolean;
|
|
12
|
+
export declare function request<T>(operation: string, variables?: Record<string, unknown>): Promise<T>;
|
|
13
|
+
/** Throws if a Shopify mutation payload contains userErrors. */
|
|
14
|
+
export declare function assertNoUserErrors(label: string, errors: UserError[] | null | undefined): void;
|
|
15
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgB,SAAS,EAAE,MAAM,SAAS,CAAC;AAWjE,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAGrG;AAED,0CAA0C;AAC1C,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAID,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAIrD;AAED,wBAAgB,SAAS,IAAI,aAAa,CAGzC;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AA4DD,wBAAsB,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAgCnG;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAO9F"}
|