@craftware/crafty-sdk 0.10.1 → 0.10.2
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/dist/cart/index.d.ts +23 -2
- package/dist/cart/index.d.ts.map +1 -1
- package/dist/cart/index.js +58 -1
- package/dist/cart/index.js.map +1 -1
- package/dist/crafty-visual-editing.global.js +1 -1
- package/dist/crafty-visual-editing.global.js.map +1 -1
- package/dist/resources/store.d.ts +7 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +11 -1
- package/dist/resources/store.js.map +1 -1
- package/dist/types/public.d.ts +8 -1
- package/dist/types/public.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/crafty-cms/references/online-store.md +13 -1
- package/skills/crafty-cms/references/sdk-development.md +2 -2
package/dist/cart/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CraftyCartItem } from "../types/public.js";
|
|
2
2
|
export type { CraftyCartItem } from "../types/public.js";
|
|
3
3
|
/** Query parameter the hosted checkout adds to the return URL with the order number. */
|
|
4
|
-
export declare const ORDER_RETURN_PARAM = "
|
|
4
|
+
export declare const ORDER_RETURN_PARAM = "order";
|
|
5
5
|
export type CraftyCartOptions = {
|
|
6
6
|
/** localStorage key; use one per site when a domain hosts several stores. */
|
|
7
7
|
key?: string;
|
|
@@ -26,9 +26,30 @@ export type CraftyCart = {
|
|
|
26
26
|
subscribe(listener: (items: CraftyCartItem[]) => void): () => void;
|
|
27
27
|
/**
|
|
28
28
|
* Empties the cart when the visitor comes back from the checkout with an
|
|
29
|
-
* order (`?
|
|
29
|
+
* order (`?order=` on the URL) and returns the order number, else null.
|
|
30
30
|
*/
|
|
31
31
|
clearOnReturn(url?: string | URL): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Remembers the checkout session the cart was sent to (pass it from
|
|
34
|
+
* `checkout.start(items, { onSession })`), so `syncCheckout()` can empty
|
|
35
|
+
* the cart once that checkout becomes an order.
|
|
36
|
+
*/
|
|
37
|
+
rememberCheckout(id: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Asks Crafty whether the remembered checkout ended in an order and, if
|
|
40
|
+
* so, empties the cart, also when the visitor never came back through the
|
|
41
|
+
* return link. Lines changed since the checkout started are kept. Call it
|
|
42
|
+
* on page load; resolves true when it emptied the cart.
|
|
43
|
+
*/
|
|
44
|
+
syncCheckout(client: CraftyCheckoutStatusSource): Promise<boolean>;
|
|
45
|
+
};
|
|
46
|
+
/** Anything with `checkout.status(id)`, such as a Crafty client. */
|
|
47
|
+
export type CraftyCheckoutStatusSource = {
|
|
48
|
+
checkout: {
|
|
49
|
+
status(id: string): Promise<{
|
|
50
|
+
placed: boolean;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
32
53
|
};
|
|
33
54
|
/**
|
|
34
55
|
* A cart kept in the visitor's browser for `crafty.checkout.start(cart.items())`.
|
package/dist/cart/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cart/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cart/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yGAAyG;IACzG,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC;CACtE,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,wBAAwB;IACxB,KAAK,IAAI,cAAc,EAAE,CAAC;IAC1B,mCAAmC;IACnC,KAAK,IAAI,MAAM,CAAC;IAChB,2FAA2F;IAC3F,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClF,4CAA4C;IAC5C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACtE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACpD,KAAK,IAAI,IAAI,CAAC;IACd,iHAAiH;IACjH,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACnE;;;OAGG;IACH,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;OAKG;IACH,YAAY,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,MAAM,EAAE,OAAO,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAChE,CAAC;AAsCF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CA6KtE"}
|
package/dist/cart/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Query parameter the hosted checkout adds to the return URL with the order number. */
|
|
2
|
-
export const ORDER_RETURN_PARAM = "
|
|
2
|
+
export const ORDER_RETURN_PARAM = "order";
|
|
3
3
|
const MAX_QUANTITY = 999;
|
|
4
4
|
function defaultStorage() {
|
|
5
5
|
try {
|
|
@@ -9,6 +9,9 @@ function defaultStorage() {
|
|
|
9
9
|
return null;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
function sameItems(a, b) {
|
|
13
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
14
|
+
}
|
|
12
15
|
function sameLine(item, slug, variant) {
|
|
13
16
|
return item.slug === slug && (item.variant ?? null) === variant;
|
|
14
17
|
}
|
|
@@ -31,6 +34,7 @@ function sanitize(value) {
|
|
|
31
34
|
*/
|
|
32
35
|
export function createCart(options = {}) {
|
|
33
36
|
const key = options.key ?? "crafty:cart";
|
|
37
|
+
const checkoutKey = `${key}:checkout`;
|
|
34
38
|
const storage = options.storage === undefined ? defaultStorage() : options.storage;
|
|
35
39
|
const listeners = new Set();
|
|
36
40
|
let memory = [];
|
|
@@ -63,6 +67,23 @@ export function createCart(options = {}) {
|
|
|
63
67
|
const snapshot = items.map((item) => ({ ...item }));
|
|
64
68
|
listeners.forEach((listener) => listener(snapshot));
|
|
65
69
|
};
|
|
70
|
+
const remembered = () => {
|
|
71
|
+
try {
|
|
72
|
+
const value = JSON.parse(storage?.getItem(checkoutKey) ?? "null");
|
|
73
|
+
return value && typeof value.id === "string" ? { id: value.id, items: sanitize(value.items) } : null;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const forgetCheckout = () => {
|
|
80
|
+
try {
|
|
81
|
+
storage?.removeItem(checkoutKey);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Storage blocked: nothing was remembered.
|
|
85
|
+
}
|
|
86
|
+
};
|
|
66
87
|
const update = (slug, quantity, variant = null) => {
|
|
67
88
|
const items = read();
|
|
68
89
|
const index = items.findIndex((item) => sameLine(item, slug, variant));
|
|
@@ -124,7 +145,43 @@ export function createCart(options = {}) {
|
|
|
124
145
|
return null;
|
|
125
146
|
}
|
|
126
147
|
write([]);
|
|
148
|
+
forgetCheckout();
|
|
127
149
|
return number;
|
|
150
|
+
},
|
|
151
|
+
rememberCheckout(id) {
|
|
152
|
+
try {
|
|
153
|
+
storage?.setItem(checkoutKey, JSON.stringify({ id, items: read() }));
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Storage full or blocked: the return link still empties the cart.
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
async syncCheckout(client) {
|
|
160
|
+
const checkout = remembered();
|
|
161
|
+
if (!checkout) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
let placed;
|
|
165
|
+
try {
|
|
166
|
+
placed = (await client.checkout.status(checkout.id)).placed;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
// A session that no longer exists can't become an order; other
|
|
170
|
+
// errors (offline) are retried on the next page.
|
|
171
|
+
if (error?.status === 404) {
|
|
172
|
+
forgetCheckout();
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
if (!placed) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
forgetCheckout();
|
|
180
|
+
if (!sameItems(read(), checkout.items)) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
write([]);
|
|
184
|
+
return true;
|
|
128
185
|
}
|
|
129
186
|
};
|
|
130
187
|
}
|
package/dist/cart/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cart/index.ts"],"names":[],"mappings":"AAIA,wFAAwF;AACxF,MAAM,CAAC,MAAM,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cart/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var CraftyVisualEditing=(()=>{var I=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var We=(e,t)=>{for(var n in t)I(e,n,{get:t[n],enumerable:!0})},Ke=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Fe(t))!He.call(e,i)&&i!==n&&I(e,i,{get:()=>t[i],enumerable:!(r=Ie(t,i))||r.enumerable});return e};var $e=e=>Ke(I({},"__esModule",{value:!0}),e);var dt={};We(dt,{PROTOCOL_VERSION:()=>k,attrs:()=>F,attrsHtml:()=>le,enableVisualEditing:()=>Le});function De(e){if(e==null||typeof e!="object")return null;let t=e,n=typeof t.id=="string"?Number(t.id.trim()):t.id;return typeof n!="number"||!Number.isInteger(n)||n<=0?null:t.kind==="block"||t.kind==="entry"?{type:t.kind,id:n}:{type:typeof t.order=="number"&&typeof t.data=="object"&&t.data!==null&&"type"in t?"block":"entry",id:n}}function F(e,t,n={}){let r=De(e),i=typeof t=="string"?t.trim():"";if(r===null||i==="")return{};let l=r.type==="block"?{"data-crafty-block":String(r.id),"data-crafty-field":i}:{"data-crafty-entry":String(r.id),"data-crafty-field":i},a=typeof n.label=="string"?n.label.trim():"";a!==""&&(l["data-crafty-label"]=a);let s=typeof n.hrefField=="string"?n.hrefField.trim():"";if(s!==""){l["data-crafty-href-field"]=s;let d=typeof n.hrefLabel=="string"?n.hrefLabel.trim():"";d!==""&&(l["data-crafty-href-label"]=d)}return l}function le(e,t,n={}){return Object.entries(F(e,t,n)).map(([r,i])=>`${r}="${Ue(String(i))}"`).join(" ")}function Ue(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}var $="crafty_preview";var T="crafty:preview-invalid",D="crafty:preview-content",U="crafty:preview-active",W="crafty:preview-token",ae="crafty:preview-url-token",Ge="crafty:preview-invalid-token",Ye="__CRAFTY_PREVIEW_CONTENT__",ze="__CRAFTY_PREVIEW_STATUS__";function A(){return typeof window=="undefined"?null:window}function H(e){var t,n;try{return(n=(t=A())==null?void 0:t.sessionStorage.getItem(e))!=null?n:null}catch{return null}}function K(e,t){var n;try{(n=A())==null||n.sessionStorage.setItem(e,t)}catch{}}function G(e){return typeof e=="string"&&e.trim()!==""?e.trim():null}function Be(e){try{return G(new URL(e,"http://localhost").searchParams.get($))}catch{return null}}function se(){var r;let e=A();if(e===null)return null;let t=Be(e.location.href),n;return t!==null&&t!==H(ae)?(K(ae,t),K(W,t),n=t):n=(r=G(H(W)))!=null?r:t,n!==null&&n===H(Ge)?null:n}function de(e){let t=G(e);t!==null&&K(W,t)}function ce(){let e=A(),t=e==null?void 0:e[Ye];return t?{page:t.page,entries:[...t.entries]}:{page:null,entries:[]}}function ue(){let e=A(),t=e==null?void 0:e[ze];return t==="active"||t==="invalid"?t:null}var fe="0.10.
|
|
1
|
+
"use strict";var CraftyVisualEditing=(()=>{var I=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var We=(e,t)=>{for(var n in t)I(e,n,{get:t[n],enumerable:!0})},Ke=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Fe(t))!He.call(e,i)&&i!==n&&I(e,i,{get:()=>t[i],enumerable:!(r=Ie(t,i))||r.enumerable});return e};var $e=e=>Ke(I({},"__esModule",{value:!0}),e);var dt={};We(dt,{PROTOCOL_VERSION:()=>k,attrs:()=>F,attrsHtml:()=>le,enableVisualEditing:()=>Le});function De(e){if(e==null||typeof e!="object")return null;let t=e,n=typeof t.id=="string"?Number(t.id.trim()):t.id;return typeof n!="number"||!Number.isInteger(n)||n<=0?null:t.kind==="block"||t.kind==="entry"?{type:t.kind,id:n}:{type:typeof t.order=="number"&&typeof t.data=="object"&&t.data!==null&&"type"in t?"block":"entry",id:n}}function F(e,t,n={}){let r=De(e),i=typeof t=="string"?t.trim():"";if(r===null||i==="")return{};let l=r.type==="block"?{"data-crafty-block":String(r.id),"data-crafty-field":i}:{"data-crafty-entry":String(r.id),"data-crafty-field":i},a=typeof n.label=="string"?n.label.trim():"";a!==""&&(l["data-crafty-label"]=a);let s=typeof n.hrefField=="string"?n.hrefField.trim():"";if(s!==""){l["data-crafty-href-field"]=s;let d=typeof n.hrefLabel=="string"?n.hrefLabel.trim():"";d!==""&&(l["data-crafty-href-label"]=d)}return l}function le(e,t,n={}){return Object.entries(F(e,t,n)).map(([r,i])=>`${r}="${Ue(String(i))}"`).join(" ")}function Ue(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}var $="crafty_preview";var T="crafty:preview-invalid",D="crafty:preview-content",U="crafty:preview-active",W="crafty:preview-token",ae="crafty:preview-url-token",Ge="crafty:preview-invalid-token",Ye="__CRAFTY_PREVIEW_CONTENT__",ze="__CRAFTY_PREVIEW_STATUS__";function A(){return typeof window=="undefined"?null:window}function H(e){var t,n;try{return(n=(t=A())==null?void 0:t.sessionStorage.getItem(e))!=null?n:null}catch{return null}}function K(e,t){var n;try{(n=A())==null||n.sessionStorage.setItem(e,t)}catch{}}function G(e){return typeof e=="string"&&e.trim()!==""?e.trim():null}function Be(e){try{return G(new URL(e,"http://localhost").searchParams.get($))}catch{return null}}function se(){var r;let e=A();if(e===null)return null;let t=Be(e.location.href),n;return t!==null&&t!==H(ae)?(K(ae,t),K(W,t),n=t):n=(r=G(H(W)))!=null?r:t,n!==null&&n===H(Ge)?null:n}function de(e){let t=G(e);t!==null&&K(W,t)}function ce(){let e=A(),t=e==null?void 0:e[Ye];return t?{page:t.page,entries:[...t.entries]}:{page:null,entries:[]}}function ue(){let e=A(),t=e==null?void 0:e[ze];return t==="active"||t==="invalid"?t:null}var fe="0.10.2";var k=1;var Xe=/^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+|\[\d+\])*$/,je=/^[\x21-\x7E]+$/;function S(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function qe(e){return typeof e=="number"&&Number.isInteger(e)&&e>0}function pe(e){if(typeof e!="string")return null;let t=e.trim();return t===""||t.length>255||!Xe.test(t)?null:t}function ye(e){return typeof e=="string"?e.trim().slice(0,120).trim():""}function x(e){if(!S(e))return null;let{type:t,id:n}=e,r=pe(e.field);return t!=="block"&&t!=="entry"||!qe(n)||r===null?null:{type:t,id:n,field:r}}function ge(e){let t=x(e);if(t===null||!S(e))return null;let n={...t},r=ye(e.label),i=pe(e.hrefField);if(r!==""&&(n.label=r),i!==null){n.hrefField=i;let l=ye(e.hrefLabel);l!==""&&(n.hrefLabel=l)}return n}function Qe(e){if(!S(e)||e.v!==1||typeof e.type!="string")return null;let t=e.payload===void 0?{}:e.payload;return S(t)?{type:e.type,payload:t}:null}function Ee(e){let t=Qe(e);if(t===null)return null;let{payload:n}=t;switch(t.type){case"crafty:token":{let r=typeof n.token=="string"?n.token.trim():"";return r!==""&&r.length<=4096&&je.test(r)?{v:1,type:"crafty:token",payload:{token:r}}:null}case"crafty:refresh":return{v:1,type:"crafty:refresh",payload:{}};case"crafty:highlight":{let r=x(n);return r?{v:1,type:"crafty:highlight",payload:r}:null}case"crafty:preview-field":{let r=x(n),i=n.value;return r&&typeof i=="string"&&i.length<=1e5?{v:1,type:"crafty:preview-field",payload:{...r,value:i}}:null}case"crafty:preview-reset":{let r=x(n);return r?{v:1,type:"crafty:preview-reset",payload:r}:null}default:return null}}var R="[data-crafty-field]";function L(e){var i;let t=e.getAttribute("data-crafty-block"),n=e.getAttribute("data-crafty-entry"),r=t!=null?t:n;return r===null?null:ge({type:t!==null?"block":"entry",id:r.trim()===""?Number.NaN:Number(r),field:(i=e.getAttribute("data-crafty-field"))!=null?i:"",label:e.getAttribute("data-crafty-label"),hrefField:e.getAttribute("data-crafty-href-field"),hrefLabel:e.getAttribute("data-crafty-href-label")})}function E(e){return`${e.type}:${e.id}:${e.field}`}function _(e){let t=[];return e.querySelectorAll(R).forEach(n=>{let r=L(n);r!==null&&t.push({element:n,field:r})}),t}function Y(e){let t=new Set,n=[];for(let{field:r}of e){let i=E(r);t.has(i)||(t.add(i),n.push(r))}return n}function ve(e){let t=new Map,n=new Map,r=a=>Array.from(e.querySelectorAll(R)).filter(s=>{let d=L(s);return d!==null&&E(d)===a}),i=(a,s)=>{var d;n.has(a)||n.set(a,(d=a.textContent)!=null?d:""),a.textContent!==s&&(a.textContent=s)},l=a=>{for(let[s,d]of n){let y=L(s);(a===null||y!==null&&E(y)===a)&&(s.textContent!==d&&(s.textContent=d),n.delete(s))}};return{set(a,s){let d=E(a);t.set(d,s),r(d).forEach(y=>i(y,s))},reset(a){let s=E(a);t.delete(s),l(s)},reapply(){for(let a of[...n.keys()])a.isConnected||n.delete(a);for(let[a,s]of t)r(a).forEach(d=>i(d,s))},resetAll(){t.clear(),l(null)},get size(){return t.size}}}var he=[/^https:\/\/([a-z0-9-]+\.)*crafty\.do$/];function me(e){try{return new URL(e).origin}catch{return null}}function ke(e,t){return e===""||e==="null"?!1:t.some(n=>typeof n=="string"?me(n)===e:(n.lastIndex=0,n.test(e)))}function be(e){let t=e.location.ancestorOrigins,n=t&&t.length>0?t[0]:void 0;if(typeof n=="string"&&n!=="")return n;let r=e.document.referrer;return r?me(r):null}var Ze="crafty-visual-editing-style",z="#4f46e5",B="crafty-ve-flash",Je=["[data-crafty-field]{cursor:pointer}",`.crafty-ve-box{position:fixed;top:0;left:0;pointer-events:none;z-index:2147483647;box-sizing:border-box;border:2px solid ${z};border-radius:4px;background:rgba(79,70,229,.06)}`,".crafty-ve-box[hidden]{display:none}",`.crafty-ve-label{position:absolute;left:-2px;bottom:100%;margin-bottom:4px;padding:2px 8px;max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;background:${z};color:#fff;font:500 12px/1.5 system-ui,-apple-system,sans-serif}`,`.${B}{outline:2px dashed ${z} !important;outline-offset:2px !important}`].join(`
|
|
2
2
|
`);function Ce(e){let t=e.defaultView,n=e.createElement("style");n.id=Ze,n.textContent=Je;let r=e.createElement("div");r.setAttribute("data-crafty-overlay",""),r.className="crafty-ve-box",r.hidden=!0;let i=e.createElement("span");i.className="crafty-ve-label",r.appendChild(i);let l=null,a=[],s,d=t==null?void 0:t.ResizeObserver,y=()=>{if(l===null)return;let c=l.getBoundingClientRect();r.style.top=`${c.top}px`,r.style.left=`${c.left}px`,r.style.width=`${c.width}px`,r.style.height=`${c.height}px`},f=typeof d=="function"?new d(()=>y()):null,v=c=>{l!==c&&(l!==null&&(f==null||f.unobserve(l)),l=c,l!==null&&(f==null||f.observe(l)))},g=()=>{a.forEach(c=>c.classList.remove(B)),a=[],s!==void 0&&(t==null||t.clearTimeout(s),s=void 0)},h=()=>{var c,m;n.isConnected||((c=e.head)!=null?c:e.documentElement).appendChild(n),r.isConnected||((m=e.body)!=null?m:e.documentElement).appendChild(r)};return h(),t==null||t.addEventListener("scroll",y,{capture:!0,passive:!0}),t==null||t.addEventListener("resize",y,{passive:!0}),{show(c,m){h(),v(c),i.textContent!==m&&(i.textContent=m),r.hidden=!1,y()},hide(){v(null),r.hidden=!0},reposition(){y()},flash(c,m){g(),a=[...c],a.forEach(w=>w.classList.add(B)),s=t==null?void 0:t.setTimeout(g,m)},ensureAttached:h,contains(c){return c!==null&&(r===c||r.contains(c)||n===c||n.contains(c))},destroy(){g(),t==null||t.removeEventListener("scroll",y,{capture:!0}),t==null||t.removeEventListener("resize",y),f==null||f.disconnect(),r.remove(),n.remove(),l=null}}}var j="crafty:scroll-y",et=50,tt=1500,nt=["data-crafty-field","data-crafty-block","data-crafty-entry","data-crafty-label","data-crafty-href-field","data-crafty-href-label"],N={active:!1,disable:()=>{}},b=null;function Le(e={}){var i;if(typeof window=="undefined"||typeof document=="undefined")return N;if(b!==null)return b;let t=window;if(t.parent===null||t.parent===t||se()===null)return N;let n=be(t);if(n===null||!ke(n,(i=e.adminOrigins)!=null?i:he))return N;let r=ue();return r==="invalid"?(we(t,n),N):(b=r==="active"?Oe(t,n,e):rt(t,n,e),b)}function we(e,t){let n={v:1,type:"crafty:preview-invalid",payload:{}};e.parent.postMessage(n,t)}function rt(e,t,n){var f;let r=null,i=!1,l=()=>{i=!0,e.removeEventListener(U,s),e.removeEventListener(T,d)},a=()=>{b===y&&(b=null)},s=()=>{i||(l(),r=Oe(e,t,n,a))},d=()=>{i||(l(),a(),we(e,t))},y={get active(){var v;return(v=r==null?void 0:r.active)!=null?v:!1},disable(){l(),r==null||r.disable(),a()}};return e.addEventListener(U,s),e.addEventListener(T,d),(f=n.client)==null||f.pages.list({per_page:1}).catch(()=>{}),y}function Oe(e,t,n,r){let i=e.document,l=Ce(i),a=ve(i),s=at(e),d=[],y=null,f,v=!1,g=!0,h=o=>{e.parent.postMessage(o,t)},c=()=>{var p,C,O;let o=Y(d),u=ce();y=Re(o),h({v:1,type:"crafty:ready",payload:{sdkVersion:fe,path:_e(e),fields:o,page:(C=(p=u.page)!=null?p:n.page)!=null?C:null,entries:it(u.entries,(O=n.entries)!=null?O:[])}})},m=()=>{f=void 0,g&&(l.ensureAttached(),d=_(i),a.reapply(),(v||Re(Y(d))!==y)&&(v=!1,c()))},w=()=>{g&&f===void 0&&(f=e.setTimeout(m,et))},q=new MutationObserver(o=>{o.some(u=>!l.contains(u.target))&&w()}),V=o=>{var u;return(u=o.label)!=null?u:o.field},Q=o=>{if(o.pointerType==="touch")return;let u=X(o.target);u!==null?l.show(u.element,V(u.field)):l.hide()},P=o=>{o.preventDefault(),o.stopPropagation()},Z=o=>{let u=X(o.target);if(u!==null){P(o),l.show(u.element,V(u.field)),h({v:1,type:"crafty:select",payload:u.field});return}let p=ot(o,e);p.kind!=="allow"&&(P(o),p.kind==="navigate"&&h({v:1,type:"crafty:navigate",payload:{path:p.path}}))},J=o=>{(X(o.target)!==null||xe(o.target)!==null)&&P(o)},ee=o=>{P(o)},te=o=>{o.key!=="Escape"||o.repeat||o.isComposing||o.defaultPrevented||h({v:1,type:"crafty:key",payload:{key:"Escape"}})},Se=o=>{var O;let u=E(o),p=_(i).find(Me=>E(Me.field)===u);if(p===void 0)return;let C=p.element;(O=C.scrollIntoView)==null||O.call(C,{block:"center",behavior:"smooth"}),l.show(p.element,V(p.field))},Ne=async()=>{if(n.onRefresh){try{await n.onRefresh()}finally{w()}return}try{e.sessionStorage.setItem(j,String(e.scrollY))}catch{}e.location.reload()},Ve=o=>{switch(o.type){case"crafty:token":de(o.payload.token);return;case"crafty:refresh":Ne().catch(u=>console.error("[crafty] onRefresh failed",u));return;case"crafty:highlight":Se(o.payload);return;case"crafty:preview-field":a.set(o.payload,o.payload.value),l.reposition();return;case"crafty:preview-reset":a.reset(o.payload),l.reposition();return}},ne=o=>{if(o.source!==e.parent||o.origin!==t)return;let u=Ee(o.data);u!==null&&Ve(u)},re=()=>{h({v:1,type:"crafty:preview-invalid",payload:{}})},ie=()=>{v=!0,w()},M=()=>{var o;g&&(d=_(i),c(),lt(e)&&l.flash(d.map(u=>u.element),(o=n.touchHighlightMs)!=null?o:tt),st(e,s))};e.addEventListener("message",ne),e.addEventListener("click",Z,!0),e.addEventListener("auxclick",J,!0),e.addEventListener("submit",ee,!0),e.addEventListener("keydown",te),i.addEventListener("pointerover",Q,!0),e.addEventListener(T,re),e.addEventListener(D,ie),q.observe(i.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:nt}),i.readyState==="loading"?i.addEventListener("DOMContentLoaded",M,{once:!0}):M();let oe={get active(){return g},disable(){g&&(g=!1,e.removeEventListener("message",ne),e.removeEventListener("click",Z,!0),e.removeEventListener("auxclick",J,!0),e.removeEventListener("submit",ee,!0),e.removeEventListener("keydown",te),i.removeEventListener("pointerover",Q,!0),i.removeEventListener("DOMContentLoaded",M),e.removeEventListener(T,re),e.removeEventListener(D,ie),q.disconnect(),f!==void 0&&(e.clearTimeout(f),f=void 0),a.resetAll(),l.destroy(),b===oe&&(b=null),r==null||r())}};return oe}function Te(e){return e!==null&&typeof e.closest=="function"?e:null}function Re(e){return e.map(t=>{var n,r,i;return`${E(t)}|${(n=t.label)!=null?n:""}|${(r=t.hrefField)!=null?r:""}|${(i=t.hrefLabel)!=null?i:""}`}).join(`
|
|
3
3
|
`)}function it(e,t){let n=new Set;return[...e,...t].filter(r=>{let i=`${r.collection}:${r.id}`;return n.has(i)?!1:(n.add(i),!0)})}function Ae(e){return e.searchParams.delete($),`${e.pathname}${e.search}`}function _e(e){return Ae(new URL(e.location.href))}var Pe="a[href], area[href]";function X(e){var r,i,l;let t=Te(e);if(t===null)return null;for(let a=t.closest(R);a!==null;a=(i=(r=a.parentElement)==null?void 0:r.closest(R))!=null?i:null){let s=L(a);if(s!==null)return{element:a,field:s}}let n=t.closest(Pe);return n!==null&&(l=_(n)[0])!=null?l:null}function xe(e){var t,n;return(n=(t=Te(e))==null?void 0:t.closest(Pe))!=null?n:null}function ot(e,t){var s;let n=xe(e.target);if(n===null)return{kind:"allow"};if(e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||n.hasAttribute("download"))return{kind:"block"};let r=n.getAttribute("target");if(r!==null&&r!==""&&r!=="_self")return{kind:"block"};let i=(s=n.getAttribute("href"))!=null?s:"",l;try{l=new URL(i,t.location.href)}catch{return{kind:"block"}}if(l.origin!==t.location.origin||l.protocol!=="http:"&&l.protocol!=="https:")return{kind:"block"};let a=Ae(l);return(l.hash!==""||i.startsWith("#"))&&a===_e(t)?{kind:"allow"}:{kind:"navigate",path:a}}function lt(e){return typeof e.matchMedia=="function"&&e.matchMedia("(hover: none)").matches}function at(e){try{let t=e.sessionStorage.getItem(j);e.sessionStorage.removeItem(j);let n=t===null?Number.NaN:Number(t);return Number.isFinite(n)?n:null}catch{return null}}function st(e,t){if(t===null)return;let n=()=>e.scrollTo(0,t);e.document.readyState==="complete"?n():e.addEventListener("load",n,{once:!0})}return $e(dt);})();
|
|
4
4
|
//# sourceMappingURL=crafty-visual-editing.global.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cdn.ts", "../src/attrs.ts", "../src/preview.ts", "../src/version.ts", "../src/visual-editing/protocol.ts", "../src/visual-editing/markers.ts", "../src/visual-editing/live-preview.ts", "../src/visual-editing/origin.ts", "../src/visual-editing/overlay.ts", "../src/visual-editing/bridge.ts"],
|
|
4
|
-
"sourcesContent": ["/** Entry for the `<script>` build: exposed as `window.CraftyVisualEditing`. */\nexport { attrs, attrsHtml } from \"./attrs.js\";\nexport { enableVisualEditing } from \"./visual-editing/bridge.js\";\nexport { PROTOCOL_VERSION } from \"./visual-editing/protocol.js\";\n", "import type { CraftyBlock, CraftyEntry } from \"./types/public.js\";\n\nexport type CraftyEditTargetType = \"block\" | \"entry\";\n\n/**\n * A block or entry as returned by the API, or an explicit reference for\n * ambiguous shapes (e.g. an entry with fields named `order`, `data` and `type`).\n */\nexport type CraftyEditTarget =\n | CraftyBlock\n | CraftyEntry\n | { kind: CraftyEditTargetType; id: number | string };\n\nexport type CraftyAttrsOptions = {\n /** Human label shown by the visual editor, e.g. \"T\u00EDtulo de la secci\u00F3n\". */\n label?: string;\n /**\n * Field holding the link destination of this element (a button or link whose\n * text is `field`), e.g. `hero.cta.href`. The editor then edits both together.\n */\n hrefField?: string;\n /** Human label for `hrefField`. Defaults to \"Enlace\" in the editor. */\n hrefLabel?: string;\n};\n\nexport type CraftyEditAttributes = {\n \"data-crafty-block\"?: string;\n \"data-crafty-entry\"?: string;\n \"data-crafty-field\"?: string;\n \"data-crafty-label\"?: string;\n \"data-crafty-href-field\"?: string;\n \"data-crafty-href-label\"?: string;\n};\n\nexport function resolveEditTarget(\n target: CraftyEditTarget | null | undefined\n): { type: CraftyEditTargetType; id: number } | null {\n if (target === null || target === undefined || typeof target !== \"object\") {\n return null;\n }\n\n const record = target as Record<string, unknown>;\n const id = typeof record.id === \"string\" ? Number(record.id.trim()) : record.id;\n\n if (typeof id !== \"number\" || !Number.isInteger(id) || id <= 0) {\n return null;\n }\n\n if (record.kind === \"block\" || record.kind === \"entry\") {\n return { type: record.kind, id };\n }\n\n const looksLikeBlock =\n typeof record.order === \"number\" &&\n typeof record.data === \"object\" &&\n record.data !== null &&\n \"type\" in record;\n\n return { type: looksLikeBlock ? \"block\" : \"entry\", id };\n}\n\n/**\n * DOM attributes that let the visual editor map an element to a field.\n * Always emitted (static sites render them at build time without a token).\n * `field` is a top-level field key or a JSON path such as `sections[3].title`.\n */\nexport function attrs(\n target: CraftyEditTarget | null | undefined,\n field: string,\n options: CraftyAttrsOptions = {}\n): CraftyEditAttributes {\n const resolved = resolveEditTarget(target);\n const normalizedField = typeof field === \"string\" ? field.trim() : \"\";\n\n if (resolved === null || normalizedField === \"\") {\n return {};\n }\n\n const attributes: CraftyEditAttributes =\n resolved.type === \"block\"\n ? { \"data-crafty-block\": String(resolved.id), \"data-crafty-field\": normalizedField }\n : { \"data-crafty-entry\": String(resolved.id), \"data-crafty-field\": normalizedField };\n\n const label = typeof options.label === \"string\" ? options.label.trim() : \"\";\n\n if (label !== \"\") {\n attributes[\"data-crafty-label\"] = label;\n }\n\n const hrefField = typeof options.hrefField === \"string\" ? options.hrefField.trim() : \"\";\n\n if (hrefField !== \"\") {\n attributes[\"data-crafty-href-field\"] = hrefField;\n\n const hrefLabel = typeof options.hrefLabel === \"string\" ? options.hrefLabel.trim() : \"\";\n\n if (hrefLabel !== \"\") {\n attributes[\"data-crafty-href-label\"] = hrefLabel;\n }\n }\n\n return attributes;\n}\n\n/** Same as `attrs()`, rendered for HTML string templates. */\nexport function attrsHtml(\n target: CraftyEditTarget | null | undefined,\n field: string,\n options: CraftyAttrsOptions = {}\n): string {\n return Object.entries(attrs(target, field, options))\n .map(([name, value]) => `${name}=\"${escapeAttribute(String(value))}\"`)\n .join(\" \");\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n", "export const PREVIEW_QUERY_PARAM = \"crafty_preview\";\nexport const PREVIEW_HEADER = \"X-Crafty-Preview\";\nexport const PREVIEW_STATUS_HEADER = \"X-Crafty-Preview-Status\";\nexport const PREVIEW_INVALID_EVENT = \"crafty:preview-invalid\";\nexport const PREVIEW_CONTENT_EVENT = \"crafty:preview-content\";\nexport const PREVIEW_ACTIVE_EVENT = \"crafty:preview-active\";\n\nconst TOKEN_STORAGE_KEY = \"crafty:preview-token\";\nconst URL_TOKEN_STORAGE_KEY = \"crafty:preview-url-token\";\nconst INVALID_TOKEN_STORAGE_KEY = \"crafty:preview-invalid-token\";\nconst CONTENT_GLOBAL_KEY = \"__CRAFTY_PREVIEW_CONTENT__\";\nconst STATUS_GLOBAL_KEY = \"__CRAFTY_PREVIEW_STATUS__\";\n\nexport type PreviewPage = { id: number; slug: string };\nexport type PreviewEntry = { id: number; collection: string };\nexport type PreviewContent = { page: PreviewPage | null; entries: PreviewEntry[] };\n/** Last `X-Crafty-Preview-Status` the API answered in this window, or null before any preview request. */\nexport type PreviewStatus = \"active\" | \"invalid\";\n\n/** A URL, a Web `Request`, a Node `IncomingMessage` or an Express-style request. */\nexport type PreviewRequestLike =\n | string\n | URL\n | { url?: string | undefined; query?: Record<string, unknown> | undefined };\n\ntype ContentHost = Record<string, PreviewContent | undefined>;\n\nfunction browserWindow(): Window | null {\n return typeof window === \"undefined\" ? null : window;\n}\n\nfunction storageGet(key: string): string | null {\n try {\n return browserWindow()?.sessionStorage.getItem(key) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction storageSet(key: string, value: string): void {\n try {\n browserWindow()?.sessionStorage.setItem(key, value);\n } catch {\n // Storage can be blocked (private mode, sandboxed frames); the URL token still works.\n }\n}\n\nfunction storageRemove(key: string): void {\n try {\n browserWindow()?.sessionStorage.removeItem(key);\n } catch {\n // Ignore blocked storage.\n }\n}\n\nfunction normalizeToken(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n}\n\nfunction tokenFromUrl(url: string): string | null {\n try {\n return normalizeToken(new URL(url, \"http://localhost\").searchParams.get(PREVIEW_QUERY_PARAM));\n } catch {\n return null;\n }\n}\n\n/**\n * Preview token for browser requests. A token the URL brings for the first time\n * wins; afterwards the stored token wins, so a renewal received over\n * `postMessage` is not overwritten by the stale token still in the URL.\n */\nexport function readPreviewToken(): string | null {\n const win = browserWindow();\n\n if (win === null) {\n return null;\n }\n\n const urlToken = tokenFromUrl(win.location.href);\n let token: string | null;\n\n if (urlToken !== null && urlToken !== storageGet(URL_TOKEN_STORAGE_KEY)) {\n storageSet(URL_TOKEN_STORAGE_KEY, urlToken);\n storageSet(TOKEN_STORAGE_KEY, urlToken);\n token = urlToken;\n } else {\n token = normalizeToken(storageGet(TOKEN_STORAGE_KEY)) ?? urlToken;\n }\n\n return token !== null && token === storageGet(INVALID_TOKEN_STORAGE_KEY) ? null : token;\n}\n\n/**\n * Forgets a browser token the API reported invalid, so later requests stop\n * sending it (the stale copy in the URL included) until a new token arrives\n * over `postMessage` or a new URL. Explicit server-side tokens are untouched.\n */\nexport function discardPreviewToken(token: string): void {\n const win = browserWindow();\n const normalized = normalizeToken(token);\n\n if (win === null || normalized === null) {\n return;\n }\n\n const isStored = normalizeToken(storageGet(TOKEN_STORAGE_KEY)) === normalized;\n\n if (!isStored && tokenFromUrl(win.location.href) !== normalized) {\n return;\n }\n\n if (isStored) {\n storageRemove(TOKEN_STORAGE_KEY);\n }\n\n storageSet(INVALID_TOKEN_STORAGE_KEY, normalized);\n}\n\nexport function storePreviewToken(token: string): void {\n const normalized = normalizeToken(token);\n\n if (normalized !== null) {\n storageSet(TOKEN_STORAGE_KEY, normalized);\n }\n}\n\nexport function clearPreviewToken(): void {\n storageRemove(TOKEN_STORAGE_KEY);\n storageRemove(URL_TOKEN_STORAGE_KEY);\n storageRemove(INVALID_TOKEN_STORAGE_KEY);\n setPreviewStatus(null);\n}\n\n/** Server-side helper: the preview token of an incoming request, or null. */\nexport function previewFromRequest(request: PreviewRequestLike | null | undefined): string | null {\n if (request === null || request === undefined) {\n return null;\n }\n\n if (typeof request === \"string\" || request instanceof URL) {\n return tokenFromUrl(String(request));\n }\n\n const queryValue = request.query?.[PREVIEW_QUERY_PARAM];\n const fromQuery = normalizeToken(Array.isArray(queryValue) ? queryValue[0] : queryValue);\n\n if (fromQuery !== null) {\n return fromQuery;\n }\n\n return typeof request.url === \"string\" ? tokenFromUrl(request.url) : null;\n}\n\nexport function getPreviewContent(): PreviewContent {\n const win = browserWindow() as (Window & ContentHost) | null;\n const content = win?.[CONTENT_GLOBAL_KEY];\n\n return content ? { page: content.page, entries: [...content.entries] } : { page: null, entries: [] };\n}\n\nexport function recordPreviewContent(\n item: ({ type: \"page\" } & PreviewPage) | ({ type: \"entry\" } & PreviewEntry)\n): void {\n const win = browserWindow() as (Window & ContentHost) | null;\n\n if (win === null) {\n return;\n }\n\n const content = win[CONTENT_GLOBAL_KEY] ?? { page: null, entries: [] };\n win[CONTENT_GLOBAL_KEY] = content;\n\n if (item.type === \"page\") {\n content.page = { id: item.id, slug: item.slug };\n } else if (!content.entries.some((entry) => entry.id === item.id && entry.collection === item.collection)) {\n content.entries.push({ id: item.id, collection: item.collection });\n }\n\n dispatch(PREVIEW_CONTENT_EVENT);\n}\n\nexport function resetPreviewContent(): void {\n const win = browserWindow() as (Window & ContentHost) | null;\n\n if (win !== null) {\n win[CONTENT_GLOBAL_KEY] = undefined;\n }\n}\n\n/**\n * Kept on `window` (like the shown content) so a separately bundled bridge, such\n * as the `<script>` build, sees what the site's own SDK copy recorded.\n */\nexport function getPreviewStatus(): PreviewStatus | null {\n const win = browserWindow() as (Window & Record<string, unknown>) | null;\n const status = win?.[STATUS_GLOBAL_KEY];\n\n return status === \"active\" || status === \"invalid\" ? status : null;\n}\n\nfunction setPreviewStatus(status: PreviewStatus | null): void {\n const win = browserWindow() as (Window & Record<string, unknown>) | null;\n\n if (win !== null) {\n win[STATUS_GLOBAL_KEY] = status ?? undefined;\n }\n}\n\nexport function notifyPreviewActive(): void {\n setPreviewStatus(\"active\");\n dispatch(PREVIEW_ACTIVE_EVENT);\n}\n\nexport function notifyPreviewInvalid(): void {\n setPreviewStatus(\"invalid\");\n dispatch(PREVIEW_INVALID_EVENT);\n}\n\nfunction dispatch(name: string): void {\n const win = browserWindow();\n\n if (win !== null && typeof win.dispatchEvent === \"function\") {\n win.dispatchEvent(new Event(name));\n }\n}\n", "// Generated by scripts/write-version.mjs from package.json. Do not edit.\nexport const SDK_VERSION = \"0.10.1\";\n", "export const PROTOCOL_VERSION = 1;\n\nexport type CraftyTargetType = \"block\" | \"entry\";\nexport type CraftyFieldRef = { type: CraftyTargetType; id: number; field: string };\n/** `hrefField` is the field with the link destination of the same element (same target). */\nexport type CraftyMarkedField = CraftyFieldRef & { label?: string; hrefField?: string; hrefLabel?: string };\nexport type CraftyShownPage = { id: number; slug: string };\nexport type CraftyShownEntry = { id: number; collection: string };\n\nexport type ReadyPayload = {\n sdkVersion: string;\n path: string;\n fields: CraftyMarkedField[];\n page: CraftyShownPage | null;\n entries: CraftyShownEntry[];\n};\n\ntype Version = typeof PROTOCOL_VERSION;\n\n/**\n * Keys forwarded to the admin (`crafty:key`, SDK >= 0.4.1): the admin never\n * sees keydowns while focus is inside the iframe, so Escape could not close\n * its sheets and dialogs. Older admins ignore the message.\n */\nexport type ForwardedKey = \"Escape\";\ntype EmptyPayload = Record<string, never>;\n\n/** iframe -> admin. `crafty:ready` is a snapshot that may be re-sent; the last one wins. */\nexport type OutboundMessage =\n | { v: Version; type: \"crafty:ready\"; payload: ReadyPayload }\n | { v: Version; type: \"crafty:select\"; payload: CraftyMarkedField }\n | { v: Version; type: \"crafty:navigate\"; payload: { path: string } }\n | { v: Version; type: \"crafty:preview-invalid\"; payload: EmptyPayload }\n | { v: Version; type: \"crafty:key\"; payload: { key: ForwardedKey } };\n\n/** admin -> iframe. */\nexport type InboundMessage =\n | { v: Version; type: \"crafty:token\"; payload: { token: string } }\n | { v: Version; type: \"crafty:refresh\"; payload: EmptyPayload }\n | { v: Version; type: \"crafty:highlight\"; payload: CraftyFieldRef }\n | { v: Version; type: \"crafty:preview-field\"; payload: CraftyFieldRef & { value: string } }\n | { v: Version; type: \"crafty:preview-reset\"; payload: CraftyFieldRef };\n\n/** Same limits as the Crafty admin and backend (content_drafts.field / label). */\nconst MAX_FIELD_LENGTH = 255;\nconst MAX_LABEL_LENGTH = 120;\nconst MAX_TOKEN_LENGTH = 4096;\nconst MAX_VALUE_LENGTH = 100_000;\nconst MAX_PATH_LENGTH = 2048;\nconst FIELD_PATTERN = /^[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+|\\[\\d+\\])*$/;\nconst TOKEN_PATTERN = /^[\\x21-\\x7E]+$/;\nconst CONTROL_CHARACTERS = /[\\u0000-\\u001F\\u007F]/;\nconst PATH_BASE = \"https://crafty.invalid\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPositiveInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isInteger(value) && value > 0;\n}\n\nfunction parseFieldPath(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n\n const trimmed = value.trim();\n\n return trimmed === \"\" || trimmed.length > MAX_FIELD_LENGTH || !FIELD_PATTERN.test(trimmed) ? null : trimmed;\n}\n\nfunction parseLabel(value: unknown): string {\n return typeof value === \"string\" ? value.trim().slice(0, MAX_LABEL_LENGTH).trim() : \"\";\n}\n\nexport function parseFieldRef(value: unknown): CraftyFieldRef | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const { type, id } = value;\n const field = parseFieldPath(value.field);\n\n if ((type !== \"block\" && type !== \"entry\") || !isPositiveInteger(id) || field === null) {\n return null;\n }\n\n return { type, id, field };\n}\n\n/** An invalid `hrefField` is dropped; the text field stays selectable. */\nexport function parseMarkedField(value: unknown): CraftyMarkedField | null {\n const ref = parseFieldRef(value);\n\n if (ref === null || !isRecord(value)) {\n return null;\n }\n\n const marked: CraftyMarkedField = { ...ref };\n const label = parseLabel(value.label);\n const hrefField = parseFieldPath(value.hrefField);\n\n if (label !== \"\") {\n marked.label = label;\n }\n\n if (hrefField !== null) {\n marked.hrefField = hrefField;\n\n const hrefLabel = parseLabel(value.hrefLabel);\n\n if (hrefLabel !== \"\") {\n marked.hrefLabel = hrefLabel;\n }\n }\n\n return marked;\n}\n\nfunction isSameOriginPath(value: string): boolean {\n if (!value.startsWith(\"/\") || value.startsWith(\"//\") || value.startsWith(\"/\\\\\")) {\n return false;\n }\n\n try {\n const url = new URL(value, PATH_BASE);\n\n // Dot segments can still resolve to a protocol-relative path (\"/.//evil.example\").\n return url.origin === PATH_BASE && !url.pathname.startsWith(\"//\") && !url.pathname.startsWith(\"/\\\\\");\n } catch {\n return false;\n }\n}\n\nfunction parsePath(value: unknown): string | null {\n if (typeof value !== \"string\" || value.length > MAX_PATH_LENGTH || CONTROL_CHARACTERS.test(value)) {\n return null;\n }\n\n return isSameOriginPath(value) ? value : null;\n}\n\nfunction parseShownEntry(value: unknown): CraftyShownEntry | null {\n return isRecord(value) && isPositiveInteger(value.id) && typeof value.collection === \"string\"\n ? { id: value.id, collection: value.collection }\n : null;\n}\n\nfunction readEnvelope(data: unknown): { type: string; payload: Record<string, unknown> } | null {\n if (!isRecord(data) || data.v !== PROTOCOL_VERSION || typeof data.type !== \"string\") {\n return null;\n }\n\n const payload = data.payload === undefined ? {} : data.payload;\n\n return isRecord(payload) ? { type: data.type, payload } : null;\n}\n\nexport function parseInboundMessage(data: unknown): InboundMessage | null {\n const message = readEnvelope(data);\n\n if (message === null) {\n return null;\n }\n\n const { payload } = message;\n\n switch (message.type) {\n case \"crafty:token\": {\n const token = typeof payload.token === \"string\" ? payload.token.trim() : \"\";\n\n return token !== \"\" && token.length <= MAX_TOKEN_LENGTH && TOKEN_PATTERN.test(token)\n ? { v: PROTOCOL_VERSION, type: \"crafty:token\", payload: { token } }\n : null;\n }\n case \"crafty:refresh\":\n return { v: PROTOCOL_VERSION, type: \"crafty:refresh\", payload: {} };\n case \"crafty:highlight\": {\n const ref = parseFieldRef(payload);\n\n return ref ? { v: PROTOCOL_VERSION, type: \"crafty:highlight\", payload: ref } : null;\n }\n case \"crafty:preview-field\": {\n const ref = parseFieldRef(payload);\n const value = payload.value;\n\n return ref && typeof value === \"string\" && value.length <= MAX_VALUE_LENGTH\n ? { v: PROTOCOL_VERSION, type: \"crafty:preview-field\", payload: { ...ref, value } }\n : null;\n }\n case \"crafty:preview-reset\": {\n const ref = parseFieldRef(payload);\n\n return ref ? { v: PROTOCOL_VERSION, type: \"crafty:preview-reset\", payload: ref } : null;\n }\n default:\n return null;\n }\n}\n\nexport function parseOutboundMessage(data: unknown): OutboundMessage | null {\n const message = readEnvelope(data);\n\n if (message === null) {\n return null;\n }\n\n const { payload } = message;\n\n switch (message.type) {\n case \"crafty:ready\": {\n const path = parsePath(payload.path);\n const rawPage = payload.page;\n\n if (typeof payload.sdkVersion !== \"string\" || path === null || !Array.isArray(payload.fields) || !Array.isArray(payload.entries)) {\n return null;\n }\n\n return {\n v: PROTOCOL_VERSION,\n type: \"crafty:ready\",\n payload: {\n sdkVersion: payload.sdkVersion,\n path,\n fields: payload.fields\n .map((field: unknown) => parseMarkedField(field))\n .filter((field): field is CraftyMarkedField => field !== null),\n page:\n isRecord(rawPage) && isPositiveInteger(rawPage.id) && typeof rawPage.slug === \"string\"\n ? { id: rawPage.id, slug: rawPage.slug }\n : null,\n entries: payload.entries\n .map((entry: unknown) => parseShownEntry(entry))\n .filter((entry): entry is CraftyShownEntry => entry !== null)\n }\n };\n }\n case \"crafty:select\": {\n const field = parseMarkedField(payload);\n\n return field ? { v: PROTOCOL_VERSION, type: \"crafty:select\", payload: field } : null;\n }\n case \"crafty:navigate\": {\n const path = parsePath(payload.path);\n\n return path ? { v: PROTOCOL_VERSION, type: \"crafty:navigate\", payload: { path } } : null;\n }\n case \"crafty:preview-invalid\":\n return { v: PROTOCOL_VERSION, type: \"crafty:preview-invalid\", payload: {} };\n case \"crafty:key\":\n return payload.key === \"Escape\" ? { v: PROTOCOL_VERSION, type: \"crafty:key\", payload: { key: \"Escape\" } } : null;\n default:\n return null;\n }\n}\n", "import { parseMarkedField, type CraftyFieldRef, type CraftyMarkedField } from \"./protocol.js\";\n\nexport const MARKED_SELECTOR = \"[data-crafty-field]\";\n\nexport type MarkedElement = { element: Element; field: CraftyMarkedField };\n\nexport function readMarkedField(element: Element): CraftyMarkedField | null {\n const blockId = element.getAttribute(\"data-crafty-block\");\n const entryId = element.getAttribute(\"data-crafty-entry\");\n const rawId = blockId ?? entryId;\n\n if (rawId === null) {\n return null;\n }\n\n return parseMarkedField({\n type: blockId !== null ? \"block\" : \"entry\",\n id: rawId.trim() === \"\" ? Number.NaN : Number(rawId),\n field: element.getAttribute(\"data-crafty-field\") ?? \"\",\n label: element.getAttribute(\"data-crafty-label\"),\n hrefField: element.getAttribute(\"data-crafty-href-field\"),\n hrefLabel: element.getAttribute(\"data-crafty-href-label\")\n });\n}\n\nexport function refKey(ref: CraftyFieldRef): string {\n return `${ref.type}:${ref.id}:${ref.field}`;\n}\n\nexport function scanMarked(root: ParentNode): MarkedElement[] {\n const marked: MarkedElement[] = [];\n\n root.querySelectorAll(MARKED_SELECTOR).forEach((element) => {\n const field = readMarkedField(element);\n\n if (field !== null) {\n marked.push({ element, field });\n }\n });\n\n return marked;\n}\n\nexport function uniqueFields(marked: MarkedElement[]): CraftyMarkedField[] {\n const seen = new Set<string>();\n const fields: CraftyMarkedField[] = [];\n\n for (const { field } of marked) {\n const key = refKey(field);\n\n if (!seen.has(key)) {\n seen.add(key);\n fields.push(field);\n }\n }\n\n return fields;\n}\n", "import { MARKED_SELECTOR, readMarkedField, refKey } from \"./markers.js\";\nimport type { CraftyFieldRef } from \"./protocol.js\";\n\nexport type LivePreview = {\n set(ref: CraftyFieldRef, value: string): void;\n reset(ref: CraftyFieldRef): void;\n reapply(): void;\n resetAll(): void;\n readonly size: number;\n};\n\n/**\n * Plain-text live preview. Values are written with `textContent` (never HTML),\n * and each element's own original text is kept so a reset restores exactly what\n * the site rendered, even for elements rendered after the value was set.\n */\nexport function createLivePreview(root: ParentNode): LivePreview {\n const values = new Map<string, string>();\n const originals = new Map<Element, string>();\n\n const matching = (key: string): Element[] =>\n Array.from(root.querySelectorAll(MARKED_SELECTOR)).filter((element) => {\n const field = readMarkedField(element);\n\n return field !== null && refKey(field) === key;\n });\n\n const write = (element: Element, value: string): void => {\n if (!originals.has(element)) {\n originals.set(element, element.textContent ?? \"\");\n }\n\n if (element.textContent !== value) {\n element.textContent = value;\n }\n };\n\n const restore = (key: string | null): void => {\n for (const [element, original] of originals) {\n const field = readMarkedField(element);\n\n if (key === null || (field !== null && refKey(field) === key)) {\n if (element.textContent !== original) {\n element.textContent = original;\n }\n\n originals.delete(element);\n }\n }\n };\n\n return {\n set(ref, value) {\n const key = refKey(ref);\n values.set(key, value);\n matching(key).forEach((element) => write(element, value));\n },\n reset(ref) {\n const key = refKey(ref);\n values.delete(key);\n restore(key);\n },\n reapply() {\n for (const element of [...originals.keys()]) {\n if (!element.isConnected) {\n originals.delete(element);\n }\n }\n\n for (const [key, value] of values) {\n matching(key).forEach((element) => write(element, value));\n }\n },\n resetAll() {\n values.clear();\n restore(null);\n },\n get size() {\n return values.size;\n }\n };\n}\n", "/** Crafty admin panels: https://crafty.do and https://<tenant>.crafty.do. */\nexport const DEFAULT_ADMIN_ORIGINS: ReadonlyArray<string | RegExp> = [/^https:\\/\\/([a-z0-9-]+\\.)*crafty\\.do$/];\n\nfunction originOf(value: string): string | null {\n try {\n return new URL(value).origin;\n } catch {\n return null;\n }\n}\n\nexport function isAllowedAdminOrigin(origin: string, allowlist: ReadonlyArray<string | RegExp>): boolean {\n if (origin === \"\" || origin === \"null\") {\n return false;\n }\n\n return allowlist.some((allowed) => {\n if (typeof allowed === \"string\") {\n return originOf(allowed) === origin;\n }\n\n allowed.lastIndex = 0;\n\n return allowed.test(origin);\n });\n}\n\n/**\n * Origin of the embedding admin. `ancestorOrigins` (Chromium, WebKit) cannot be\n * spoofed by the framed page; Firefox falls back to the referrer the admin sent\n * when it set the iframe `src`.\n */\nexport function resolveParentOrigin(win: Window): string | null {\n const ancestors = win.location.ancestorOrigins as ArrayLike<string> | undefined;\n const first = ancestors && ancestors.length > 0 ? ancestors[0] : undefined;\n\n if (typeof first === \"string\" && first !== \"\") {\n return first;\n }\n\n const referrer = win.document.referrer;\n\n return referrer ? originOf(referrer) : null;\n}\n", "const STYLE_ELEMENT_ID = \"crafty-visual-editing-style\";\nconst ACCENT = \"#4f46e5\";\n\nexport const FLASH_CLASS = \"crafty-ve-flash\";\n\nconst STYLES = [\n \"[data-crafty-field]{cursor:pointer}\",\n `.crafty-ve-box{position:fixed;top:0;left:0;pointer-events:none;z-index:2147483647;box-sizing:border-box;border:2px solid ${ACCENT};border-radius:4px;background:rgba(79,70,229,.06)}`,\n \".crafty-ve-box[hidden]{display:none}\",\n `.crafty-ve-label{position:absolute;left:-2px;bottom:100%;margin-bottom:4px;padding:2px 8px;max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;background:${ACCENT};color:#fff;font:500 12px/1.5 system-ui,-apple-system,sans-serif}`,\n `.${FLASH_CLASS}{outline:2px dashed ${ACCENT} !important;outline-offset:2px !important}`\n].join(\"\\n\");\n\nexport type Overlay = {\n show(element: Element, label: string): void;\n hide(): void;\n /** Re-measures the highlighted element, e.g. after its content changed. */\n reposition(): void;\n flash(elements: Element[], durationMs: number): void;\n ensureAttached(): void;\n contains(node: Node | null): boolean;\n destroy(): void;\n};\n\nexport function createOverlay(doc: Document): Overlay {\n const win = doc.defaultView;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ELEMENT_ID;\n style.textContent = STYLES;\n\n const box = doc.createElement(\"div\");\n box.setAttribute(\"data-crafty-overlay\", \"\");\n box.className = \"crafty-ve-box\";\n box.hidden = true;\n\n const label = doc.createElement(\"span\");\n label.className = \"crafty-ve-label\";\n box.appendChild(label);\n\n let target: Element | null = null;\n let flashed: Element[] = [];\n let flashTimer: number | undefined;\n const Observer = (win as (Window & { ResizeObserver?: typeof ResizeObserver }) | null)?.ResizeObserver;\n\n const place = (): void => {\n if (target === null) {\n return;\n }\n\n const rect = target.getBoundingClientRect();\n box.style.top = `${rect.top}px`;\n box.style.left = `${rect.left}px`;\n box.style.width = `${rect.width}px`;\n box.style.height = `${rect.height}px`;\n };\n\n const resizeObserver = typeof Observer === \"function\" ? new Observer(() => place()) : null;\n\n const track = (element: Element | null): void => {\n if (target === element) {\n return;\n }\n\n if (target !== null) {\n resizeObserver?.unobserve(target);\n }\n\n target = element;\n\n if (target !== null) {\n resizeObserver?.observe(target);\n }\n };\n\n const clearFlash = (): void => {\n flashed.forEach((element) => element.classList.remove(FLASH_CLASS));\n flashed = [];\n\n if (flashTimer !== undefined) {\n win?.clearTimeout(flashTimer);\n flashTimer = undefined;\n }\n };\n\n const ensureAttached = (): void => {\n if (!style.isConnected) {\n (doc.head ?? doc.documentElement).appendChild(style);\n }\n\n if (!box.isConnected) {\n (doc.body ?? doc.documentElement).appendChild(box);\n }\n };\n\n ensureAttached();\n win?.addEventListener(\"scroll\", place, { capture: true, passive: true });\n win?.addEventListener(\"resize\", place, { passive: true });\n\n return {\n show(element, text) {\n ensureAttached();\n track(element);\n\n if (label.textContent !== text) {\n label.textContent = text;\n }\n\n box.hidden = false;\n place();\n },\n hide() {\n track(null);\n box.hidden = true;\n },\n reposition() {\n place();\n },\n flash(elements, durationMs) {\n clearFlash();\n flashed = [...elements];\n flashed.forEach((element) => element.classList.add(FLASH_CLASS));\n flashTimer = win?.setTimeout(clearFlash, durationMs);\n },\n ensureAttached,\n contains(node) {\n return node !== null && (box === node || box.contains(node) || style === node || style.contains(node));\n },\n destroy() {\n clearFlash();\n win?.removeEventListener(\"scroll\", place, { capture: true });\n win?.removeEventListener(\"resize\", place);\n resizeObserver?.disconnect();\n box.remove();\n style.remove();\n target = null;\n }\n };\n}\n", "import type { CraftyClient } from \"../client.js\";\nimport {\n PREVIEW_ACTIVE_EVENT,\n PREVIEW_CONTENT_EVENT,\n PREVIEW_INVALID_EVENT,\n PREVIEW_QUERY_PARAM,\n getPreviewContent,\n getPreviewStatus,\n readPreviewToken,\n storePreviewToken\n} from \"../preview.js\";\nimport { SDK_VERSION } from \"../version.js\";\nimport { createLivePreview } from \"./live-preview.js\";\nimport { MARKED_SELECTOR, readMarkedField, refKey, scanMarked, uniqueFields, type MarkedElement } from \"./markers.js\";\nimport { DEFAULT_ADMIN_ORIGINS, isAllowedAdminOrigin, resolveParentOrigin } from \"./origin.js\";\nimport { createOverlay } from \"./overlay.js\";\nimport {\n PROTOCOL_VERSION,\n parseInboundMessage,\n type CraftyFieldRef,\n type CraftyMarkedField,\n type CraftyShownEntry,\n type CraftyShownPage,\n type InboundMessage,\n type OutboundMessage\n} from \"./protocol.js\";\n\nexport type VisualEditingOptions = {\n /** Allowed admin origins. Replaces the default (`https://*.crafty.do`). */\n adminOrigins?: ReadonlyArray<string | RegExp>;\n /** Re-fetch and re-render instead of a full reload when the admin asks for a refresh. */\n onRefresh?: () => void | Promise<void>;\n /** Page rendered by the server (SSR sites, where the browser did not fetch it). */\n page?: CraftyShownPage | null;\n /** Entries rendered by the server (SSR sites). */\n entries?: CraftyShownEntry[];\n /** How long touch devices highlight every editable after load. Default 1500 ms. */\n touchHighlightMs?: number;\n /**\n * Client used to confirm the preview token when no preview request has been\n * answered yet (one `pages.list({ per_page: 1 })` call). Without it the bridge\n * waits for the site's own first Crafty request to confirm the token.\n */\n client?: Pick<CraftyClient, \"pages\">;\n};\n\nexport type VisualEditingHandle = {\n readonly active: boolean;\n disable(): void;\n};\n\nconst SCROLL_STORAGE_KEY = \"crafty:scroll-y\";\nconst RESCAN_DELAY_MS = 50;\nconst DEFAULT_TOUCH_HIGHLIGHT_MS = 1500;\nconst WATCHED_ATTRIBUTES = [\n \"data-crafty-field\",\n \"data-crafty-block\",\n \"data-crafty-entry\",\n \"data-crafty-label\",\n \"data-crafty-href-field\",\n \"data-crafty-href-label\"\n];\n\nconst inactiveHandle: VisualEditingHandle = { active: false, disable: () => undefined };\nlet activeHandle: VisualEditingHandle | null = null;\n\n/**\n * Connects the page to the Crafty visual editor. No-op unless the page runs in\n * an iframe, carries a preview token, and its parent is an allowed admin origin.\n *\n * The default allowlist (`*.crafty.do`) also covers sites hosted by Crafty, so\n * the bridge stays inert (no overlay, no listeners, no messages) until the API\n * answers a preview request with `X-Crafty-Preview-Status: active`. On `invalid`\n * it only tells the admin `crafty:preview-invalid` and stays inert.\n */\nexport function enableVisualEditing(options: VisualEditingOptions = {}): VisualEditingHandle {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return inactiveHandle;\n }\n\n if (activeHandle !== null) {\n return activeHandle;\n }\n\n const win = window;\n\n if (win.parent === null || win.parent === win || readPreviewToken() === null) {\n return inactiveHandle;\n }\n\n const parentOrigin = resolveParentOrigin(win);\n\n if (parentOrigin === null || !isAllowedAdminOrigin(parentOrigin, options.adminOrigins ?? DEFAULT_ADMIN_ORIGINS)) {\n return inactiveHandle;\n }\n\n const status = getPreviewStatus();\n\n if (status === \"invalid\") {\n postPreviewInvalid(win, parentOrigin);\n\n return inactiveHandle;\n }\n\n activeHandle = status === \"active\" ? startBridge(win, parentOrigin, options) : awaitConfirmation(win, parentOrigin, options);\n\n return activeHandle;\n}\n\nfunction postPreviewInvalid(win: Window, parentOrigin: string): void {\n const message: OutboundMessage = { v: PROTOCOL_VERSION, type: \"crafty:preview-invalid\", payload: {} };\n win.parent.postMessage(message, parentOrigin);\n}\n\n/**\n * Pending handle: waits for the API to confirm the token before starting the\n * bridge, verifying it through `options.client` when one is given.\n */\nfunction awaitConfirmation(win: Window, parentOrigin: string, options: VisualEditingOptions): VisualEditingHandle {\n let bridge: VisualEditingHandle | null = null;\n let settled = false;\n\n const stopWaiting = (): void => {\n settled = true;\n win.removeEventListener(PREVIEW_ACTIVE_EVENT, onActive);\n win.removeEventListener(PREVIEW_INVALID_EVENT, onInvalid);\n };\n\n const release = (): void => {\n if (activeHandle === handle) {\n activeHandle = null;\n }\n };\n\n const onActive = (): void => {\n if (settled) {\n return;\n }\n\n stopWaiting();\n bridge = startBridge(win, parentOrigin, options, release);\n };\n\n const onInvalid = (): void => {\n if (settled) {\n return;\n }\n\n stopWaiting();\n release();\n postPreviewInvalid(win, parentOrigin);\n };\n\n const handle: VisualEditingHandle = {\n get active() {\n return bridge?.active ?? false;\n },\n disable() {\n stopWaiting();\n bridge?.disable();\n release();\n }\n };\n\n win.addEventListener(PREVIEW_ACTIVE_EVENT, onActive);\n win.addEventListener(PREVIEW_INVALID_EVENT, onInvalid);\n\n // The status handlers above settle the outcome; request errors leave the bridge waiting.\n options.client?.pages.list({ per_page: 1 }).catch(() => undefined);\n\n return handle;\n}\n\nfunction startBridge(\n win: Window,\n parentOrigin: string,\n options: VisualEditingOptions,\n onDisable?: () => void\n): VisualEditingHandle {\n const doc = win.document;\n const overlay = createOverlay(doc);\n const livePreview = createLivePreview(doc);\n const pendingScrollY = takeStoredScroll(win);\n\n let marked: MarkedElement[] = [];\n let sentSignature: string | null = null;\n let rescanTimer: number | undefined;\n let forceReady = false;\n let active = true;\n\n const post = (message: OutboundMessage): void => {\n win.parent.postMessage(message, parentOrigin);\n };\n\n const sendReady = (): void => {\n const fields = uniqueFields(marked);\n const content = getPreviewContent();\n sentSignature = signatureOf(fields);\n\n post({\n v: PROTOCOL_VERSION,\n type: \"crafty:ready\",\n payload: {\n sdkVersion: SDK_VERSION,\n path: currentPath(win),\n fields,\n page: content.page ?? options.page ?? null,\n entries: mergeEntries(content.entries, options.entries ?? [])\n }\n });\n };\n\n const rescan = (): void => {\n rescanTimer = undefined;\n\n if (!active) {\n return;\n }\n\n overlay.ensureAttached();\n marked = scanMarked(doc);\n livePreview.reapply();\n\n if (forceReady || signatureOf(uniqueFields(marked)) !== sentSignature) {\n forceReady = false;\n sendReady();\n }\n };\n\n const scheduleRescan = (): void => {\n if (active && rescanTimer === undefined) {\n rescanTimer = win.setTimeout(rescan, RESCAN_DELAY_MS);\n }\n };\n\n const observer = new MutationObserver((records) => {\n if (records.some((record) => !overlay.contains(record.target))) {\n scheduleRescan();\n }\n });\n\n const labelOf = (field: CraftyMarkedField): string => field.label ?? field.field;\n\n const onPointerOver = (event: PointerEvent): void => {\n if (event.pointerType === \"touch\") {\n return;\n }\n\n const hit = hitFrom(event.target);\n\n if (hit !== null) {\n overlay.show(hit.element, labelOf(hit.field));\n } else {\n overlay.hide();\n }\n };\n\n const block = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n };\n\n /**\n * Runs in the capture phase on `window`, before any site listener, so a marked\n * element always selects even when it is (or sits inside) a link or button,\n * and nothing the site renders can take the iframe out of the editor.\n */\n const onClick = (event: MouseEvent): void => {\n const hit = hitFrom(event.target);\n\n if (hit !== null) {\n block(event);\n overlay.show(hit.element, labelOf(hit.field));\n post({ v: PROTOCOL_VERSION, type: \"crafty:select\", payload: hit.field });\n\n return;\n }\n\n const action = linkAction(event, win);\n\n if (action.kind === \"allow\") {\n return;\n }\n\n block(event);\n\n if (action.kind === \"navigate\") {\n post({ v: PROTOCOL_VERSION, type: \"crafty:navigate\", payload: { path: action.path } });\n }\n };\n\n /** Middle clicks open links in a new tab: never let them leave the editor. */\n const onAuxClick = (event: MouseEvent): void => {\n if (hitFrom(event.target) !== null || closestLink(event.target) !== null) {\n block(event);\n }\n };\n\n const onSubmit = (event: Event): void => {\n block(event);\n };\n\n /**\n * Escape pressed while focus is inside the iframe never reaches the admin\n * window: forward it so the admin closes its topmost sheet or dialog. Runs in\n * the bubble phase, after the site, and skips an Escape the site handled\n * (`preventDefault`, e.g. to close its own menu).\n */\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== \"Escape\" || event.repeat || event.isComposing || event.defaultPrevented) {\n return;\n }\n\n post({ v: PROTOCOL_VERSION, type: \"crafty:key\", payload: { key: \"Escape\" } });\n };\n\n const highlight = (ref: CraftyFieldRef): void => {\n const key = refKey(ref);\n const match = scanMarked(doc).find((item) => refKey(item.field) === key);\n\n if (match === undefined) {\n return;\n }\n\n const element = match.element as Element & { scrollIntoView?: (options?: ScrollIntoViewOptions) => void };\n element.scrollIntoView?.({ block: \"center\", behavior: \"smooth\" });\n overlay.show(match.element, labelOf(match.field));\n };\n\n const refresh = async (): Promise<void> => {\n if (options.onRefresh) {\n try {\n await options.onRefresh();\n } finally {\n scheduleRescan();\n }\n\n return;\n }\n\n try {\n win.sessionStorage.setItem(SCROLL_STORAGE_KEY, String(win.scrollY));\n } catch {\n // Storage blocked: reload without restoring the scroll position.\n }\n\n win.location.reload();\n };\n\n const handleInbound = (message: InboundMessage): void => {\n switch (message.type) {\n case \"crafty:token\":\n storePreviewToken(message.payload.token);\n return;\n case \"crafty:refresh\":\n refresh().catch((error: unknown) => console.error(\"[crafty] onRefresh failed\", error));\n return;\n case \"crafty:highlight\":\n highlight(message.payload);\n return;\n case \"crafty:preview-field\":\n livePreview.set(message.payload, message.payload.value);\n overlay.reposition();\n return;\n case \"crafty:preview-reset\":\n livePreview.reset(message.payload);\n overlay.reposition();\n return;\n }\n };\n\n const onMessage = (event: MessageEvent): void => {\n if (event.source !== win.parent || event.origin !== parentOrigin) {\n return;\n }\n\n const message = parseInboundMessage(event.data);\n\n if (message !== null) {\n handleInbound(message);\n }\n };\n\n const onPreviewInvalid = (): void => {\n post({ v: PROTOCOL_VERSION, type: \"crafty:preview-invalid\", payload: {} });\n };\n\n const onPreviewContent = (): void => {\n forceReady = true;\n scheduleRescan();\n };\n\n const start = (): void => {\n if (!active) {\n return;\n }\n\n marked = scanMarked(doc);\n sendReady();\n\n if (isTouchDevice(win)) {\n overlay.flash(\n marked.map((item) => item.element),\n options.touchHighlightMs ?? DEFAULT_TOUCH_HIGHLIGHT_MS\n );\n }\n\n restoreScroll(win, pendingScrollY);\n };\n\n win.addEventListener(\"message\", onMessage);\n win.addEventListener(\"click\", onClick, true);\n win.addEventListener(\"auxclick\", onAuxClick, true);\n win.addEventListener(\"submit\", onSubmit, true);\n win.addEventListener(\"keydown\", onKeyDown);\n doc.addEventListener(\"pointerover\", onPointerOver, true);\n win.addEventListener(PREVIEW_INVALID_EVENT, onPreviewInvalid);\n win.addEventListener(PREVIEW_CONTENT_EVENT, onPreviewContent);\n observer.observe(doc.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: WATCHED_ATTRIBUTES\n });\n\n if (doc.readyState === \"loading\") {\n doc.addEventListener(\"DOMContentLoaded\", start, { once: true });\n } else {\n start();\n }\n\n const handle: VisualEditingHandle = {\n get active() {\n return active;\n },\n disable() {\n if (!active) {\n return;\n }\n\n active = false;\n win.removeEventListener(\"message\", onMessage);\n win.removeEventListener(\"click\", onClick, true);\n win.removeEventListener(\"auxclick\", onAuxClick, true);\n win.removeEventListener(\"submit\", onSubmit, true);\n win.removeEventListener(\"keydown\", onKeyDown);\n doc.removeEventListener(\"pointerover\", onPointerOver, true);\n doc.removeEventListener(\"DOMContentLoaded\", start);\n win.removeEventListener(PREVIEW_INVALID_EVENT, onPreviewInvalid);\n win.removeEventListener(PREVIEW_CONTENT_EVENT, onPreviewContent);\n observer.disconnect();\n\n if (rescanTimer !== undefined) {\n win.clearTimeout(rescanTimer);\n rescanTimer = undefined;\n }\n\n livePreview.resetAll();\n overlay.destroy();\n\n if (activeHandle === handle) {\n activeHandle = null;\n }\n\n onDisable?.();\n }\n };\n\n return handle;\n}\n\nfunction asElement(target: EventTarget | null): Element | null {\n return target !== null && typeof (target as Element).closest === \"function\" ? (target as Element) : null;\n}\n\nfunction signatureOf(fields: CraftyMarkedField[]): string {\n return fields.map((field) => `${refKey(field)}|${field.label ?? \"\"}|${field.hrefField ?? \"\"}|${field.hrefLabel ?? \"\"}`).join(\"\\n\");\n}\n\nfunction mergeEntries(fetched: CraftyShownEntry[], declared: CraftyShownEntry[]): CraftyShownEntry[] {\n const seen = new Set<string>();\n\n return [...fetched, ...declared].filter((entry) => {\n const key = `${entry.collection}:${entry.id}`;\n\n if (seen.has(key)) {\n return false;\n }\n\n seen.add(key);\n\n return true;\n });\n}\n\nfunction stripPreviewParam(url: URL): string {\n url.searchParams.delete(PREVIEW_QUERY_PARAM);\n\n return `${url.pathname}${url.search}`;\n}\n\nfunction currentPath(win: Window): string {\n return stripPreviewParam(new URL(win.location.href));\n}\n\ntype LinkAction = { kind: \"allow\" } | { kind: \"block\" } | { kind: \"navigate\"; path: string };\n\n/**\n * Only links fall back to their marked descendant: following them would leave\n * the editor. Buttons, `<summary>` and labels keep their own behavior (menus,\n * accordions, tabs) when the click misses the marked element.\n */\nconst LINK_SELECTOR = \"a[href], area[href]\";\n\n/**\n * The marked element a pointer or click target maps to: the innermost valid\n * marked ancestor (or the target itself), else the first marked element inside\n * the link that was clicked, so clicking a link button's padding or icon\n * selects its label.\n */\nfunction hitFrom(target: EventTarget | null): MarkedElement | null {\n const element = asElement(target);\n\n if (element === null) {\n return null;\n }\n\n for (let node = element.closest(MARKED_SELECTOR); node !== null; node = node.parentElement?.closest(MARKED_SELECTOR) ?? null) {\n const field = readMarkedField(node);\n\n if (field !== null) {\n return { element: node, field };\n }\n }\n\n const link = element.closest(LINK_SELECTOR);\n\n return link !== null ? (scanMarked(link)[0] ?? null) : null;\n}\n\nfunction closestLink(target: EventTarget | null): Element | null {\n return asElement(target)?.closest(LINK_SELECTOR) ?? null;\n}\n\n/**\n * What to do with a click that hit no marked element. Only same-page anchors\n * run as usual; same-origin links become `crafty:navigate`; anything that\n * would leave the editor (other origins, `mailto:`/`tel:`, new tabs,\n * downloads, modified clicks) is blocked.\n */\nfunction linkAction(event: MouseEvent, win: Window): LinkAction {\n const anchor = closestLink(event.target);\n\n if (anchor === null) {\n return { kind: \"allow\" };\n }\n\n if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || anchor.hasAttribute(\"download\")) {\n return { kind: \"block\" };\n }\n\n const target = anchor.getAttribute(\"target\");\n\n if (target !== null && target !== \"\" && target !== \"_self\") {\n return { kind: \"block\" };\n }\n\n const href = anchor.getAttribute(\"href\") ?? \"\";\n let url: URL;\n\n try {\n url = new URL(href, win.location.href);\n } catch {\n return { kind: \"block\" };\n }\n\n if (url.origin !== win.location.origin || (url.protocol !== \"http:\" && url.protocol !== \"https:\")) {\n return { kind: \"block\" };\n }\n\n const path = stripPreviewParam(url);\n\n if ((url.hash !== \"\" || href.startsWith(\"#\")) && path === currentPath(win)) {\n return { kind: \"allow\" };\n }\n\n return { kind: \"navigate\", path };\n}\n\nfunction isTouchDevice(win: Window): boolean {\n return typeof win.matchMedia === \"function\" && win.matchMedia(\"(hover: none)\").matches;\n}\n\nfunction takeStoredScroll(win: Window): number | null {\n try {\n const raw = win.sessionStorage.getItem(SCROLL_STORAGE_KEY);\n win.sessionStorage.removeItem(SCROLL_STORAGE_KEY);\n const scrollY = raw === null ? Number.NaN : Number(raw);\n\n return Number.isFinite(scrollY) ? scrollY : null;\n } catch {\n return null;\n }\n}\n\nfunction restoreScroll(win: Window, scrollY: number | null): void {\n if (scrollY === null) {\n return;\n }\n\n const apply = (): void => win.scrollTo(0, scrollY);\n\n if (win.document.readyState === \"complete\") {\n apply();\n } else {\n win.addEventListener(\"load\", apply, { once: true });\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["/** Entry for the `<script>` build: exposed as `window.CraftyVisualEditing`. */\nexport { attrs, attrsHtml } from \"./attrs.js\";\nexport { enableVisualEditing } from \"./visual-editing/bridge.js\";\nexport { PROTOCOL_VERSION } from \"./visual-editing/protocol.js\";\n", "import type { CraftyBlock, CraftyEntry } from \"./types/public.js\";\n\nexport type CraftyEditTargetType = \"block\" | \"entry\";\n\n/**\n * A block or entry as returned by the API, or an explicit reference for\n * ambiguous shapes (e.g. an entry with fields named `order`, `data` and `type`).\n */\nexport type CraftyEditTarget =\n | CraftyBlock\n | CraftyEntry\n | { kind: CraftyEditTargetType; id: number | string };\n\nexport type CraftyAttrsOptions = {\n /** Human label shown by the visual editor, e.g. \"T\u00EDtulo de la secci\u00F3n\". */\n label?: string;\n /**\n * Field holding the link destination of this element (a button or link whose\n * text is `field`), e.g. `hero.cta.href`. The editor then edits both together.\n */\n hrefField?: string;\n /** Human label for `hrefField`. Defaults to \"Enlace\" in the editor. */\n hrefLabel?: string;\n};\n\nexport type CraftyEditAttributes = {\n \"data-crafty-block\"?: string;\n \"data-crafty-entry\"?: string;\n \"data-crafty-field\"?: string;\n \"data-crafty-label\"?: string;\n \"data-crafty-href-field\"?: string;\n \"data-crafty-href-label\"?: string;\n};\n\nexport function resolveEditTarget(\n target: CraftyEditTarget | null | undefined\n): { type: CraftyEditTargetType; id: number } | null {\n if (target === null || target === undefined || typeof target !== \"object\") {\n return null;\n }\n\n const record = target as Record<string, unknown>;\n const id = typeof record.id === \"string\" ? Number(record.id.trim()) : record.id;\n\n if (typeof id !== \"number\" || !Number.isInteger(id) || id <= 0) {\n return null;\n }\n\n if (record.kind === \"block\" || record.kind === \"entry\") {\n return { type: record.kind, id };\n }\n\n const looksLikeBlock =\n typeof record.order === \"number\" &&\n typeof record.data === \"object\" &&\n record.data !== null &&\n \"type\" in record;\n\n return { type: looksLikeBlock ? \"block\" : \"entry\", id };\n}\n\n/**\n * DOM attributes that let the visual editor map an element to a field.\n * Always emitted (static sites render them at build time without a token).\n * `field` is a top-level field key or a JSON path such as `sections[3].title`.\n */\nexport function attrs(\n target: CraftyEditTarget | null | undefined,\n field: string,\n options: CraftyAttrsOptions = {}\n): CraftyEditAttributes {\n const resolved = resolveEditTarget(target);\n const normalizedField = typeof field === \"string\" ? field.trim() : \"\";\n\n if (resolved === null || normalizedField === \"\") {\n return {};\n }\n\n const attributes: CraftyEditAttributes =\n resolved.type === \"block\"\n ? { \"data-crafty-block\": String(resolved.id), \"data-crafty-field\": normalizedField }\n : { \"data-crafty-entry\": String(resolved.id), \"data-crafty-field\": normalizedField };\n\n const label = typeof options.label === \"string\" ? options.label.trim() : \"\";\n\n if (label !== \"\") {\n attributes[\"data-crafty-label\"] = label;\n }\n\n const hrefField = typeof options.hrefField === \"string\" ? options.hrefField.trim() : \"\";\n\n if (hrefField !== \"\") {\n attributes[\"data-crafty-href-field\"] = hrefField;\n\n const hrefLabel = typeof options.hrefLabel === \"string\" ? options.hrefLabel.trim() : \"\";\n\n if (hrefLabel !== \"\") {\n attributes[\"data-crafty-href-label\"] = hrefLabel;\n }\n }\n\n return attributes;\n}\n\n/** Same as `attrs()`, rendered for HTML string templates. */\nexport function attrsHtml(\n target: CraftyEditTarget | null | undefined,\n field: string,\n options: CraftyAttrsOptions = {}\n): string {\n return Object.entries(attrs(target, field, options))\n .map(([name, value]) => `${name}=\"${escapeAttribute(String(value))}\"`)\n .join(\" \");\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n", "export const PREVIEW_QUERY_PARAM = \"crafty_preview\";\nexport const PREVIEW_HEADER = \"X-Crafty-Preview\";\nexport const PREVIEW_STATUS_HEADER = \"X-Crafty-Preview-Status\";\nexport const PREVIEW_INVALID_EVENT = \"crafty:preview-invalid\";\nexport const PREVIEW_CONTENT_EVENT = \"crafty:preview-content\";\nexport const PREVIEW_ACTIVE_EVENT = \"crafty:preview-active\";\n\nconst TOKEN_STORAGE_KEY = \"crafty:preview-token\";\nconst URL_TOKEN_STORAGE_KEY = \"crafty:preview-url-token\";\nconst INVALID_TOKEN_STORAGE_KEY = \"crafty:preview-invalid-token\";\nconst CONTENT_GLOBAL_KEY = \"__CRAFTY_PREVIEW_CONTENT__\";\nconst STATUS_GLOBAL_KEY = \"__CRAFTY_PREVIEW_STATUS__\";\n\nexport type PreviewPage = { id: number; slug: string };\nexport type PreviewEntry = { id: number; collection: string };\nexport type PreviewContent = { page: PreviewPage | null; entries: PreviewEntry[] };\n/** Last `X-Crafty-Preview-Status` the API answered in this window, or null before any preview request. */\nexport type PreviewStatus = \"active\" | \"invalid\";\n\n/** A URL, a Web `Request`, a Node `IncomingMessage` or an Express-style request. */\nexport type PreviewRequestLike =\n | string\n | URL\n | { url?: string | undefined; query?: Record<string, unknown> | undefined };\n\ntype ContentHost = Record<string, PreviewContent | undefined>;\n\nfunction browserWindow(): Window | null {\n return typeof window === \"undefined\" ? null : window;\n}\n\nfunction storageGet(key: string): string | null {\n try {\n return browserWindow()?.sessionStorage.getItem(key) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction storageSet(key: string, value: string): void {\n try {\n browserWindow()?.sessionStorage.setItem(key, value);\n } catch {\n // Storage can be blocked (private mode, sandboxed frames); the URL token still works.\n }\n}\n\nfunction storageRemove(key: string): void {\n try {\n browserWindow()?.sessionStorage.removeItem(key);\n } catch {\n // Ignore blocked storage.\n }\n}\n\nfunction normalizeToken(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n}\n\nfunction tokenFromUrl(url: string): string | null {\n try {\n return normalizeToken(new URL(url, \"http://localhost\").searchParams.get(PREVIEW_QUERY_PARAM));\n } catch {\n return null;\n }\n}\n\n/**\n * Preview token for browser requests. A token the URL brings for the first time\n * wins; afterwards the stored token wins, so a renewal received over\n * `postMessage` is not overwritten by the stale token still in the URL.\n */\nexport function readPreviewToken(): string | null {\n const win = browserWindow();\n\n if (win === null) {\n return null;\n }\n\n const urlToken = tokenFromUrl(win.location.href);\n let token: string | null;\n\n if (urlToken !== null && urlToken !== storageGet(URL_TOKEN_STORAGE_KEY)) {\n storageSet(URL_TOKEN_STORAGE_KEY, urlToken);\n storageSet(TOKEN_STORAGE_KEY, urlToken);\n token = urlToken;\n } else {\n token = normalizeToken(storageGet(TOKEN_STORAGE_KEY)) ?? urlToken;\n }\n\n return token !== null && token === storageGet(INVALID_TOKEN_STORAGE_KEY) ? null : token;\n}\n\n/**\n * Forgets a browser token the API reported invalid, so later requests stop\n * sending it (the stale copy in the URL included) until a new token arrives\n * over `postMessage` or a new URL. Explicit server-side tokens are untouched.\n */\nexport function discardPreviewToken(token: string): void {\n const win = browserWindow();\n const normalized = normalizeToken(token);\n\n if (win === null || normalized === null) {\n return;\n }\n\n const isStored = normalizeToken(storageGet(TOKEN_STORAGE_KEY)) === normalized;\n\n if (!isStored && tokenFromUrl(win.location.href) !== normalized) {\n return;\n }\n\n if (isStored) {\n storageRemove(TOKEN_STORAGE_KEY);\n }\n\n storageSet(INVALID_TOKEN_STORAGE_KEY, normalized);\n}\n\nexport function storePreviewToken(token: string): void {\n const normalized = normalizeToken(token);\n\n if (normalized !== null) {\n storageSet(TOKEN_STORAGE_KEY, normalized);\n }\n}\n\nexport function clearPreviewToken(): void {\n storageRemove(TOKEN_STORAGE_KEY);\n storageRemove(URL_TOKEN_STORAGE_KEY);\n storageRemove(INVALID_TOKEN_STORAGE_KEY);\n setPreviewStatus(null);\n}\n\n/** Server-side helper: the preview token of an incoming request, or null. */\nexport function previewFromRequest(request: PreviewRequestLike | null | undefined): string | null {\n if (request === null || request === undefined) {\n return null;\n }\n\n if (typeof request === \"string\" || request instanceof URL) {\n return tokenFromUrl(String(request));\n }\n\n const queryValue = request.query?.[PREVIEW_QUERY_PARAM];\n const fromQuery = normalizeToken(Array.isArray(queryValue) ? queryValue[0] : queryValue);\n\n if (fromQuery !== null) {\n return fromQuery;\n }\n\n return typeof request.url === \"string\" ? tokenFromUrl(request.url) : null;\n}\n\nexport function getPreviewContent(): PreviewContent {\n const win = browserWindow() as (Window & ContentHost) | null;\n const content = win?.[CONTENT_GLOBAL_KEY];\n\n return content ? { page: content.page, entries: [...content.entries] } : { page: null, entries: [] };\n}\n\nexport function recordPreviewContent(\n item: ({ type: \"page\" } & PreviewPage) | ({ type: \"entry\" } & PreviewEntry)\n): void {\n const win = browserWindow() as (Window & ContentHost) | null;\n\n if (win === null) {\n return;\n }\n\n const content = win[CONTENT_GLOBAL_KEY] ?? { page: null, entries: [] };\n win[CONTENT_GLOBAL_KEY] = content;\n\n if (item.type === \"page\") {\n content.page = { id: item.id, slug: item.slug };\n } else if (!content.entries.some((entry) => entry.id === item.id && entry.collection === item.collection)) {\n content.entries.push({ id: item.id, collection: item.collection });\n }\n\n dispatch(PREVIEW_CONTENT_EVENT);\n}\n\nexport function resetPreviewContent(): void {\n const win = browserWindow() as (Window & ContentHost) | null;\n\n if (win !== null) {\n win[CONTENT_GLOBAL_KEY] = undefined;\n }\n}\n\n/**\n * Kept on `window` (like the shown content) so a separately bundled bridge, such\n * as the `<script>` build, sees what the site's own SDK copy recorded.\n */\nexport function getPreviewStatus(): PreviewStatus | null {\n const win = browserWindow() as (Window & Record<string, unknown>) | null;\n const status = win?.[STATUS_GLOBAL_KEY];\n\n return status === \"active\" || status === \"invalid\" ? status : null;\n}\n\nfunction setPreviewStatus(status: PreviewStatus | null): void {\n const win = browserWindow() as (Window & Record<string, unknown>) | null;\n\n if (win !== null) {\n win[STATUS_GLOBAL_KEY] = status ?? undefined;\n }\n}\n\nexport function notifyPreviewActive(): void {\n setPreviewStatus(\"active\");\n dispatch(PREVIEW_ACTIVE_EVENT);\n}\n\nexport function notifyPreviewInvalid(): void {\n setPreviewStatus(\"invalid\");\n dispatch(PREVIEW_INVALID_EVENT);\n}\n\nfunction dispatch(name: string): void {\n const win = browserWindow();\n\n if (win !== null && typeof win.dispatchEvent === \"function\") {\n win.dispatchEvent(new Event(name));\n }\n}\n", "// Generated by scripts/write-version.mjs from package.json. Do not edit.\nexport const SDK_VERSION = \"0.10.2\";\n", "export const PROTOCOL_VERSION = 1;\n\nexport type CraftyTargetType = \"block\" | \"entry\";\nexport type CraftyFieldRef = { type: CraftyTargetType; id: number; field: string };\n/** `hrefField` is the field with the link destination of the same element (same target). */\nexport type CraftyMarkedField = CraftyFieldRef & { label?: string; hrefField?: string; hrefLabel?: string };\nexport type CraftyShownPage = { id: number; slug: string };\nexport type CraftyShownEntry = { id: number; collection: string };\n\nexport type ReadyPayload = {\n sdkVersion: string;\n path: string;\n fields: CraftyMarkedField[];\n page: CraftyShownPage | null;\n entries: CraftyShownEntry[];\n};\n\ntype Version = typeof PROTOCOL_VERSION;\n\n/**\n * Keys forwarded to the admin (`crafty:key`, SDK >= 0.4.1): the admin never\n * sees keydowns while focus is inside the iframe, so Escape could not close\n * its sheets and dialogs. Older admins ignore the message.\n */\nexport type ForwardedKey = \"Escape\";\ntype EmptyPayload = Record<string, never>;\n\n/** iframe -> admin. `crafty:ready` is a snapshot that may be re-sent; the last one wins. */\nexport type OutboundMessage =\n | { v: Version; type: \"crafty:ready\"; payload: ReadyPayload }\n | { v: Version; type: \"crafty:select\"; payload: CraftyMarkedField }\n | { v: Version; type: \"crafty:navigate\"; payload: { path: string } }\n | { v: Version; type: \"crafty:preview-invalid\"; payload: EmptyPayload }\n | { v: Version; type: \"crafty:key\"; payload: { key: ForwardedKey } };\n\n/** admin -> iframe. */\nexport type InboundMessage =\n | { v: Version; type: \"crafty:token\"; payload: { token: string } }\n | { v: Version; type: \"crafty:refresh\"; payload: EmptyPayload }\n | { v: Version; type: \"crafty:highlight\"; payload: CraftyFieldRef }\n | { v: Version; type: \"crafty:preview-field\"; payload: CraftyFieldRef & { value: string } }\n | { v: Version; type: \"crafty:preview-reset\"; payload: CraftyFieldRef };\n\n/** Same limits as the Crafty admin and backend (content_drafts.field / label). */\nconst MAX_FIELD_LENGTH = 255;\nconst MAX_LABEL_LENGTH = 120;\nconst MAX_TOKEN_LENGTH = 4096;\nconst MAX_VALUE_LENGTH = 100_000;\nconst MAX_PATH_LENGTH = 2048;\nconst FIELD_PATTERN = /^[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+|\\[\\d+\\])*$/;\nconst TOKEN_PATTERN = /^[\\x21-\\x7E]+$/;\nconst CONTROL_CHARACTERS = /[\\u0000-\\u001F\\u007F]/;\nconst PATH_BASE = \"https://crafty.invalid\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isPositiveInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isInteger(value) && value > 0;\n}\n\nfunction parseFieldPath(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n\n const trimmed = value.trim();\n\n return trimmed === \"\" || trimmed.length > MAX_FIELD_LENGTH || !FIELD_PATTERN.test(trimmed) ? null : trimmed;\n}\n\nfunction parseLabel(value: unknown): string {\n return typeof value === \"string\" ? value.trim().slice(0, MAX_LABEL_LENGTH).trim() : \"\";\n}\n\nexport function parseFieldRef(value: unknown): CraftyFieldRef | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const { type, id } = value;\n const field = parseFieldPath(value.field);\n\n if ((type !== \"block\" && type !== \"entry\") || !isPositiveInteger(id) || field === null) {\n return null;\n }\n\n return { type, id, field };\n}\n\n/** An invalid `hrefField` is dropped; the text field stays selectable. */\nexport function parseMarkedField(value: unknown): CraftyMarkedField | null {\n const ref = parseFieldRef(value);\n\n if (ref === null || !isRecord(value)) {\n return null;\n }\n\n const marked: CraftyMarkedField = { ...ref };\n const label = parseLabel(value.label);\n const hrefField = parseFieldPath(value.hrefField);\n\n if (label !== \"\") {\n marked.label = label;\n }\n\n if (hrefField !== null) {\n marked.hrefField = hrefField;\n\n const hrefLabel = parseLabel(value.hrefLabel);\n\n if (hrefLabel !== \"\") {\n marked.hrefLabel = hrefLabel;\n }\n }\n\n return marked;\n}\n\nfunction isSameOriginPath(value: string): boolean {\n if (!value.startsWith(\"/\") || value.startsWith(\"//\") || value.startsWith(\"/\\\\\")) {\n return false;\n }\n\n try {\n const url = new URL(value, PATH_BASE);\n\n // Dot segments can still resolve to a protocol-relative path (\"/.//evil.example\").\n return url.origin === PATH_BASE && !url.pathname.startsWith(\"//\") && !url.pathname.startsWith(\"/\\\\\");\n } catch {\n return false;\n }\n}\n\nfunction parsePath(value: unknown): string | null {\n if (typeof value !== \"string\" || value.length > MAX_PATH_LENGTH || CONTROL_CHARACTERS.test(value)) {\n return null;\n }\n\n return isSameOriginPath(value) ? value : null;\n}\n\nfunction parseShownEntry(value: unknown): CraftyShownEntry | null {\n return isRecord(value) && isPositiveInteger(value.id) && typeof value.collection === \"string\"\n ? { id: value.id, collection: value.collection }\n : null;\n}\n\nfunction readEnvelope(data: unknown): { type: string; payload: Record<string, unknown> } | null {\n if (!isRecord(data) || data.v !== PROTOCOL_VERSION || typeof data.type !== \"string\") {\n return null;\n }\n\n const payload = data.payload === undefined ? {} : data.payload;\n\n return isRecord(payload) ? { type: data.type, payload } : null;\n}\n\nexport function parseInboundMessage(data: unknown): InboundMessage | null {\n const message = readEnvelope(data);\n\n if (message === null) {\n return null;\n }\n\n const { payload } = message;\n\n switch (message.type) {\n case \"crafty:token\": {\n const token = typeof payload.token === \"string\" ? payload.token.trim() : \"\";\n\n return token !== \"\" && token.length <= MAX_TOKEN_LENGTH && TOKEN_PATTERN.test(token)\n ? { v: PROTOCOL_VERSION, type: \"crafty:token\", payload: { token } }\n : null;\n }\n case \"crafty:refresh\":\n return { v: PROTOCOL_VERSION, type: \"crafty:refresh\", payload: {} };\n case \"crafty:highlight\": {\n const ref = parseFieldRef(payload);\n\n return ref ? { v: PROTOCOL_VERSION, type: \"crafty:highlight\", payload: ref } : null;\n }\n case \"crafty:preview-field\": {\n const ref = parseFieldRef(payload);\n const value = payload.value;\n\n return ref && typeof value === \"string\" && value.length <= MAX_VALUE_LENGTH\n ? { v: PROTOCOL_VERSION, type: \"crafty:preview-field\", payload: { ...ref, value } }\n : null;\n }\n case \"crafty:preview-reset\": {\n const ref = parseFieldRef(payload);\n\n return ref ? { v: PROTOCOL_VERSION, type: \"crafty:preview-reset\", payload: ref } : null;\n }\n default:\n return null;\n }\n}\n\nexport function parseOutboundMessage(data: unknown): OutboundMessage | null {\n const message = readEnvelope(data);\n\n if (message === null) {\n return null;\n }\n\n const { payload } = message;\n\n switch (message.type) {\n case \"crafty:ready\": {\n const path = parsePath(payload.path);\n const rawPage = payload.page;\n\n if (typeof payload.sdkVersion !== \"string\" || path === null || !Array.isArray(payload.fields) || !Array.isArray(payload.entries)) {\n return null;\n }\n\n return {\n v: PROTOCOL_VERSION,\n type: \"crafty:ready\",\n payload: {\n sdkVersion: payload.sdkVersion,\n path,\n fields: payload.fields\n .map((field: unknown) => parseMarkedField(field))\n .filter((field): field is CraftyMarkedField => field !== null),\n page:\n isRecord(rawPage) && isPositiveInteger(rawPage.id) && typeof rawPage.slug === \"string\"\n ? { id: rawPage.id, slug: rawPage.slug }\n : null,\n entries: payload.entries\n .map((entry: unknown) => parseShownEntry(entry))\n .filter((entry): entry is CraftyShownEntry => entry !== null)\n }\n };\n }\n case \"crafty:select\": {\n const field = parseMarkedField(payload);\n\n return field ? { v: PROTOCOL_VERSION, type: \"crafty:select\", payload: field } : null;\n }\n case \"crafty:navigate\": {\n const path = parsePath(payload.path);\n\n return path ? { v: PROTOCOL_VERSION, type: \"crafty:navigate\", payload: { path } } : null;\n }\n case \"crafty:preview-invalid\":\n return { v: PROTOCOL_VERSION, type: \"crafty:preview-invalid\", payload: {} };\n case \"crafty:key\":\n return payload.key === \"Escape\" ? { v: PROTOCOL_VERSION, type: \"crafty:key\", payload: { key: \"Escape\" } } : null;\n default:\n return null;\n }\n}\n", "import { parseMarkedField, type CraftyFieldRef, type CraftyMarkedField } from \"./protocol.js\";\n\nexport const MARKED_SELECTOR = \"[data-crafty-field]\";\n\nexport type MarkedElement = { element: Element; field: CraftyMarkedField };\n\nexport function readMarkedField(element: Element): CraftyMarkedField | null {\n const blockId = element.getAttribute(\"data-crafty-block\");\n const entryId = element.getAttribute(\"data-crafty-entry\");\n const rawId = blockId ?? entryId;\n\n if (rawId === null) {\n return null;\n }\n\n return parseMarkedField({\n type: blockId !== null ? \"block\" : \"entry\",\n id: rawId.trim() === \"\" ? Number.NaN : Number(rawId),\n field: element.getAttribute(\"data-crafty-field\") ?? \"\",\n label: element.getAttribute(\"data-crafty-label\"),\n hrefField: element.getAttribute(\"data-crafty-href-field\"),\n hrefLabel: element.getAttribute(\"data-crafty-href-label\")\n });\n}\n\nexport function refKey(ref: CraftyFieldRef): string {\n return `${ref.type}:${ref.id}:${ref.field}`;\n}\n\nexport function scanMarked(root: ParentNode): MarkedElement[] {\n const marked: MarkedElement[] = [];\n\n root.querySelectorAll(MARKED_SELECTOR).forEach((element) => {\n const field = readMarkedField(element);\n\n if (field !== null) {\n marked.push({ element, field });\n }\n });\n\n return marked;\n}\n\nexport function uniqueFields(marked: MarkedElement[]): CraftyMarkedField[] {\n const seen = new Set<string>();\n const fields: CraftyMarkedField[] = [];\n\n for (const { field } of marked) {\n const key = refKey(field);\n\n if (!seen.has(key)) {\n seen.add(key);\n fields.push(field);\n }\n }\n\n return fields;\n}\n", "import { MARKED_SELECTOR, readMarkedField, refKey } from \"./markers.js\";\nimport type { CraftyFieldRef } from \"./protocol.js\";\n\nexport type LivePreview = {\n set(ref: CraftyFieldRef, value: string): void;\n reset(ref: CraftyFieldRef): void;\n reapply(): void;\n resetAll(): void;\n readonly size: number;\n};\n\n/**\n * Plain-text live preview. Values are written with `textContent` (never HTML),\n * and each element's own original text is kept so a reset restores exactly what\n * the site rendered, even for elements rendered after the value was set.\n */\nexport function createLivePreview(root: ParentNode): LivePreview {\n const values = new Map<string, string>();\n const originals = new Map<Element, string>();\n\n const matching = (key: string): Element[] =>\n Array.from(root.querySelectorAll(MARKED_SELECTOR)).filter((element) => {\n const field = readMarkedField(element);\n\n return field !== null && refKey(field) === key;\n });\n\n const write = (element: Element, value: string): void => {\n if (!originals.has(element)) {\n originals.set(element, element.textContent ?? \"\");\n }\n\n if (element.textContent !== value) {\n element.textContent = value;\n }\n };\n\n const restore = (key: string | null): void => {\n for (const [element, original] of originals) {\n const field = readMarkedField(element);\n\n if (key === null || (field !== null && refKey(field) === key)) {\n if (element.textContent !== original) {\n element.textContent = original;\n }\n\n originals.delete(element);\n }\n }\n };\n\n return {\n set(ref, value) {\n const key = refKey(ref);\n values.set(key, value);\n matching(key).forEach((element) => write(element, value));\n },\n reset(ref) {\n const key = refKey(ref);\n values.delete(key);\n restore(key);\n },\n reapply() {\n for (const element of [...originals.keys()]) {\n if (!element.isConnected) {\n originals.delete(element);\n }\n }\n\n for (const [key, value] of values) {\n matching(key).forEach((element) => write(element, value));\n }\n },\n resetAll() {\n values.clear();\n restore(null);\n },\n get size() {\n return values.size;\n }\n };\n}\n", "/** Crafty admin panels: https://crafty.do and https://<tenant>.crafty.do. */\nexport const DEFAULT_ADMIN_ORIGINS: ReadonlyArray<string | RegExp> = [/^https:\\/\\/([a-z0-9-]+\\.)*crafty\\.do$/];\n\nfunction originOf(value: string): string | null {\n try {\n return new URL(value).origin;\n } catch {\n return null;\n }\n}\n\nexport function isAllowedAdminOrigin(origin: string, allowlist: ReadonlyArray<string | RegExp>): boolean {\n if (origin === \"\" || origin === \"null\") {\n return false;\n }\n\n return allowlist.some((allowed) => {\n if (typeof allowed === \"string\") {\n return originOf(allowed) === origin;\n }\n\n allowed.lastIndex = 0;\n\n return allowed.test(origin);\n });\n}\n\n/**\n * Origin of the embedding admin. `ancestorOrigins` (Chromium, WebKit) cannot be\n * spoofed by the framed page; Firefox falls back to the referrer the admin sent\n * when it set the iframe `src`.\n */\nexport function resolveParentOrigin(win: Window): string | null {\n const ancestors = win.location.ancestorOrigins as ArrayLike<string> | undefined;\n const first = ancestors && ancestors.length > 0 ? ancestors[0] : undefined;\n\n if (typeof first === \"string\" && first !== \"\") {\n return first;\n }\n\n const referrer = win.document.referrer;\n\n return referrer ? originOf(referrer) : null;\n}\n", "const STYLE_ELEMENT_ID = \"crafty-visual-editing-style\";\nconst ACCENT = \"#4f46e5\";\n\nexport const FLASH_CLASS = \"crafty-ve-flash\";\n\nconst STYLES = [\n \"[data-crafty-field]{cursor:pointer}\",\n `.crafty-ve-box{position:fixed;top:0;left:0;pointer-events:none;z-index:2147483647;box-sizing:border-box;border:2px solid ${ACCENT};border-radius:4px;background:rgba(79,70,229,.06)}`,\n \".crafty-ve-box[hidden]{display:none}\",\n `.crafty-ve-label{position:absolute;left:-2px;bottom:100%;margin-bottom:4px;padding:2px 8px;max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;background:${ACCENT};color:#fff;font:500 12px/1.5 system-ui,-apple-system,sans-serif}`,\n `.${FLASH_CLASS}{outline:2px dashed ${ACCENT} !important;outline-offset:2px !important}`\n].join(\"\\n\");\n\nexport type Overlay = {\n show(element: Element, label: string): void;\n hide(): void;\n /** Re-measures the highlighted element, e.g. after its content changed. */\n reposition(): void;\n flash(elements: Element[], durationMs: number): void;\n ensureAttached(): void;\n contains(node: Node | null): boolean;\n destroy(): void;\n};\n\nexport function createOverlay(doc: Document): Overlay {\n const win = doc.defaultView;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ELEMENT_ID;\n style.textContent = STYLES;\n\n const box = doc.createElement(\"div\");\n box.setAttribute(\"data-crafty-overlay\", \"\");\n box.className = \"crafty-ve-box\";\n box.hidden = true;\n\n const label = doc.createElement(\"span\");\n label.className = \"crafty-ve-label\";\n box.appendChild(label);\n\n let target: Element | null = null;\n let flashed: Element[] = [];\n let flashTimer: number | undefined;\n const Observer = (win as (Window & { ResizeObserver?: typeof ResizeObserver }) | null)?.ResizeObserver;\n\n const place = (): void => {\n if (target === null) {\n return;\n }\n\n const rect = target.getBoundingClientRect();\n box.style.top = `${rect.top}px`;\n box.style.left = `${rect.left}px`;\n box.style.width = `${rect.width}px`;\n box.style.height = `${rect.height}px`;\n };\n\n const resizeObserver = typeof Observer === \"function\" ? new Observer(() => place()) : null;\n\n const track = (element: Element | null): void => {\n if (target === element) {\n return;\n }\n\n if (target !== null) {\n resizeObserver?.unobserve(target);\n }\n\n target = element;\n\n if (target !== null) {\n resizeObserver?.observe(target);\n }\n };\n\n const clearFlash = (): void => {\n flashed.forEach((element) => element.classList.remove(FLASH_CLASS));\n flashed = [];\n\n if (flashTimer !== undefined) {\n win?.clearTimeout(flashTimer);\n flashTimer = undefined;\n }\n };\n\n const ensureAttached = (): void => {\n if (!style.isConnected) {\n (doc.head ?? doc.documentElement).appendChild(style);\n }\n\n if (!box.isConnected) {\n (doc.body ?? doc.documentElement).appendChild(box);\n }\n };\n\n ensureAttached();\n win?.addEventListener(\"scroll\", place, { capture: true, passive: true });\n win?.addEventListener(\"resize\", place, { passive: true });\n\n return {\n show(element, text) {\n ensureAttached();\n track(element);\n\n if (label.textContent !== text) {\n label.textContent = text;\n }\n\n box.hidden = false;\n place();\n },\n hide() {\n track(null);\n box.hidden = true;\n },\n reposition() {\n place();\n },\n flash(elements, durationMs) {\n clearFlash();\n flashed = [...elements];\n flashed.forEach((element) => element.classList.add(FLASH_CLASS));\n flashTimer = win?.setTimeout(clearFlash, durationMs);\n },\n ensureAttached,\n contains(node) {\n return node !== null && (box === node || box.contains(node) || style === node || style.contains(node));\n },\n destroy() {\n clearFlash();\n win?.removeEventListener(\"scroll\", place, { capture: true });\n win?.removeEventListener(\"resize\", place);\n resizeObserver?.disconnect();\n box.remove();\n style.remove();\n target = null;\n }\n };\n}\n", "import type { CraftyClient } from \"../client.js\";\nimport {\n PREVIEW_ACTIVE_EVENT,\n PREVIEW_CONTENT_EVENT,\n PREVIEW_INVALID_EVENT,\n PREVIEW_QUERY_PARAM,\n getPreviewContent,\n getPreviewStatus,\n readPreviewToken,\n storePreviewToken\n} from \"../preview.js\";\nimport { SDK_VERSION } from \"../version.js\";\nimport { createLivePreview } from \"./live-preview.js\";\nimport { MARKED_SELECTOR, readMarkedField, refKey, scanMarked, uniqueFields, type MarkedElement } from \"./markers.js\";\nimport { DEFAULT_ADMIN_ORIGINS, isAllowedAdminOrigin, resolveParentOrigin } from \"./origin.js\";\nimport { createOverlay } from \"./overlay.js\";\nimport {\n PROTOCOL_VERSION,\n parseInboundMessage,\n type CraftyFieldRef,\n type CraftyMarkedField,\n type CraftyShownEntry,\n type CraftyShownPage,\n type InboundMessage,\n type OutboundMessage\n} from \"./protocol.js\";\n\nexport type VisualEditingOptions = {\n /** Allowed admin origins. Replaces the default (`https://*.crafty.do`). */\n adminOrigins?: ReadonlyArray<string | RegExp>;\n /** Re-fetch and re-render instead of a full reload when the admin asks for a refresh. */\n onRefresh?: () => void | Promise<void>;\n /** Page rendered by the server (SSR sites, where the browser did not fetch it). */\n page?: CraftyShownPage | null;\n /** Entries rendered by the server (SSR sites). */\n entries?: CraftyShownEntry[];\n /** How long touch devices highlight every editable after load. Default 1500 ms. */\n touchHighlightMs?: number;\n /**\n * Client used to confirm the preview token when no preview request has been\n * answered yet (one `pages.list({ per_page: 1 })` call). Without it the bridge\n * waits for the site's own first Crafty request to confirm the token.\n */\n client?: Pick<CraftyClient, \"pages\">;\n};\n\nexport type VisualEditingHandle = {\n readonly active: boolean;\n disable(): void;\n};\n\nconst SCROLL_STORAGE_KEY = \"crafty:scroll-y\";\nconst RESCAN_DELAY_MS = 50;\nconst DEFAULT_TOUCH_HIGHLIGHT_MS = 1500;\nconst WATCHED_ATTRIBUTES = [\n \"data-crafty-field\",\n \"data-crafty-block\",\n \"data-crafty-entry\",\n \"data-crafty-label\",\n \"data-crafty-href-field\",\n \"data-crafty-href-label\"\n];\n\nconst inactiveHandle: VisualEditingHandle = { active: false, disable: () => undefined };\nlet activeHandle: VisualEditingHandle | null = null;\n\n/**\n * Connects the page to the Crafty visual editor. No-op unless the page runs in\n * an iframe, carries a preview token, and its parent is an allowed admin origin.\n *\n * The default allowlist (`*.crafty.do`) also covers sites hosted by Crafty, so\n * the bridge stays inert (no overlay, no listeners, no messages) until the API\n * answers a preview request with `X-Crafty-Preview-Status: active`. On `invalid`\n * it only tells the admin `crafty:preview-invalid` and stays inert.\n */\nexport function enableVisualEditing(options: VisualEditingOptions = {}): VisualEditingHandle {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return inactiveHandle;\n }\n\n if (activeHandle !== null) {\n return activeHandle;\n }\n\n const win = window;\n\n if (win.parent === null || win.parent === win || readPreviewToken() === null) {\n return inactiveHandle;\n }\n\n const parentOrigin = resolveParentOrigin(win);\n\n if (parentOrigin === null || !isAllowedAdminOrigin(parentOrigin, options.adminOrigins ?? DEFAULT_ADMIN_ORIGINS)) {\n return inactiveHandle;\n }\n\n const status = getPreviewStatus();\n\n if (status === \"invalid\") {\n postPreviewInvalid(win, parentOrigin);\n\n return inactiveHandle;\n }\n\n activeHandle = status === \"active\" ? startBridge(win, parentOrigin, options) : awaitConfirmation(win, parentOrigin, options);\n\n return activeHandle;\n}\n\nfunction postPreviewInvalid(win: Window, parentOrigin: string): void {\n const message: OutboundMessage = { v: PROTOCOL_VERSION, type: \"crafty:preview-invalid\", payload: {} };\n win.parent.postMessage(message, parentOrigin);\n}\n\n/**\n * Pending handle: waits for the API to confirm the token before starting the\n * bridge, verifying it through `options.client` when one is given.\n */\nfunction awaitConfirmation(win: Window, parentOrigin: string, options: VisualEditingOptions): VisualEditingHandle {\n let bridge: VisualEditingHandle | null = null;\n let settled = false;\n\n const stopWaiting = (): void => {\n settled = true;\n win.removeEventListener(PREVIEW_ACTIVE_EVENT, onActive);\n win.removeEventListener(PREVIEW_INVALID_EVENT, onInvalid);\n };\n\n const release = (): void => {\n if (activeHandle === handle) {\n activeHandle = null;\n }\n };\n\n const onActive = (): void => {\n if (settled) {\n return;\n }\n\n stopWaiting();\n bridge = startBridge(win, parentOrigin, options, release);\n };\n\n const onInvalid = (): void => {\n if (settled) {\n return;\n }\n\n stopWaiting();\n release();\n postPreviewInvalid(win, parentOrigin);\n };\n\n const handle: VisualEditingHandle = {\n get active() {\n return bridge?.active ?? false;\n },\n disable() {\n stopWaiting();\n bridge?.disable();\n release();\n }\n };\n\n win.addEventListener(PREVIEW_ACTIVE_EVENT, onActive);\n win.addEventListener(PREVIEW_INVALID_EVENT, onInvalid);\n\n // The status handlers above settle the outcome; request errors leave the bridge waiting.\n options.client?.pages.list({ per_page: 1 }).catch(() => undefined);\n\n return handle;\n}\n\nfunction startBridge(\n win: Window,\n parentOrigin: string,\n options: VisualEditingOptions,\n onDisable?: () => void\n): VisualEditingHandle {\n const doc = win.document;\n const overlay = createOverlay(doc);\n const livePreview = createLivePreview(doc);\n const pendingScrollY = takeStoredScroll(win);\n\n let marked: MarkedElement[] = [];\n let sentSignature: string | null = null;\n let rescanTimer: number | undefined;\n let forceReady = false;\n let active = true;\n\n const post = (message: OutboundMessage): void => {\n win.parent.postMessage(message, parentOrigin);\n };\n\n const sendReady = (): void => {\n const fields = uniqueFields(marked);\n const content = getPreviewContent();\n sentSignature = signatureOf(fields);\n\n post({\n v: PROTOCOL_VERSION,\n type: \"crafty:ready\",\n payload: {\n sdkVersion: SDK_VERSION,\n path: currentPath(win),\n fields,\n page: content.page ?? options.page ?? null,\n entries: mergeEntries(content.entries, options.entries ?? [])\n }\n });\n };\n\n const rescan = (): void => {\n rescanTimer = undefined;\n\n if (!active) {\n return;\n }\n\n overlay.ensureAttached();\n marked = scanMarked(doc);\n livePreview.reapply();\n\n if (forceReady || signatureOf(uniqueFields(marked)) !== sentSignature) {\n forceReady = false;\n sendReady();\n }\n };\n\n const scheduleRescan = (): void => {\n if (active && rescanTimer === undefined) {\n rescanTimer = win.setTimeout(rescan, RESCAN_DELAY_MS);\n }\n };\n\n const observer = new MutationObserver((records) => {\n if (records.some((record) => !overlay.contains(record.target))) {\n scheduleRescan();\n }\n });\n\n const labelOf = (field: CraftyMarkedField): string => field.label ?? field.field;\n\n const onPointerOver = (event: PointerEvent): void => {\n if (event.pointerType === \"touch\") {\n return;\n }\n\n const hit = hitFrom(event.target);\n\n if (hit !== null) {\n overlay.show(hit.element, labelOf(hit.field));\n } else {\n overlay.hide();\n }\n };\n\n const block = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n };\n\n /**\n * Runs in the capture phase on `window`, before any site listener, so a marked\n * element always selects even when it is (or sits inside) a link or button,\n * and nothing the site renders can take the iframe out of the editor.\n */\n const onClick = (event: MouseEvent): void => {\n const hit = hitFrom(event.target);\n\n if (hit !== null) {\n block(event);\n overlay.show(hit.element, labelOf(hit.field));\n post({ v: PROTOCOL_VERSION, type: \"crafty:select\", payload: hit.field });\n\n return;\n }\n\n const action = linkAction(event, win);\n\n if (action.kind === \"allow\") {\n return;\n }\n\n block(event);\n\n if (action.kind === \"navigate\") {\n post({ v: PROTOCOL_VERSION, type: \"crafty:navigate\", payload: { path: action.path } });\n }\n };\n\n /** Middle clicks open links in a new tab: never let them leave the editor. */\n const onAuxClick = (event: MouseEvent): void => {\n if (hitFrom(event.target) !== null || closestLink(event.target) !== null) {\n block(event);\n }\n };\n\n const onSubmit = (event: Event): void => {\n block(event);\n };\n\n /**\n * Escape pressed while focus is inside the iframe never reaches the admin\n * window: forward it so the admin closes its topmost sheet or dialog. Runs in\n * the bubble phase, after the site, and skips an Escape the site handled\n * (`preventDefault`, e.g. to close its own menu).\n */\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== \"Escape\" || event.repeat || event.isComposing || event.defaultPrevented) {\n return;\n }\n\n post({ v: PROTOCOL_VERSION, type: \"crafty:key\", payload: { key: \"Escape\" } });\n };\n\n const highlight = (ref: CraftyFieldRef): void => {\n const key = refKey(ref);\n const match = scanMarked(doc).find((item) => refKey(item.field) === key);\n\n if (match === undefined) {\n return;\n }\n\n const element = match.element as Element & { scrollIntoView?: (options?: ScrollIntoViewOptions) => void };\n element.scrollIntoView?.({ block: \"center\", behavior: \"smooth\" });\n overlay.show(match.element, labelOf(match.field));\n };\n\n const refresh = async (): Promise<void> => {\n if (options.onRefresh) {\n try {\n await options.onRefresh();\n } finally {\n scheduleRescan();\n }\n\n return;\n }\n\n try {\n win.sessionStorage.setItem(SCROLL_STORAGE_KEY, String(win.scrollY));\n } catch {\n // Storage blocked: reload without restoring the scroll position.\n }\n\n win.location.reload();\n };\n\n const handleInbound = (message: InboundMessage): void => {\n switch (message.type) {\n case \"crafty:token\":\n storePreviewToken(message.payload.token);\n return;\n case \"crafty:refresh\":\n refresh().catch((error: unknown) => console.error(\"[crafty] onRefresh failed\", error));\n return;\n case \"crafty:highlight\":\n highlight(message.payload);\n return;\n case \"crafty:preview-field\":\n livePreview.set(message.payload, message.payload.value);\n overlay.reposition();\n return;\n case \"crafty:preview-reset\":\n livePreview.reset(message.payload);\n overlay.reposition();\n return;\n }\n };\n\n const onMessage = (event: MessageEvent): void => {\n if (event.source !== win.parent || event.origin !== parentOrigin) {\n return;\n }\n\n const message = parseInboundMessage(event.data);\n\n if (message !== null) {\n handleInbound(message);\n }\n };\n\n const onPreviewInvalid = (): void => {\n post({ v: PROTOCOL_VERSION, type: \"crafty:preview-invalid\", payload: {} });\n };\n\n const onPreviewContent = (): void => {\n forceReady = true;\n scheduleRescan();\n };\n\n const start = (): void => {\n if (!active) {\n return;\n }\n\n marked = scanMarked(doc);\n sendReady();\n\n if (isTouchDevice(win)) {\n overlay.flash(\n marked.map((item) => item.element),\n options.touchHighlightMs ?? DEFAULT_TOUCH_HIGHLIGHT_MS\n );\n }\n\n restoreScroll(win, pendingScrollY);\n };\n\n win.addEventListener(\"message\", onMessage);\n win.addEventListener(\"click\", onClick, true);\n win.addEventListener(\"auxclick\", onAuxClick, true);\n win.addEventListener(\"submit\", onSubmit, true);\n win.addEventListener(\"keydown\", onKeyDown);\n doc.addEventListener(\"pointerover\", onPointerOver, true);\n win.addEventListener(PREVIEW_INVALID_EVENT, onPreviewInvalid);\n win.addEventListener(PREVIEW_CONTENT_EVENT, onPreviewContent);\n observer.observe(doc.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: WATCHED_ATTRIBUTES\n });\n\n if (doc.readyState === \"loading\") {\n doc.addEventListener(\"DOMContentLoaded\", start, { once: true });\n } else {\n start();\n }\n\n const handle: VisualEditingHandle = {\n get active() {\n return active;\n },\n disable() {\n if (!active) {\n return;\n }\n\n active = false;\n win.removeEventListener(\"message\", onMessage);\n win.removeEventListener(\"click\", onClick, true);\n win.removeEventListener(\"auxclick\", onAuxClick, true);\n win.removeEventListener(\"submit\", onSubmit, true);\n win.removeEventListener(\"keydown\", onKeyDown);\n doc.removeEventListener(\"pointerover\", onPointerOver, true);\n doc.removeEventListener(\"DOMContentLoaded\", start);\n win.removeEventListener(PREVIEW_INVALID_EVENT, onPreviewInvalid);\n win.removeEventListener(PREVIEW_CONTENT_EVENT, onPreviewContent);\n observer.disconnect();\n\n if (rescanTimer !== undefined) {\n win.clearTimeout(rescanTimer);\n rescanTimer = undefined;\n }\n\n livePreview.resetAll();\n overlay.destroy();\n\n if (activeHandle === handle) {\n activeHandle = null;\n }\n\n onDisable?.();\n }\n };\n\n return handle;\n}\n\nfunction asElement(target: EventTarget | null): Element | null {\n return target !== null && typeof (target as Element).closest === \"function\" ? (target as Element) : null;\n}\n\nfunction signatureOf(fields: CraftyMarkedField[]): string {\n return fields.map((field) => `${refKey(field)}|${field.label ?? \"\"}|${field.hrefField ?? \"\"}|${field.hrefLabel ?? \"\"}`).join(\"\\n\");\n}\n\nfunction mergeEntries(fetched: CraftyShownEntry[], declared: CraftyShownEntry[]): CraftyShownEntry[] {\n const seen = new Set<string>();\n\n return [...fetched, ...declared].filter((entry) => {\n const key = `${entry.collection}:${entry.id}`;\n\n if (seen.has(key)) {\n return false;\n }\n\n seen.add(key);\n\n return true;\n });\n}\n\nfunction stripPreviewParam(url: URL): string {\n url.searchParams.delete(PREVIEW_QUERY_PARAM);\n\n return `${url.pathname}${url.search}`;\n}\n\nfunction currentPath(win: Window): string {\n return stripPreviewParam(new URL(win.location.href));\n}\n\ntype LinkAction = { kind: \"allow\" } | { kind: \"block\" } | { kind: \"navigate\"; path: string };\n\n/**\n * Only links fall back to their marked descendant: following them would leave\n * the editor. Buttons, `<summary>` and labels keep their own behavior (menus,\n * accordions, tabs) when the click misses the marked element.\n */\nconst LINK_SELECTOR = \"a[href], area[href]\";\n\n/**\n * The marked element a pointer or click target maps to: the innermost valid\n * marked ancestor (or the target itself), else the first marked element inside\n * the link that was clicked, so clicking a link button's padding or icon\n * selects its label.\n */\nfunction hitFrom(target: EventTarget | null): MarkedElement | null {\n const element = asElement(target);\n\n if (element === null) {\n return null;\n }\n\n for (let node = element.closest(MARKED_SELECTOR); node !== null; node = node.parentElement?.closest(MARKED_SELECTOR) ?? null) {\n const field = readMarkedField(node);\n\n if (field !== null) {\n return { element: node, field };\n }\n }\n\n const link = element.closest(LINK_SELECTOR);\n\n return link !== null ? (scanMarked(link)[0] ?? null) : null;\n}\n\nfunction closestLink(target: EventTarget | null): Element | null {\n return asElement(target)?.closest(LINK_SELECTOR) ?? null;\n}\n\n/**\n * What to do with a click that hit no marked element. Only same-page anchors\n * run as usual; same-origin links become `crafty:navigate`; anything that\n * would leave the editor (other origins, `mailto:`/`tel:`, new tabs,\n * downloads, modified clicks) is blocked.\n */\nfunction linkAction(event: MouseEvent, win: Window): LinkAction {\n const anchor = closestLink(event.target);\n\n if (anchor === null) {\n return { kind: \"allow\" };\n }\n\n if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || anchor.hasAttribute(\"download\")) {\n return { kind: \"block\" };\n }\n\n const target = anchor.getAttribute(\"target\");\n\n if (target !== null && target !== \"\" && target !== \"_self\") {\n return { kind: \"block\" };\n }\n\n const href = anchor.getAttribute(\"href\") ?? \"\";\n let url: URL;\n\n try {\n url = new URL(href, win.location.href);\n } catch {\n return { kind: \"block\" };\n }\n\n if (url.origin !== win.location.origin || (url.protocol !== \"http:\" && url.protocol !== \"https:\")) {\n return { kind: \"block\" };\n }\n\n const path = stripPreviewParam(url);\n\n if ((url.hash !== \"\" || href.startsWith(\"#\")) && path === currentPath(win)) {\n return { kind: \"allow\" };\n }\n\n return { kind: \"navigate\", path };\n}\n\nfunction isTouchDevice(win: Window): boolean {\n return typeof win.matchMedia === \"function\" && win.matchMedia(\"(hover: none)\").matches;\n}\n\nfunction takeStoredScroll(win: Window): number | null {\n try {\n const raw = win.sessionStorage.getItem(SCROLL_STORAGE_KEY);\n win.sessionStorage.removeItem(SCROLL_STORAGE_KEY);\n const scrollY = raw === null ? Number.NaN : Number(raw);\n\n return Number.isFinite(scrollY) ? scrollY : null;\n } catch {\n return null;\n }\n}\n\nfunction restoreScroll(win: Window, scrollY: number | null): void {\n if (scrollY === null) {\n return;\n }\n\n const apply = (): void => win.scrollTo(0, scrollY);\n\n if (win.document.readyState === \"complete\") {\n apply();\n } else {\n win.addEventListener(\"load\", apply, { once: true });\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["cdn_exports", "__export", "PROTOCOL_VERSION", "attrs", "attrsHtml", "enableVisualEditing", "resolveEditTarget", "target", "record", "id", "attrs", "field", "options", "resolved", "normalizedField", "attributes", "label", "hrefField", "hrefLabel", "attrsHtml", "name", "value", "escapeAttribute", "PREVIEW_QUERY_PARAM", "PREVIEW_INVALID_EVENT", "PREVIEW_CONTENT_EVENT", "PREVIEW_ACTIVE_EVENT", "TOKEN_STORAGE_KEY", "URL_TOKEN_STORAGE_KEY", "INVALID_TOKEN_STORAGE_KEY", "CONTENT_GLOBAL_KEY", "STATUS_GLOBAL_KEY", "browserWindow", "storageGet", "key", "_a", "_b", "storageSet", "value", "normalizeToken", "value", "tokenFromUrl", "url", "PREVIEW_QUERY_PARAM", "readPreviewToken", "_a", "win", "browserWindow", "urlToken", "token", "storageGet", "URL_TOKEN_STORAGE_KEY", "storageSet", "TOKEN_STORAGE_KEY", "INVALID_TOKEN_STORAGE_KEY", "storePreviewToken", "token", "normalized", "normalizeToken", "storageSet", "TOKEN_STORAGE_KEY", "getPreviewContent", "win", "browserWindow", "content", "CONTENT_GLOBAL_KEY", "getPreviewStatus", "win", "browserWindow", "status", "STATUS_GLOBAL_KEY", "SDK_VERSION", "PROTOCOL_VERSION", "FIELD_PATTERN", "TOKEN_PATTERN", "isRecord", "value", "isPositiveInteger", "parseFieldPath", "trimmed", "FIELD_PATTERN", "parseLabel", "parseFieldRef", "type", "id", "field", "parseMarkedField", "ref", "marked", "label", "hrefField", "hrefLabel", "readEnvelope", "data", "isRecord", "payload", "parseInboundMessage", "message", "token", "TOKEN_PATTERN", "ref", "parseFieldRef", "value", "MARKED_SELECTOR", "readMarkedField", "element", "_a", "blockId", "entryId", "rawId", "parseMarkedField", "refKey", "ref", "scanMarked", "root", "marked", "field", "uniqueFields", "seen", "fields", "key", "createLivePreview", "root", "values", "originals", "matching", "key", "MARKED_SELECTOR", "element", "field", "readMarkedField", "refKey", "write", "value", "_a", "restore", "original", "ref", "DEFAULT_ADMIN_ORIGINS", "originOf", "value", "isAllowedAdminOrigin", "origin", "allowlist", "allowed", "resolveParentOrigin", "win", "ancestors", "first", "referrer", "STYLE_ELEMENT_ID", "ACCENT", "FLASH_CLASS", "STYLES", "createOverlay", "doc", "win", "style", "box", "label", "target", "flashed", "flashTimer", "Observer", "place", "rect", "resizeObserver", "track", "element", "clearFlash", "ensureAttached", "_a", "_b", "text", "elements", "durationMs", "node", "SCROLL_STORAGE_KEY", "RESCAN_DELAY_MS", "DEFAULT_TOUCH_HIGHLIGHT_MS", "WATCHED_ATTRIBUTES", "inactiveHandle", "activeHandle", "enableVisualEditing", "options", "_a", "win", "readPreviewToken", "parentOrigin", "resolveParentOrigin", "isAllowedAdminOrigin", "DEFAULT_ADMIN_ORIGINS", "status", "getPreviewStatus", "postPreviewInvalid", "startBridge", "awaitConfirmation", "message", "bridge", "settled", "stopWaiting", "PREVIEW_ACTIVE_EVENT", "onActive", "PREVIEW_INVALID_EVENT", "onInvalid", "release", "handle", "onDisable", "doc", "overlay", "createOverlay", "livePreview", "createLivePreview", "pendingScrollY", "takeStoredScroll", "marked", "sentSignature", "rescanTimer", "forceReady", "active", "post", "sendReady", "_b", "_c", "fields", "uniqueFields", "content", "getPreviewContent", "signatureOf", "SDK_VERSION", "currentPath", "mergeEntries", "rescan", "scanMarked", "scheduleRescan", "observer", "records", "record", "labelOf", "field", "onPointerOver", "event", "hit", "hitFrom", "block", "onClick", "action", "linkAction", "onAuxClick", "closestLink", "onSubmit", "onKeyDown", "highlight", "ref", "key", "refKey", "match", "item", "element", "refresh", "handleInbound", "storePreviewToken", "error", "onMessage", "parseInboundMessage", "onPreviewInvalid", "onPreviewContent", "start", "isTouchDevice", "restoreScroll", "PREVIEW_CONTENT_EVENT", "asElement", "target", "fetched", "declared", "seen", "entry", "stripPreviewParam", "url", "PREVIEW_QUERY_PARAM", "LINK_SELECTOR", "node", "MARKED_SELECTOR", "readMarkedField", "link", "anchor", "href", "path", "raw", "scrollY", "apply"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from "../http.js";
|
|
2
|
-
import type { CraftyCartItem, CraftyCheckoutOptions, CraftyCheckoutSession, CraftyFulfillment, CraftyOrder, CraftyQuote, CraftyStore, RequestOptions } from "../types/public.js";
|
|
2
|
+
import type { CraftyCartItem, CraftyCheckoutOptions, CraftyCheckoutStatus, CraftyCheckoutSession, CraftyFulfillment, CraftyOrder, CraftyQuote, CraftyStore, RequestOptions } from "../types/public.js";
|
|
3
3
|
export declare class StoreResource {
|
|
4
4
|
private readonly http;
|
|
5
5
|
constructor(http: HttpClient);
|
|
@@ -25,6 +25,12 @@ export declare class CheckoutResource {
|
|
|
25
25
|
constructor(http: HttpClient);
|
|
26
26
|
/** Opens a checkout session for the cart and returns its hosted checkout URL. */
|
|
27
27
|
create(items: readonly CraftyCartItem[], options?: CraftyCheckoutOptions): Promise<CraftyCheckoutSession>;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the checkout session ended in an order. A cart can use it to
|
|
30
|
+
* empty itself when the visitor never came back through the return link
|
|
31
|
+
* (see `cart.syncCheckout()`). Rejects with 404 once the session is gone.
|
|
32
|
+
*/
|
|
33
|
+
status(id: string, options?: RequestOptions): Promise<CraftyCheckoutStatus>;
|
|
28
34
|
/**
|
|
29
35
|
* Opens a checkout session and sends the browser to Crafty's hosted
|
|
30
36
|
* checkout, where the visitor picks delivery or pickup, pays, and gets the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/resources/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EAErB,iBAAiB,EACjB,WAAW,EAEX,WAAW,EAEX,WAAW,EAEX,cAAc,EACf,MAAM,oBAAoB,CAAC;AAmB5B,qBAAa,aAAa;IACL,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpD,0FAA0F;IAC7E,GAAG,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;CAKjE;AAED,qBAAa,cAAc;IACN,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpD;;;;OAIG;IACU,KAAK,CAChB,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,OAAO,CAAC,EAAE,cAAc,GAAG;QAAE,WAAW,CAAC,EAAE,iBAAiB,CAAA;KAAE,GAC7D,OAAO,CAAC,WAAW,CAAC;IAWvB,2EAA2E;IAC9D,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;CAUhG;AAED,qBAAa,gBAAgB;IACR,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpD,iFAAiF;IACpE,MAAM,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAWtH;;;;OAIG;IACU,KAAK,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/resources/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EAEpB,qBAAqB,EAErB,iBAAiB,EACjB,WAAW,EAEX,WAAW,EAEX,WAAW,EAEX,cAAc,EACf,MAAM,oBAAoB,CAAC;AAmB5B,qBAAa,aAAa;IACL,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpD,0FAA0F;IAC7E,GAAG,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;CAKjE;AAED,qBAAa,cAAc;IACN,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpD;;;;OAIG;IACU,KAAK,CAChB,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,OAAO,CAAC,EAAE,cAAc,GAAG;QAAE,WAAW,CAAC,EAAE,iBAAiB,CAAA;KAAE,GAC7D,OAAO,CAAC,WAAW,CAAC;IAWvB,2EAA2E;IAC9D,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;CAUhG;AAED,qBAAa,gBAAgB;IACR,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpD,iFAAiF;IACpE,MAAM,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAWtH;;;;OAIG;IACU,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAMxF;;;;OAIG;IACU,KAAK,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAUtH"}
|
package/dist/resources/store.js
CHANGED
|
@@ -56,10 +56,19 @@ export class CheckoutResource {
|
|
|
56
56
|
}
|
|
57
57
|
/** Opens a checkout session for the cart and returns its hosted checkout URL. */
|
|
58
58
|
async create(items, options) {
|
|
59
|
-
const { returnUrl, fields, fulfillment, ...requestOptions } = options ?? {};
|
|
59
|
+
const { returnUrl, fields, fulfillment, onSession, ...requestOptions } = options ?? {};
|
|
60
60
|
const response = await this.http.post(storePath(this.http, "/checkout"), { items: lines(items), ...(fields ? { fields } : {}), ...(fulfillment ? { fulfillment } : {}), ...(returnUrl ? { return_url: returnUrl } : {}) }, this.http.withLocale(requestOptions));
|
|
61
61
|
return response.data;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Whether the checkout session ended in an order. A cart can use it to
|
|
65
|
+
* empty itself when the visitor never came back through the return link
|
|
66
|
+
* (see `cart.syncCheckout()`). Rejects with 404 once the session is gone.
|
|
67
|
+
*/
|
|
68
|
+
async status(id, options) {
|
|
69
|
+
const response = await this.http.get(storePath(this.http, `/checkout/${encodeURIComponent(id)}`), options);
|
|
70
|
+
return response.data;
|
|
71
|
+
}
|
|
63
72
|
/**
|
|
64
73
|
* Opens a checkout session and sends the browser to Crafty's hosted
|
|
65
74
|
* checkout, where the visitor picks delivery or pickup, pays, and gets the
|
|
@@ -67,6 +76,7 @@ export class CheckoutResource {
|
|
|
67
76
|
*/
|
|
68
77
|
async start(items, options) {
|
|
69
78
|
const session = await this.create(items, options);
|
|
79
|
+
options?.onSession?.(session);
|
|
70
80
|
if (typeof window !== "undefined") {
|
|
71
81
|
window.location.assign(session.url);
|
|
72
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/resources/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/resources/store.ts"],"names":[],"mappings":"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"}
|
package/dist/types/public.d.ts
CHANGED
|
@@ -502,12 +502,19 @@ export type CraftyCheckoutSession = {
|
|
|
502
502
|
expires_at: string;
|
|
503
503
|
};
|
|
504
504
|
export type CraftyCheckoutSessionResponse = SingleResponse<CraftyCheckoutSession>;
|
|
505
|
+
/** Whether a checkout session ended in an order. */
|
|
506
|
+
export type CraftyCheckoutStatus = {
|
|
507
|
+
placed: boolean;
|
|
508
|
+
};
|
|
509
|
+
export type CraftyCheckoutStatusResponse = SingleResponse<CraftyCheckoutStatus>;
|
|
505
510
|
export type CraftyCheckoutOptions = RequestOptions & {
|
|
506
|
-
/** Where "Volver a la tienda" leads after the order; Crafty adds `?
|
|
511
|
+
/** Where "Volver a la tienda" leads after the order; Crafty adds `?order=<number>`. Defaults to the store's setting. */
|
|
507
512
|
returnUrl?: string;
|
|
508
513
|
/** Prefills the checkout's own fields by key (up to 30, strings). */
|
|
509
514
|
fields?: Record<string, string>;
|
|
510
515
|
/** Delivery or pickup as chosen in the cart; the checkout opens with it selected. */
|
|
511
516
|
fulfillment?: CraftyFulfillment;
|
|
517
|
+
/** Called with the new session before the browser leaves, e.g. `(session) => cart.rememberCheckout(session.id)`. */
|
|
518
|
+
onSession?: (session: CraftyCheckoutSession) => void;
|
|
512
519
|
};
|
|
513
520
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "0.10.
|
|
1
|
+
export declare const SDK_VERSION = "0.10.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -97,7 +97,18 @@ await crafty.checkout.start(cart.items(), {
|
|
|
97
97
|
|
|
98
98
|
`start()` creates a checkout session (valid 24 hours) and sends the browser to the hosted checkout. `checkout.create()` returns `{ id, url, expires_at }` without redirecting, for SSR or links. The checkout re-prices the cart; if a price changed since the page loaded it shows the new total and asks the customer to confirm.
|
|
99
99
|
|
|
100
|
-
After the order, **Volver a
|
|
100
|
+
After the order, the order page shows a **Volver a {tienda}** button to the return URL with `?order=<number>`, and goes there on its own after three minutes. On that page call `cart.clearOnReturn()`: it empties the cart and returns the order number so you can thank the customer.
|
|
101
|
+
|
|
102
|
+
A visitor may close the tab instead. To empty the cart anyway, remember the session when the checkout starts and check it on every page load:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
await crafty.checkout.start(cart.items(), { onSession: (session) => cart.rememberCheckout(session.id) });
|
|
106
|
+
|
|
107
|
+
// on page load
|
|
108
|
+
await cart.syncCheckout(crafty); // empties the cart once that checkout became an order
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`syncCheckout()` asks `GET /api/v1/sites/{site}/checkout/{id}` (`{ placed }` only) and keeps the cart when its lines changed after the checkout started.
|
|
101
112
|
|
|
102
113
|
An order can be read back with its token, which is in the order page link (`?t=`):
|
|
103
114
|
|
|
@@ -135,6 +146,7 @@ No API key is required; the site is in the URL. Errors use the usual `{ error, m
|
|
|
135
146
|
| POST | `/api/v1/sites/{site}/orders/quote` | Body `{ items: [{ slug, variant?, quantity }], fulfillment?: "delivery" \| "pickup", locale? }`. |
|
|
136
147
|
| POST | `/api/v1/sites/{site}/checkout` | Body `{ items, return_url?, fields?, fulfillment?, locale? }` → 201 `{ data: { id, url, expires_at } }`. |
|
|
137
148
|
| GET | `/api/v1/sites/{site}/orders/{number}` | Token in `?token=` or `X-Order-Token`. |
|
|
149
|
+
| GET | `/api/v1/sites/{site}/checkout/{id}` | `{ data: { placed } }`: whether the session became an order; 404 once pruned. |
|
|
138
150
|
|
|
139
151
|
A closed store answers `404 STORE_DISABLED`. The quote and checkout endpoints are rate limited per visitor.
|
|
140
152
|
|
|
@@ -324,10 +324,10 @@ crafty.orders.get(number, token) // => the order, with the t
|
|
|
324
324
|
const cart = createCart(); // localStorage, key "crafty:cart" (pass { key } per site)
|
|
325
325
|
cart.add("geisha", { variant: "Molido", quantity: 2 });
|
|
326
326
|
cart.update("geisha", 3, "Molido"); cart.remove("taza"); cart.count(); cart.subscribe(render);
|
|
327
|
-
cart.clearOnReturn(); // on the return page: empties the cart when the URL has ?
|
|
327
|
+
cart.clearOnReturn(); // on the return page: empties the cart when the URL has ?order=, returns the number
|
|
328
328
|
```
|
|
329
329
|
|
|
330
|
-
`quote().unavailable` lists lines Crafty left out (`not_found`, `sold_out`, `variant_not_found`, `variant_required`, `no_price`). A closed store answers 404 `STORE_DISABLED`. After the order, "Volver a la tienda" leads to `returnUrl` (or the store's setting) with `?
|
|
330
|
+
`quote().unavailable` lists lines Crafty left out (`not_found`, `sold_out`, `variant_not_found`, `variant_required`, `no_price`). A closed store answers 404 `STORE_DISABLED`. After the order, "Volver a la tienda" leads to `returnUrl` (or the store's setting) with `?order=<number>`.
|
|
331
331
|
|
|
332
332
|
## Error handling
|
|
333
333
|
|