@obelism/content 0.17.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -7
- package/dist/bridge.d.mts +16 -3
- package/dist/bridge.d.mts.map +1 -1
- package/dist/bridge.d.ts +16 -3
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.global.js +16 -5
- package/dist/bridge.js +239 -28
- package/dist/bridge.mjs +239 -28
- package/dist/index.d.mts +15 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.mjs +3 -3
- package/dist/{preview-mpwfmnla.js → preview-ijk3ixwb.js} +17 -0
- package/dist/{preview-h7rwp06v.mjs → preview-jcmxxj92.mjs} +15 -1
- package/dist/site.js +5 -0
- package/dist/site.mjs +5 -0
- package/dist/{types-e5nvgudo.d.ts → types-mtjco3a5.d.ts} +10 -2
- package/dist/types-mtjco3a5.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/types-e5nvgudo.d.ts.map +0 -1
package/dist/bridge.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, E as ENTRY_ATTRIBUTE } from './preview-
|
|
1
|
+
import { P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, E as ENTRY_ATTRIBUTE, a as PRODUCT_ATTRIBUTE, b as PRODUCT_HANDLE_ATTRIBUTE } from './preview-jcmxxj92.mjs';
|
|
2
2
|
import { SITE_EDITING_COOKIE, SITE_REQUEST_HEADER } from './site.mjs';
|
|
3
3
|
import { n as normalizeUrl, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
|
|
4
4
|
|
|
@@ -227,6 +227,7 @@ const onlyWhileEditingSite = ()=>Promise.reject(new Error('Only while signed in
|
|
|
227
227
|
const INERT_METHODS = {
|
|
228
228
|
prompt: inertPrompt,
|
|
229
229
|
createPage: ()=>Promise.reject(new Error('New pages are made on the site itself')),
|
|
230
|
+
createProductPage: ()=>Promise.reject(new Error('Product pages are made on the site itself')),
|
|
230
231
|
view: onlyWhileEditingSite,
|
|
231
232
|
applyJson: onlyWhileEditingSite,
|
|
232
233
|
openForm: (_container, options = {})=>{
|
|
@@ -284,6 +285,7 @@ const createBridge = (win, cmsOrigin)=>{
|
|
|
284
285
|
mode: isEditing ? 'editor' : null,
|
|
285
286
|
entryId: params.get(PREVIEW_PARAMS.entry),
|
|
286
287
|
environment: params.get(PREVIEW_PARAMS.environment),
|
|
288
|
+
product: null,
|
|
287
289
|
on: emitter.on,
|
|
288
290
|
getState: ()=>state,
|
|
289
291
|
...INERT_METHODS,
|
|
@@ -476,6 +478,7 @@ const wrapScriptBridge = (script, params)=>{
|
|
|
476
478
|
mode: script.isEditing ? 'editor' : null,
|
|
477
479
|
entryId: script.entryId,
|
|
478
480
|
environment: params.get(PREVIEW_PARAMS.environment),
|
|
481
|
+
product: null,
|
|
479
482
|
on: (event, listener)=>{
|
|
480
483
|
if (event === 'update' && !forwardingUpdates) {
|
|
481
484
|
forwardingUpdates = true;
|
|
@@ -535,8 +538,24 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
535
538
|
pagesEmpty: 'No pages match',
|
|
536
539
|
pageCurrent: 'This page',
|
|
537
540
|
pageDraft: 'Draft',
|
|
538
|
-
pageChanged: 'Changed'
|
|
541
|
+
pageChanged: 'Changed',
|
|
542
|
+
addProductPage: 'Add a product page',
|
|
543
|
+
addingProductPage: 'Making the product page…',
|
|
544
|
+
addedProductPage: 'Opening the product page…',
|
|
545
|
+
productPageHint: 'This product has no page yet. Add one for what the store doesn’t say.'
|
|
539
546
|
};
|
|
547
|
+
const SIDE_KEY = 'obelism-content-prompt-side';
|
|
548
|
+
// How far the pointer moves before it drags the box, not clicks it.
|
|
549
|
+
const DRAG_THRESHOLD_PX = 6;
|
|
550
|
+
// How far ahead a flick carries the box: its speed for this long.
|
|
551
|
+
const FLICK_MS = 150;
|
|
552
|
+
// …at most this far, so one coarse pointer event isn't a flick across the
|
|
553
|
+
// screen…
|
|
554
|
+
const FLICK_MAX_PX = 120;
|
|
555
|
+
// …and none when the pointer stood still this long before letting go.
|
|
556
|
+
const FLICK_STALE_MS = 80;
|
|
557
|
+
// Its distance from the side of the screen, as in the CSS.
|
|
558
|
+
const EDGE_PX = 16;
|
|
540
559
|
// Icons (Lucide), drawn in the text colour.
|
|
541
560
|
const ICONS = {
|
|
542
561
|
page: '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>',
|
|
@@ -549,6 +568,7 @@ const ICONS = {
|
|
|
549
568
|
chevrons: '<path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/>',
|
|
550
569
|
search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
|
|
551
570
|
check: '<path d="M20 6 9 17l-5-5"/>',
|
|
571
|
+
mark: '<path d="M12 3v18M3 12h18"/><g fill="currentColor" stroke="none"><circle cx="7" cy="7" r="1.75"/><circle cx="17" cy="7" r="1.75"/><circle cx="7" cy="17" r="1.75"/><circle cx="17" cy="17" r="1.75"/></g>',
|
|
552
572
|
send: '<path d="M3.714 3.048a.498.498 0 0 0-.683.627l2.843 7.627a2 2 0 0 1 0 1.396l-2.842 7.627a.498.498 0 0 0 .682.627l18-8.5a.5.5 0 0 0 0-.904z"/><path d="M6 12h16"/>'
|
|
553
573
|
};
|
|
554
574
|
// Obelism's design tokens (obelism.studio/design.md), under their own names:
|
|
@@ -574,10 +594,20 @@ const CSS = `
|
|
|
574
594
|
--font-inter: 'InterVariable', 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
|
|
575
595
|
Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
|
|
576
596
|
position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%);
|
|
597
|
+
transition: translate .45s cubic-bezier(0.34, 1.3, 0.64, 1);
|
|
577
598
|
z-index: 2147483647; width: min(640px, calc(100vw - 32px)); color-scheme: light dark;
|
|
578
599
|
font: 400 14px/1.4 var(--font-inter); color: rgb(var(--theme-foreground-rgb));
|
|
579
600
|
-webkit-font-smoothing: antialiased;
|
|
580
601
|
}
|
|
602
|
+
/* Dragged to a side of the screen, it stays there, springing into place. */
|
|
603
|
+
.root[data-side='left'] { left: 16px; transform: none; }
|
|
604
|
+
.root[data-side='right'] { left: auto; right: 16px; transform: none; }
|
|
605
|
+
.root[data-side='left'] .bar { justify-content: flex-start; }
|
|
606
|
+
.root[data-side='right'] .bar { justify-content: flex-end; }
|
|
607
|
+
.root.dragging { transition: none; user-select: none; -webkit-user-select: none; }
|
|
608
|
+
.root.dragging, .root.dragging * { cursor: grabbing !important; }
|
|
609
|
+
.toolbar, .footer, .status { cursor: grab; touch-action: none; }
|
|
610
|
+
.pill { touch-action: none; }
|
|
581
611
|
@media (prefers-color-scheme: dark) {
|
|
582
612
|
.root {
|
|
583
613
|
--theme-foreground-rgb: var(--color-white-rgb);
|
|
@@ -613,7 +643,8 @@ button:focus-visible { outline: 2px solid rgb(var(--theme-accent-rgb)); outline-
|
|
|
613
643
|
}
|
|
614
644
|
button.pill:hover { color: rgb(var(--theme-foreground-rgb)); transform: translateY(-2px); }
|
|
615
645
|
.pill > span:first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
616
|
-
.mark { color: rgb(var(--theme-accent-rgb));
|
|
646
|
+
.mark { color: rgb(var(--theme-accent-rgb)); }
|
|
647
|
+
.mark svg { width: 20px; height: 20px; }
|
|
617
648
|
.pill.compact { width: auto; height: 40px; padding: 0 18px; font-size: 14px; gap: 4px; }
|
|
618
649
|
|
|
619
650
|
/* Open: a floating card, the text on top and a row of pill buttons below. */
|
|
@@ -631,7 +662,7 @@ button.pill:hover { color: rgb(var(--theme-foreground-rgb)); transform: translat
|
|
|
631
662
|
@keyframes rise { from { opacity: 0; transform: translateY(8px) scale(.98); } }
|
|
632
663
|
@keyframes spin { to { transform: rotate(1turn); } }
|
|
633
664
|
@media (prefers-reduced-motion: reduce) {
|
|
634
|
-
.panel { animation: none; }
|
|
665
|
+
.root, .panel { animation: none; transition: none; }
|
|
635
666
|
.pill { transition: none; }
|
|
636
667
|
}
|
|
637
668
|
.status {
|
|
@@ -783,6 +814,11 @@ const icon = (doc, name)=>{
|
|
|
783
814
|
span.innerHTML = `<svg viewBox="0 0 24 24">${ICONS[name]}</svg>`;
|
|
784
815
|
return span;
|
|
785
816
|
};
|
|
817
|
+
const mark = (doc)=>{
|
|
818
|
+
const span = icon(doc, 'mark');
|
|
819
|
+
span.classList.add('mark');
|
|
820
|
+
return span;
|
|
821
|
+
};
|
|
786
822
|
// Mounts the box on the page; returns a function that removes it.
|
|
787
823
|
const mountPromptBox = (doc, bridge, options = {})=>{
|
|
788
824
|
const labels = {
|
|
@@ -801,11 +837,8 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
801
837
|
const pill = element(doc, 'button', {
|
|
802
838
|
className: 'pill',
|
|
803
839
|
type: 'button'
|
|
804
|
-
}, pillText, // The Obelism mark.
|
|
805
|
-
|
|
806
|
-
className: 'mark',
|
|
807
|
-
textContent: '⁜'
|
|
808
|
-
}));
|
|
840
|
+
}, pillText, // The Obelism mark (⁜), drawn: the glyph sits low in most fonts.
|
|
841
|
+
mark(doc));
|
|
809
842
|
// Someone signed in who may only read: a note that drafts show, and a
|
|
810
843
|
// way out.
|
|
811
844
|
const viewing = element(doc, 'span', {
|
|
@@ -870,6 +903,12 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
870
903
|
className: 'action chip',
|
|
871
904
|
type: 'button'
|
|
872
905
|
}, icon(doc, 'newPage'), labels.newPage);
|
|
906
|
+
// A product the site marks (editableProduct) without a page of its own:
|
|
907
|
+
// one click makes its product page, which the page then shows.
|
|
908
|
+
const addProduct = element(doc, 'button', {
|
|
909
|
+
className: 'action chip product',
|
|
910
|
+
type: 'button'
|
|
911
|
+
}, icon(doc, 'newPage'), labels.addProductPage);
|
|
873
912
|
const cancelNew = element(doc, 'button', {
|
|
874
913
|
type: 'button',
|
|
875
914
|
title: labels.newPageCancel
|
|
@@ -919,7 +958,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
919
958
|
});
|
|
920
959
|
const toolbar = element(doc, 'div', {
|
|
921
960
|
className: 'toolbar'
|
|
922
|
-
}, scope, newScope, modes, undo, newPage, element(doc, 'span', {
|
|
961
|
+
}, scope, newScope, modes, undo, addProduct, newPage, element(doc, 'span', {
|
|
923
962
|
className: 'spacer'
|
|
924
963
|
}), minimize, close, divider, send);
|
|
925
964
|
// The pages (on the site): a chip naming this page, opening a search
|
|
@@ -998,6 +1037,95 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
998
1037
|
shadow.append(element(doc, 'style', {
|
|
999
1038
|
textContent: CSS
|
|
1000
1039
|
}), root);
|
|
1040
|
+
// Dragged sideways, the box moves to the left, the middle or the right
|
|
1041
|
+
// of the screen, whichever third it is let go (or flicked) in; this
|
|
1042
|
+
// browser remembers where. From the pill, or the open box's bars, not its
|
|
1043
|
+
// fields and buttons.
|
|
1044
|
+
const win = doc.defaultView;
|
|
1045
|
+
const readSide = ()=>{
|
|
1046
|
+
try {
|
|
1047
|
+
const side = win?.localStorage.getItem(SIDE_KEY);
|
|
1048
|
+
return side === 'left' || side === 'right' ? side : 'center';
|
|
1049
|
+
} catch {
|
|
1050
|
+
return 'center';
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
const placeAt = (side)=>{
|
|
1054
|
+
if (side === 'center') delete root.dataset.side;
|
|
1055
|
+
else root.dataset.side = side;
|
|
1056
|
+
};
|
|
1057
|
+
placeAt(readSide());
|
|
1058
|
+
let drag = null;
|
|
1059
|
+
// A drag that ends on the pill isn't a click on it.
|
|
1060
|
+
let dragged = false;
|
|
1061
|
+
root.addEventListener('pointerdown', (event)=>{
|
|
1062
|
+
dragged = false;
|
|
1063
|
+
if (event.button !== 0 || !event.isPrimary) return;
|
|
1064
|
+
const target = event.target;
|
|
1065
|
+
const control = target.closest('button, input, textarea, iframe, a, label, .pages, .form');
|
|
1066
|
+
if (control && control !== pill) return;
|
|
1067
|
+
const { left, right } = root.getBoundingClientRect();
|
|
1068
|
+
drag = {
|
|
1069
|
+
id: event.pointerId,
|
|
1070
|
+
startX: event.clientX,
|
|
1071
|
+
x: event.clientX,
|
|
1072
|
+
velocity: 0,
|
|
1073
|
+
time: event.timeStamp,
|
|
1074
|
+
moved: false,
|
|
1075
|
+
min: Math.min(0, EDGE_PX - left),
|
|
1076
|
+
max: Math.max(0, (win?.innerWidth ?? 0) - EDGE_PX - right)
|
|
1077
|
+
};
|
|
1078
|
+
});
|
|
1079
|
+
root.addEventListener('pointermove', (event)=>{
|
|
1080
|
+
if (!drag || event.pointerId !== drag.id) return;
|
|
1081
|
+
const dx = event.clientX - drag.startX;
|
|
1082
|
+
if (!drag.moved) {
|
|
1083
|
+
if (Math.abs(dx) < DRAG_THRESHOLD_PX) return;
|
|
1084
|
+
drag.moved = true;
|
|
1085
|
+
root.classList.add('dragging');
|
|
1086
|
+
try {
|
|
1087
|
+
root.setPointerCapture(event.pointerId);
|
|
1088
|
+
} catch {}
|
|
1089
|
+
}
|
|
1090
|
+
const elapsed = event.timeStamp - drag.time;
|
|
1091
|
+
if (elapsed > 0) drag.velocity = (event.clientX - drag.x) / elapsed;
|
|
1092
|
+
drag.x = event.clientX;
|
|
1093
|
+
drag.time = event.timeStamp;
|
|
1094
|
+
// Past the edge, a third as far.
|
|
1095
|
+
const clamped = Math.min(Math.max(dx, drag.min), drag.max);
|
|
1096
|
+
root.style.translate = `${clamped + (dx - clamped) / 3}px 0`;
|
|
1097
|
+
});
|
|
1098
|
+
const drop = (event)=>{
|
|
1099
|
+
if (!drag || event.pointerId !== drag.id) return;
|
|
1100
|
+
const { moved, x, velocity, time } = drag;
|
|
1101
|
+
drag = null;
|
|
1102
|
+
if (!moved) return;
|
|
1103
|
+
dragged = true;
|
|
1104
|
+
// Springs from where it was let go to its new place.
|
|
1105
|
+
const before = root.getBoundingClientRect().left;
|
|
1106
|
+
const width = win?.innerWidth ?? 0;
|
|
1107
|
+
const flick = event.timeStamp - time > FLICK_STALE_MS ? 0 : Math.min(Math.max(velocity * FLICK_MS, -FLICK_MAX_PX), FLICK_MAX_PX);
|
|
1108
|
+
const projected = x + flick;
|
|
1109
|
+
const side = projected < width / 3 ? 'left' : projected > width * 2 / 3 ? 'right' : 'center';
|
|
1110
|
+
placeAt(side);
|
|
1111
|
+
root.style.translate = '';
|
|
1112
|
+
const after = root.getBoundingClientRect().left;
|
|
1113
|
+
root.style.translate = `${before - after}px 0`;
|
|
1114
|
+
void root.offsetWidth;
|
|
1115
|
+
root.classList.remove('dragging');
|
|
1116
|
+
root.style.translate = '';
|
|
1117
|
+
try {
|
|
1118
|
+
win?.localStorage.setItem(SIDE_KEY, side);
|
|
1119
|
+
} catch {}
|
|
1120
|
+
};
|
|
1121
|
+
root.addEventListener('pointerup', drop);
|
|
1122
|
+
root.addEventListener('pointercancel', drop);
|
|
1123
|
+
root.addEventListener('click', (event)=>{
|
|
1124
|
+
if (!dragged) return;
|
|
1125
|
+
dragged = false;
|
|
1126
|
+
event.preventDefault();
|
|
1127
|
+
event.stopPropagation();
|
|
1128
|
+
}, true);
|
|
1001
1129
|
let open = false;
|
|
1002
1130
|
let minimized = false;
|
|
1003
1131
|
let creating = false;
|
|
@@ -1030,7 +1158,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1030
1158
|
// A page of the site that isn't an entry (no `editable(entry)`, like a
|
|
1031
1159
|
// hand-written /about) has nothing to edit: only New page.
|
|
1032
1160
|
const pageless = site && bridge.entryId === null;
|
|
1033
|
-
|
|
1161
|
+
// …unless it shows a product: then Add a product page first.
|
|
1162
|
+
const productHere = pageless && canCreate && bridge.product !== null;
|
|
1163
|
+
const onlyNew = pageless && canCreate && !productHere;
|
|
1034
1164
|
if (!canCreate) creating = false;
|
|
1035
1165
|
if (onlyNew) creating = true;
|
|
1036
1166
|
if (creating || pageless || !site) form = false;
|
|
@@ -1038,16 +1168,19 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1038
1168
|
const showForm = open && available && form;
|
|
1039
1169
|
if (showForm && !formHandle) mountForm();
|
|
1040
1170
|
else if (!showForm && formHandle) unmountForm();
|
|
1041
|
-
|
|
1171
|
+
const offerProduct = productHere && !creating;
|
|
1172
|
+
pillText.textContent = offerProduct ? labels.addProductPage : onlyNew ? labels.newPage : labels.open;
|
|
1042
1173
|
cancelNew.hidden = onlyNew;
|
|
1043
|
-
scope.hidden = creating;
|
|
1174
|
+
scope.hidden = creating || offerProduct;
|
|
1044
1175
|
newScope.hidden = !creating;
|
|
1176
|
+
addProduct.hidden = !offerProduct;
|
|
1177
|
+
addProduct.disabled = busy;
|
|
1045
1178
|
newPage.hidden = creating || form || !canCreate;
|
|
1046
1179
|
newPage.disabled = busy;
|
|
1047
1180
|
if (minimized) picking = false;
|
|
1048
1181
|
pathRow.hidden = !creating || picking || minimized;
|
|
1049
1182
|
pathInput.disabled = busy;
|
|
1050
|
-
input.hidden = form || picking || minimized;
|
|
1183
|
+
input.hidden = form || picking || minimized || offerProduct;
|
|
1051
1184
|
formBox.hidden = !form || picking || minimized;
|
|
1052
1185
|
formBox.classList.toggle('loading', formLoading);
|
|
1053
1186
|
toolbar.hidden = picking;
|
|
@@ -1067,8 +1200,8 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1067
1200
|
undo.hidden = creating || !state.canUndo;
|
|
1068
1201
|
undo.disabled = busy;
|
|
1069
1202
|
// The form applies edits as they are made.
|
|
1070
|
-
send.hidden = form || minimized;
|
|
1071
|
-
divider.hidden = form || minimized;
|
|
1203
|
+
send.hidden = form || minimized || offerProduct;
|
|
1204
|
+
divider.hidden = form || minimized || offerProduct;
|
|
1072
1205
|
const toggleLabel = minimized ? labels.expand : labels.minimize;
|
|
1073
1206
|
minimize.title = toggleLabel;
|
|
1074
1207
|
minimize.setAttribute('aria-label', toggleLabel);
|
|
@@ -1091,7 +1224,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1091
1224
|
pageChipText.textContent = pages?.find(({ entryId })=>entryId === bridge.entryId)?.name ?? labels.pages;
|
|
1092
1225
|
const loadingForm = form && formLoading && !picking;
|
|
1093
1226
|
const working = state.prompting || loadingForm;
|
|
1094
|
-
const note = state.prompting ? creating ? labels.creating : labels.working : loadingForm ? labels.formLoading : message?.text ?? (site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1227
|
+
const note = state.prompting ? creating ? labels.creating : offerProduct ? labels.addingProductPage : labels.working : loadingForm ? labels.formLoading : message?.text ?? (offerProduct ? labels.productPageHint : site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1095
1228
|
status.textContent = note;
|
|
1096
1229
|
status.hidden = !note || minimized;
|
|
1097
1230
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
@@ -1295,12 +1428,35 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1295
1428
|
refresh();
|
|
1296
1429
|
if (!minimized) (form ? minimize : input).focus();
|
|
1297
1430
|
});
|
|
1431
|
+
// Any other button of the minimized box expands it first (capture, so
|
|
1432
|
+
// its own handler then sees the box open), e.g. the pages or New page.
|
|
1433
|
+
panel.addEventListener('click', (event)=>{
|
|
1434
|
+
if (!minimized) return;
|
|
1435
|
+
const button = event.target.closest('button');
|
|
1436
|
+
if (!button || button === minimize || button === close) return;
|
|
1437
|
+
minimized = false;
|
|
1438
|
+
refresh();
|
|
1439
|
+
}, true);
|
|
1298
1440
|
save.addEventListener('click', ()=>void store('save'));
|
|
1299
1441
|
publish.addEventListener('click', ()=>void store('publish'));
|
|
1300
1442
|
signOut.addEventListener('click', ()=>bridge.signOut());
|
|
1301
1443
|
pillSignOut.addEventListener('click', ()=>bridge.signOut());
|
|
1302
1444
|
clearBlock.addEventListener('click', ()=>bridge.select(null));
|
|
1303
1445
|
newPage.addEventListener('click', ()=>setCreating(true));
|
|
1446
|
+
addProduct.addEventListener('click', async ()=>{
|
|
1447
|
+
message = null;
|
|
1448
|
+
try {
|
|
1449
|
+
// The bridge reloads the page; this shows until it does.
|
|
1450
|
+
await bridge.createProductPage();
|
|
1451
|
+
message = {
|
|
1452
|
+
text: labels.addedProductPage,
|
|
1453
|
+
error: false
|
|
1454
|
+
};
|
|
1455
|
+
} catch (error) {
|
|
1456
|
+
message = failure(error);
|
|
1457
|
+
}
|
|
1458
|
+
refresh();
|
|
1459
|
+
});
|
|
1304
1460
|
cancelNew.addEventListener('click', ()=>setCreating(false));
|
|
1305
1461
|
promptMode.addEventListener('click', ()=>setForm(false));
|
|
1306
1462
|
formMode.addEventListener('click', ()=>setForm(true));
|
|
@@ -1372,13 +1528,15 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1372
1528
|
// Messages are only exchanged with the URL's origin, and only with the
|
|
1373
1529
|
// iframe's window:
|
|
1374
1530
|
// - form → bridge: { source: 'obelism-content-form', type: 'ready' |
|
|
1375
|
-
// 'change' | 'error' | 'height', content?, message?,
|
|
1376
|
-
// `
|
|
1377
|
-
//
|
|
1531
|
+
// 'loaded' | 'change' | 'error' | 'height', loading?, content?, message?,
|
|
1532
|
+
// height? } — `ready` with `loading: true` when the form still loads the
|
|
1533
|
+
// entry after it and says `loaded` once it shows (a CMS from before says
|
|
1534
|
+
// only `ready`), `change` carries the whole entry content after an edit,
|
|
1535
|
+
// `height` the form's own height in px, which the iframe takes (up to 60vh)
|
|
1378
1536
|
// - bridge → form: { source: 'obelism-content-bridge', type: 'content',
|
|
1379
1537
|
// entryId, content, locale, selectedUid }
|
|
1380
1538
|
const FORM_SOURCE = 'obelism-content-form';
|
|
1381
|
-
// How long the form may take to
|
|
1539
|
+
// How long the form may take to show.
|
|
1382
1540
|
const FORM_READY_TIMEOUT_MS = 30_000;
|
|
1383
1541
|
const isObject = (value)=>!!value && typeof value === 'object' && !Array.isArray(value);
|
|
1384
1542
|
// Mounts the form at `url` in `container`. The URL is single use: mount a
|
|
@@ -1396,6 +1554,7 @@ const mountFormFrame = (win, container, url, title, handlers)=>{
|
|
|
1396
1554
|
iframe.title = title;
|
|
1397
1555
|
iframe.src = url;
|
|
1398
1556
|
let ready = false;
|
|
1557
|
+
let shown = false;
|
|
1399
1558
|
let latest = null;
|
|
1400
1559
|
const post = ()=>{
|
|
1401
1560
|
if (!ready || !latest) return;
|
|
@@ -1406,8 +1565,13 @@ const mountFormFrame = (win, container, url, title, handlers)=>{
|
|
|
1406
1565
|
}, origin);
|
|
1407
1566
|
};
|
|
1408
1567
|
const timer = setTimeout(()=>{
|
|
1409
|
-
if (!
|
|
1568
|
+
if (!shown) handlers.onError('The form did not open');
|
|
1410
1569
|
}, FORM_READY_TIMEOUT_MS);
|
|
1570
|
+
const show = ()=>{
|
|
1571
|
+
shown = true;
|
|
1572
|
+
clearTimeout(timer);
|
|
1573
|
+
handlers.onReady();
|
|
1574
|
+
};
|
|
1411
1575
|
const onMessage = (event)=>{
|
|
1412
1576
|
if (event.origin !== origin || !iframe.contentWindow || event.source !== iframe.contentWindow) {
|
|
1413
1577
|
return;
|
|
@@ -1417,9 +1581,12 @@ const mountFormFrame = (win, container, url, title, handlers)=>{
|
|
|
1417
1581
|
if (data.type === 'ready') {
|
|
1418
1582
|
// Again after the form reloads itself: it gets the content again.
|
|
1419
1583
|
ready = true;
|
|
1420
|
-
clearTimeout(timer);
|
|
1421
|
-
handlers.onReady();
|
|
1422
1584
|
post();
|
|
1585
|
+
// Until the form loaded the entry, the box's own loading state
|
|
1586
|
+
// stands in for the form's.
|
|
1587
|
+
if (data.loading !== true) show();
|
|
1588
|
+
} else if (data.type === 'loaded') {
|
|
1589
|
+
if (ready) show();
|
|
1423
1590
|
} else if (data.type === 'change' && isObject(data.content)) {
|
|
1424
1591
|
handlers.onChange(data.content, typeof data.entryId === 'string' ? data.entryId : undefined);
|
|
1425
1592
|
} else if (data.type === 'height') {
|
|
@@ -1481,7 +1648,7 @@ const FORM_BURST_MS = 1000;
|
|
|
1481
1648
|
// How long the page waits for the form's edits to settle before it shows
|
|
1482
1649
|
// them.
|
|
1483
1650
|
const FORM_RENDER_MS = 300;
|
|
1484
|
-
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}
|
|
1651
|
+
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath } = {})=>{
|
|
1485
1652
|
const doc = win.document;
|
|
1486
1653
|
const emitter = createEmitter();
|
|
1487
1654
|
const cleanup = [];
|
|
@@ -1491,6 +1658,7 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1491
1658
|
// Entries changed here since the last publish.
|
|
1492
1659
|
const touched = new Set();
|
|
1493
1660
|
let session = null;
|
|
1661
|
+
const productPath = (handle, locale)=>ownProductPath ? ownProductPath(handle, locale) : (session?.productPath ?? '/products/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1494
1662
|
// The open form's, if any; and when the form last changed content, for
|
|
1495
1663
|
// undo steps (-Infinity: the next edit starts a new step).
|
|
1496
1664
|
let closeForm = null;
|
|
@@ -1535,6 +1703,16 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1535
1703
|
return data;
|
|
1536
1704
|
};
|
|
1537
1705
|
const pageEntryId = ()=>doc.querySelector(`[${ENTRY_ATTRIBUTE}]`)?.getAttribute(ENTRY_ATTRIBUTE) ?? null;
|
|
1706
|
+
// The product the page shows (editableProduct), if it marks one.
|
|
1707
|
+
const pageProduct = ()=>{
|
|
1708
|
+
const element = doc.querySelector(`[${PRODUCT_ATTRIBUTE}]`);
|
|
1709
|
+
const id = element?.getAttribute(PRODUCT_ATTRIBUTE);
|
|
1710
|
+
const handle = element?.getAttribute(PRODUCT_HANDLE_ATTRIBUTE);
|
|
1711
|
+
return id && handle ? {
|
|
1712
|
+
id,
|
|
1713
|
+
handle
|
|
1714
|
+
} : null;
|
|
1715
|
+
};
|
|
1538
1716
|
const entryFor = (uid)=>{
|
|
1539
1717
|
const block = uid ? doc.querySelector(blockSelector(uid)) : null;
|
|
1540
1718
|
return block?.closest(`[${ENTRY_ATTRIBUTE}]`)?.getAttribute(ENTRY_ATTRIBUTE) ?? pageEntryId();
|
|
@@ -1642,6 +1820,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1642
1820
|
get entryId () {
|
|
1643
1821
|
return pageEntryId();
|
|
1644
1822
|
},
|
|
1823
|
+
get product () {
|
|
1824
|
+
return pageProduct();
|
|
1825
|
+
},
|
|
1645
1826
|
environment: null,
|
|
1646
1827
|
on: emitter.on,
|
|
1647
1828
|
getState: ()=>state,
|
|
@@ -1711,6 +1892,34 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1711
1892
|
});
|
|
1712
1893
|
}
|
|
1713
1894
|
},
|
|
1895
|
+
async createProductPage (product = pageProduct() ?? undefined) {
|
|
1896
|
+
if (!product) {
|
|
1897
|
+
throw new Error('Nothing on this page is marked as a product: add editableProduct(product)');
|
|
1898
|
+
}
|
|
1899
|
+
if (!has('create')) throw new Error('You may not add pages here');
|
|
1900
|
+
if (state.unsaved) {
|
|
1901
|
+
throw new Error('Save or undo your changes before adding a page');
|
|
1902
|
+
}
|
|
1903
|
+
setState({
|
|
1904
|
+
prompting: true
|
|
1905
|
+
});
|
|
1906
|
+
try {
|
|
1907
|
+
const made = await api('product-pages', {
|
|
1908
|
+
product: {
|
|
1909
|
+
id: product.id,
|
|
1910
|
+
handle: product.handle
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
// The site's product route finds its page now (drafts, while
|
|
1914
|
+
// editing): show it.
|
|
1915
|
+
win.location.reload();
|
|
1916
|
+
return made;
|
|
1917
|
+
} finally{
|
|
1918
|
+
setState({
|
|
1919
|
+
prompting: false
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
},
|
|
1714
1923
|
async view (options = {}) {
|
|
1715
1924
|
const { uid, entryId } = target(options.uid);
|
|
1716
1925
|
const entry = await load(entryId);
|
|
@@ -1864,7 +2073,8 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1864
2073
|
contentType: page.contentType,
|
|
1865
2074
|
status: page.status,
|
|
1866
2075
|
path,
|
|
1867
|
-
url: pagePath(path, code)
|
|
2076
|
+
url: page.product ? productPath(page.product.handle, code) : pagePath(path, code),
|
|
2077
|
+
product: page.product ?? null
|
|
1868
2078
|
}
|
|
1869
2079
|
];
|
|
1870
2080
|
});
|
|
@@ -2009,7 +2219,7 @@ const peekContentBridge = ()=>typeof window === 'undefined' ? null : window[KEY]
|
|
|
2009
2219
|
// if (bridge.isEditing) bridge.on('update', ({ entry }) => render(entry))
|
|
2010
2220
|
//
|
|
2011
2221
|
// The first call's options win: there is one bridge per page.
|
|
2012
|
-
const getContentBridge = ({ url, prompt = true, pagePath } = {})=>{
|
|
2222
|
+
const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
2013
2223
|
if (typeof window === 'undefined') return SERVER_BRIDGE;
|
|
2014
2224
|
const win = window;
|
|
2015
2225
|
if (win[KEY]) return win[KEY];
|
|
@@ -2022,7 +2232,8 @@ const getContentBridge = ({ url, prompt = true, pagePath } = {})=>{
|
|
|
2022
2232
|
// own `/cms/login` (@obelism/content/site).
|
|
2023
2233
|
const sitePath = bridge.isEditing || win.parent !== win ? null : readSiteEditing(win.document);
|
|
2024
2234
|
if (sitePath) bridge = createSiteBridge(win, sitePath, {
|
|
2025
|
-
pagePath
|
|
2235
|
+
pagePath,
|
|
2236
|
+
productPath
|
|
2026
2237
|
});
|
|
2027
2238
|
if (bridge.isEditing && prompt) {
|
|
2028
2239
|
const unmount = mountPromptBox(win.document, bridge, prompt === true ? {} : prompt);
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RichTextFormat, E as Entry, a as RedirectList, b as Redirect, c as EntryList, M as ModelFile, A as Asset, B as Block, I as ImproveBlock,
|
|
2
|
-
export { C as ContentTypeDefinition,
|
|
1
|
+
import { R as RichTextFormat, E as Entry, a as RedirectList, b as Redirect, c as EntryList, M as ModelFile, A as Asset, B as Block, I as ImproveBlock, S as ShopifyItem, L as LinkTarget, d as Link, e as EntryStub, f as RichTextNode } from './types-mtjco3a5.js';
|
|
2
|
+
export { C as ContentTypeDefinition, g as ContentTypeKind, h as Environment, F as FieldDefinition, i as FieldType, j as RichTextDocument, k as RichTextMark } from './types-mtjco3a5.js';
|
|
3
3
|
|
|
4
4
|
type ContentClientOptions = {
|
|
5
5
|
token: string;
|
|
@@ -60,6 +60,8 @@ declare const DEFAULT_URL = "https://content.obelism.studio";
|
|
|
60
60
|
|
|
61
61
|
declare const UID_ATTRIBUTE = "data-cms-uid";
|
|
62
62
|
declare const ENTRY_ATTRIBUTE = "data-cms-entry";
|
|
63
|
+
declare const PRODUCT_ATTRIBUTE = "data-cms-product";
|
|
64
|
+
declare const PRODUCT_HANDLE_ATTRIBUTE = "data-cms-product-handle";
|
|
63
65
|
type Editable = {
|
|
64
66
|
'data-cms-uid'?: string;
|
|
65
67
|
'data-cms-entry'?: string;
|
|
@@ -70,6 +72,14 @@ declare const editable: (target: {
|
|
|
70
72
|
id: string;
|
|
71
73
|
fields: unknown;
|
|
72
74
|
} | null | undefined) => Editable;
|
|
75
|
+
type EditableProduct = {
|
|
76
|
+
'data-cms-product'?: string;
|
|
77
|
+
'data-cms-product-handle'?: string;
|
|
78
|
+
};
|
|
79
|
+
declare const editableProduct: (product: {
|
|
80
|
+
id: string;
|
|
81
|
+
handle: string;
|
|
82
|
+
} | null | undefined) => EditableProduct;
|
|
73
83
|
|
|
74
84
|
declare class ContentApiError extends Error {
|
|
75
85
|
readonly status: number;
|
|
@@ -98,8 +108,9 @@ declare const pickImproveVariant: <TBlock extends Block>(block: ImproveBlock<TBl
|
|
|
98
108
|
|
|
99
109
|
type LinkHrefOptions = {
|
|
100
110
|
url?: ((path: string) => string) | undefined;
|
|
111
|
+
product?: ((product: ShopifyItem, page: LinkTarget | null) => string) | undefined;
|
|
101
112
|
};
|
|
102
|
-
declare const linkHref: (link: Link | null | undefined, { url }?: LinkHrefOptions) => string | null;
|
|
113
|
+
declare const linkHref: (link: Link | null | undefined, { url, product, }?: LinkHrefOptions) => string | null;
|
|
103
114
|
|
|
104
115
|
declare const PREVIEW_PARAMS: {
|
|
105
116
|
readonly preview: "cms_preview";
|
|
@@ -184,6 +195,6 @@ type SitemapOptions = LocalizedUrlOptions & {
|
|
|
184
195
|
};
|
|
185
196
|
declare const sitemapXml: (entries: Iterable<Page>, { exclude, ...options }: SitemapOptions) => string;
|
|
186
197
|
|
|
187
|
-
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, ModelFile, PREVIEW_PARAMS, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
198
|
+
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, LinkTarget, ModelFile, PREVIEW_PARAMS, PRODUCT_ATTRIBUTE, PRODUCT_HANDLE_ATTRIBUTE, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, editableProduct, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
188
199
|
export type { AlternateLink, ContentClientOptions, EntriesQuery, ImageTransform, LinkHrefOptions, LocalizedUrlOptions, PageLookup, PreviewParams, RedirectsQuery, RequestOptions, RichTextHtmlOptions, ShopifyCollection, ShopifyImage, ShopifyMoney, ShopifyProduct, ShopifyStorefrontOptions, SitemapOptions };
|
|
189
200
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,gBAAgB;AACrB,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA,aAAa,MAAM,SAAS,gBAAgB,YAAY,gBAAgB;AACxE;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA,KAAK,UAAU,gBAAgB,KAAK,GAAG,KAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO,CAAC,UAAU;AAC1G,oDAAoD,cAAc,KAAK,OAAO,CAAC,YAAY;AAC3F,4BAA4B,IAAI,CAAC,cAAc,YAAY,cAAc,CAAC,QAAQ;AAClF,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,wEAAwE,YAAY,KAAK,OAAO,CAAC,SAAS;AACvJ,mCAAmC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,wBAAwB,OAAO;AAC1G,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;ACtDA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,KAAK,QAAQ;AACb;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RichTextFormat, E as Entry, a as RedirectList, b as Redirect, c as EntryList, M as ModelFile, A as Asset, B as Block, I as ImproveBlock,
|
|
2
|
-
export { C as ContentTypeDefinition,
|
|
1
|
+
import { R as RichTextFormat, E as Entry, a as RedirectList, b as Redirect, c as EntryList, M as ModelFile, A as Asset, B as Block, I as ImproveBlock, S as ShopifyItem, L as LinkTarget, d as Link, e as EntryStub, f as RichTextNode } from './types-mtjco3a5.js';
|
|
2
|
+
export { C as ContentTypeDefinition, g as ContentTypeKind, h as Environment, F as FieldDefinition, i as FieldType, j as RichTextDocument, k as RichTextMark } from './types-mtjco3a5.js';
|
|
3
3
|
|
|
4
4
|
type ContentClientOptions = {
|
|
5
5
|
token: string;
|
|
@@ -60,6 +60,8 @@ declare const DEFAULT_URL = "https://content.obelism.studio";
|
|
|
60
60
|
|
|
61
61
|
declare const UID_ATTRIBUTE = "data-cms-uid";
|
|
62
62
|
declare const ENTRY_ATTRIBUTE = "data-cms-entry";
|
|
63
|
+
declare const PRODUCT_ATTRIBUTE = "data-cms-product";
|
|
64
|
+
declare const PRODUCT_HANDLE_ATTRIBUTE = "data-cms-product-handle";
|
|
63
65
|
type Editable = {
|
|
64
66
|
'data-cms-uid'?: string;
|
|
65
67
|
'data-cms-entry'?: string;
|
|
@@ -70,6 +72,14 @@ declare const editable: (target: {
|
|
|
70
72
|
id: string;
|
|
71
73
|
fields: unknown;
|
|
72
74
|
} | null | undefined) => Editable;
|
|
75
|
+
type EditableProduct = {
|
|
76
|
+
'data-cms-product'?: string;
|
|
77
|
+
'data-cms-product-handle'?: string;
|
|
78
|
+
};
|
|
79
|
+
declare const editableProduct: (product: {
|
|
80
|
+
id: string;
|
|
81
|
+
handle: string;
|
|
82
|
+
} | null | undefined) => EditableProduct;
|
|
73
83
|
|
|
74
84
|
declare class ContentApiError extends Error {
|
|
75
85
|
readonly status: number;
|
|
@@ -98,8 +108,9 @@ declare const pickImproveVariant: <TBlock extends Block>(block: ImproveBlock<TBl
|
|
|
98
108
|
|
|
99
109
|
type LinkHrefOptions = {
|
|
100
110
|
url?: ((path: string) => string) | undefined;
|
|
111
|
+
product?: ((product: ShopifyItem, page: LinkTarget | null) => string) | undefined;
|
|
101
112
|
};
|
|
102
|
-
declare const linkHref: (link: Link | null | undefined, { url }?: LinkHrefOptions) => string | null;
|
|
113
|
+
declare const linkHref: (link: Link | null | undefined, { url, product, }?: LinkHrefOptions) => string | null;
|
|
103
114
|
|
|
104
115
|
declare const PREVIEW_PARAMS: {
|
|
105
116
|
readonly preview: "cms_preview";
|
|
@@ -184,6 +195,6 @@ type SitemapOptions = LocalizedUrlOptions & {
|
|
|
184
195
|
};
|
|
185
196
|
declare const sitemapXml: (entries: Iterable<Page>, { exclude, ...options }: SitemapOptions) => string;
|
|
186
197
|
|
|
187
|
-
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, ModelFile, PREVIEW_PARAMS, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
198
|
+
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, LinkTarget, ModelFile, PREVIEW_PARAMS, PRODUCT_ATTRIBUTE, PRODUCT_HANDLE_ATTRIBUTE, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, editableProduct, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
188
199
|
export type { AlternateLink, ContentClientOptions, EntriesQuery, ImageTransform, LinkHrefOptions, LocalizedUrlOptions, PageLookup, PreviewParams, RedirectsQuery, RequestOptions, RichTextHtmlOptions, ShopifyCollection, ShopifyImage, ShopifyMoney, ShopifyProduct, ShopifyStorefrontOptions, SitemapOptions };
|
|
189
200
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,gBAAgB;AACrB,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA,aAAa,MAAM,SAAS,gBAAgB,YAAY,gBAAgB;AACxE;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA,KAAK,UAAU,gBAAgB,KAAK,GAAG,KAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO,CAAC,UAAU;AAC1G,oDAAoD,cAAc,KAAK,OAAO,CAAC,YAAY;AAC3F,4BAA4B,IAAI,CAAC,cAAc,YAAY,cAAc,CAAC,QAAQ;AAClF,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,wEAAwE,YAAY,KAAK,OAAO,CAAC,SAAS;AACvJ,mCAAmC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,wBAAwB,OAAO;AAC1G,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;ACtDA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,KAAK,QAAQ;AACb;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":"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","names":[]}
|