@popcraft/runtime 0.13.1 → 0.14.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 +1 -0
- package/dist/commerce.d.ts +131 -0
- package/dist/commerce.js +127 -0
- package/dist/commerce.js.map +7 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ You do not install this by hand: an exported project's `package.json` asks for i
|
|
|
10
10
|
| Import | What it is |
|
|
11
11
|
| --- | --- |
|
|
12
12
|
| `@popcraft/runtime` | What an expression means (`ops`, `truthy`, `num`, `exprText`, `FUNCTIONS`); the players for a prototype (`popcraftMount`) and a state machine (`popcraftMachine`); the page controls (`switchMode`, `controlTimeline`, `scrubTimeline`, `orbitDrag`); the site contract (endpoints, sign-in and record rules); and `createSiteClient`, what a page asks of its site's server |
|
|
13
|
+
| `@popcraft/runtime/commerce` | What [storefront components](https://popcraft.app/docs/exporting/commerce) bind to: Next.js Commerce's types (`Product`, `Cart`, `CartItem`, `Collection`, `Menu`), the fields a design reads for each (`COMMERCE_FIELDS`), `commerceItem` to flatten one into them, `formatMoney`, and the storefront form actions |
|
|
13
14
|
| `@popcraft/runtime/server` | For Node: `siteRequest`, which answers a site's own requests (forms, sign-in, each visitor's records); the Neon Auth relay; `neonStore`, a site's forms and records in its own Postgres database |
|
|
14
15
|
|
|
15
16
|
An exported project with forms or accounts answers `/_pc/…` in one route handler:
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
export interface Money {
|
|
2
|
+
amount: string;
|
|
3
|
+
currencyCode: string;
|
|
4
|
+
}
|
|
5
|
+
export interface Image {
|
|
6
|
+
url: string;
|
|
7
|
+
altText: string;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ProductOption {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
values: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface ProductVariant {
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
availableForSale: boolean;
|
|
20
|
+
selectedOptions: {
|
|
21
|
+
name: string;
|
|
22
|
+
value: string;
|
|
23
|
+
}[];
|
|
24
|
+
price: Money;
|
|
25
|
+
}
|
|
26
|
+
export interface SEO {
|
|
27
|
+
title: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}
|
|
30
|
+
export interface Product {
|
|
31
|
+
id: string;
|
|
32
|
+
handle: string;
|
|
33
|
+
availableForSale: boolean;
|
|
34
|
+
title: string;
|
|
35
|
+
description: string;
|
|
36
|
+
descriptionHtml: string;
|
|
37
|
+
options: ProductOption[];
|
|
38
|
+
priceRange: {
|
|
39
|
+
maxVariantPrice: Money;
|
|
40
|
+
minVariantPrice: Money;
|
|
41
|
+
};
|
|
42
|
+
variants: ProductVariant[];
|
|
43
|
+
featuredImage: Image;
|
|
44
|
+
images: Image[];
|
|
45
|
+
seo: SEO;
|
|
46
|
+
tags: string[];
|
|
47
|
+
updatedAt: string;
|
|
48
|
+
}
|
|
49
|
+
export interface Collection {
|
|
50
|
+
handle: string;
|
|
51
|
+
title: string;
|
|
52
|
+
description: string;
|
|
53
|
+
seo: SEO;
|
|
54
|
+
updatedAt: string;
|
|
55
|
+
path: string;
|
|
56
|
+
}
|
|
57
|
+
export interface CartProduct {
|
|
58
|
+
id: string;
|
|
59
|
+
handle: string;
|
|
60
|
+
title: string;
|
|
61
|
+
featuredImage: Image;
|
|
62
|
+
}
|
|
63
|
+
export interface CartItem {
|
|
64
|
+
id: string | undefined;
|
|
65
|
+
quantity: number;
|
|
66
|
+
cost: {
|
|
67
|
+
totalAmount: Money;
|
|
68
|
+
};
|
|
69
|
+
merchandise: {
|
|
70
|
+
id: string;
|
|
71
|
+
title: string;
|
|
72
|
+
selectedOptions: {
|
|
73
|
+
name: string;
|
|
74
|
+
value: string;
|
|
75
|
+
}[];
|
|
76
|
+
product: CartProduct;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export interface Cart {
|
|
80
|
+
id: string | undefined;
|
|
81
|
+
checkoutUrl: string;
|
|
82
|
+
cost: {
|
|
83
|
+
subtotalAmount: Money;
|
|
84
|
+
totalAmount: Money;
|
|
85
|
+
totalTaxAmount: Money;
|
|
86
|
+
};
|
|
87
|
+
lines: CartItem[];
|
|
88
|
+
totalQuantity: number;
|
|
89
|
+
}
|
|
90
|
+
export interface Menu {
|
|
91
|
+
title: string;
|
|
92
|
+
path: string;
|
|
93
|
+
}
|
|
94
|
+
/** What a design's collection can stand for. */
|
|
95
|
+
export type CommerceSchema = 'commerce.product' | 'commerce.collection' | 'commerce.cart' | 'commerce.cartLine' | 'commerce.menu';
|
|
96
|
+
export declare const COMMERCE_SCHEMAS: readonly CommerceSchema[];
|
|
97
|
+
/** One field a schema gives a design: its name (its key is `fieldKey(name)`) and the kind of value. */
|
|
98
|
+
export interface CommerceField {
|
|
99
|
+
name: string;
|
|
100
|
+
type: 'TEXT' | 'NUMBER' | 'BOOLEAN' | 'MEDIA' | 'URL';
|
|
101
|
+
}
|
|
102
|
+
export declare const COMMERCE_FIELDS: Record<CommerceSchema, readonly CommerceField[]>;
|
|
103
|
+
/**
|
|
104
|
+
* The prop a component takes this schema as: a list, or (`one`) a single value a design shows through a list of one
|
|
105
|
+
* (the cart's totals).
|
|
106
|
+
*/
|
|
107
|
+
export declare const COMMERCE_PROP: Record<CommerceSchema, {
|
|
108
|
+
name: string;
|
|
109
|
+
type: string;
|
|
110
|
+
one?: true;
|
|
111
|
+
}>;
|
|
112
|
+
/** Money as a shopper reads it: `$24.00`. */
|
|
113
|
+
export declare function formatMoney(m: Money | undefined, locale?: string): string;
|
|
114
|
+
/** A record as a design's list draws it: an id, and each field under its key. */
|
|
115
|
+
export interface CommerceItem {
|
|
116
|
+
id: string;
|
|
117
|
+
values: Record<string, string | number | boolean>;
|
|
118
|
+
}
|
|
119
|
+
/** One product, collection, cart line or menu entry as the fields its schema gives a design. */
|
|
120
|
+
export declare function commerceItem(schema: CommerceSchema, value: unknown): CommerceItem;
|
|
121
|
+
/** A field of an item as words on a page (a yes-or-no as Yes or No). */
|
|
122
|
+
export declare function commerceWords(item: CommerceItem, key: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* What a commerce form does. A component takes each as a prop (`onAddToCart`) and gives it to its `<form action>`,
|
|
125
|
+
* so a Next.js server action (Next.js Commerce's `addItem`, `updateItemQuantity`, `removeItem`, `redirectToCheckout`)
|
|
126
|
+
* plugs straight in. A form inside a list's copy sends that copy's fields as hidden inputs.
|
|
127
|
+
*/
|
|
128
|
+
export type CommerceAction = 'addToCart' | 'updateCartLine' | 'removeCartLine' | 'checkout' | 'search';
|
|
129
|
+
export declare const COMMERCE_ACTIONS: readonly CommerceAction[];
|
|
130
|
+
export declare const COMMERCE_ACTION_PROP: Record<CommerceAction, string>;
|
|
131
|
+
export declare const isCommerceAction: (a: unknown) => a is CommerceAction;
|
package/dist/commerce.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// src/commerce.ts
|
|
2
|
+
var COMMERCE_SCHEMAS = ["commerce.product", "commerce.collection", "commerce.cart", "commerce.cartLine", "commerce.menu"];
|
|
3
|
+
var COMMERCE_FIELDS = {
|
|
4
|
+
"commerce.product": [
|
|
5
|
+
{ name: "Title", type: "TEXT" },
|
|
6
|
+
{ name: "Handle", type: "TEXT" },
|
|
7
|
+
{ name: "URL", type: "URL" },
|
|
8
|
+
{ name: "Description", type: "TEXT" },
|
|
9
|
+
{ name: "Price", type: "TEXT" },
|
|
10
|
+
{ name: "Max price", type: "TEXT" },
|
|
11
|
+
{ name: "Image", type: "MEDIA" },
|
|
12
|
+
{ name: "Image alt", type: "TEXT" },
|
|
13
|
+
{ name: "Available", type: "BOOLEAN" },
|
|
14
|
+
{ name: "Variant ID", type: "TEXT" },
|
|
15
|
+
{ name: "Tags", type: "TEXT" }
|
|
16
|
+
],
|
|
17
|
+
"commerce.collection": [{ name: "Title", type: "TEXT" }, { name: "Handle", type: "TEXT" }, { name: "URL", type: "URL" }, { name: "Description", type: "TEXT" }],
|
|
18
|
+
"commerce.cart": [
|
|
19
|
+
{ name: "Count", type: "NUMBER" },
|
|
20
|
+
{ name: "Subtotal", type: "TEXT" },
|
|
21
|
+
{ name: "Taxes", type: "TEXT" },
|
|
22
|
+
{ name: "Total", type: "TEXT" },
|
|
23
|
+
{ name: "Checkout URL", type: "URL" }
|
|
24
|
+
],
|
|
25
|
+
"commerce.cartLine": [
|
|
26
|
+
{ name: "Title", type: "TEXT" },
|
|
27
|
+
{ name: "Variant", type: "TEXT" },
|
|
28
|
+
{ name: "URL", type: "URL" },
|
|
29
|
+
{ name: "Image", type: "MEDIA" },
|
|
30
|
+
{ name: "Quantity", type: "NUMBER" },
|
|
31
|
+
{ name: "Price", type: "TEXT" },
|
|
32
|
+
{ name: "Merchandise ID", type: "TEXT" }
|
|
33
|
+
],
|
|
34
|
+
"commerce.menu": [{ name: "Title", type: "TEXT" }, { name: "URL", type: "URL" }]
|
|
35
|
+
};
|
|
36
|
+
var COMMERCE_PROP = {
|
|
37
|
+
"commerce.product": { name: "products", type: "Product" },
|
|
38
|
+
"commerce.collection": { name: "collections", type: "Collection" },
|
|
39
|
+
"commerce.cart": { name: "cart", type: "Cart", one: true },
|
|
40
|
+
"commerce.cartLine": { name: "lines", type: "CartItem" },
|
|
41
|
+
"commerce.menu": { name: "menu", type: "Menu" }
|
|
42
|
+
};
|
|
43
|
+
function formatMoney(m, locale = "en-US") {
|
|
44
|
+
if (!m) return "";
|
|
45
|
+
try {
|
|
46
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency: m.currencyCode, currencyDisplay: "narrowSymbol" }).format(Number(m.amount));
|
|
47
|
+
} catch {
|
|
48
|
+
return `${m.amount} ${m.currencyCode}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function commerceItem(schema, value) {
|
|
52
|
+
switch (schema) {
|
|
53
|
+
case "commerce.product": {
|
|
54
|
+
const p = value;
|
|
55
|
+
return { id: p.id, values: {
|
|
56
|
+
title: p.title,
|
|
57
|
+
handle: p.handle,
|
|
58
|
+
url: `/product/${p.handle}`,
|
|
59
|
+
description: p.description,
|
|
60
|
+
price: formatMoney(p.priceRange?.minVariantPrice),
|
|
61
|
+
max_price: formatMoney(p.priceRange?.maxVariantPrice),
|
|
62
|
+
image: p.featuredImage?.url ?? "",
|
|
63
|
+
image_alt: p.featuredImage?.altText || p.title,
|
|
64
|
+
available: !!p.availableForSale,
|
|
65
|
+
variant_id: p.variants?.find((v) => v.availableForSale)?.id ?? p.variants?.[0]?.id ?? "",
|
|
66
|
+
tags: (p.tags ?? []).join(", ")
|
|
67
|
+
} };
|
|
68
|
+
}
|
|
69
|
+
case "commerce.collection": {
|
|
70
|
+
const c = value;
|
|
71
|
+
return { id: c.handle || "all", values: { title: c.title, handle: c.handle, url: c.path, description: c.description } };
|
|
72
|
+
}
|
|
73
|
+
case "commerce.cart": {
|
|
74
|
+
const c = value;
|
|
75
|
+
return { id: c.id ?? "cart", values: {
|
|
76
|
+
count: c.totalQuantity,
|
|
77
|
+
subtotal: formatMoney(c.cost?.subtotalAmount),
|
|
78
|
+
taxes: formatMoney(c.cost?.totalTaxAmount),
|
|
79
|
+
total: formatMoney(c.cost?.totalAmount),
|
|
80
|
+
checkout_url: c.checkoutUrl
|
|
81
|
+
} };
|
|
82
|
+
}
|
|
83
|
+
case "commerce.cartLine": {
|
|
84
|
+
const l = value;
|
|
85
|
+
const m = l.merchandise;
|
|
86
|
+
return { id: l.id ?? m.id, values: {
|
|
87
|
+
title: m.product.title,
|
|
88
|
+
variant: m.title === "Default Title" ? "" : m.title,
|
|
89
|
+
url: `/product/${m.product.handle}`,
|
|
90
|
+
image: m.product.featuredImage?.url ?? "",
|
|
91
|
+
quantity: l.quantity,
|
|
92
|
+
price: formatMoney(l.cost?.totalAmount),
|
|
93
|
+
merchandise_id: m.id
|
|
94
|
+
} };
|
|
95
|
+
}
|
|
96
|
+
case "commerce.menu": {
|
|
97
|
+
const m = value;
|
|
98
|
+
return { id: m.path, values: { title: m.title, url: m.path } };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function commerceWords(item, key) {
|
|
103
|
+
if (key === "id") return item.id;
|
|
104
|
+
const v = item.values[key];
|
|
105
|
+
return typeof v === "boolean" ? v ? "Yes" : "No" : v === void 0 ? "" : String(v);
|
|
106
|
+
}
|
|
107
|
+
var COMMERCE_ACTIONS = ["addToCart", "updateCartLine", "removeCartLine", "checkout", "search"];
|
|
108
|
+
var COMMERCE_ACTION_PROP = {
|
|
109
|
+
addToCart: "onAddToCart",
|
|
110
|
+
updateCartLine: "onUpdateCartLine",
|
|
111
|
+
removeCartLine: "onRemoveCartLine",
|
|
112
|
+
checkout: "onCheckout",
|
|
113
|
+
search: "onSearch"
|
|
114
|
+
};
|
|
115
|
+
var isCommerceAction = (a) => typeof a === "string" && COMMERCE_ACTIONS.includes(a);
|
|
116
|
+
export {
|
|
117
|
+
COMMERCE_ACTIONS,
|
|
118
|
+
COMMERCE_ACTION_PROP,
|
|
119
|
+
COMMERCE_FIELDS,
|
|
120
|
+
COMMERCE_PROP,
|
|
121
|
+
COMMERCE_SCHEMAS,
|
|
122
|
+
commerceItem,
|
|
123
|
+
commerceWords,
|
|
124
|
+
formatMoney,
|
|
125
|
+
isCommerceAction
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=commerce.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/commerce.ts"],
|
|
4
|
+
"sourcesContent": ["// Commerce data a PopCraft design binds to. The shapes are Next.js Commerce's (vercel/commerce, lib/shopify/types.ts),\n// so a storefront built on it hands its own products, collections, cart and menus to an exported design unchanged.\n// A design names one of the schemas below on a collection (`Collection.schema`); the editor offers its fields, the\n// export types the component's props by it, and `commerceItem` flattens one value into the fields the design reads.\n\nexport interface Money { amount: string; currencyCode: string }\nexport interface Image { url: string; altText: string; width: number; height: number }\nexport interface ProductOption { id: string; name: string; values: string[] }\nexport interface ProductVariant { id: string; title: string; availableForSale: boolean; selectedOptions: { name: string; value: string }[]; price: Money }\nexport interface SEO { title: string; description: string }\nexport interface Product {\n id: string; handle: string; availableForSale: boolean; title: string; description: string; descriptionHtml: string\n options: ProductOption[]; priceRange: { maxVariantPrice: Money; minVariantPrice: Money }; variants: ProductVariant[]\n featuredImage: Image; images: Image[]; seo: SEO; tags: string[]; updatedAt: string\n}\nexport interface Collection { handle: string; title: string; description: string; seo: SEO; updatedAt: string; path: string }\nexport interface CartProduct { id: string; handle: string; title: string; featuredImage: Image }\nexport interface CartItem {\n id: string | undefined; quantity: number; cost: { totalAmount: Money }\n merchandise: { id: string; title: string; selectedOptions: { name: string; value: string }[]; product: CartProduct }\n}\nexport interface Cart { id: string | undefined; checkoutUrl: string; cost: { subtotalAmount: Money; totalAmount: Money; totalTaxAmount: Money }; lines: CartItem[]; totalQuantity: number }\nexport interface Menu { title: string; path: string }\n\n/** What a design's collection can stand for. */\nexport type CommerceSchema = 'commerce.product' | 'commerce.collection' | 'commerce.cart' | 'commerce.cartLine' | 'commerce.menu'\nexport const COMMERCE_SCHEMAS: readonly CommerceSchema[] = ['commerce.product', 'commerce.collection', 'commerce.cart', 'commerce.cartLine', 'commerce.menu']\n\n/** One field a schema gives a design: its name (its key is `fieldKey(name)`) and the kind of value. */\nexport interface CommerceField { name: string; type: 'TEXT' | 'NUMBER' | 'BOOLEAN' | 'MEDIA' | 'URL' }\n\nexport const COMMERCE_FIELDS: Record<CommerceSchema, readonly CommerceField[]> = {\n 'commerce.product': [\n { name: 'Title', type: 'TEXT' }, { name: 'Handle', type: 'TEXT' }, { name: 'URL', type: 'URL' },\n { name: 'Description', type: 'TEXT' }, { name: 'Price', type: 'TEXT' }, { name: 'Max price', type: 'TEXT' },\n { name: 'Image', type: 'MEDIA' }, { name: 'Image alt', type: 'TEXT' }, { name: 'Available', type: 'BOOLEAN' },\n { name: 'Variant ID', type: 'TEXT' }, { name: 'Tags', type: 'TEXT' },\n ],\n 'commerce.collection': [{ name: 'Title', type: 'TEXT' }, { name: 'Handle', type: 'TEXT' }, { name: 'URL', type: 'URL' }, { name: 'Description', type: 'TEXT' }],\n 'commerce.cart': [\n { name: 'Count', type: 'NUMBER' }, { name: 'Subtotal', type: 'TEXT' }, { name: 'Taxes', type: 'TEXT' }, { name: 'Total', type: 'TEXT' }, { name: 'Checkout URL', type: 'URL' },\n ],\n 'commerce.cartLine': [\n { name: 'Title', type: 'TEXT' }, { name: 'Variant', type: 'TEXT' }, { name: 'URL', type: 'URL' }, { name: 'Image', type: 'MEDIA' },\n { name: 'Quantity', type: 'NUMBER' }, { name: 'Price', type: 'TEXT' }, { name: 'Merchandise ID', type: 'TEXT' },\n ],\n 'commerce.menu': [{ name: 'Title', type: 'TEXT' }, { name: 'URL', type: 'URL' }],\n}\n\n/**\n * The prop a component takes this schema as: a list, or (`one`) a single value a design shows through a list of one\n * (the cart's totals).\n */\nexport const COMMERCE_PROP: Record<CommerceSchema, { name: string; type: string; one?: true }> = {\n 'commerce.product': { name: 'products', type: 'Product' },\n 'commerce.collection': { name: 'collections', type: 'Collection' },\n 'commerce.cart': { name: 'cart', type: 'Cart', one: true },\n 'commerce.cartLine': { name: 'lines', type: 'CartItem' },\n 'commerce.menu': { name: 'menu', type: 'Menu' },\n}\n\n/** Money as a shopper reads it: `$24.00`. */\nexport function formatMoney(m: Money | undefined, locale = 'en-US'): string {\n if (!m) return ''\n try { return new Intl.NumberFormat(locale, { style: 'currency', currency: m.currencyCode, currencyDisplay: 'narrowSymbol' }).format(Number(m.amount)) }\n catch { return `${m.amount} ${m.currencyCode}` }\n}\n\n/** A record as a design's list draws it: an id, and each field under its key. */\nexport interface CommerceItem { id: string; values: Record<string, string | number | boolean> }\n\n/** One product, collection, cart line or menu entry as the fields its schema gives a design. */\nexport function commerceItem(schema: CommerceSchema, value: unknown): CommerceItem {\n switch (schema) {\n case 'commerce.product': {\n const p = value as Product\n return { id: p.id, values: {\n title: p.title, handle: p.handle, url: `/product/${p.handle}`, description: p.description,\n price: formatMoney(p.priceRange?.minVariantPrice), max_price: formatMoney(p.priceRange?.maxVariantPrice),\n image: p.featuredImage?.url ?? '', image_alt: p.featuredImage?.altText || p.title, available: !!p.availableForSale,\n variant_id: p.variants?.find(v => v.availableForSale)?.id ?? p.variants?.[0]?.id ?? '', tags: (p.tags ?? []).join(', '),\n } }\n }\n case 'commerce.collection': {\n const c = value as Collection\n return { id: c.handle || 'all', values: { title: c.title, handle: c.handle, url: c.path, description: c.description } }\n }\n case 'commerce.cart': {\n const c = value as Cart\n return { id: c.id ?? 'cart', values: {\n count: c.totalQuantity, subtotal: formatMoney(c.cost?.subtotalAmount), taxes: formatMoney(c.cost?.totalTaxAmount),\n total: formatMoney(c.cost?.totalAmount), checkout_url: c.checkoutUrl,\n } }\n }\n case 'commerce.cartLine': {\n const l = value as CartItem\n const m = l.merchandise\n return { id: l.id ?? m.id, values: {\n title: m.product.title, variant: m.title === 'Default Title' ? '' : m.title, url: `/product/${m.product.handle}`,\n image: m.product.featuredImage?.url ?? '', quantity: l.quantity, price: formatMoney(l.cost?.totalAmount), merchandise_id: m.id,\n } }\n }\n case 'commerce.menu': {\n const m = value as Menu\n return { id: m.path, values: { title: m.title, url: m.path } }\n }\n }\n}\n\n/** A field of an item as words on a page (a yes-or-no as Yes or No). */\nexport function commerceWords(item: CommerceItem, key: string): string {\n if (key === 'id') return item.id\n const v = item.values[key]\n return typeof v === 'boolean' ? (v ? 'Yes' : 'No') : v === undefined ? '' : String(v)\n}\n\n/**\n * What a commerce form does. A component takes each as a prop (`onAddToCart`) and gives it to its `<form action>`,\n * so a Next.js server action (Next.js Commerce's `addItem`, `updateItemQuantity`, `removeItem`, `redirectToCheckout`)\n * plugs straight in. A form inside a list's copy sends that copy's fields as hidden inputs.\n */\nexport type CommerceAction = 'addToCart' | 'updateCartLine' | 'removeCartLine' | 'checkout' | 'search'\nexport const COMMERCE_ACTIONS: readonly CommerceAction[] = ['addToCart', 'updateCartLine', 'removeCartLine', 'checkout', 'search']\nexport const COMMERCE_ACTION_PROP: Record<CommerceAction, string> = {\n addToCart: 'onAddToCart', updateCartLine: 'onUpdateCartLine', removeCartLine: 'onRemoveCartLine', checkout: 'onCheckout', search: 'onSearch',\n}\nexport const isCommerceAction = (a: unknown): a is CommerceAction => typeof a === 'string' && (COMMERCE_ACTIONS as readonly string[]).includes(a)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popcraft/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "What code exported from PopCraft shares: the meaning of expressions (operators and functions) and, as it grows, the parts of a design's behaviour that are common code rather than generated React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://popcraft.app/docs/exporting/nextjs",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
17
|
"import": "./dist/index.js"
|
|
18
18
|
},
|
|
19
|
+
"./commerce": {
|
|
20
|
+
"types": "./dist/commerce.d.ts",
|
|
21
|
+
"import": "./dist/commerce.js"
|
|
22
|
+
},
|
|
19
23
|
"./server": {
|
|
20
24
|
"types": "./dist/server/index.d.ts",
|
|
21
25
|
"import": "./dist/server.js"
|