@obelism/content 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -0
- package/dist/bin/content.js +32 -1
- 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 +3 -3
- package/dist/bridge.js +90 -14
- package/dist/bridge.mjs +90 -14
- package/dist/index.d.mts +64 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +64 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +90 -1
- package/dist/index.mjs +83 -2
- 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-m3j4tltp.d.ts → types-mtjco3a5.d.ts} +40 -2
- package/dist/types-mtjco3a5.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/types-m3j4tltp.d.ts.map +0 -1
package/dist/bridge.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
2
|
|
|
3
|
-
var preview = require('./preview-
|
|
3
|
+
var preview = require('./preview-ijk3ixwb.js');
|
|
4
4
|
var site = require('./site.js');
|
|
5
5
|
var config = require('./config-ci2hxmas.js');
|
|
6
6
|
|
|
@@ -229,6 +229,7 @@ const onlyWhileEditingSite = ()=>Promise.reject(new Error('Only while signed in
|
|
|
229
229
|
const INERT_METHODS = {
|
|
230
230
|
prompt: inertPrompt,
|
|
231
231
|
createPage: ()=>Promise.reject(new Error('New pages are made on the site itself')),
|
|
232
|
+
createProductPage: ()=>Promise.reject(new Error('Product pages are made on the site itself')),
|
|
232
233
|
view: onlyWhileEditingSite,
|
|
233
234
|
applyJson: onlyWhileEditingSite,
|
|
234
235
|
openForm: (_container, options = {})=>{
|
|
@@ -286,6 +287,7 @@ const createBridge = (win, cmsOrigin)=>{
|
|
|
286
287
|
mode: isEditing ? 'editor' : null,
|
|
287
288
|
entryId: params.get(preview.PREVIEW_PARAMS.entry),
|
|
288
289
|
environment: params.get(preview.PREVIEW_PARAMS.environment),
|
|
290
|
+
product: null,
|
|
289
291
|
on: emitter.on,
|
|
290
292
|
getState: ()=>state,
|
|
291
293
|
...INERT_METHODS,
|
|
@@ -478,6 +480,7 @@ const wrapScriptBridge = (script, params)=>{
|
|
|
478
480
|
mode: script.isEditing ? 'editor' : null,
|
|
479
481
|
entryId: script.entryId,
|
|
480
482
|
environment: params.get(preview.PREVIEW_PARAMS.environment),
|
|
483
|
+
product: null,
|
|
481
484
|
on: (event, listener)=>{
|
|
482
485
|
if (event === 'update' && !forwardingUpdates) {
|
|
483
486
|
forwardingUpdates = true;
|
|
@@ -537,7 +540,11 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
537
540
|
pagesEmpty: 'No pages match',
|
|
538
541
|
pageCurrent: 'This page',
|
|
539
542
|
pageDraft: 'Draft',
|
|
540
|
-
pageChanged: 'Changed'
|
|
543
|
+
pageChanged: 'Changed',
|
|
544
|
+
addProductPage: 'Add a product page',
|
|
545
|
+
addingProductPage: 'Making the product page…',
|
|
546
|
+
addedProductPage: 'Opening the product page…',
|
|
547
|
+
productPageHint: 'This product has no page yet. Add one for what the store doesn’t say.'
|
|
541
548
|
};
|
|
542
549
|
// Icons (Lucide), drawn in the text colour.
|
|
543
550
|
const ICONS = {
|
|
@@ -872,6 +879,12 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
872
879
|
className: 'action chip',
|
|
873
880
|
type: 'button'
|
|
874
881
|
}, icon(doc, 'newPage'), labels.newPage);
|
|
882
|
+
// A product the site marks (editableProduct) without a page of its own:
|
|
883
|
+
// one click makes its product page, which the page then shows.
|
|
884
|
+
const addProduct = element(doc, 'button', {
|
|
885
|
+
className: 'action chip product',
|
|
886
|
+
type: 'button'
|
|
887
|
+
}, icon(doc, 'newPage'), labels.addProductPage);
|
|
875
888
|
const cancelNew = element(doc, 'button', {
|
|
876
889
|
type: 'button',
|
|
877
890
|
title: labels.newPageCancel
|
|
@@ -921,7 +934,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
921
934
|
});
|
|
922
935
|
const toolbar = element(doc, 'div', {
|
|
923
936
|
className: 'toolbar'
|
|
924
|
-
}, scope, newScope, modes, undo, newPage, element(doc, 'span', {
|
|
937
|
+
}, scope, newScope, modes, undo, addProduct, newPage, element(doc, 'span', {
|
|
925
938
|
className: 'spacer'
|
|
926
939
|
}), minimize, close, divider, send);
|
|
927
940
|
// The pages (on the site): a chip naming this page, opening a search
|
|
@@ -1032,7 +1045,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1032
1045
|
// A page of the site that isn't an entry (no `editable(entry)`, like a
|
|
1033
1046
|
// hand-written /about) has nothing to edit: only New page.
|
|
1034
1047
|
const pageless = site && bridge.entryId === null;
|
|
1035
|
-
|
|
1048
|
+
// …unless it shows a product: then Add a product page first.
|
|
1049
|
+
const productHere = pageless && canCreate && bridge.product !== null;
|
|
1050
|
+
const onlyNew = pageless && canCreate && !productHere;
|
|
1036
1051
|
if (!canCreate) creating = false;
|
|
1037
1052
|
if (onlyNew) creating = true;
|
|
1038
1053
|
if (creating || pageless || !site) form = false;
|
|
@@ -1040,16 +1055,19 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1040
1055
|
const showForm = open && available && form;
|
|
1041
1056
|
if (showForm && !formHandle) mountForm();
|
|
1042
1057
|
else if (!showForm && formHandle) unmountForm();
|
|
1043
|
-
|
|
1058
|
+
const offerProduct = productHere && !creating;
|
|
1059
|
+
pillText.textContent = offerProduct ? labels.addProductPage : onlyNew ? labels.newPage : labels.open;
|
|
1044
1060
|
cancelNew.hidden = onlyNew;
|
|
1045
|
-
scope.hidden = creating;
|
|
1061
|
+
scope.hidden = creating || offerProduct;
|
|
1046
1062
|
newScope.hidden = !creating;
|
|
1063
|
+
addProduct.hidden = !offerProduct;
|
|
1064
|
+
addProduct.disabled = busy;
|
|
1047
1065
|
newPage.hidden = creating || form || !canCreate;
|
|
1048
1066
|
newPage.disabled = busy;
|
|
1049
1067
|
if (minimized) picking = false;
|
|
1050
1068
|
pathRow.hidden = !creating || picking || minimized;
|
|
1051
1069
|
pathInput.disabled = busy;
|
|
1052
|
-
input.hidden = form || picking || minimized;
|
|
1070
|
+
input.hidden = form || picking || minimized || offerProduct;
|
|
1053
1071
|
formBox.hidden = !form || picking || minimized;
|
|
1054
1072
|
formBox.classList.toggle('loading', formLoading);
|
|
1055
1073
|
toolbar.hidden = picking;
|
|
@@ -1069,8 +1087,8 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1069
1087
|
undo.hidden = creating || !state.canUndo;
|
|
1070
1088
|
undo.disabled = busy;
|
|
1071
1089
|
// The form applies edits as they are made.
|
|
1072
|
-
send.hidden = form || minimized;
|
|
1073
|
-
divider.hidden = form || minimized;
|
|
1090
|
+
send.hidden = form || minimized || offerProduct;
|
|
1091
|
+
divider.hidden = form || minimized || offerProduct;
|
|
1074
1092
|
const toggleLabel = minimized ? labels.expand : labels.minimize;
|
|
1075
1093
|
minimize.title = toggleLabel;
|
|
1076
1094
|
minimize.setAttribute('aria-label', toggleLabel);
|
|
@@ -1093,7 +1111,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1093
1111
|
pageChipText.textContent = pages?.find(({ entryId })=>entryId === bridge.entryId)?.name ?? labels.pages;
|
|
1094
1112
|
const loadingForm = form && formLoading && !picking;
|
|
1095
1113
|
const working = state.prompting || loadingForm;
|
|
1096
|
-
const note = state.prompting ? creating ? labels.creating : labels.working : loadingForm ? labels.formLoading : message?.text ?? (site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1114
|
+
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 : '');
|
|
1097
1115
|
status.textContent = note;
|
|
1098
1116
|
status.hidden = !note || minimized;
|
|
1099
1117
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
@@ -1303,6 +1321,20 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1303
1321
|
pillSignOut.addEventListener('click', ()=>bridge.signOut());
|
|
1304
1322
|
clearBlock.addEventListener('click', ()=>bridge.select(null));
|
|
1305
1323
|
newPage.addEventListener('click', ()=>setCreating(true));
|
|
1324
|
+
addProduct.addEventListener('click', async ()=>{
|
|
1325
|
+
message = null;
|
|
1326
|
+
try {
|
|
1327
|
+
// The bridge reloads the page; this shows until it does.
|
|
1328
|
+
await bridge.createProductPage();
|
|
1329
|
+
message = {
|
|
1330
|
+
text: labels.addedProductPage,
|
|
1331
|
+
error: false
|
|
1332
|
+
};
|
|
1333
|
+
} catch (error) {
|
|
1334
|
+
message = failure(error);
|
|
1335
|
+
}
|
|
1336
|
+
refresh();
|
|
1337
|
+
});
|
|
1306
1338
|
cancelNew.addEventListener('click', ()=>setCreating(false));
|
|
1307
1339
|
promptMode.addEventListener('click', ()=>setForm(false));
|
|
1308
1340
|
formMode.addEventListener('click', ()=>setForm(true));
|
|
@@ -1483,7 +1515,7 @@ const FORM_BURST_MS = 1000;
|
|
|
1483
1515
|
// How long the page waits for the form's edits to settle before it shows
|
|
1484
1516
|
// them.
|
|
1485
1517
|
const FORM_RENDER_MS = 300;
|
|
1486
|
-
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}
|
|
1518
|
+
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath } = {})=>{
|
|
1487
1519
|
const doc = win.document;
|
|
1488
1520
|
const emitter = createEmitter();
|
|
1489
1521
|
const cleanup = [];
|
|
@@ -1493,6 +1525,7 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1493
1525
|
// Entries changed here since the last publish.
|
|
1494
1526
|
const touched = new Set();
|
|
1495
1527
|
let session = null;
|
|
1528
|
+
const productPath = (handle, locale)=>ownProductPath ? ownProductPath(handle, locale) : (session?.productPath ?? '/products/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1496
1529
|
// The open form's, if any; and when the form last changed content, for
|
|
1497
1530
|
// undo steps (-Infinity: the next edit starts a new step).
|
|
1498
1531
|
let closeForm = null;
|
|
@@ -1537,6 +1570,16 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1537
1570
|
return data;
|
|
1538
1571
|
};
|
|
1539
1572
|
const pageEntryId = ()=>doc.querySelector(`[${preview.ENTRY_ATTRIBUTE}]`)?.getAttribute(preview.ENTRY_ATTRIBUTE) ?? null;
|
|
1573
|
+
// The product the page shows (editableProduct), if it marks one.
|
|
1574
|
+
const pageProduct = ()=>{
|
|
1575
|
+
const element = doc.querySelector(`[${preview.PRODUCT_ATTRIBUTE}]`);
|
|
1576
|
+
const id = element?.getAttribute(preview.PRODUCT_ATTRIBUTE);
|
|
1577
|
+
const handle = element?.getAttribute(preview.PRODUCT_HANDLE_ATTRIBUTE);
|
|
1578
|
+
return id && handle ? {
|
|
1579
|
+
id,
|
|
1580
|
+
handle
|
|
1581
|
+
} : null;
|
|
1582
|
+
};
|
|
1540
1583
|
const entryFor = (uid)=>{
|
|
1541
1584
|
const block = uid ? doc.querySelector(blockSelector(uid)) : null;
|
|
1542
1585
|
return block?.closest(`[${preview.ENTRY_ATTRIBUTE}]`)?.getAttribute(preview.ENTRY_ATTRIBUTE) ?? pageEntryId();
|
|
@@ -1644,6 +1687,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1644
1687
|
get entryId () {
|
|
1645
1688
|
return pageEntryId();
|
|
1646
1689
|
},
|
|
1690
|
+
get product () {
|
|
1691
|
+
return pageProduct();
|
|
1692
|
+
},
|
|
1647
1693
|
environment: null,
|
|
1648
1694
|
on: emitter.on,
|
|
1649
1695
|
getState: ()=>state,
|
|
@@ -1713,6 +1759,34 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1713
1759
|
});
|
|
1714
1760
|
}
|
|
1715
1761
|
},
|
|
1762
|
+
async createProductPage (product = pageProduct() ?? undefined) {
|
|
1763
|
+
if (!product) {
|
|
1764
|
+
throw new Error('Nothing on this page is marked as a product: add editableProduct(product)');
|
|
1765
|
+
}
|
|
1766
|
+
if (!has('create')) throw new Error('You may not add pages here');
|
|
1767
|
+
if (state.unsaved) {
|
|
1768
|
+
throw new Error('Save or undo your changes before adding a page');
|
|
1769
|
+
}
|
|
1770
|
+
setState({
|
|
1771
|
+
prompting: true
|
|
1772
|
+
});
|
|
1773
|
+
try {
|
|
1774
|
+
const made = await api('product-pages', {
|
|
1775
|
+
product: {
|
|
1776
|
+
id: product.id,
|
|
1777
|
+
handle: product.handle
|
|
1778
|
+
}
|
|
1779
|
+
});
|
|
1780
|
+
// The site's product route finds its page now (drafts, while
|
|
1781
|
+
// editing): show it.
|
|
1782
|
+
win.location.reload();
|
|
1783
|
+
return made;
|
|
1784
|
+
} finally{
|
|
1785
|
+
setState({
|
|
1786
|
+
prompting: false
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
},
|
|
1716
1790
|
async view (options = {}) {
|
|
1717
1791
|
const { uid, entryId } = target(options.uid);
|
|
1718
1792
|
const entry = await load(entryId);
|
|
@@ -1866,7 +1940,8 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1866
1940
|
contentType: page.contentType,
|
|
1867
1941
|
status: page.status,
|
|
1868
1942
|
path,
|
|
1869
|
-
url: pagePath(path, code)
|
|
1943
|
+
url: page.product ? productPath(page.product.handle, code) : pagePath(path, code),
|
|
1944
|
+
product: page.product ?? null
|
|
1870
1945
|
}
|
|
1871
1946
|
];
|
|
1872
1947
|
});
|
|
@@ -2011,7 +2086,7 @@ const peekContentBridge = ()=>typeof window === 'undefined' ? null : window[KEY]
|
|
|
2011
2086
|
// if (bridge.isEditing) bridge.on('update', ({ entry }) => render(entry))
|
|
2012
2087
|
//
|
|
2013
2088
|
// The first call's options win: there is one bridge per page.
|
|
2014
|
-
const getContentBridge = ({ url, prompt = true, pagePath } = {})=>{
|
|
2089
|
+
const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
2015
2090
|
if (typeof window === 'undefined') return SERVER_BRIDGE;
|
|
2016
2091
|
const win = window;
|
|
2017
2092
|
if (win[KEY]) return win[KEY];
|
|
@@ -2024,7 +2099,8 @@ const getContentBridge = ({ url, prompt = true, pagePath } = {})=>{
|
|
|
2024
2099
|
// own `/cms/login` (@obelism/content/site).
|
|
2025
2100
|
const sitePath = bridge.isEditing || win.parent !== win ? null : readSiteEditing(win.document);
|
|
2026
2101
|
if (sitePath) bridge = createSiteBridge(win, sitePath, {
|
|
2027
|
-
pagePath
|
|
2102
|
+
pagePath,
|
|
2103
|
+
productPath
|
|
2028
2104
|
});
|
|
2029
2105
|
if (bridge.isEditing && prompt) {
|
|
2030
2106
|
const unmount = mountPromptBox(win.document, bridge, prompt === true ? {} : prompt);
|
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,7 +538,11 @@ 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
|
};
|
|
540
547
|
// Icons (Lucide), drawn in the text colour.
|
|
541
548
|
const ICONS = {
|
|
@@ -870,6 +877,12 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
870
877
|
className: 'action chip',
|
|
871
878
|
type: 'button'
|
|
872
879
|
}, icon(doc, 'newPage'), labels.newPage);
|
|
880
|
+
// A product the site marks (editableProduct) without a page of its own:
|
|
881
|
+
// one click makes its product page, which the page then shows.
|
|
882
|
+
const addProduct = element(doc, 'button', {
|
|
883
|
+
className: 'action chip product',
|
|
884
|
+
type: 'button'
|
|
885
|
+
}, icon(doc, 'newPage'), labels.addProductPage);
|
|
873
886
|
const cancelNew = element(doc, 'button', {
|
|
874
887
|
type: 'button',
|
|
875
888
|
title: labels.newPageCancel
|
|
@@ -919,7 +932,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
919
932
|
});
|
|
920
933
|
const toolbar = element(doc, 'div', {
|
|
921
934
|
className: 'toolbar'
|
|
922
|
-
}, scope, newScope, modes, undo, newPage, element(doc, 'span', {
|
|
935
|
+
}, scope, newScope, modes, undo, addProduct, newPage, element(doc, 'span', {
|
|
923
936
|
className: 'spacer'
|
|
924
937
|
}), minimize, close, divider, send);
|
|
925
938
|
// The pages (on the site): a chip naming this page, opening a search
|
|
@@ -1030,7 +1043,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1030
1043
|
// A page of the site that isn't an entry (no `editable(entry)`, like a
|
|
1031
1044
|
// hand-written /about) has nothing to edit: only New page.
|
|
1032
1045
|
const pageless = site && bridge.entryId === null;
|
|
1033
|
-
|
|
1046
|
+
// …unless it shows a product: then Add a product page first.
|
|
1047
|
+
const productHere = pageless && canCreate && bridge.product !== null;
|
|
1048
|
+
const onlyNew = pageless && canCreate && !productHere;
|
|
1034
1049
|
if (!canCreate) creating = false;
|
|
1035
1050
|
if (onlyNew) creating = true;
|
|
1036
1051
|
if (creating || pageless || !site) form = false;
|
|
@@ -1038,16 +1053,19 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1038
1053
|
const showForm = open && available && form;
|
|
1039
1054
|
if (showForm && !formHandle) mountForm();
|
|
1040
1055
|
else if (!showForm && formHandle) unmountForm();
|
|
1041
|
-
|
|
1056
|
+
const offerProduct = productHere && !creating;
|
|
1057
|
+
pillText.textContent = offerProduct ? labels.addProductPage : onlyNew ? labels.newPage : labels.open;
|
|
1042
1058
|
cancelNew.hidden = onlyNew;
|
|
1043
|
-
scope.hidden = creating;
|
|
1059
|
+
scope.hidden = creating || offerProduct;
|
|
1044
1060
|
newScope.hidden = !creating;
|
|
1061
|
+
addProduct.hidden = !offerProduct;
|
|
1062
|
+
addProduct.disabled = busy;
|
|
1045
1063
|
newPage.hidden = creating || form || !canCreate;
|
|
1046
1064
|
newPage.disabled = busy;
|
|
1047
1065
|
if (minimized) picking = false;
|
|
1048
1066
|
pathRow.hidden = !creating || picking || minimized;
|
|
1049
1067
|
pathInput.disabled = busy;
|
|
1050
|
-
input.hidden = form || picking || minimized;
|
|
1068
|
+
input.hidden = form || picking || minimized || offerProduct;
|
|
1051
1069
|
formBox.hidden = !form || picking || minimized;
|
|
1052
1070
|
formBox.classList.toggle('loading', formLoading);
|
|
1053
1071
|
toolbar.hidden = picking;
|
|
@@ -1067,8 +1085,8 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1067
1085
|
undo.hidden = creating || !state.canUndo;
|
|
1068
1086
|
undo.disabled = busy;
|
|
1069
1087
|
// The form applies edits as they are made.
|
|
1070
|
-
send.hidden = form || minimized;
|
|
1071
|
-
divider.hidden = form || minimized;
|
|
1088
|
+
send.hidden = form || minimized || offerProduct;
|
|
1089
|
+
divider.hidden = form || minimized || offerProduct;
|
|
1072
1090
|
const toggleLabel = minimized ? labels.expand : labels.minimize;
|
|
1073
1091
|
minimize.title = toggleLabel;
|
|
1074
1092
|
minimize.setAttribute('aria-label', toggleLabel);
|
|
@@ -1091,7 +1109,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1091
1109
|
pageChipText.textContent = pages?.find(({ entryId })=>entryId === bridge.entryId)?.name ?? labels.pages;
|
|
1092
1110
|
const loadingForm = form && formLoading && !picking;
|
|
1093
1111
|
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 : '');
|
|
1112
|
+
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
1113
|
status.textContent = note;
|
|
1096
1114
|
status.hidden = !note || minimized;
|
|
1097
1115
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
@@ -1301,6 +1319,20 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1301
1319
|
pillSignOut.addEventListener('click', ()=>bridge.signOut());
|
|
1302
1320
|
clearBlock.addEventListener('click', ()=>bridge.select(null));
|
|
1303
1321
|
newPage.addEventListener('click', ()=>setCreating(true));
|
|
1322
|
+
addProduct.addEventListener('click', async ()=>{
|
|
1323
|
+
message = null;
|
|
1324
|
+
try {
|
|
1325
|
+
// The bridge reloads the page; this shows until it does.
|
|
1326
|
+
await bridge.createProductPage();
|
|
1327
|
+
message = {
|
|
1328
|
+
text: labels.addedProductPage,
|
|
1329
|
+
error: false
|
|
1330
|
+
};
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
message = failure(error);
|
|
1333
|
+
}
|
|
1334
|
+
refresh();
|
|
1335
|
+
});
|
|
1304
1336
|
cancelNew.addEventListener('click', ()=>setCreating(false));
|
|
1305
1337
|
promptMode.addEventListener('click', ()=>setForm(false));
|
|
1306
1338
|
formMode.addEventListener('click', ()=>setForm(true));
|
|
@@ -1481,7 +1513,7 @@ const FORM_BURST_MS = 1000;
|
|
|
1481
1513
|
// How long the page waits for the form's edits to settle before it shows
|
|
1482
1514
|
// them.
|
|
1483
1515
|
const FORM_RENDER_MS = 300;
|
|
1484
|
-
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}
|
|
1516
|
+
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath } = {})=>{
|
|
1485
1517
|
const doc = win.document;
|
|
1486
1518
|
const emitter = createEmitter();
|
|
1487
1519
|
const cleanup = [];
|
|
@@ -1491,6 +1523,7 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1491
1523
|
// Entries changed here since the last publish.
|
|
1492
1524
|
const touched = new Set();
|
|
1493
1525
|
let session = null;
|
|
1526
|
+
const productPath = (handle, locale)=>ownProductPath ? ownProductPath(handle, locale) : (session?.productPath ?? '/products/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1494
1527
|
// The open form's, if any; and when the form last changed content, for
|
|
1495
1528
|
// undo steps (-Infinity: the next edit starts a new step).
|
|
1496
1529
|
let closeForm = null;
|
|
@@ -1535,6 +1568,16 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1535
1568
|
return data;
|
|
1536
1569
|
};
|
|
1537
1570
|
const pageEntryId = ()=>doc.querySelector(`[${ENTRY_ATTRIBUTE}]`)?.getAttribute(ENTRY_ATTRIBUTE) ?? null;
|
|
1571
|
+
// The product the page shows (editableProduct), if it marks one.
|
|
1572
|
+
const pageProduct = ()=>{
|
|
1573
|
+
const element = doc.querySelector(`[${PRODUCT_ATTRIBUTE}]`);
|
|
1574
|
+
const id = element?.getAttribute(PRODUCT_ATTRIBUTE);
|
|
1575
|
+
const handle = element?.getAttribute(PRODUCT_HANDLE_ATTRIBUTE);
|
|
1576
|
+
return id && handle ? {
|
|
1577
|
+
id,
|
|
1578
|
+
handle
|
|
1579
|
+
} : null;
|
|
1580
|
+
};
|
|
1538
1581
|
const entryFor = (uid)=>{
|
|
1539
1582
|
const block = uid ? doc.querySelector(blockSelector(uid)) : null;
|
|
1540
1583
|
return block?.closest(`[${ENTRY_ATTRIBUTE}]`)?.getAttribute(ENTRY_ATTRIBUTE) ?? pageEntryId();
|
|
@@ -1642,6 +1685,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1642
1685
|
get entryId () {
|
|
1643
1686
|
return pageEntryId();
|
|
1644
1687
|
},
|
|
1688
|
+
get product () {
|
|
1689
|
+
return pageProduct();
|
|
1690
|
+
},
|
|
1645
1691
|
environment: null,
|
|
1646
1692
|
on: emitter.on,
|
|
1647
1693
|
getState: ()=>state,
|
|
@@ -1711,6 +1757,34 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1711
1757
|
});
|
|
1712
1758
|
}
|
|
1713
1759
|
},
|
|
1760
|
+
async createProductPage (product = pageProduct() ?? undefined) {
|
|
1761
|
+
if (!product) {
|
|
1762
|
+
throw new Error('Nothing on this page is marked as a product: add editableProduct(product)');
|
|
1763
|
+
}
|
|
1764
|
+
if (!has('create')) throw new Error('You may not add pages here');
|
|
1765
|
+
if (state.unsaved) {
|
|
1766
|
+
throw new Error('Save or undo your changes before adding a page');
|
|
1767
|
+
}
|
|
1768
|
+
setState({
|
|
1769
|
+
prompting: true
|
|
1770
|
+
});
|
|
1771
|
+
try {
|
|
1772
|
+
const made = await api('product-pages', {
|
|
1773
|
+
product: {
|
|
1774
|
+
id: product.id,
|
|
1775
|
+
handle: product.handle
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
// The site's product route finds its page now (drafts, while
|
|
1779
|
+
// editing): show it.
|
|
1780
|
+
win.location.reload();
|
|
1781
|
+
return made;
|
|
1782
|
+
} finally{
|
|
1783
|
+
setState({
|
|
1784
|
+
prompting: false
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
},
|
|
1714
1788
|
async view (options = {}) {
|
|
1715
1789
|
const { uid, entryId } = target(options.uid);
|
|
1716
1790
|
const entry = await load(entryId);
|
|
@@ -1864,7 +1938,8 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}` } = {})
|
|
|
1864
1938
|
contentType: page.contentType,
|
|
1865
1939
|
status: page.status,
|
|
1866
1940
|
path,
|
|
1867
|
-
url: pagePath(path, code)
|
|
1941
|
+
url: page.product ? productPath(page.product.handle, code) : pagePath(path, code),
|
|
1942
|
+
product: page.product ?? null
|
|
1868
1943
|
}
|
|
1869
1944
|
];
|
|
1870
1945
|
});
|
|
@@ -2009,7 +2084,7 @@ const peekContentBridge = ()=>typeof window === 'undefined' ? null : window[KEY]
|
|
|
2009
2084
|
// if (bridge.isEditing) bridge.on('update', ({ entry }) => render(entry))
|
|
2010
2085
|
//
|
|
2011
2086
|
// The first call's options win: there is one bridge per page.
|
|
2012
|
-
const getContentBridge = ({ url, prompt = true, pagePath } = {})=>{
|
|
2087
|
+
const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
2013
2088
|
if (typeof window === 'undefined') return SERVER_BRIDGE;
|
|
2014
2089
|
const win = window;
|
|
2015
2090
|
if (win[KEY]) return win[KEY];
|
|
@@ -2022,7 +2097,8 @@ const getContentBridge = ({ url, prompt = true, pagePath } = {})=>{
|
|
|
2022
2097
|
// own `/cms/login` (@obelism/content/site).
|
|
2023
2098
|
const sitePath = bridge.isEditing || win.parent !== win ? null : readSiteEditing(win.document);
|
|
2024
2099
|
if (sitePath) bridge = createSiteBridge(win, sitePath, {
|
|
2025
|
-
pagePath
|
|
2100
|
+
pagePath,
|
|
2101
|
+
productPath
|
|
2026
2102
|
});
|
|
2027
2103
|
if (bridge.isEditing && prompt) {
|
|
2028
2104
|
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, d as
|
|
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;
|
|
@@ -96,6 +106,12 @@ declare const IMPROVE_BLOCK = "_improve";
|
|
|
96
106
|
declare const isImproveBlock: (block: Block) => block is ImproveBlock;
|
|
97
107
|
declare const pickImproveVariant: <TBlock extends Block>(block: ImproveBlock<TBlock>, option: string | null | undefined, fallback?: string) => TBlock[];
|
|
98
108
|
|
|
109
|
+
type LinkHrefOptions = {
|
|
110
|
+
url?: ((path: string) => string) | undefined;
|
|
111
|
+
product?: ((product: ShopifyItem, page: LinkTarget | null) => string) | undefined;
|
|
112
|
+
};
|
|
113
|
+
declare const linkHref: (link: Link | null | undefined, { url, product, }?: LinkHrefOptions) => string | null;
|
|
114
|
+
|
|
99
115
|
declare const PREVIEW_PARAMS: {
|
|
100
116
|
readonly preview: "cms_preview";
|
|
101
117
|
readonly entry: "cms_entry";
|
|
@@ -110,6 +126,50 @@ type PreviewParams = {
|
|
|
110
126
|
type SearchParamsInput = URL | URLSearchParams | string | Record<string, string | string[] | undefined>;
|
|
111
127
|
declare const readPreviewParams: (input: SearchParamsInput) => PreviewParams | null;
|
|
112
128
|
|
|
129
|
+
declare const SHOPIFY_STOREFRONT_API_VERSION = "2026-10";
|
|
130
|
+
type ShopifyStorefrontOptions = {
|
|
131
|
+
shop: string;
|
|
132
|
+
storefrontToken: string;
|
|
133
|
+
country?: string | undefined;
|
|
134
|
+
language?: string | undefined;
|
|
135
|
+
init?: RequestInit | undefined;
|
|
136
|
+
fetch?: typeof fetch | undefined;
|
|
137
|
+
};
|
|
138
|
+
type ShopifyMoney = {
|
|
139
|
+
amount: string;
|
|
140
|
+
currencyCode: string;
|
|
141
|
+
};
|
|
142
|
+
type ShopifyImage = {
|
|
143
|
+
url: string;
|
|
144
|
+
altText: string | null;
|
|
145
|
+
width: number | null;
|
|
146
|
+
height: number | null;
|
|
147
|
+
};
|
|
148
|
+
type ShopifyProduct = {
|
|
149
|
+
id: string;
|
|
150
|
+
handle: string;
|
|
151
|
+
title: string;
|
|
152
|
+
availableForSale: boolean;
|
|
153
|
+
featuredImage: ShopifyImage | null;
|
|
154
|
+
priceRange: {
|
|
155
|
+
minVariantPrice: ShopifyMoney;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
type ShopifyCollection = {
|
|
159
|
+
id: string;
|
|
160
|
+
handle: string;
|
|
161
|
+
title: string;
|
|
162
|
+
products: ShopifyProduct[];
|
|
163
|
+
};
|
|
164
|
+
declare class ShopifyStorefrontError extends Error {
|
|
165
|
+
readonly status: number;
|
|
166
|
+
constructor(status: number, message: string);
|
|
167
|
+
}
|
|
168
|
+
declare const fetchShopifyCollection: (item: ShopifyItem, options: ShopifyStorefrontOptions & {
|
|
169
|
+
first?: number | undefined;
|
|
170
|
+
}) => Promise<ShopifyCollection | null>;
|
|
171
|
+
declare const fetchShopifyProducts: (items: ShopifyItem | ShopifyItem[] | null | undefined, options: ShopifyStorefrontOptions) => Promise<ShopifyProduct[]>;
|
|
172
|
+
|
|
113
173
|
declare const SAFE_HREF: RegExp;
|
|
114
174
|
declare const escapeHtml: (value: string) => string;
|
|
115
175
|
type RichTextHtmlOptions = {
|
|
@@ -135,6 +195,6 @@ type SitemapOptions = LocalizedUrlOptions & {
|
|
|
135
195
|
};
|
|
136
196
|
declare const sitemapXml: (entries: Iterable<Page>, { exclude, ...options }: SitemapOptions) => string;
|
|
137
197
|
|
|
138
|
-
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, ModelFile, PREVIEW_PARAMS, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, UID_ATTRIBUTE, alternateLinks, editable, escapeHtml, headingLevel, imageSrcSet, imageUrl, isImproveBlock, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
139
|
-
export type { AlternateLink, ContentClientOptions, EntriesQuery, ImageTransform, LocalizedUrlOptions, PageLookup, PreviewParams, RedirectsQuery, RequestOptions, RichTextHtmlOptions, SitemapOptions };
|
|
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 };
|
|
199
|
+
export type { AlternateLink, ContentClientOptions, EntriesQuery, ImageTransform, LinkHrefOptions, LocalizedUrlOptions, PageLookup, PreviewParams, RedirectsQuery, RequestOptions, RichTextHtmlOptions, ShopifyCollection, ShopifyImage, ShopifyMoney, ShopifyProduct, ShopifyStorefrontOptions, SitemapOptions };
|
|
140
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/preview.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":[]}
|