@redeemid/emdash 0.0.2 → 0.0.4
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 +64 -28
- package/docs/shopify-setup.md +1 -1
- package/package.json +3 -1
- package/src/access.ts +186 -18
- package/src/astro-modules.d.ts +4 -0
- package/src/blocks/PaywallBreak.astro +6 -0
- package/src/blocks/PlanBlock.astro +13 -0
- package/src/blocks/index.ts +11 -0
- package/src/blocks-names.ts +46 -0
- package/src/cart.ts +25 -0
- package/src/components/AccessBadge.astro +45 -0
- package/src/components/Account.astro +3 -2
- package/src/components/Cart.astro +21 -0
- package/src/components/Content.astro +60 -0
- package/src/config.ts +29 -4
- package/src/descriptor.ts +29 -0
- package/src/index.ts +3 -0
- package/src/plugin.ts +290 -0
- package/src/routes/account.ts +31 -0
- package/src/routes/buy.ts +10 -5
- package/src/routes/cart.ts +37 -0
- package/src/shopify.ts +10 -3
- package/src/storefront.ts +64 -1
- package/src/version.ts +1 -0
package/src/storefront.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { env, ENV, shopOrigin, type RedeemIDConfig } from "./config.js";
|
|
11
|
+
import { USER_AGENT } from "./shopify.js";
|
|
11
12
|
|
|
12
13
|
export const STOREFRONT_API_VERSION = "2026-10";
|
|
13
14
|
|
|
@@ -34,7 +35,11 @@ export async function storefront<T>(
|
|
|
34
35
|
variables: Record<string, unknown> = {},
|
|
35
36
|
opts: { buyerIp?: string | null; fetcher?: typeof fetch } = {},
|
|
36
37
|
): Promise<T> {
|
|
37
|
-
const headers: Record<string, string> = {
|
|
38
|
+
const headers: Record<string, string> = {
|
|
39
|
+
"Content-Type": "application/json",
|
|
40
|
+
Accept: "application/json",
|
|
41
|
+
"User-Agent": USER_AGENT,
|
|
42
|
+
};
|
|
38
43
|
const priv = env(ENV.storefrontPrivateToken);
|
|
39
44
|
const pub = env(ENV.storefrontPublicToken);
|
|
40
45
|
if (priv) {
|
|
@@ -121,3 +126,61 @@ export async function checkoutUrl(
|
|
|
121
126
|
if (!url) throw new Error(data.cartCreate.userErrors[0]?.message ?? "Shopify returned no checkout.");
|
|
122
127
|
return url;
|
|
123
128
|
}
|
|
129
|
+
|
|
130
|
+
// ---------------------------------------------------------------- cart
|
|
131
|
+
|
|
132
|
+
export interface Cart {
|
|
133
|
+
id: string;
|
|
134
|
+
checkoutUrl: string;
|
|
135
|
+
totalQuantity: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const CART_FIELDS = "id checkoutUrl totalQuantity";
|
|
139
|
+
|
|
140
|
+
const CART_GET = `query Cart($id: ID!) { cart(id: $id) { ${CART_FIELDS} } }`;
|
|
141
|
+
|
|
142
|
+
const CART_NEW = `mutation CartNew($input: CartInput!) {
|
|
143
|
+
cartCreate(input: $input) { cart { ${CART_FIELDS} } userErrors { message } }
|
|
144
|
+
}`;
|
|
145
|
+
|
|
146
|
+
const CART_ADD = `mutation CartAdd($id: ID!, $lines: [CartLineInput!]!) {
|
|
147
|
+
cartLinesAdd(cartId: $id, lines: $lines) { cart { ${CART_FIELDS} } userErrors { message } }
|
|
148
|
+
}`;
|
|
149
|
+
|
|
150
|
+
type CartResult = { cart: Cart | null; userErrors: Array<{ message: string }> };
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A cart by id. Null once Shopify no longer has it, which is what happens
|
|
154
|
+
* after its checkout completes.
|
|
155
|
+
*/
|
|
156
|
+
export async function getCart(
|
|
157
|
+
config: RedeemIDConfig,
|
|
158
|
+
id: string,
|
|
159
|
+
opts: { buyerIp?: string | null; fetcher?: typeof fetch } = {},
|
|
160
|
+
): Promise<Cart | null> {
|
|
161
|
+
const data = await storefront<{ cart: Cart | null }>(config, CART_GET, { id }, opts);
|
|
162
|
+
return data.cart;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Add one line to the visitor's cart, creating the cart when there is none
|
|
167
|
+
* (or Shopify has dropped it). A new cart carries the member's email.
|
|
168
|
+
*/
|
|
169
|
+
export async function addToCart(
|
|
170
|
+
config: RedeemIDConfig,
|
|
171
|
+
cartId: string | null,
|
|
172
|
+
line: { variantId: string; sellingPlanId?: string | null },
|
|
173
|
+
opts: { email?: string | null; buyerIp?: string | null; fetcher?: typeof fetch } = {},
|
|
174
|
+
): Promise<Cart> {
|
|
175
|
+
const lines = [{ merchandiseId: line.variantId, quantity: 1, ...(line.sellingPlanId ? { sellingPlanId: line.sellingPlanId } : {}) }];
|
|
176
|
+
if (cartId) {
|
|
177
|
+
const data = await storefront<{ cartLinesAdd: CartResult }>(config, CART_ADD, { id: cartId, lines }, opts).catch(() => null);
|
|
178
|
+
if (data?.cartLinesAdd.cart) return data.cartLinesAdd.cart;
|
|
179
|
+
}
|
|
180
|
+
const input: Record<string, unknown> = { lines };
|
|
181
|
+
if (opts.email) input.buyerIdentity = { email: opts.email };
|
|
182
|
+
const data = await storefront<{ cartCreate: CartResult }>(config, CART_NEW, { input }, opts);
|
|
183
|
+
const cart = data.cartCreate.cart;
|
|
184
|
+
if (!cart) throw new Error(data.cartCreate.userErrors[0]?.message ?? "Shopify returned no cart.");
|
|
185
|
+
return cart;
|
|
186
|
+
}
|
package/src/version.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const VERSION = "0.0.4";
|