@407dev/cms-astro 0.1.0 → 0.2.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 +4 -4
- package/dist/{chunk-7E3XJLKX.js → chunk-SGHAANOW.js} +30 -3
- package/dist/chunk-SGHAANOW.js.map +1 -0
- package/dist/{chunk-QYUVAKMC.js → chunk-YCQMH2T7.js} +51 -10
- package/dist/chunk-YCQMH2T7.js.map +1 -0
- package/dist/fields/collections.js +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +32 -31
- package/dist/index.js.map +1 -1
- package/dist/middleware/index.js +2 -2
- package/package.json +5 -5
- package/src/client.ts +0 -1
- package/src/fields/attrs.ts +4 -0
- package/src/fields/collection.ts +8 -0
- package/src/fields/entryScope.test.ts +22 -1
- package/src/fields/index.ts +10 -1
- package/src/index.test.ts +117 -1
- package/src/integration.ts +29 -7
- package/src/middleware/preview.test.ts +39 -7
- package/src/middleware/preview.ts +18 -4
- package/src/preview/bridge-script.test.ts +81 -2
- package/src/preview/bridge-script.ts +30 -1
- package/dist/chunk-53OQ5RXJ.js +0 -912
- package/dist/chunk-53OQ5RXJ.js.map +0 -1
- package/dist/chunk-56OMNQLH.js +0 -1013
- package/dist/chunk-56OMNQLH.js.map +0 -1
- package/dist/chunk-5AOOMQ7K.js +0 -1031
- package/dist/chunk-5AOOMQ7K.js.map +0 -1
- package/dist/chunk-5XRUCFDC.js +0 -743
- package/dist/chunk-5XRUCFDC.js.map +0 -1
- package/dist/chunk-62ZHCOLZ.js +0 -25
- package/dist/chunk-62ZHCOLZ.js.map +0 -1
- package/dist/chunk-6AZLRSYA.js +0 -126
- package/dist/chunk-6AZLRSYA.js.map +0 -1
- package/dist/chunk-6L3ZTCFB.js +0 -14
- package/dist/chunk-6L3ZTCFB.js.map +0 -1
- package/dist/chunk-6O7ZNNDT.js +0 -697
- package/dist/chunk-6O7ZNNDT.js.map +0 -1
- package/dist/chunk-6PQIXTMK.js +0 -697
- package/dist/chunk-6PQIXTMK.js.map +0 -1
- package/dist/chunk-7AW6M7QW.js +0 -1013
- package/dist/chunk-7AW6M7QW.js.map +0 -1
- package/dist/chunk-7E3XJLKX.js.map +0 -1
- package/dist/chunk-7LM54OTA.js +0 -1031
- package/dist/chunk-7LM54OTA.js.map +0 -1
- package/dist/chunk-A3OGL4OX.js +0 -706
- package/dist/chunk-A3OGL4OX.js.map +0 -1
- package/dist/chunk-AO4UAWOV.js +0 -1030
- package/dist/chunk-AO4UAWOV.js.map +0 -1
- package/dist/chunk-BDFVGXM2.js +0 -697
- package/dist/chunk-BDFVGXM2.js.map +0 -1
- package/dist/chunk-CXM7NZVX.js +0 -1031
- package/dist/chunk-CXM7NZVX.js.map +0 -1
- package/dist/chunk-DXJSYGS6.js +0 -743
- package/dist/chunk-DXJSYGS6.js.map +0 -1
- package/dist/chunk-EFUSAQZM.js +0 -72
- package/dist/chunk-EFUSAQZM.js.map +0 -1
- package/dist/chunk-F7KDGPBN.js +0 -1013
- package/dist/chunk-F7KDGPBN.js.map +0 -1
- package/dist/chunk-FBSQT45X.js +0 -126
- package/dist/chunk-FBSQT45X.js.map +0 -1
- package/dist/chunk-FEPDOMVH.js +0 -697
- package/dist/chunk-FEPDOMVH.js.map +0 -1
- package/dist/chunk-FQDOL2QW.js +0 -25
- package/dist/chunk-FQDOL2QW.js.map +0 -1
- package/dist/chunk-GB3LGQJM.js +0 -109
- package/dist/chunk-GB3LGQJM.js.map +0 -1
- package/dist/chunk-HCNP6R3P.js +0 -736
- package/dist/chunk-HCNP6R3P.js.map +0 -1
- package/dist/chunk-J6WEJDRI.js +0 -743
- package/dist/chunk-J6WEJDRI.js.map +0 -1
- package/dist/chunk-JHEAPNJ2.js +0 -117
- package/dist/chunk-JHEAPNJ2.js.map +0 -1
- package/dist/chunk-JOJDJ6GW.js +0 -25
- package/dist/chunk-JOJDJ6GW.js.map +0 -1
- package/dist/chunk-KTDV6WYB.js +0 -202
- package/dist/chunk-KTDV6WYB.js.map +0 -1
- package/dist/chunk-KZWJBKPC.js +0 -734
- package/dist/chunk-KZWJBKPC.js.map +0 -1
- package/dist/chunk-LEAQBGL6.js +0 -109
- package/dist/chunk-LEAQBGL6.js.map +0 -1
- package/dist/chunk-LGZJL2Q7.js +0 -697
- package/dist/chunk-LGZJL2Q7.js.map +0 -1
- package/dist/chunk-LQPBU46R.js +0 -109
- package/dist/chunk-LQPBU46R.js.map +0 -1
- package/dist/chunk-M55NNUTY.js +0 -1013
- package/dist/chunk-M55NNUTY.js.map +0 -1
- package/dist/chunk-M6NCYCC3.js +0 -1013
- package/dist/chunk-M6NCYCC3.js.map +0 -1
- package/dist/chunk-MGN7OZAU.js +0 -109
- package/dist/chunk-MGN7OZAU.js.map +0 -1
- package/dist/chunk-MGYZOX4K.js +0 -1013
- package/dist/chunk-MGYZOX4K.js.map +0 -1
- package/dist/chunk-MY4IEKJS.js +0 -1031
- package/dist/chunk-MY4IEKJS.js.map +0 -1
- package/dist/chunk-NCQRGAB4.js +0 -705
- package/dist/chunk-NCQRGAB4.js.map +0 -1
- package/dist/chunk-NI4NHXI4.js +0 -697
- package/dist/chunk-NI4NHXI4.js.map +0 -1
- package/dist/chunk-NPI5N7AU.js +0 -14
- package/dist/chunk-NPI5N7AU.js.map +0 -1
- package/dist/chunk-QN4CPMJF.js +0 -126
- package/dist/chunk-QN4CPMJF.js.map +0 -1
- package/dist/chunk-QYUVAKMC.js.map +0 -1
- package/dist/chunk-RAAT6PDT.js +0 -25
- package/dist/chunk-RAAT6PDT.js.map +0 -1
- package/dist/chunk-RDPO5VPS.js +0 -1013
- package/dist/chunk-RDPO5VPS.js.map +0 -1
- package/dist/chunk-RQHIW2PF.js +0 -25
- package/dist/chunk-RQHIW2PF.js.map +0 -1
- package/dist/chunk-RREVHA52.js +0 -722
- package/dist/chunk-RREVHA52.js.map +0 -1
- package/dist/chunk-S7PT4PZN.js +0 -25
- package/dist/chunk-S7PT4PZN.js.map +0 -1
- package/dist/chunk-SUXV5M32.js +0 -109
- package/dist/chunk-SUXV5M32.js.map +0 -1
- package/dist/chunk-SZEORUY6.js +0 -696
- package/dist/chunk-SZEORUY6.js.map +0 -1
- package/dist/chunk-T7NGGWGY.js +0 -25
- package/dist/chunk-T7NGGWGY.js.map +0 -1
- package/dist/chunk-UEVWP5VE.js +0 -696
- package/dist/chunk-UEVWP5VE.js.map +0 -1
- package/dist/chunk-UJNKNP7U.js +0 -748
- package/dist/chunk-UJNKNP7U.js.map +0 -1
- package/dist/chunk-V4XVFWFI.js +0 -1013
- package/dist/chunk-V4XVFWFI.js.map +0 -1
- package/dist/chunk-VJU2CIKZ.js +0 -729
- package/dist/chunk-VJU2CIKZ.js.map +0 -1
- package/dist/chunk-VRQUP5L3.js +0 -202
- package/dist/chunk-VRQUP5L3.js.map +0 -1
- package/dist/chunk-WBJ5E7CL.js +0 -742
- package/dist/chunk-WBJ5E7CL.js.map +0 -1
- package/dist/chunk-Y3Q65C7R.js +0 -14
- package/dist/chunk-Y3Q65C7R.js.map +0 -1
- package/dist/chunk-YHEGFPTR.js +0 -1030
- package/dist/chunk-YHEGFPTR.js.map +0 -1
- package/dist/chunk-ZDLBN46C.js +0 -697
- package/dist/chunk-ZDLBN46C.js.map +0 -1
- package/dist/preview-BEkLMD6N.d.ts +0 -23
- package/dist/preview-DJEA4fj7.d.ts +0 -23
- package/dist/preview-DeD1Jn7U.d.ts +0 -23
- package/dist/types-15jfCQKb.d.ts +0 -141
- package/dist/types-BREdL9Gx.d.ts +0 -140
- package/dist/types-C6sUZNa2.d.ts +0 -104
- package/dist/types-DpeHpobR.d.ts +0 -104
package/dist/chunk-NI4NHXI4.js
DELETED
|
@@ -1,697 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_DEV_CONTENT_URL, getJwtSecret, verifyPreviewToken } from './chunk-LEAQBGL6.js';
|
|
2
|
-
import { isDraftMode, setActiveDraftBundle, runWithDraftBundle } from './chunk-DMLOBKYE.js';
|
|
3
|
-
import { resolveEditorOrigins } from './chunk-XJPVYMZM.js';
|
|
4
|
-
|
|
5
|
-
// src/client.ts
|
|
6
|
-
function createCmsClient(config) {
|
|
7
|
-
const siteId = config.siteId;
|
|
8
|
-
const contentUrl = config.contentUrl.replace(/\/+$/, "");
|
|
9
|
-
const fetchFn = config.fetch || fetch;
|
|
10
|
-
let cachedPublishedBundle = null;
|
|
11
|
-
const client = {
|
|
12
|
-
siteId,
|
|
13
|
-
contentUrl,
|
|
14
|
-
previewSecret: config.previewSecret,
|
|
15
|
-
async getBundle(options) {
|
|
16
|
-
const isDraft = Boolean(options?.previewToken);
|
|
17
|
-
if (!isDraft && cachedPublishedBundle) {
|
|
18
|
-
return cachedPublishedBundle;
|
|
19
|
-
}
|
|
20
|
-
const url = isDraft ? `${contentUrl}/draft/${siteId}/bundle` : `${contentUrl}/content/${siteId}/bundle`;
|
|
21
|
-
const headers = {};
|
|
22
|
-
if (options?.previewToken) {
|
|
23
|
-
headers["x-preview-token"] = options.previewToken;
|
|
24
|
-
}
|
|
25
|
-
const res = await fetchFn(url, {
|
|
26
|
-
headers,
|
|
27
|
-
cache: "no-store"
|
|
28
|
-
});
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
throw new Error(
|
|
31
|
-
`CMS Client: Failed to fetch bundle from ${url} (status ${res.status}): ${res.statusText}`
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
const bundle = await res.json();
|
|
35
|
-
if (!isDraft) {
|
|
36
|
-
cachedPublishedBundle = bundle;
|
|
37
|
-
}
|
|
38
|
-
return bundle;
|
|
39
|
-
},
|
|
40
|
-
async getFields(options) {
|
|
41
|
-
const bundle = await this.getBundle(options);
|
|
42
|
-
return bundle.fields || {};
|
|
43
|
-
},
|
|
44
|
-
async getField(key, options) {
|
|
45
|
-
const fields = await this.getFields(options);
|
|
46
|
-
return fields[key] ?? null;
|
|
47
|
-
},
|
|
48
|
-
async getCollections(options) {
|
|
49
|
-
const bundle = await this.getBundle(options);
|
|
50
|
-
return bundle.collections || {};
|
|
51
|
-
},
|
|
52
|
-
async getEntries(collectionKey, options) {
|
|
53
|
-
const bundle = await this.getBundle(options);
|
|
54
|
-
return bundle.entries?.[collectionKey] || [];
|
|
55
|
-
},
|
|
56
|
-
async getEntry(collectionKey, slug, options) {
|
|
57
|
-
const entries = await this.getEntries(collectionKey, options);
|
|
58
|
-
return entries.find((e) => e.slug === slug) || null;
|
|
59
|
-
},
|
|
60
|
-
async getRoutes(options) {
|
|
61
|
-
const bundle = await this.getBundle(options);
|
|
62
|
-
return bundle.routes || [];
|
|
63
|
-
},
|
|
64
|
-
async getSiteConfig(options) {
|
|
65
|
-
const bundle = await this.getBundle(options);
|
|
66
|
-
return {
|
|
67
|
-
site_id: bundle.site_id,
|
|
68
|
-
redirects: bundle.redirects || [],
|
|
69
|
-
robots: bundle.settings?.robots || {},
|
|
70
|
-
default_seo: bundle.settings?.default_seo || {},
|
|
71
|
-
sitemap: bundle.settings?.sitemap || {},
|
|
72
|
-
not_found_path: bundle.settings?.not_found_path || null
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
clearCache() {
|
|
76
|
-
cachedPublishedBundle = null;
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
return client;
|
|
80
|
-
}
|
|
81
|
-
var globalWithCms = globalThis;
|
|
82
|
-
var globalClient = typeof globalThis !== "undefined" && globalWithCms.__CMS_CLIENT__ || null;
|
|
83
|
-
function initCmsClient(options) {
|
|
84
|
-
if (options.client) {
|
|
85
|
-
globalClient = options.client;
|
|
86
|
-
if (typeof globalThis !== "undefined") {
|
|
87
|
-
globalWithCms.__CMS_CLIENT__ = options.client;
|
|
88
|
-
}
|
|
89
|
-
return globalClient;
|
|
90
|
-
}
|
|
91
|
-
globalClient = createCmsClient({
|
|
92
|
-
siteId: options.siteId || process.env.CMS_SITE_ID || "",
|
|
93
|
-
contentUrl: options.contentUrl || process.env.CMS_CONTENT_URL || DEFAULT_DEV_CONTENT_URL,
|
|
94
|
-
previewSecret: options.previewSecret || process.env.CMS_PREVIEW_SECRET
|
|
95
|
-
});
|
|
96
|
-
if (typeof globalThis !== "undefined") {
|
|
97
|
-
globalWithCms.__CMS_CLIENT__ = globalClient;
|
|
98
|
-
}
|
|
99
|
-
return globalClient;
|
|
100
|
-
}
|
|
101
|
-
function getClient() {
|
|
102
|
-
return globalClient || typeof globalThis !== "undefined" && globalWithCms.__CMS_CLIENT__ || null;
|
|
103
|
-
}
|
|
104
|
-
function setClient(client) {
|
|
105
|
-
globalClient = client;
|
|
106
|
-
if (typeof globalThis !== "undefined") {
|
|
107
|
-
globalWithCms.__CMS_CLIENT__ = client;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// src/preview/bridge-script.ts
|
|
112
|
-
var BRIDGE_PROTOCOL_VERSION = 1;
|
|
113
|
-
function buildBridgeScript(options = {}) {
|
|
114
|
-
const allowedOrigins = resolveEditorOrigins(options.editorOrigins);
|
|
115
|
-
const allowedOriginsJson = JSON.stringify(allowedOrigins);
|
|
116
|
-
return `(function() {
|
|
117
|
-
if (typeof window === 'undefined') return;
|
|
118
|
-
if (window.__CMS_BRIDGE_INITIALIZED__) return;
|
|
119
|
-
window.__CMS_BRIDGE_INITIALIZED__ = true;
|
|
120
|
-
|
|
121
|
-
var PROTOCOL_VERSION = ${BRIDGE_PROTOCOL_VERSION};
|
|
122
|
-
var allowedOrigins = ${allowedOriginsJson};
|
|
123
|
-
var connectedOrigin = null;
|
|
124
|
-
var connectedSource = null;
|
|
125
|
-
var activeKey = null;
|
|
126
|
-
var rafScheduled = false;
|
|
127
|
-
var isPatchingDom = false;
|
|
128
|
-
var debounceRescanTimer = null;
|
|
129
|
-
|
|
130
|
-
function normalizeOrigin(raw) {
|
|
131
|
-
if (!raw || typeof raw !== 'string') return null;
|
|
132
|
-
var trimmed = raw.trim();
|
|
133
|
-
if (!trimmed) return null;
|
|
134
|
-
try {
|
|
135
|
-
var withScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\//.test(trimmed) ? trimmed : 'https://' + trimmed;
|
|
136
|
-
var url = new URL(withScheme);
|
|
137
|
-
if (!url.protocol || !url.host) return null;
|
|
138
|
-
return (url.protocol + '//' + url.host).toLowerCase();
|
|
139
|
-
} catch (e) {
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
var normalizedAllowed = allowedOrigins.map(normalizeOrigin).filter(Boolean);
|
|
145
|
-
|
|
146
|
-
function isOriginAllowed(origin) {
|
|
147
|
-
var norm = normalizeOrigin(origin);
|
|
148
|
-
if (!norm) return false;
|
|
149
|
-
return normalizedAllowed.indexOf(norm) !== -1;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function postToEditor(msg) {
|
|
153
|
-
if (!connectedSource || !connectedOrigin) return;
|
|
154
|
-
try {
|
|
155
|
-
connectedSource.postMessage(msg, connectedOrigin);
|
|
156
|
-
} catch (err) {
|
|
157
|
-
// Failed to post
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Inject Bridge Styles
|
|
162
|
-
var style = document.createElement('style');
|
|
163
|
-
style.id = 'cms-bridge-styles';
|
|
164
|
-
style.textContent = [
|
|
165
|
-
'html[data-cms-edit-mode] [data-cms-field],',
|
|
166
|
-
'html[data-cms-edit-mode] [data-cms-entry-field] {',
|
|
167
|
-
' cursor: pointer !important;',
|
|
168
|
-
' outline: 1px dashed rgba(59, 130, 246, 0.5) !important;',
|
|
169
|
-
' outline-offset: 2px !important;',
|
|
170
|
-
' transition: outline 0.15s ease-in-out !important;',
|
|
171
|
-
'}',
|
|
172
|
-
'html[data-cms-edit-mode] [data-cms-field]:hover,',
|
|
173
|
-
'html[data-cms-edit-mode] [data-cms-entry-field]:hover {',
|
|
174
|
-
' outline: 2px solid #3b82f6 !important;',
|
|
175
|
-
' outline-offset: 2px !important;',
|
|
176
|
-
'}',
|
|
177
|
-
'html[data-cms-edit-mode] [data-cms-group] {',
|
|
178
|
-
' outline: 1px dashed rgba(16, 185, 129, 0.4) !important;',
|
|
179
|
-
' outline-offset: 3px !important;',
|
|
180
|
-
'}',
|
|
181
|
-
'html[data-cms-edit-mode] [data-cms-group]:hover {',
|
|
182
|
-
' outline: 2px solid #10b981 !important;',
|
|
183
|
-
' outline-offset: 3px !important;',
|
|
184
|
-
'}'
|
|
185
|
-
].join('\\n');
|
|
186
|
-
if (document.head) {
|
|
187
|
-
document.head.appendChild(style);
|
|
188
|
-
} else {
|
|
189
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
190
|
-
if (document.head) document.head.appendChild(style);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function inferFieldKind(el) {
|
|
195
|
-
if (!el) return 'unknown';
|
|
196
|
-
var tag = el.tagName ? el.tagName.toLowerCase() : '';
|
|
197
|
-
if (tag === 'img') return 'image';
|
|
198
|
-
if (tag === 'video') return 'video';
|
|
199
|
-
var explicitKind = el.getAttribute('data-cms-kind');
|
|
200
|
-
if (explicitKind) return explicitKind;
|
|
201
|
-
if (el.classList.contains('rich-body') || el.classList.contains('cms-richtext') || el.getAttribute('data-cms-richtext') === 'true') {
|
|
202
|
-
return 'richtext';
|
|
203
|
-
}
|
|
204
|
-
return 'text';
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function getElementRect(el) {
|
|
208
|
-
var r = el.getBoundingClientRect();
|
|
209
|
-
return {
|
|
210
|
-
top: r.top,
|
|
211
|
-
left: r.left,
|
|
212
|
-
width: r.width,
|
|
213
|
-
height: r.height
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function parseGroupAttr(raw) {
|
|
218
|
-
if (!raw) return undefined;
|
|
219
|
-
var idx = raw.indexOf(':');
|
|
220
|
-
if (idx === -1) return { group: raw, scope: '' };
|
|
221
|
-
return {
|
|
222
|
-
group: raw.slice(0, idx),
|
|
223
|
-
scope: raw.slice(idx + 1)
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function scanRenderedFields() {
|
|
228
|
-
var fieldEls = document.querySelectorAll('[data-cms-field], [data-cms-entry-field]');
|
|
229
|
-
var fieldMap = {};
|
|
230
|
-
|
|
231
|
-
for (var i = 0; i < fieldEls.length; i++) {
|
|
232
|
-
var el = fieldEls[i];
|
|
233
|
-
var key = el.getAttribute('data-cms-field') || el.getAttribute('data-cms-entry-field') || '';
|
|
234
|
-
if (!key) continue;
|
|
235
|
-
|
|
236
|
-
var isEntry = el.hasAttribute('data-cms-entry-field');
|
|
237
|
-
var groupEl = el.closest('[data-cms-group]');
|
|
238
|
-
var collectionEl = el.closest('[data-cms-collection]');
|
|
239
|
-
var groupName = undefined;
|
|
240
|
-
if (groupEl) {
|
|
241
|
-
var g = parseGroupAttr(groupEl.getAttribute('data-cms-group'));
|
|
242
|
-
if (g) groupName = g.group;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
var entryRef = undefined;
|
|
246
|
-
if (isEntry || collectionEl) {
|
|
247
|
-
entryRef = {
|
|
248
|
-
collection: collectionEl ? collectionEl.getAttribute('data-cms-collection') || '' : '',
|
|
249
|
-
slug: collectionEl ? collectionEl.getAttribute('data-cms-entry') || '' : '',
|
|
250
|
-
path: isEntry ? key : key
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
var uniqueId = (isEntry && entryRef ? entryRef.collection + ':' + entryRef.slug + ':' : '') + key;
|
|
255
|
-
|
|
256
|
-
if (!fieldMap[uniqueId]) {
|
|
257
|
-
fieldMap[uniqueId] = {
|
|
258
|
-
key: key,
|
|
259
|
-
kind: inferFieldKind(el),
|
|
260
|
-
group: groupName,
|
|
261
|
-
entryRef: entryRef,
|
|
262
|
-
instances: 1
|
|
263
|
-
};
|
|
264
|
-
} else {
|
|
265
|
-
fieldMap[uniqueId].instances++;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
var fields = [];
|
|
270
|
-
for (var k in fieldMap) {
|
|
271
|
-
if (Object.prototype.hasOwnProperty.call(fieldMap, k)) {
|
|
272
|
-
fields.push(fieldMap[k]);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
window.__CMS_FIELDS__ = fields;
|
|
277
|
-
window.__CMS_RESCAN__ = scanRenderedFields;
|
|
278
|
-
|
|
279
|
-
try {
|
|
280
|
-
document.dispatchEvent(new CustomEvent('cms:fields-updated', { detail: fields }));
|
|
281
|
-
} catch (_e) {}
|
|
282
|
-
|
|
283
|
-
postToEditor({
|
|
284
|
-
source: 'cms-preview',
|
|
285
|
-
v: PROTOCOL_VERSION,
|
|
286
|
-
type: 'rendered-fields',
|
|
287
|
-
fields: fields
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
function debouncedRescan() {
|
|
292
|
-
if (isPatchingDom) return;
|
|
293
|
-
if (debounceRescanTimer) clearTimeout(debounceRescanTimer);
|
|
294
|
-
debounceRescanTimer = setTimeout(function() {
|
|
295
|
-
scanRenderedFields();
|
|
296
|
-
scheduleRectsUpdate();
|
|
297
|
-
}, 150);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function setupMutationObserver() {
|
|
301
|
-
if (typeof MutationObserver === 'undefined' || !document.body) return;
|
|
302
|
-
var observer = new MutationObserver(function(mutations) {
|
|
303
|
-
if (isPatchingDom) return;
|
|
304
|
-
debouncedRescan();
|
|
305
|
-
});
|
|
306
|
-
observer.observe(document.body, {
|
|
307
|
-
childList: true,
|
|
308
|
-
subtree: true,
|
|
309
|
-
attributeFilter: ['data-cms-field', 'data-cms-entry-field', 'data-cms-group', 'data-cms-collection', 'data-cms-entry']
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
function scheduleRectsUpdate() {
|
|
314
|
-
if (rafScheduled) return;
|
|
315
|
-
rafScheduled = true;
|
|
316
|
-
requestAnimationFrame(function() {
|
|
317
|
-
rafScheduled = false;
|
|
318
|
-
var rects = {};
|
|
319
|
-
if (activeKey) {
|
|
320
|
-
var el = document.querySelector('[data-cms-field="' + activeKey + '"], [data-cms-entry-field="' + activeKey + '"]');
|
|
321
|
-
if (el) {
|
|
322
|
-
rects[activeKey] = getElementRect(el);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
postToEditor({
|
|
326
|
-
source: 'cms-preview',
|
|
327
|
-
v: PROTOCOL_VERSION,
|
|
328
|
-
type: 'rects-update',
|
|
329
|
-
rects: rects,
|
|
330
|
-
scrollY: window.scrollY || window.pageYOffset || 0
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Click handler
|
|
336
|
-
document.addEventListener('click', function(e) {
|
|
337
|
-
if (!document.documentElement.hasAttribute('data-cms-edit-mode')) return;
|
|
338
|
-
var target = e.target;
|
|
339
|
-
if (!target || !(target instanceof Element)) return;
|
|
340
|
-
|
|
341
|
-
var fieldEl = target.closest('[data-cms-field], [data-cms-entry-field]');
|
|
342
|
-
var groupEl = target.closest('[data-cms-group]');
|
|
343
|
-
|
|
344
|
-
if (fieldEl) {
|
|
345
|
-
e.preventDefault();
|
|
346
|
-
e.stopPropagation();
|
|
347
|
-
|
|
348
|
-
var isEntry = fieldEl.hasAttribute('data-cms-entry-field');
|
|
349
|
-
var key = fieldEl.getAttribute('data-cms-field') || fieldEl.getAttribute('data-cms-entry-field') || '';
|
|
350
|
-
var kind = inferFieldKind(fieldEl);
|
|
351
|
-
var rect = getElementRect(fieldEl);
|
|
352
|
-
activeKey = key;
|
|
353
|
-
|
|
354
|
-
var selector = isEntry ? '[data-cms-entry-field="' + key + '"]' : '[data-cms-field="' + key + '"]';
|
|
355
|
-
var all = Array.prototype.slice.call(document.querySelectorAll(selector));
|
|
356
|
-
var instance = Math.max(0, all.indexOf(fieldEl));
|
|
357
|
-
|
|
358
|
-
var collectionEl = fieldEl.closest('[data-cms-collection]');
|
|
359
|
-
var entryRef = (isEntry || collectionEl) ? {
|
|
360
|
-
collection: collectionEl ? collectionEl.getAttribute('data-cms-collection') || '' : '',
|
|
361
|
-
slug: collectionEl ? collectionEl.getAttribute('data-cms-entry') || '' : '',
|
|
362
|
-
path: isEntry ? key : key
|
|
363
|
-
} : undefined;
|
|
364
|
-
|
|
365
|
-
var groupPath = groupEl ? parseGroupAttr(groupEl.getAttribute('data-cms-group')) : undefined;
|
|
366
|
-
|
|
367
|
-
try {
|
|
368
|
-
document.dispatchEvent(new CustomEvent('cms:field-selected', {
|
|
369
|
-
detail: {
|
|
370
|
-
key: key,
|
|
371
|
-
kind: kind,
|
|
372
|
-
entryRef: entryRef,
|
|
373
|
-
groupPath: groupPath
|
|
374
|
-
}
|
|
375
|
-
}));
|
|
376
|
-
} catch (_e) {}
|
|
377
|
-
|
|
378
|
-
postToEditor({
|
|
379
|
-
source: 'cms-preview',
|
|
380
|
-
v: PROTOCOL_VERSION,
|
|
381
|
-
type: 'field-click',
|
|
382
|
-
key: key,
|
|
383
|
-
kind: kind,
|
|
384
|
-
rect: rect,
|
|
385
|
-
instance: instance,
|
|
386
|
-
entryRef: entryRef,
|
|
387
|
-
groupPath: groupPath
|
|
388
|
-
});
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (groupEl) {
|
|
393
|
-
e.preventDefault();
|
|
394
|
-
e.stopPropagation();
|
|
395
|
-
|
|
396
|
-
var g = parseGroupAttr(groupEl.getAttribute('data-cms-group'));
|
|
397
|
-
if (g) {
|
|
398
|
-
var gRect = getElementRect(groupEl);
|
|
399
|
-
postToEditor({
|
|
400
|
-
source: 'cms-preview',
|
|
401
|
-
v: PROTOCOL_VERSION,
|
|
402
|
-
type: 'group-click',
|
|
403
|
-
group: g.group,
|
|
404
|
-
scope: g.scope,
|
|
405
|
-
rect: gRect
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}, true);
|
|
410
|
-
|
|
411
|
-
// Message handler
|
|
412
|
-
window.addEventListener('message', function(e) {
|
|
413
|
-
var data = e.data;
|
|
414
|
-
if (!data || typeof data !== 'object') return;
|
|
415
|
-
if (data.source !== 'cms-editor') return;
|
|
416
|
-
|
|
417
|
-
if (data.type === 'hello') {
|
|
418
|
-
if (!isOriginAllowed(e.origin)) return;
|
|
419
|
-
connectedOrigin = e.origin;
|
|
420
|
-
connectedSource = e.source;
|
|
421
|
-
|
|
422
|
-
postToEditor({
|
|
423
|
-
source: 'cms-preview',
|
|
424
|
-
v: PROTOCOL_VERSION,
|
|
425
|
-
type: 'ready',
|
|
426
|
-
protocolVersion: PROTOCOL_VERSION
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
scanRenderedFields();
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (!connectedOrigin || e.origin !== connectedOrigin) return;
|
|
434
|
-
|
|
435
|
-
if (data.type === 'highlight-mode') {
|
|
436
|
-
if (data.on) {
|
|
437
|
-
document.documentElement.setAttribute('data-cms-edit-mode', 'true');
|
|
438
|
-
} else {
|
|
439
|
-
document.documentElement.removeAttribute('data-cms-edit-mode');
|
|
440
|
-
}
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
if (data.type === 'patch') {
|
|
445
|
-
isPatchingDom = true;
|
|
446
|
-
var patchKey = data.key;
|
|
447
|
-
var patchKind = data.kind;
|
|
448
|
-
var patchVal = data.value;
|
|
449
|
-
var patchEntry = data.entryRef;
|
|
450
|
-
|
|
451
|
-
var patchSelector;
|
|
452
|
-
var fPath = patchEntry && patchEntry.path ? patchEntry.path : patchKey;
|
|
453
|
-
if (patchEntry && (patchEntry.collection || patchEntry.slug)) {
|
|
454
|
-
var colAttr = patchEntry.collection ? '[data-cms-collection="' + patchEntry.collection + '"]' : '';
|
|
455
|
-
var entryAttr = patchEntry.slug ? '[data-cms-entry="' + patchEntry.slug + '"]' : '';
|
|
456
|
-
var scopeSel = colAttr + entryAttr;
|
|
457
|
-
patchSelector = scopeSel + ' [data-cms-entry-field="' + fPath + '"], ' +
|
|
458
|
-
scopeSel + '[data-cms-entry-field="' + fPath + '"]';
|
|
459
|
-
} else if (patchEntry) {
|
|
460
|
-
patchSelector = '[data-cms-entry-field="' + fPath + '"]';
|
|
461
|
-
} else {
|
|
462
|
-
patchSelector = '[data-cms-field="' + patchKey + '"]';
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
var matchingEls = document.querySelectorAll(patchSelector);
|
|
466
|
-
for (var j = 0; j < matchingEls.length; j++) {
|
|
467
|
-
var mEl = matchingEls[j];
|
|
468
|
-
if (patchKind === 'image' || mEl.tagName.toLowerCase() === 'img') {
|
|
469
|
-
if (patchVal && typeof patchVal === 'object') {
|
|
470
|
-
if (patchVal.url) mEl.setAttribute('src', patchVal.url);
|
|
471
|
-
if (patchVal.alt !== undefined) mEl.setAttribute('alt', patchVal.alt);
|
|
472
|
-
} else if (typeof patchVal === 'string') {
|
|
473
|
-
mEl.setAttribute('src', patchVal);
|
|
474
|
-
}
|
|
475
|
-
} else if (patchKind === 'video' || mEl.tagName.toLowerCase() === 'video') {
|
|
476
|
-
if (patchVal && typeof patchVal === 'object') {
|
|
477
|
-
if (patchVal.url) mEl.setAttribute('src', patchVal.url);
|
|
478
|
-
if (patchVal.poster !== undefined) mEl.setAttribute('poster', patchVal.poster);
|
|
479
|
-
} else if (typeof patchVal === 'string') {
|
|
480
|
-
mEl.setAttribute('src', patchVal);
|
|
481
|
-
}
|
|
482
|
-
if (typeof mEl.load === 'function') mEl.load();
|
|
483
|
-
} else if (patchVal && typeof patchVal === 'object') {
|
|
484
|
-
// Structured non-image field values (e.g. videoList, geoArea, address) cannot be rendered
|
|
485
|
-
// via simple textContent replacement without producing [object Object].
|
|
486
|
-
// Skip the text write and leave server-rendered markup intact; structured fields refresh via reload.
|
|
487
|
-
} else {
|
|
488
|
-
mEl.textContent = patchVal !== null && patchVal !== undefined ? String(patchVal) : '';
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
isPatchingDom = false;
|
|
493
|
-
scanRenderedFields();
|
|
494
|
-
scheduleRectsUpdate();
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
if (data.type === 'scroll-to') {
|
|
499
|
-
var scrollKey = data.key;
|
|
500
|
-
var scrollInstance = typeof data.instance === 'number' ? data.instance : 0;
|
|
501
|
-
var scrollEls = document.querySelectorAll('[data-cms-field="' + scrollKey + '"], [data-cms-entry-field="' + scrollKey + '"]');
|
|
502
|
-
if (scrollEls.length > scrollInstance) {
|
|
503
|
-
scrollEls[scrollInstance].scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
504
|
-
activeKey = scrollKey;
|
|
505
|
-
scheduleRectsUpdate();
|
|
506
|
-
}
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
if (data.type === 'reload') {
|
|
511
|
-
window.location.reload();
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
window.addEventListener('scroll', scheduleRectsUpdate, { passive: true });
|
|
517
|
-
window.addEventListener('resize', scheduleRectsUpdate, { passive: true });
|
|
518
|
-
|
|
519
|
-
document.addEventListener('astro:page-load', scanRenderedFields);
|
|
520
|
-
document.addEventListener('astro:after-swap', scanRenderedFields);
|
|
521
|
-
|
|
522
|
-
if (document.readyState === 'loading') {
|
|
523
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
524
|
-
scanRenderedFields();
|
|
525
|
-
setupMutationObserver();
|
|
526
|
-
});
|
|
527
|
-
} else {
|
|
528
|
-
scanRenderedFields();
|
|
529
|
-
setupMutationObserver();
|
|
530
|
-
}
|
|
531
|
-
})();`;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// src/middleware/preview.ts
|
|
535
|
-
function createPreviewMiddleware(options = {}) {
|
|
536
|
-
let client = options.client;
|
|
537
|
-
return async (context, next) => {
|
|
538
|
-
const globalWithCms2 = globalThis;
|
|
539
|
-
if (typeof globalThis !== "undefined" && globalWithCms2.__CMS_IS_REWRITING__ || isDraftMode() || context.locals?.__cms_is_draft) {
|
|
540
|
-
return next();
|
|
541
|
-
}
|
|
542
|
-
const rawUrl = context.url;
|
|
543
|
-
const url = rawUrl && typeof rawUrl.href === "string" ? new URL(rawUrl.href) : rawUrl && typeof rawUrl.pathname === "string" ? rawUrl : new URL(context.request?.url || "/", "http://localhost");
|
|
544
|
-
const pathname = url.pathname || "/";
|
|
545
|
-
const isPreviewRoute = pathname === "/_preview" || pathname.startsWith("/_preview/");
|
|
546
|
-
const previewToken = (rawUrl?.searchParams?.get ? rawUrl.searchParams.get("preview_token") : null) || (url?.searchParams?.get ? url.searchParams.get("preview_token") : null) || (context.request?.headers?.get ? context.request.headers.get("x-preview-token") : null);
|
|
547
|
-
if (!isPreviewRoute && !previewToken) {
|
|
548
|
-
return next();
|
|
549
|
-
}
|
|
550
|
-
if (!client) {
|
|
551
|
-
client = getClient() || void 0;
|
|
552
|
-
}
|
|
553
|
-
if (!client) {
|
|
554
|
-
const metaEnv = import.meta.env;
|
|
555
|
-
const siteId = options.siteId || typeof process !== "undefined" && process.env?.CMS_SITE_ID || typeof import.meta !== "undefined" && metaEnv?.CMS_SITE_ID || "";
|
|
556
|
-
const contentUrl = options.contentUrl || typeof process !== "undefined" && process.env?.CMS_CONTENT_URL || typeof import.meta !== "undefined" && metaEnv?.CMS_CONTENT_URL || "";
|
|
557
|
-
const previewSecret = options.previewSecret || (typeof process !== "undefined" ? process.env?.CMS_PREVIEW_SECRET || process.env?.PREVIEW_TOKEN_SECRET || process.env?.JWT_SECRET : void 0) || (typeof import.meta !== "undefined" ? metaEnv?.CMS_PREVIEW_SECRET || metaEnv?.PREVIEW_TOKEN_SECRET || metaEnv?.JWT_SECRET : void 0);
|
|
558
|
-
if (siteId && contentUrl) {
|
|
559
|
-
client = createCmsClient({
|
|
560
|
-
siteId,
|
|
561
|
-
contentUrl,
|
|
562
|
-
previewSecret
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
if (!previewToken) {
|
|
567
|
-
return new Response("Preview token is missing", {
|
|
568
|
-
status: 400,
|
|
569
|
-
headers: {
|
|
570
|
-
"Cache-Control": "private, no-store",
|
|
571
|
-
"X-Robots-Tag": "noindex, nofollow"
|
|
572
|
-
}
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
if (!client) {
|
|
576
|
-
return new Response("CMS client is missing or not configured", {
|
|
577
|
-
status: 500,
|
|
578
|
-
headers: {
|
|
579
|
-
"Cache-Control": "private, no-store",
|
|
580
|
-
"X-Robots-Tag": "noindex, nofollow"
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
let secret = options.previewSecret || client.previewSecret || typeof process !== "undefined" && (process.env?.CMS_PREVIEW_SECRET || process.env?.PREVIEW_TOKEN_SECRET || process.env?.JWT_SECRET);
|
|
585
|
-
if (!secret) {
|
|
586
|
-
try {
|
|
587
|
-
secret = getJwtSecret();
|
|
588
|
-
} catch {
|
|
589
|
-
return new Response("Preview secret not configured", {
|
|
590
|
-
status: 404,
|
|
591
|
-
headers: {
|
|
592
|
-
"Cache-Control": "private, no-store",
|
|
593
|
-
"X-Robots-Tag": "noindex, nofollow"
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
const tokenResult = await verifyPreviewToken(previewToken, secret, client.siteId);
|
|
599
|
-
if (!tokenResult.valid) {
|
|
600
|
-
return new Response(tokenResult.error || "Invalid or expired preview token", {
|
|
601
|
-
status: 404,
|
|
602
|
-
headers: {
|
|
603
|
-
"Cache-Control": "private, no-store",
|
|
604
|
-
"X-Robots-Tag": "noindex, nofollow"
|
|
605
|
-
}
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
let draftBundle;
|
|
609
|
-
try {
|
|
610
|
-
draftBundle = await client.getBundle({ previewToken });
|
|
611
|
-
} catch (err) {
|
|
612
|
-
return new Response(
|
|
613
|
-
`Failed to fetch draft bundle: ${err instanceof Error ? err.message : String(err)}`,
|
|
614
|
-
{
|
|
615
|
-
status: 404,
|
|
616
|
-
headers: {
|
|
617
|
-
"Cache-Control": "private, no-store",
|
|
618
|
-
"X-Robots-Tag": "noindex, nofollow"
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
if (context.locals) {
|
|
624
|
-
context.locals.__cms_is_draft = true;
|
|
625
|
-
context.locals.__cms_draft_bundle = draftBundle;
|
|
626
|
-
}
|
|
627
|
-
let finalResponse;
|
|
628
|
-
setActiveDraftBundle(draftBundle);
|
|
629
|
-
try {
|
|
630
|
-
finalResponse = await runWithDraftBundle(draftBundle, async () => {
|
|
631
|
-
let response;
|
|
632
|
-
if (isPreviewRoute) {
|
|
633
|
-
const basePath = pathname.replace(/^\/_preview/, "") || "/";
|
|
634
|
-
if (typeof context.rewrite === "function") {
|
|
635
|
-
if (typeof globalThis !== "undefined") {
|
|
636
|
-
globalWithCms2.__CMS_IS_REWRITING__ = true;
|
|
637
|
-
}
|
|
638
|
-
try {
|
|
639
|
-
const rewritten = await context.rewrite(basePath);
|
|
640
|
-
if (rewritten) {
|
|
641
|
-
response = rewritten;
|
|
642
|
-
} else {
|
|
643
|
-
response = await next();
|
|
644
|
-
}
|
|
645
|
-
} finally {
|
|
646
|
-
if (typeof globalThis !== "undefined") {
|
|
647
|
-
globalWithCms2.__CMS_IS_REWRITING__ = false;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
} else {
|
|
651
|
-
response = await next();
|
|
652
|
-
}
|
|
653
|
-
} else {
|
|
654
|
-
response = await next();
|
|
655
|
-
}
|
|
656
|
-
const contentType = response?.headers?.get ? response.headers.get("content-type") : "";
|
|
657
|
-
const isStaticAsset = Boolean(
|
|
658
|
-
pathname.match(/\.(js|css|png|jpg|jpeg|gif|svg|ico|webp|woff|woff2|ttf|json|map)$/i)
|
|
659
|
-
);
|
|
660
|
-
const isHtml = typeof contentType === "string" && contentType.includes("text/html") || !contentType && !isStaticAsset;
|
|
661
|
-
if (isHtml) {
|
|
662
|
-
const html = await response.text();
|
|
663
|
-
const bridgeScript = buildBridgeScript({ editorOrigins: options.editorOrigins });
|
|
664
|
-
const scriptTag = `<script>${bridgeScript}</script>`;
|
|
665
|
-
const modifiedHtml = html.includes("</body>") ? html.replace("</body>", `${scriptTag}</body>`) : `${html}${scriptTag}`;
|
|
666
|
-
const newHeaders = new Headers(response.headers);
|
|
667
|
-
if (!newHeaders.has("content-type")) {
|
|
668
|
-
newHeaders.set("content-type", "text/html; charset=utf-8");
|
|
669
|
-
}
|
|
670
|
-
newHeaders.delete("content-length");
|
|
671
|
-
newHeaders.set("Cache-Control", "private, no-store, no-cache, must-revalidate");
|
|
672
|
-
newHeaders.set("X-Robots-Tag", "noindex, nofollow");
|
|
673
|
-
return new Response(modifiedHtml, {
|
|
674
|
-
status: response.status,
|
|
675
|
-
statusText: response.statusText,
|
|
676
|
-
headers: newHeaders
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
const nonHtmlHeaders = new Headers(response.headers);
|
|
680
|
-
nonHtmlHeaders.set("Cache-Control", "private, no-store, no-cache, must-revalidate");
|
|
681
|
-
nonHtmlHeaders.set("X-Robots-Tag", "noindex, nofollow");
|
|
682
|
-
return new Response(response.body, {
|
|
683
|
-
status: response.status,
|
|
684
|
-
statusText: response.statusText,
|
|
685
|
-
headers: nonHtmlHeaders
|
|
686
|
-
});
|
|
687
|
-
});
|
|
688
|
-
} finally {
|
|
689
|
-
setActiveDraftBundle(null);
|
|
690
|
-
}
|
|
691
|
-
return finalResponse;
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
export { buildBridgeScript, createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient };
|
|
696
|
-
//# sourceMappingURL=chunk-NI4NHXI4.js.map
|
|
697
|
-
//# sourceMappingURL=chunk-NI4NHXI4.js.map
|