@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/README.md
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
## Surface
|
|
8
8
|
|
|
9
|
-
- Declarative field helpers & scopes: [src/fields/index.ts](src/fields/index.ts) (`f`, `f.text`, `f.img`, `f.video`, `f.richText`, `f.number`, `f.toggle`, `f.select`, `f.videoList`, `f.geoArea`, `f.addressList`, `f.scope`, `f.entryScope`, `f.group`, `defineCollection`, `collectionPaths`)
|
|
9
|
+
- Declarative field helpers & scopes: [src/fields/index.ts](src/fields/index.ts) (`f`, `f.text`, `f.img`, `f.video`, `f.richText`, `f.number`, `f.toggle`, `f.select`, `f.videoList`, `f.geoArea`, `f.addressList`, `f.scope`, `f.entryScope`, `f.collectionAttrs`, `cmsCollectionAttr`, `f.group`, `defineCollection`, `collectionPaths`)
|
|
10
10
|
- Collection factories (`@407dev/cms-astro/collections`): [src/fields/collections.ts](src/fields/collections.ts) (`defineEmailCampaignCollection`, `defineSmsCampaignCollection`)
|
|
11
11
|
- Dynamic dual-callable helper generator derived from `@407dev/field-types`: [src/fields/helpers.ts](src/fields/helpers.ts)
|
|
12
12
|
- Scope & key prefixing: [src/fields/scope.ts](src/fields/scope.ts)
|
|
13
13
|
- Entry scoping: [src/fields/entryScope.ts](src/fields/entryScope.ts) (`f.entryScope`)
|
|
14
14
|
- Group definition & accessor binding: [src/fields/group.ts](src/fields/group.ts)
|
|
15
|
-
- Collection handle & routing: [src/fields/collection.ts](src/fields/collection.ts)
|
|
15
|
+
- Collection handle & routing: [src/fields/collection.ts](src/fields/collection.ts) (`collectionAttrs`)
|
|
16
16
|
- ProseMirror RichText renderer: [src/RichText.astro](src/RichText.astro) & [src/richtext/render.ts](src/richtext/render.ts)
|
|
17
17
|
- Preview bridge script generator: [src/preview/bridge-script.ts](src/preview/bridge-script.ts)
|
|
18
18
|
- Dev toolbar app & UI: [src/toolbar/app.ts](src/toolbar/app.ts) & [src/toolbar/widgets.ts](src/toolbar/widgets.ts)
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
|
|
33
33
|
- **Usage is the Schema**: Reading `f.text('home.hero.heading')` or `<f.text k="home.hero.heading" />` simultaneously marks the DOM editable region and defines the manifest entry for static extraction.
|
|
34
34
|
- **Dual-Callable Helpers**: Helpers work synchronously as functions (`f.text('key', { defaultValue: '...' })`) returning typed primitives or as Astro JSX components (`<f.text k="key" />`) emitting DOM marker attributes (`data-cms-field`, `data-cms-entry-field`).
|
|
35
|
-
- **Entry Scoping**: `f.entryScope('blog', entry.slug)` creates bound helpers
|
|
35
|
+
- **Entry Scoping & Collection Listings**: `f.entryScope('blog', entry.slug)` creates bound helpers emitting `data-cms-entry-field` and provides `.attrs()` emitting `data-cms-collection` + `data-cms-entry`. `f.collectionAttrs('blog')` emits `data-cms-collection` on listing containers for visual canvas collection editing.
|
|
36
36
|
- **Group Multiplication**: `f.group` defines reusable multi-field shapes instantiated at different prefixes (`Hero('home.hero')`, `Hero('about.hero')`), passing bound helpers to prop-drilled components.
|
|
37
|
-
- **Preview Bridge Injection**: In preview requests (`/_preview/*?preview_token=...`) and Astro dev mode, the bridge IIFE is injected before `</body>` to handle handshake, capabilities (`capabilities: ['comments']`), click capturing, comment mode click suppression, anchor chain derivation, live `anchor-rects` streaming, outlines, and DOM patching.
|
|
37
|
+
- **Preview Bridge Injection**: In preview requests (`/_preview/*?preview_token=...`) and Astro dev mode, the bridge IIFE is injected before `</body>` to handle handshake, capabilities (`capabilities: ['comments', 'collection-click']`), click capturing (field -> group -> entry -> collection priority), collection outlines with dashed borders and label chips, comment mode click suppression, anchor chain derivation, live `anchor-rects` streaming, outlines, and DOM patching.
|
|
38
38
|
- **Dev-Server Middleware API**: In dev mode (`command === 'dev'`), Vite middleware mounts `/_cms/dev/*` for status, bundle, and draft field writes without polluting production bundles.
|
|
39
39
|
- **Single Bundle Fetch**: Published bundle is fetched once per build and hydrated across all static pages synchronously via store singleton and `.cms/bundle.json`.
|
|
40
40
|
- **Zero-Config Integration**: `cmsAstro()` accepts no arguments, automatically falling back to environment variables `CMS_SITE_ID` and `CMS_CONTENT_URL` populated by `cms link` (preview secrets are never stored on site hosts; preview tokens are verified directly by content-worker).
|
|
@@ -24,6 +24,29 @@ function markBundleReady(bundle) {
|
|
|
24
24
|
function isBundleReady() {
|
|
25
25
|
return isReady || getActiveBundle() !== null;
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
// src/fields/attrs.ts
|
|
29
|
+
function cmsFieldAttr(key) {
|
|
30
|
+
return { "data-cms-field": key };
|
|
31
|
+
}
|
|
32
|
+
function cmsGroupAttr(groupName, prefix) {
|
|
33
|
+
return { "data-cms-group": `${groupName}:${prefix}` };
|
|
34
|
+
}
|
|
35
|
+
function cmsEntryAttr(collectionKey, slug) {
|
|
36
|
+
if (slug) {
|
|
37
|
+
return {
|
|
38
|
+
"data-cms-collection": collectionKey,
|
|
39
|
+
"data-cms-entry": slug
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return { "data-cms-collection": collectionKey };
|
|
43
|
+
}
|
|
44
|
+
function cmsCollectionAttr(collectionKey) {
|
|
45
|
+
return cmsEntryAttr(collectionKey);
|
|
46
|
+
}
|
|
47
|
+
function cmsEntryFieldAttr(path) {
|
|
48
|
+
return { "data-cms-entry-field": path };
|
|
49
|
+
}
|
|
27
50
|
function defineCollection(options) {
|
|
28
51
|
const jsonSchema = zodToJsonSchema(options.schema);
|
|
29
52
|
return {
|
|
@@ -67,7 +90,11 @@ async function collectionPaths(handleOrKey) {
|
|
|
67
90
|
}
|
|
68
91
|
}));
|
|
69
92
|
}
|
|
93
|
+
function collectionAttrs(handleOrKey) {
|
|
94
|
+
const collectionKey = typeof handleOrKey === "string" ? handleOrKey : handleOrKey.key;
|
|
95
|
+
return cmsCollectionAttr(collectionKey);
|
|
96
|
+
}
|
|
70
97
|
|
|
71
|
-
export { bundleReady, collectionPaths, defineCollection, getEntries, getEntry, isBundleReady, markBundleReady };
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
73
|
-
//# sourceMappingURL=chunk-
|
|
98
|
+
export { bundleReady, cmsCollectionAttr, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionAttrs, collectionPaths, defineCollection, getEntries, getEntry, isBundleReady, markBundleReady };
|
|
99
|
+
//# sourceMappingURL=chunk-SGHAANOW.js.map
|
|
100
|
+
//# sourceMappingURL=chunk-SGHAANOW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/bundle.ts","../src/fields/attrs.ts","../src/fields/collection.ts"],"names":[],"mappings":"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","file":"chunk-SGHAANOW.js","sourcesContent":["import type { ContentBundle } from '../types';\nimport { getActiveBundle, setBuildBundle } from './store';\n\nlet resolveBundleReady: ((bundle: ContentBundle) => void) | null = null;\nlet isReady = false;\n\nexport const bundleReady = new Promise<ContentBundle>((resolve) => {\n const active = getActiveBundle();\n if (active) {\n isReady = true;\n resolve(active);\n } else {\n resolveBundleReady = resolve;\n }\n});\n\nexport function markBundleReady(bundle: ContentBundle): void {\n setBuildBundle(bundle);\n isReady = true;\n if (resolveBundleReady) {\n resolveBundleReady(bundle);\n resolveBundleReady = null;\n }\n}\n\nexport function isBundleReady(): boolean {\n return isReady || getActiveBundle() !== null;\n}\n","export function cmsFieldAttr(key: string): { 'data-cms-field': string } {\n return { 'data-cms-field': key };\n}\n\nexport function cmsGroupAttr(groupName: string, prefix: string): { 'data-cms-group': string } {\n return { 'data-cms-group': `${groupName}:${prefix}` };\n}\n\nexport function cmsEntryAttr(\n collectionKey: string,\n slug?: string,\n): { 'data-cms-collection': string; 'data-cms-entry'?: string } {\n if (slug) {\n return {\n 'data-cms-collection': collectionKey,\n 'data-cms-entry': slug,\n };\n }\n return { 'data-cms-collection': collectionKey };\n}\n\nexport function cmsCollectionAttr(collectionKey: string): { 'data-cms-collection': string } {\n return cmsEntryAttr(collectionKey) as { 'data-cms-collection': string };\n}\n\nexport function cmsEntryFieldAttr(path: string): { 'data-cms-entry-field': string } {\n return { 'data-cms-entry-field': path };\n}\n","import { type z, zodToJsonSchema } from '@407dev/blocks';\nimport { bundleReady } from '../runtime/bundle';\nimport { getActiveBundle, isDraftMode } from '../runtime/store';\nimport { cmsCollectionAttr } from './attrs';\nimport type {\n CollectionEntry,\n CollectionHandle,\n CollectionStaticPath,\n DefineCollectionOptions,\n InferEntryContent,\n} from './types';\n\nexport function defineCollection<TSchema extends z.ZodTypeAny>(\n options: DefineCollectionOptions<TSchema>,\n): CollectionHandle<TSchema> {\n const jsonSchema = zodToJsonSchema(options.schema);\n\n return {\n key: options.key,\n schema: options.schema,\n route: options.route,\n presentation: options.presentation,\n titleField: options.titleField,\n listColumns: options.listColumns,\n bodyField: options.bodyField,\n orderable: options.orderable,\n seed: options.seed,\n jsonSchema: jsonSchema as Record<string, unknown>,\n schemaVersion: 1,\n };\n}\n\nexport function getEntries<T extends CollectionHandle<z.ZodTypeAny> | string>(\n handleOrKey: T,\n): Array<CollectionEntry<InferEntryContent<T>>> {\n const collectionKey = typeof handleOrKey === 'string' ? handleOrKey : handleOrKey.key;\n const bundle = getActiveBundle();\n const rawEntries = bundle?.entries?.[collectionKey] || [];\n const draft = isDraftMode();\n\n const filtered = draft ? rawEntries : rawEntries.filter((e) => e.status === 'published');\n\n return filtered as unknown as Array<CollectionEntry<InferEntryContent<T>>>;\n}\n\nexport function getEntry<T extends CollectionHandle<z.ZodTypeAny> | string>(\n handleOrKey: T,\n slug: string,\n): CollectionEntry<InferEntryContent<T>> | null {\n const entries = getEntries(handleOrKey);\n const found = entries.find((e) => e.slug === slug);\n return (found || null) as CollectionEntry<InferEntryContent<T>> | null;\n}\n\nexport async function collectionPaths<T extends CollectionHandle<z.ZodTypeAny> | string>(\n handleOrKey: T,\n): Promise<Array<CollectionStaticPath<InferEntryContent<T>>>> {\n const bundle = getActiveBundle() || (await bundleReady);\n const collectionKey = typeof handleOrKey === 'string' ? handleOrKey : handleOrKey.key;\n const rawEntries = bundle?.entries?.[collectionKey] || [];\n\n // Build static paths only for published entries\n const publishedEntries = rawEntries.filter((e) => e.status === 'published');\n\n return publishedEntries.map((entry) => ({\n params: {\n slug: entry.slug,\n },\n props: {\n entry: entry as CollectionEntry<InferEntryContent<T>>,\n },\n }));\n}\n\nexport function collectionAttrs<T extends CollectionHandle<z.ZodTypeAny> | string>(\n handleOrKey: T,\n): { 'data-cms-collection': string } {\n const collectionKey = typeof handleOrKey === 'string' ? handleOrKey : handleOrKey.key;\n return cmsCollectionAttr(collectionKey);\n}\n"]}
|
|
@@ -5,7 +5,7 @@ import { resolveEditorOrigins } from './chunk-XJPVYMZM.js';
|
|
|
5
5
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
|
-
version: "0.
|
|
8
|
+
version: "0.2.0"};
|
|
9
9
|
|
|
10
10
|
// src/version.ts
|
|
11
11
|
var CMS_ASTRO_VERSION = package_default.version;
|
|
@@ -33,8 +33,7 @@ function createCmsClient(config) {
|
|
|
33
33
|
headers["x-preview-token"] = options.previewToken;
|
|
34
34
|
}
|
|
35
35
|
const res = await fetchFn(url, {
|
|
36
|
-
headers
|
|
37
|
-
cache: "no-store"
|
|
36
|
+
headers
|
|
38
37
|
});
|
|
39
38
|
if (!res.ok) {
|
|
40
39
|
const error = new Error(
|
|
@@ -211,6 +210,13 @@ function buildBridgeScript(options = {}) {
|
|
|
211
210
|
'html[data-cms-edit-mode] [data-cms-group]:hover {',
|
|
212
211
|
' outline: 2px solid ${chromeTokens.success} !important;',
|
|
213
212
|
' outline-offset: 3px !important;',
|
|
213
|
+
'}',
|
|
214
|
+
'html[data-cms-edit-mode] [data-cms-collection] {',
|
|
215
|
+
' cursor: pointer !important;',
|
|
216
|
+
'}',
|
|
217
|
+
'html[data-cms-edit-mode] [data-cms-collection]:hover {',
|
|
218
|
+
' outline: 2px dashed ${chromeTokens.warning} !important;',
|
|
219
|
+
' outline-offset: 4px !important;',
|
|
214
220
|
'}'
|
|
215
221
|
].filter(Boolean).join('\\n');
|
|
216
222
|
|
|
@@ -703,6 +709,28 @@ function buildBridgeScript(options = {}) {
|
|
|
703
709
|
rect: gRect
|
|
704
710
|
});
|
|
705
711
|
}
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
var collectionEl = target.closest('[data-cms-collection]');
|
|
716
|
+
if (collectionEl) {
|
|
717
|
+
e.preventDefault();
|
|
718
|
+
e.stopPropagation();
|
|
719
|
+
|
|
720
|
+
var collKey = collectionEl.getAttribute('data-cms-collection') || '';
|
|
721
|
+
var entryEl = target.closest('[data-cms-entry]');
|
|
722
|
+
var slug = collectionEl.getAttribute('data-cms-entry') || (entryEl ? entryEl.getAttribute('data-cms-entry') : null) || undefined;
|
|
723
|
+
var cRect = getElementRect(collectionEl);
|
|
724
|
+
|
|
725
|
+
postToEditor({
|
|
726
|
+
source: 'cms-preview',
|
|
727
|
+
v: PROTOCOL_VERSION,
|
|
728
|
+
type: 'collection-click',
|
|
729
|
+
collection: collKey,
|
|
730
|
+
slug: slug,
|
|
731
|
+
rect: cRect
|
|
732
|
+
});
|
|
733
|
+
return;
|
|
706
734
|
}
|
|
707
735
|
}, true);
|
|
708
736
|
|
|
@@ -722,7 +750,7 @@ function buildBridgeScript(options = {}) {
|
|
|
722
750
|
v: PROTOCOL_VERSION,
|
|
723
751
|
type: 'ready',
|
|
724
752
|
protocolVersion: PROTOCOL_VERSION,
|
|
725
|
-
capabilities: ['comments']
|
|
753
|
+
capabilities: ['comments', 'collection-click']
|
|
726
754
|
});
|
|
727
755
|
|
|
728
756
|
scanRenderedFields();
|
|
@@ -927,9 +955,20 @@ function createPreviewMiddleware(options = {}) {
|
|
|
927
955
|
let draftBundle;
|
|
928
956
|
try {
|
|
929
957
|
draftBundle = await client.getBundle({ previewToken });
|
|
930
|
-
} catch (
|
|
931
|
-
|
|
932
|
-
|
|
958
|
+
} catch (err) {
|
|
959
|
+
const status = err?.status;
|
|
960
|
+
if (status === 401 || status === 403 || status === 404) {
|
|
961
|
+
return new Response("Preview token is not valid for this site", {
|
|
962
|
+
status: 404,
|
|
963
|
+
headers: {
|
|
964
|
+
"Cache-Control": "private, no-store",
|
|
965
|
+
"X-Robots-Tag": "noindex, nofollow"
|
|
966
|
+
}
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
console.error(err);
|
|
970
|
+
return new Response("Failed to load preview content", {
|
|
971
|
+
status: 502,
|
|
933
972
|
headers: {
|
|
934
973
|
"Cache-Control": "private, no-store",
|
|
935
974
|
"X-Robots-Tag": "noindex, nofollow"
|
|
@@ -976,7 +1015,9 @@ function createPreviewMiddleware(options = {}) {
|
|
|
976
1015
|
const isHtml = typeof contentType === "string" && contentType.includes("text/html") || !contentType && !isStaticAsset;
|
|
977
1016
|
if (isHtml) {
|
|
978
1017
|
const html = await response.text();
|
|
979
|
-
const bridgeScript = buildBridgeScript({
|
|
1018
|
+
const bridgeScript = buildBridgeScript({
|
|
1019
|
+
editorOrigins: options.editorOrigins
|
|
1020
|
+
});
|
|
980
1021
|
const scriptTag = `<script>${bridgeScript}</script>`;
|
|
981
1022
|
const modifiedHtml = html.includes("</body>") ? html.replace("</body>", `${scriptTag}</body>`) : `${html}${scriptTag}`;
|
|
982
1023
|
const newHeaders = new Headers(response.headers);
|
|
@@ -1009,5 +1050,5 @@ function createPreviewMiddleware(options = {}) {
|
|
|
1009
1050
|
}
|
|
1010
1051
|
|
|
1011
1052
|
export { buildBridgeScript, createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient };
|
|
1012
|
-
//# sourceMappingURL=chunk-
|
|
1013
|
-
//# sourceMappingURL=chunk-
|
|
1053
|
+
//# sourceMappingURL=chunk-YCQMH2T7.js.map
|
|
1054
|
+
//# sourceMappingURL=chunk-YCQMH2T7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/version.ts","../src/client.ts","../src/preview/bridge-script.ts","../src/middleware/preview.ts"],"names":["globalWithCms"],"mappings":"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A;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AA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","file":"chunk-YCQMH2T7.js","sourcesContent":["{\n \"name\": \"@407dev/cms-astro\",\n \"version\": \"0.2.0\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/407dev/cms.git\",\n \"directory\": \"packages/astro\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"source\": \"./src/index.ts\",\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./collections\": {\n \"source\": \"./src/fields/collections.ts\",\n \"types\": \"./dist/fields/collections.d.ts\",\n \"import\": \"./dist/fields/collections.js\"\n },\n \"./CmsImage.astro\": \"./src/CmsImage.astro\",\n \"./CmsVideo.astro\": \"./src/CmsVideo.astro\",\n \"./CmsHead.astro\": \"./src/CmsHead.astro\",\n \"./RichText.astro\": \"./src/RichText.astro\",\n \"./middleware\": {\n \"source\": \"./src/middleware/index.ts\",\n \"types\": \"./dist/middleware/index.d.ts\",\n \"import\": \"./dist/middleware/index.js\",\n \"default\": \"./dist/middleware/index.js\"\n },\n \"./toolbar\": {\n \"source\": \"./src/toolbar/app.ts\",\n \"types\": \"./dist/toolbar/app.d.ts\",\n \"import\": \"./dist/toolbar/app.js\",\n \"default\": \"./dist/toolbar/app.js\"\n },\n \"./dev\": {\n \"source\": \"./src/dev/index.ts\",\n \"types\": \"./dist/dev/index.d.ts\",\n \"import\": \"./dist/dev/index.js\",\n \"default\": \"./dist/dev/index.js\"\n }\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"files\": [\n \"dist\",\n \"src\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"biome check src\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\"\n },\n \"dependencies\": {\n \"@407dev/blocks\": \"workspace:*\",\n \"@407dev/field-types\": \"workspace:*\",\n \"zod\": \"^4.4.3\"\n },\n \"peerDependencies\": {\n \"@407dev/cli\": \"workspace:*\",\n \"astro\": \"^5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"@407dev/cli\": {\n \"optional\": true\n },\n \"astro\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@407dev/api-client\": \"workspace:*\",\n \"@407dev/cli\": \"workspace:*\",\n \"@407dev/config\": \"workspace:*\",\n \"@407dev/design-tokens\": \"workspace:*\",\n \"astro\": \"^5.3.0\",\n \"expect-type\": \"^0.20.0\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.7.3\",\n \"vite\": \"^6.1.0\",\n \"vitest\": \"3.0.7\"\n }\n}\n","import pkg from '../package.json';\n\nexport const CMS_ASTRO_VERSION: string = pkg.version;\n","import { DEFAULT_DEV_CONTENT_URL } from '@407dev/config';\nimport type {\n CmsClient,\n CmsClientConfig,\n CmsSiteConfig,\n ContentBundle,\n GetBundleOptions,\n} from './types';\nimport { CMS_ASTRO_VERSION } from './version.js';\n\nexport function createCmsClient(config: CmsClientConfig): CmsClient {\n const siteId = config.siteId;\n const contentUrl = config.contentUrl.replace(/\\/+$/, '');\n const fetchFn = config.fetch || fetch;\n\n // In-memory cache for published bundle to ensure build determinism\n let cachedPublishedBundle: ContentBundle | null = null;\n\n const client: CmsClient = {\n siteId,\n contentUrl,\n previewSecret: config.previewSecret,\n\n async getBundle(options?: GetBundleOptions): Promise<ContentBundle> {\n const isDraft = Boolean(options?.previewToken);\n\n if (!isDraft && cachedPublishedBundle) {\n return cachedPublishedBundle;\n }\n\n const url = isDraft\n ? `${contentUrl}/draft/${siteId}/bundle`\n : `${contentUrl}/content/${siteId}/bundle`;\n\n const headers: Record<string, string> = {\n 'x-cms-sdk': `cms-astro@${CMS_ASTRO_VERSION}`,\n };\n if (options?.previewToken) {\n headers['x-preview-token'] = options.previewToken;\n }\n\n const res = await fetchFn(url, {\n headers,\n });\n if (!res.ok) {\n const error = new Error(\n `CMS Client: Failed to fetch bundle from ${url} (status ${res.status}): ${res.statusText}`,\n );\n (error as unknown as { status?: number }).status = res.status;\n throw error;\n }\n\n const bundle = (await res.json()) as ContentBundle;\n\n if (!isDraft) {\n cachedPublishedBundle = bundle;\n }\n\n return bundle;\n },\n\n async getFields(options?: GetBundleOptions): Promise<ContentBundle['fields']> {\n const bundle = await this.getBundle(options);\n return bundle.fields || {};\n },\n\n async getField<T = unknown>(key: string, options?: GetBundleOptions): Promise<T | null> {\n const fields = await this.getFields(options);\n return (fields[key] as T) ?? null;\n },\n\n async getCollections(options?: GetBundleOptions): Promise<ContentBundle['collections']> {\n const bundle = await this.getBundle(options);\n return bundle.collections || {};\n },\n\n async getEntries(\n collectionKey: string,\n options?: GetBundleOptions,\n ): Promise<ContentBundle['entries'][string]> {\n const bundle = await this.getBundle(options);\n return bundle.entries?.[collectionKey] || [];\n },\n\n async getEntry(\n collectionKey: string,\n slug: string,\n options?: GetBundleOptions,\n ): Promise<ContentBundle['entries'][string][number] | null> {\n const entries = await this.getEntries(collectionKey, options);\n return entries.find((e) => e.slug === slug) || null;\n },\n\n async getRoutes(options?: GetBundleOptions): Promise<ContentBundle['routes']> {\n const bundle = await this.getBundle(options);\n return bundle.routes || [];\n },\n\n async getSiteConfig(options?: GetBundleOptions): Promise<CmsSiteConfig> {\n const bundle = await this.getBundle(options);\n return {\n site_id: bundle.site_id,\n redirects: bundle.redirects || [],\n robots: bundle.settings?.robots || {},\n default_seo: bundle.settings?.default_seo || {},\n sitemap: bundle.settings?.sitemap || {},\n not_found_path: bundle.settings?.not_found_path || null,\n };\n },\n\n clearCache(): void {\n cachedPublishedBundle = null;\n },\n };\n\n return client;\n}\n\nconst globalWithCms = globalThis as typeof globalThis & {\n __CMS_CLIENT__?: CmsClient | null;\n};\n\nlet globalClient: CmsClient | null =\n (typeof globalThis !== 'undefined' && globalWithCms.__CMS_CLIENT__) || null;\n\nexport function initCmsClient(options: {\n siteId?: string;\n contentUrl?: string;\n previewSecret?: string;\n client?: CmsClient;\n}): CmsClient {\n if (options.client) {\n globalClient = options.client;\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_CLIENT__ = options.client;\n }\n return globalClient;\n }\n\n globalClient = createCmsClient({\n siteId: options.siteId || process.env.CMS_SITE_ID || '',\n contentUrl: options.contentUrl || process.env.CMS_CONTENT_URL || DEFAULT_DEV_CONTENT_URL,\n previewSecret: options.previewSecret || process.env.CMS_PREVIEW_SECRET,\n });\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_CLIENT__ = globalClient;\n }\n\n return globalClient;\n}\n\nexport function getClient(): CmsClient | null {\n return (\n globalClient || (typeof globalThis !== 'undefined' && globalWithCms.__CMS_CLIENT__) || null\n );\n}\n\nexport function setClient(client: CmsClient | null): void {\n globalClient = client;\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_CLIENT__ = client;\n }\n}\n","import { chromeTokens } from '@407dev/design-tokens/tokens';\nimport { resolveEditorOrigins } from './origins';\n\nexport const BRIDGE_PROTOCOL_VERSION = 1;\n\nexport interface BridgeScriptOptions {\n editorOrigins?: string[];\n}\n\nexport function buildBridgeScript(options: BridgeScriptOptions = {}): string {\n const allowedOrigins = resolveEditorOrigins(options.editorOrigins);\n const allowedOriginsJson = JSON.stringify(allowedOrigins);\n\n return `(function() {\n if (typeof window === 'undefined') return;\n if (window.__CMS_BRIDGE_INITIALIZED__) return;\n window.__CMS_BRIDGE_INITIALIZED__ = true;\n\n var PROTOCOL_VERSION = ${BRIDGE_PROTOCOL_VERSION};\n var allowedOrigins = ${allowedOriginsJson};\n var connectedOrigin = null;\n var connectedSource = null;\n var activeKey = null;\n var watchedAnchors = [];\n var rafScheduled = false;\n var isPatchingDom = false;\n var debounceRescanTimer = null;\n\n function normalizeOrigin(raw) {\n if (!raw || typeof raw !== 'string') return null;\n var trimmed = raw.trim();\n if (!trimmed) return null;\n try {\n var withScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:\\\\/\\\\//.test(trimmed) ? trimmed : 'https://' + trimmed;\n var url = new URL(withScheme);\n if (!url.protocol || !url.host) return null;\n return (url.protocol + '//' + url.host).toLowerCase();\n } catch (e) {\n return null;\n }\n }\n\n var normalizedAllowed = allowedOrigins.map(normalizeOrigin).filter(Boolean);\n\n function isOriginAllowed(origin) {\n var norm = normalizeOrigin(origin);\n if (!norm) return false;\n return normalizedAllowed.indexOf(norm) !== -1;\n }\n\n function postToEditor(msg) {\n if (!connectedSource || !connectedOrigin) return;\n try {\n connectedSource.postMessage(msg, connectedOrigin);\n } catch (err) {\n // Failed to post\n }\n }\n\n // Inject Bridge Styles\n var isEmbedded = false;\n try {\n isEmbedded = window.self !== window.top || window.parent !== window;\n } catch (_e) {\n isEmbedded = true;\n }\n\n var toolbarTag = 'astro-' + 'dev-toolbar';\n\n function ensureBridgeStyles() {\n if (typeof document === 'undefined' || !document || typeof document.getElementById !== 'function') return;\n if (document.getElementById('cms-bridge-styles')) return;\n var style = document.createElement('style');\n style.id = 'cms-bridge-styles';\n style.textContent = [\n isEmbedded ? toolbarTag + ' { display: none !important; }' : '',\n 'html[data-cms-comment-mode],',\n 'html[data-cms-comment-mode] * {',\n ' cursor: crosshair !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-field],',\n 'html[data-cms-edit-mode] [data-cms-entry-field] {',\n ' cursor: pointer !important;',\n ' outline: 1px dashed rgba(99, 102, 241, 0.5) !important;',\n ' outline-offset: 2px !important;',\n ' transition: outline 0.15s ease-in-out !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-field]:hover,',\n 'html[data-cms-edit-mode] [data-cms-entry-field]:hover {',\n ' outline: 2px solid ${chromeTokens.primary} !important;',\n ' outline-offset: 2px !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-group] {',\n ' outline: 1px dashed rgba(16, 185, 129, 0.4) !important;',\n ' outline-offset: 3px !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-group]:hover {',\n ' outline: 2px solid ${chromeTokens.success} !important;',\n ' outline-offset: 3px !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-collection] {',\n ' cursor: pointer !important;',\n '}',\n 'html[data-cms-edit-mode] [data-cms-collection]:hover {',\n ' outline: 2px dashed ${chromeTokens.warning} !important;',\n ' outline-offset: 4px !important;',\n '}'\n ].filter(Boolean).join('\\\\n');\n\n var target = document.head || document.documentElement;\n if (target) {\n target.appendChild(style);\n }\n }\n\n function hideDevToolbar() {\n if (!isEmbedded) return;\n ensureBridgeStyles();\n if (typeof document === 'undefined' || !document || typeof document.querySelector !== 'function') return;\n try {\n var tb = document.querySelector(toolbarTag);\n if (tb && tb instanceof HTMLElement) {\n tb.style.setProperty('display', 'none', 'important');\n }\n } catch (_e) {}\n }\n\n ensureBridgeStyles();\n hideDevToolbar();\n\n function inferFieldKind(el) {\n if (!el) return 'unknown';\n var tag = el.tagName ? el.tagName.toLowerCase() : '';\n if (tag === 'img') return 'image';\n if (tag === 'video') return 'video';\n var explicitKind = el.getAttribute('data-cms-kind');\n if (explicitKind) return explicitKind;\n if (el.classList.contains('rich-body') || el.classList.contains('cms-richtext') || el.getAttribute('data-cms-richtext') === 'true') {\n return 'richtext';\n }\n return 'text';\n }\n\n function getElementRect(el) {\n var r = el.getBoundingClientRect();\n return {\n top: r.top,\n left: r.left,\n width: r.width,\n height: r.height\n };\n }\n\n function parseGroupAttr(raw) {\n if (!raw) return undefined;\n var idx = raw.indexOf(':');\n if (idx === -1) return { group: raw, scope: '' };\n return {\n group: raw.slice(0, idx),\n scope: raw.slice(idx + 1)\n };\n }\n\n function scanRenderedFields() {\n var fieldEls = document.querySelectorAll('[data-cms-field], [data-cms-entry-field]');\n var fieldMap = {};\n\n for (var i = 0; i < fieldEls.length; i++) {\n var el = fieldEls[i];\n var key = el.getAttribute('data-cms-field') || el.getAttribute('data-cms-entry-field') || '';\n if (!key) continue;\n\n var isEntry = el.hasAttribute('data-cms-entry-field');\n var groupEl = el.closest('[data-cms-group]');\n var collectionEl = el.closest('[data-cms-collection]');\n var groupName = undefined;\n if (groupEl) {\n var g = parseGroupAttr(groupEl.getAttribute('data-cms-group'));\n if (g) groupName = g.group;\n }\n\n var entryRef = undefined;\n if (isEntry || collectionEl) {\n entryRef = {\n collection: collectionEl ? collectionEl.getAttribute('data-cms-collection') || '' : '',\n slug: collectionEl ? collectionEl.getAttribute('data-cms-entry') || '' : '',\n path: isEntry ? key : key\n };\n }\n\n var uniqueId = (isEntry && entryRef ? entryRef.collection + ':' + entryRef.slug + ':' : '') + key;\n\n if (!fieldMap[uniqueId]) {\n fieldMap[uniqueId] = {\n key: key,\n kind: inferFieldKind(el),\n group: groupName,\n entryRef: entryRef,\n instances: 1\n };\n } else {\n fieldMap[uniqueId].instances++;\n }\n }\n\n var fields = [];\n for (var k in fieldMap) {\n if (Object.prototype.hasOwnProperty.call(fieldMap, k)) {\n fields.push(fieldMap[k]);\n }\n }\n\n window.__CMS_FIELDS__ = fields;\n window.__CMS_RESCAN__ = scanRenderedFields;\n\n try {\n document.dispatchEvent(new CustomEvent('cms:fields-updated', { detail: fields }));\n } catch (_e) {}\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'rendered-fields',\n fields: fields\n });\n }\n\n function debouncedRescan() {\n if (isPatchingDom) return;\n if (debounceRescanTimer) clearTimeout(debounceRescanTimer);\n debounceRescanTimer = setTimeout(function() {\n scanRenderedFields();\n scheduleRectsUpdate();\n }, 150);\n }\n\n var currentObserver = null;\n function setupMutationObserver() {\n if (typeof MutationObserver === 'undefined' || !document.body) return;\n if (currentObserver) {\n try {\n currentObserver.disconnect();\n } catch (_e) {}\n }\n currentObserver = new MutationObserver(function(mutations) {\n if (isPatchingDom) return;\n hideDevToolbar();\n debouncedRescan();\n });\n currentObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributeFilter: ['data-cms-field', 'data-cms-entry-field', 'data-cms-group', 'data-cms-collection', 'data-cms-entry']\n });\n }\n\n function buildStableSelector(target) {\n if (!target || !target.tagName) return '';\n if (target === document.documentElement) return 'html';\n if (target === document.body) return 'body';\n\n var parts = [];\n var curr = target;\n var maxLevels = 8;\n\n while (curr && curr !== document.documentElement && parts.length < maxLevels) {\n if (curr === document.body) {\n parts.unshift('body');\n break;\n }\n var id = curr.getAttribute('id');\n if (id && id.trim()) {\n var escapedId = (typeof CSS !== 'undefined' && CSS.escape) ? CSS.escape(id.trim()) : id.trim();\n parts.unshift('#' + escapedId);\n break;\n }\n var tag = curr.tagName ? curr.tagName.toLowerCase() : '';\n if (!tag) break;\n var count = 1;\n var sib = curr.previousElementSibling;\n while (sib) {\n if (sib.tagName && sib.tagName.toLowerCase() === tag) {\n count++;\n }\n sib = sib.previousElementSibling;\n }\n parts.unshift(tag + ':nth-of-type(' + count + ')');\n curr = curr.parentElement;\n }\n\n return parts.join(' > ');\n }\n\n function buildElementLabel(el) {\n if (!el || !el.tagName) return 'element';\n\n var ariaLabel = el.getAttribute('aria-label');\n if (ariaLabel && ariaLabel.trim()) {\n return ariaLabel.trim();\n }\n\n var id = el.getAttribute('id');\n if (id && id.trim()) {\n return '#' + id.trim();\n }\n\n var tag = el.tagName.toLowerCase();\n\n if (tag === 'nav') return 'Navigation';\n if (tag === 'header') return 'Header';\n if (tag === 'footer') return 'Footer';\n if (tag === 'aside') return 'Sidebar';\n if (tag === 'form') return 'Form';\n\n if (tag === 'img') {\n var alt = el.getAttribute('alt');\n if (alt && alt.trim()) return alt.trim();\n return 'img';\n }\n\n if (tag === 'a' || tag === 'button') {\n var text = (el.textContent || '').trim().replace(/\\\\s+/g, ' ');\n if (text) {\n return text.length > 40 ? text.slice(0, 37) + '...' : text;\n }\n return tag;\n }\n\n return tag || 'element';\n }\n\n function buildCandidateEntry(targetEl, clientX, clientY) {\n if (!targetEl || !targetEl.tagName) return null;\n var selector = buildStableSelector(targetEl);\n if (!selector) return null;\n var all = Array.prototype.slice.call(document.querySelectorAll(selector));\n var instance = Math.max(0, all.indexOf(targetEl));\n var hitRect = targetEl.getBoundingClientRect();\n var offsetX = typeof clientX === 'number' ? Math.round(clientX - hitRect.left) : 0;\n var offsetY = typeof clientY === 'number' ? Math.round(clientY - hitRect.top) : 0;\n return {\n selector: selector,\n instance: instance,\n kind: 'element',\n label: buildElementLabel(targetEl),\n offsetX: offsetX,\n offsetY: offsetY,\n rect: getElementRect(targetEl)\n };\n }\n\n function buildAnchorChain(el, clientX, clientY) {\n var chain = [];\n var curr = el;\n while (curr && curr !== document.documentElement && curr !== document.body) {\n var hit = curr.closest('[data-cms-field], [data-cms-entry-field], [data-cms-group], [data-cms-collection][data-cms-entry]');\n if (!hit) break;\n\n var selector = '';\n var kind = 'unknown';\n var label = '';\n\n if (hit.hasAttribute('data-cms-field')) {\n var fieldKey = hit.getAttribute('data-cms-field') || '';\n selector = '[data-cms-field=\"' + fieldKey + '\"]';\n kind = inferFieldKind(hit);\n label = fieldKey;\n } else if (hit.hasAttribute('data-cms-entry-field')) {\n var entryFieldKey = hit.getAttribute('data-cms-entry-field') || '';\n selector = '[data-cms-entry-field=\"' + entryFieldKey + '\"]';\n kind = inferFieldKind(hit);\n label = entryFieldKey;\n } else if (hit.hasAttribute('data-cms-group')) {\n var groupAttr = hit.getAttribute('data-cms-group') || '';\n selector = '[data-cms-group=\"' + groupAttr + '\"]';\n kind = 'group';\n var parsed = parseGroupAttr(groupAttr);\n label = parsed ? parsed.group : groupAttr;\n } else if (hit.hasAttribute('data-cms-collection') && hit.hasAttribute('data-cms-entry')) {\n var col = hit.getAttribute('data-cms-collection') || '';\n var ent = hit.getAttribute('data-cms-entry') || '';\n selector = '[data-cms-collection=\"' + col + '\"][data-cms-entry=\"' + ent + '\"]';\n kind = 'entry';\n label = col + '/' + ent;\n }\n\n if (selector) {\n var all = Array.prototype.slice.call(document.querySelectorAll(selector));\n var instance = Math.max(0, all.indexOf(hit));\n var hitRect = hit.getBoundingClientRect();\n var offsetX = typeof clientX === 'number' ? Math.round(clientX - hitRect.left) : 0;\n var offsetY = typeof clientY === 'number' ? Math.round(clientY - hitRect.top) : 0;\n chain.push({\n selector: selector,\n instance: instance,\n kind: kind,\n label: label,\n offsetX: offsetX,\n offsetY: offsetY,\n rect: getElementRect(hit)\n });\n }\n\n curr = hit.parentElement;\n }\n\n if (chain.length > 0) {\n return chain;\n }\n\n if (!el || !el.tagName) return chain;\n\n var interactiveEl = el.closest ? el.closest('a, button') : null;\n var selfEl = interactiveEl || (el.closest ? el.closest('a, button, nav, header, footer, aside, main, section, article, form, img, svg, [role]') : null) || el;\n var landmarkEl = selfEl.closest ? selfEl.closest('nav, header, footer, aside, main, section, article, form, [role=\"navigation\"], [role=\"banner\"], [role=\"contentinfo\"]') : null;\n\n var selfEntry = buildCandidateEntry(selfEl, clientX, clientY);\n if (selfEntry) {\n chain.push(selfEntry);\n }\n\n if (landmarkEl && landmarkEl !== selfEl) {\n var landmarkEntry = buildCandidateEntry(landmarkEl, clientX, clientY);\n if (landmarkEntry) {\n chain.push(landmarkEntry);\n }\n }\n\n return chain;\n }\n\n function resolveAnchorEl(anchor) {\n if (!anchor || !anchor.selector) return null;\n try {\n var els = document.querySelectorAll(anchor.selector);\n if (!els || els.length === 0) return null;\n var inst = typeof anchor.instance === 'number' ? anchor.instance : 0;\n if (inst >= 0 && inst < els.length) return els[inst];\n return els[0];\n } catch (_e) {\n return null;\n }\n }\n\n function scheduleRectsUpdate() {\n if (rafScheduled) return;\n rafScheduled = true;\n requestAnimationFrame(function() {\n rafScheduled = false;\n var rects = {};\n if (activeKey) {\n var el = document.querySelector('[data-cms-field=\"' + activeKey + '\"], [data-cms-entry-field=\"' + activeKey + '\"]');\n if (el) {\n rects[activeKey] = getElementRect(el);\n }\n }\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'rects-update',\n rects: rects,\n scrollY: window.scrollY || window.pageYOffset || 0\n });\n\n if (watchedAnchors && watchedAnchors.length > 0) {\n var anchorRects = {};\n for (var a = 0; a < watchedAnchors.length; a++) {\n var wAnchor = watchedAnchors[a];\n var resolvedEl = resolveAnchorEl(wAnchor);\n if (resolvedEl) {\n anchorRects[wAnchor.id] = getElementRect(resolvedEl);\n } else {\n anchorRects[wAnchor.id] = null;\n }\n }\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'anchor-rects',\n rects: anchorRects\n });\n }\n });\n }\n\n // Click handler\n document.addEventListener('click', function(e) {\n if (document.documentElement.hasAttribute('data-cms-comment-mode')) {\n e.preventDefault();\n e.stopPropagation();\n var target = e.target;\n if (!target || !(target instanceof Element)) return;\n\n var docWidth = Math.max(\n document.documentElement.scrollWidth || 0,\n document.body ? document.body.scrollWidth : 0,\n window.innerWidth || 0\n );\n var docHeight = Math.max(\n document.documentElement.scrollHeight || 0,\n document.body ? document.body.scrollHeight : 0,\n window.innerHeight || 0\n );\n var pageX = e.pageX !== undefined ? e.pageX : (e.clientX + (window.scrollX || window.pageXOffset || 0));\n var pageY = e.pageY !== undefined ? e.pageY : (e.clientY + (window.scrollY || window.pageYOffset || 0));\n var pageXPct = docWidth > 0 ? Math.round((pageX / docWidth) * 10000) / 100 : 0;\n var pageYPct = docHeight > 0 ? Math.round((pageY / docHeight) * 10000) / 100 : 0;\n\n var chain = buildAnchorChain(target, e.clientX, e.clientY);\n var clickRect = chain.length > 0 ? chain[0].rect : {\n top: e.clientY,\n left: e.clientX,\n width: 0,\n height: 0\n };\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'comment-click',\n chain: chain,\n point: { pageXPct: pageXPct, pageYPct: pageYPct },\n rect: clickRect\n });\n return;\n }\n\n if (!document.documentElement.hasAttribute('data-cms-edit-mode')) return;\n var target = e.target;\n if (!target || !(target instanceof Element)) return;\n\n var fieldEl = target.closest('[data-cms-field], [data-cms-entry-field]');\n var groupEl = target.closest('[data-cms-group]');\n\n if (fieldEl) {\n e.preventDefault();\n e.stopPropagation();\n\n var isEntry = fieldEl.hasAttribute('data-cms-entry-field');\n var key = fieldEl.getAttribute('data-cms-field') || fieldEl.getAttribute('data-cms-entry-field') || '';\n var kind = inferFieldKind(fieldEl);\n var rect = getElementRect(fieldEl);\n activeKey = key;\n\n var selector = isEntry ? '[data-cms-entry-field=\"' + key + '\"]' : '[data-cms-field=\"' + key + '\"]';\n var all = Array.prototype.slice.call(document.querySelectorAll(selector));\n var instance = Math.max(0, all.indexOf(fieldEl));\n\n var collectionEl = fieldEl.closest('[data-cms-collection]');\n var entryRef = (isEntry || collectionEl) ? {\n collection: collectionEl ? collectionEl.getAttribute('data-cms-collection') || '' : '',\n slug: collectionEl ? collectionEl.getAttribute('data-cms-entry') || '' : '',\n path: isEntry ? key : key\n } : undefined;\n\n var groupPath = groupEl ? parseGroupAttr(groupEl.getAttribute('data-cms-group')) : undefined;\n\n try {\n document.dispatchEvent(new CustomEvent('cms:field-selected', {\n detail: {\n key: key,\n kind: kind,\n entryRef: entryRef,\n groupPath: groupPath\n }\n }));\n } catch (_e) {}\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'field-click',\n key: key,\n kind: kind,\n rect: rect,\n instance: instance,\n entryRef: entryRef,\n groupPath: groupPath\n });\n return;\n }\n\n if (groupEl) {\n e.preventDefault();\n e.stopPropagation();\n\n var g = parseGroupAttr(groupEl.getAttribute('data-cms-group'));\n if (g) {\n var gRect = getElementRect(groupEl);\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'group-click',\n group: g.group,\n scope: g.scope,\n rect: gRect\n });\n }\n return;\n }\n\n var collectionEl = target.closest('[data-cms-collection]');\n if (collectionEl) {\n e.preventDefault();\n e.stopPropagation();\n\n var collKey = collectionEl.getAttribute('data-cms-collection') || '';\n var entryEl = target.closest('[data-cms-entry]');\n var slug = collectionEl.getAttribute('data-cms-entry') || (entryEl ? entryEl.getAttribute('data-cms-entry') : null) || undefined;\n var cRect = getElementRect(collectionEl);\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'collection-click',\n collection: collKey,\n slug: slug,\n rect: cRect\n });\n return;\n }\n }, true);\n\n // Message handler\n window.addEventListener('message', function(e) {\n var data = e.data;\n if (!data || typeof data !== 'object') return;\n if (data.source !== 'cms-editor') return;\n\n if (data.type === 'hello') {\n if (!isOriginAllowed(e.origin)) return;\n connectedOrigin = e.origin;\n connectedSource = e.source;\n\n postToEditor({\n source: 'cms-preview',\n v: PROTOCOL_VERSION,\n type: 'ready',\n protocolVersion: PROTOCOL_VERSION,\n capabilities: ['comments', 'collection-click']\n });\n\n scanRenderedFields();\n return;\n }\n\n if (!connectedOrigin || e.origin !== connectedOrigin) return;\n\n if (data.type === 'highlight-mode') {\n if (data.on) {\n document.documentElement.setAttribute('data-cms-edit-mode', 'true');\n } else {\n document.documentElement.removeAttribute('data-cms-edit-mode');\n }\n return;\n }\n\n if (data.type === 'comment-mode') {\n if (data.on) {\n document.documentElement.setAttribute('data-cms-comment-mode', 'true');\n } else {\n document.documentElement.removeAttribute('data-cms-comment-mode');\n }\n return;\n }\n\n if (data.type === 'watch-anchors') {\n watchedAnchors = Array.isArray(data.anchors) ? data.anchors : [];\n scheduleRectsUpdate();\n return;\n }\n\n if (data.type === 'scroll-to-anchor') {\n var sId = data.id;\n var targetItem = null;\n for (var si = 0; si < watchedAnchors.length; si++) {\n if (watchedAnchors[si].id === sId) {\n targetItem = watchedAnchors[si];\n break;\n }\n }\n if (targetItem) {\n var elToScroll = resolveAnchorEl(targetItem);\n if (elToScroll) {\n elToScroll.scrollIntoView({ behavior: 'smooth', block: 'center' });\n scheduleRectsUpdate();\n }\n }\n return;\n }\n\n if (data.type === 'patch') {\n isPatchingDom = true;\n var patchKey = data.key;\n var patchKind = data.kind;\n var patchVal = data.value;\n var patchEntry = data.entryRef;\n\n var patchSelector;\n var fPath = patchEntry && patchEntry.path ? patchEntry.path : patchKey;\n if (patchEntry && (patchEntry.collection || patchEntry.slug)) {\n var colAttr = patchEntry.collection ? '[data-cms-collection=\"' + patchEntry.collection + '\"]' : '';\n var entryAttr = patchEntry.slug ? '[data-cms-entry=\"' + patchEntry.slug + '\"]' : '';\n var scopeSel = colAttr + entryAttr;\n patchSelector = scopeSel + ' [data-cms-entry-field=\"' + fPath + '\"], ' +\n scopeSel + '[data-cms-entry-field=\"' + fPath + '\"]';\n } else if (patchEntry) {\n patchSelector = '[data-cms-entry-field=\"' + fPath + '\"]';\n } else {\n patchSelector = '[data-cms-field=\"' + patchKey + '\"]';\n }\n\n var matchingEls = document.querySelectorAll(patchSelector);\n for (var j = 0; j < matchingEls.length; j++) {\n var mEl = matchingEls[j];\n var isStructured = patchKind === 'geo.area' || patchKind === 'geoArea' ||\n patchKind === 'address' || patchKind === 'address.list' ||\n patchKind === 'media.videoList' || patchKind === 'videoList' ||\n mEl.getAttribute('data-cms-kind') === 'geo.area' ||\n mEl.getAttribute('data-cms-kind') === 'address.list' ||\n mEl.getAttribute('data-cms-kind') === 'media.videoList';\n\n if (patchKind === 'image' || mEl.tagName.toLowerCase() === 'img') {\n if (patchVal && typeof patchVal === 'object') {\n if (patchVal.url) mEl.setAttribute('src', patchVal.url);\n if (patchVal.alt !== undefined) mEl.setAttribute('alt', patchVal.alt);\n } else if (typeof patchVal === 'string') {\n mEl.setAttribute('src', patchVal);\n }\n } else if (patchKind === 'video' || mEl.tagName.toLowerCase() === 'video') {\n if (patchVal && typeof patchVal === 'object') {\n if (patchVal.url) mEl.setAttribute('src', patchVal.url);\n if (patchVal.poster !== undefined) mEl.setAttribute('poster', patchVal.poster);\n } else if (typeof patchVal === 'string') {\n mEl.setAttribute('src', patchVal);\n }\n if (typeof mEl.load === 'function') mEl.load();\n } else if (isStructured || (patchVal && typeof patchVal === 'object')) {\n // Structured non-image field values (e.g. videoList, geoArea, address) cannot be rendered\n // via simple textContent replacement without producing [object Object].\n // Skip the text write and leave server-rendered markup intact; structured fields refresh via reload.\n } else {\n mEl.textContent = patchVal !== null && patchVal !== undefined ? String(patchVal) : '';\n }\n }\n\n isPatchingDom = false;\n scanRenderedFields();\n scheduleRectsUpdate();\n return;\n }\n\n if (data.type === 'scroll-to') {\n var scrollKey = data.key;\n var scrollInstance = typeof data.instance === 'number' ? data.instance : 0;\n var scrollEls = document.querySelectorAll('[data-cms-field=\"' + scrollKey + '\"], [data-cms-entry-field=\"' + scrollKey + '\"]');\n if (scrollEls.length > scrollInstance) {\n scrollEls[scrollInstance].scrollIntoView({ behavior: 'smooth', block: 'center' });\n activeKey = scrollKey;\n scheduleRectsUpdate();\n }\n return;\n }\n\n if (data.type === 'reload') {\n window.location.reload();\n return;\n }\n });\n\n function handlePageTransition() {\n hideDevToolbar();\n scanRenderedFields();\n setupMutationObserver();\n }\n\n window.addEventListener('scroll', scheduleRectsUpdate, { passive: true });\n window.addEventListener('resize', scheduleRectsUpdate, { passive: true });\n\n document.addEventListener('astro:page-load', handlePageTransition);\n document.addEventListener('astro:after-swap', handlePageTransition);\n window.addEventListener('popstate', handlePageTransition);\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', function() {\n handlePageTransition();\n });\n } else {\n handlePageTransition();\n }\n})();`;\n}\n","import { createCmsClient, getClient } from '../client';\nimport { buildBridgeScript } from '../preview/bridge-script';\nimport { isDraftMode, runWithDraftBundle, setActiveDraftBundle } from '../runtime/store';\nimport type { CmsClient, ContentBundle } from '../types';\n\nexport interface PreviewMiddlewareOptions {\n client?: CmsClient;\n siteId?: string;\n contentUrl?: string;\n /** @deprecated Site hosts no longer verify preview tokens. Ignored outside astro dev. */\n previewSecret?: string;\n editorOrigins?: string[];\n}\n\ninterface PreviewContextLocals {\n __cms_is_draft?: boolean;\n __cms_draft_bundle?: ContentBundle;\n [key: string]: unknown;\n}\n\nexport interface PreviewMiddlewareContext {\n request: Request;\n url?: URL;\n locals?: PreviewContextLocals;\n rewrite?: (path: string) => Promise<Response> | undefined;\n}\n\nexport function createPreviewMiddleware(options: PreviewMiddlewareOptions = {}) {\n let client = options.client;\n\n return async (\n context: PreviewMiddlewareContext,\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const globalWithCms = globalThis as typeof globalThis & {\n __CMS_IS_REWRITING__?: boolean;\n };\n\n // If already running within an active draft bundle context or internal rewrite, pass through\n if (\n (typeof globalThis !== 'undefined' && globalWithCms.__CMS_IS_REWRITING__) ||\n isDraftMode() ||\n context.locals?.__cms_is_draft\n ) {\n return next();\n }\n\n const rawUrl = context.url;\n const url =\n rawUrl && typeof rawUrl.href === 'string'\n ? new URL(rawUrl.href)\n : rawUrl && typeof (rawUrl as unknown as { pathname?: string }).pathname === 'string'\n ? rawUrl\n : new URL(context.request?.url || '/', 'http://localhost');\n const pathname = url.pathname || '/';\n const isPreviewRoute = pathname === '/_preview' || pathname.startsWith('/_preview/');\n\n const previewToken =\n (rawUrl?.searchParams?.get ? rawUrl.searchParams.get('preview_token') : null) ||\n (url?.searchParams?.get ? url.searchParams.get('preview_token') : null) ||\n (context.request?.headers?.get ? context.request.headers.get('x-preview-token') : null);\n\n if (!isPreviewRoute && !previewToken) {\n return next();\n }\n\n if (!client) {\n client = getClient() || undefined;\n }\n\n if (!client) {\n const metaEnv = (import.meta as unknown as { env?: Record<string, string | undefined> }).env;\n const siteId =\n options.siteId ||\n (typeof process !== 'undefined' && process.env?.CMS_SITE_ID) ||\n (typeof import.meta !== 'undefined' && metaEnv?.CMS_SITE_ID) ||\n '';\n const contentUrl =\n options.contentUrl ||\n (typeof process !== 'undefined' && process.env?.CMS_CONTENT_URL) ||\n (typeof import.meta !== 'undefined' && metaEnv?.CMS_CONTENT_URL) ||\n '';\n if (siteId && contentUrl) {\n client = createCmsClient({\n siteId,\n contentUrl,\n });\n }\n }\n\n if (!previewToken) {\n return new Response('Preview token is missing', {\n status: 400,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n if (!client) {\n return new Response('CMS client is missing or not configured', {\n status: 500,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n let draftBundle: ContentBundle;\n try {\n draftBundle = await client.getBundle({ previewToken });\n } catch (err) {\n const status = (err as { status?: number })?.status;\n if (status === 401 || status === 403 || status === 404) {\n return new Response('Preview token is not valid for this site', {\n status: 404,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n console.error(err);\n return new Response('Failed to load preview content', {\n status: 502,\n headers: {\n 'Cache-Control': 'private, no-store',\n 'X-Robots-Tag': 'noindex, nofollow',\n },\n });\n }\n\n // Run downstream request within the draft bundle context\n if (context.locals) {\n context.locals.__cms_is_draft = true;\n context.locals.__cms_draft_bundle = draftBundle;\n }\n\n let finalResponse: Response;\n setActiveDraftBundle(draftBundle);\n try {\n finalResponse = await runWithDraftBundle(draftBundle, async () => {\n let response: Response;\n if (isPreviewRoute) {\n const basePath = pathname.replace(/^\\/_preview/, '') || '/';\n if (typeof context.rewrite === 'function') {\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_IS_REWRITING__ = true;\n }\n try {\n const rewritten = await context.rewrite(basePath);\n if (rewritten) {\n response = rewritten as Response;\n } else {\n response = await next();\n }\n } finally {\n if (typeof globalThis !== 'undefined') {\n globalWithCms.__CMS_IS_REWRITING__ = false;\n }\n }\n } else {\n response = await next();\n }\n } else {\n response = await next();\n }\n\n const contentType = response?.headers?.get ? response.headers.get('content-type') : '';\n const isStaticAsset = Boolean(\n pathname.match(/\\.(js|css|png|jpg|jpeg|gif|svg|ico|webp|woff|woff2|ttf|json|map)$/i),\n );\n const isHtml =\n (typeof contentType === 'string' && contentType.includes('text/html')) ||\n (!contentType && !isStaticAsset);\n\n if (isHtml) {\n const html = await response.text();\n const bridgeScript = buildBridgeScript({\n editorOrigins: options.editorOrigins,\n });\n const scriptTag = `<script>${bridgeScript}</script>`;\n const modifiedHtml = html.includes('</body>')\n ? html.replace('</body>', `${scriptTag}</body>`)\n : `${html}${scriptTag}`;\n\n const newHeaders = new Headers(response.headers);\n if (!newHeaders.has('content-type')) {\n newHeaders.set('content-type', 'text/html; charset=utf-8');\n }\n newHeaders.delete('content-length');\n newHeaders.set('Cache-Control', 'private, no-store, no-cache, must-revalidate');\n newHeaders.set('X-Robots-Tag', 'noindex, nofollow');\n\n return new Response(modifiedHtml, {\n status: response.status,\n statusText: response.statusText,\n headers: newHeaders,\n });\n }\n\n const nonHtmlHeaders = new Headers(response.headers);\n nonHtmlHeaders.set('Cache-Control', 'private, no-store, no-cache, must-revalidate');\n nonHtmlHeaders.set('X-Robots-Tag', 'noindex, nofollow');\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: nonHtmlHeaders,\n });\n });\n } finally {\n setActiveDraftBundle(null);\n }\n\n return finalResponse;\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,9 @@ declare function defineCollection<TSchema extends z.ZodTypeAny>(options: DefineC
|
|
|
21
21
|
declare function getEntries<T extends CollectionHandle<z.ZodTypeAny> | string>(handleOrKey: T): Array<CollectionEntry<InferEntryContent<T>>>;
|
|
22
22
|
declare function getEntry<T extends CollectionHandle<z.ZodTypeAny> | string>(handleOrKey: T, slug: string): CollectionEntry<InferEntryContent<T>> | null;
|
|
23
23
|
declare function collectionPaths<T extends CollectionHandle<z.ZodTypeAny> | string>(handleOrKey: T): Promise<Array<CollectionStaticPath<InferEntryContent<T>>>>;
|
|
24
|
+
declare function collectionAttrs<T extends CollectionHandle<z.ZodTypeAny> | string>(handleOrKey: T): {
|
|
25
|
+
'data-cms-collection': string;
|
|
26
|
+
};
|
|
24
27
|
|
|
25
28
|
declare function createEntryDualCallableHelper<TValue = unknown, TDefault = TValue>(typeId: string, publicName: string, collectionKey: string, slug: string, defaultPath?: string): DualCallableHelper<TValue, TDefault>;
|
|
26
29
|
type EntryScopeAccessor = {
|
|
@@ -57,6 +60,9 @@ declare function cmsEntryAttr(collectionKey: string, slug?: string): {
|
|
|
57
60
|
'data-cms-collection': string;
|
|
58
61
|
'data-cms-entry'?: string;
|
|
59
62
|
};
|
|
63
|
+
declare function cmsCollectionAttr(collectionKey: string): {
|
|
64
|
+
'data-cms-collection': string;
|
|
65
|
+
};
|
|
60
66
|
declare function cmsEntryFieldAttr(path: string): {
|
|
61
67
|
'data-cms-entry-field': string;
|
|
62
68
|
};
|
|
@@ -69,6 +75,7 @@ type CmsF = FieldHelpersMap & {
|
|
|
69
75
|
entry: typeof getEntry;
|
|
70
76
|
defineCollection: typeof defineCollection;
|
|
71
77
|
collectionPaths: typeof collectionPaths;
|
|
78
|
+
collectionAttrs: typeof collectionAttrs;
|
|
72
79
|
};
|
|
73
80
|
declare const f: CmsF;
|
|
74
81
|
|
|
@@ -232,4 +239,4 @@ interface SitemapRouteItem {
|
|
|
232
239
|
*/
|
|
233
240
|
declare function renderSitemapXml(routes: SitemapRouteItem[], options: RenderSitemapOptions): string;
|
|
234
241
|
|
|
235
|
-
export { type BuildHeadTagsOptions, CmsAstroOptions, CmsClient, CmsClientConfig, type CmsF, CmsRedirect, CmsSiteConfig, CollectionEntry, CollectionHandle, CollectionStaticPath, ContentBundle, DEFAULT_EDITOR_ORIGINS, DefineCollectionOptions, DualCallableHelper, type EntryScopeAccessor, FieldHelpersMap, FieldScope, type GetPreviewDataOptions, GroupDefinition, type HeadRouteInput, type HeadTag, type ImageTransformOptions, InferEntryContent, KNOWN_NODES, type LinkMarkAttrs, type PreviewBundleResult, type RenderRobotsOptions, type RenderSitemapOptions, type RichTextNodeShape, type RichTextRenderOptions, RouteSeo, type SitemapRouteItem, VerifyTokenResult, buildCdnImageUrl, buildHeadTags, buildSrcSet, bundleReady, clearMissingFieldWarnings, cms, cmsAstro, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionPaths, createCmsClient, createEntryDualCallableHelper, createEntryScope, createScope, defineCollection, defineGroup, entryScope, escapeHtml, f, getActiveBundle, getBuildBundle, getClient, getEntries, getEntry, getLinkMarkAttrs, getMissingFieldWarnings, getPreviewData, initCmsClient, isBundleReady, isCdnTransformableUrl, isDraftMode, markBundleReady, parseRichTextDoc, recordMissingField, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml, resolveEditorOrigins, runWithDraftBundle, setActiveDraftBundle, setBuildBundle, setClient, signPreviewToken, updateBundleFieldValue, verifyPreviewToken };
|
|
242
|
+
export { type BuildHeadTagsOptions, CmsAstroOptions, CmsClient, CmsClientConfig, type CmsF, CmsRedirect, CmsSiteConfig, CollectionEntry, CollectionHandle, CollectionStaticPath, ContentBundle, DEFAULT_EDITOR_ORIGINS, DefineCollectionOptions, DualCallableHelper, type EntryScopeAccessor, FieldHelpersMap, FieldScope, type GetPreviewDataOptions, GroupDefinition, type HeadRouteInput, type HeadTag, type ImageTransformOptions, InferEntryContent, KNOWN_NODES, type LinkMarkAttrs, type PreviewBundleResult, type RenderRobotsOptions, type RenderSitemapOptions, type RichTextNodeShape, type RichTextRenderOptions, RouteSeo, type SitemapRouteItem, VerifyTokenResult, buildCdnImageUrl, buildHeadTags, buildSrcSet, bundleReady, clearMissingFieldWarnings, cms, cmsAstro, cmsCollectionAttr, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionAttrs, collectionPaths, createCmsClient, createEntryDualCallableHelper, createEntryScope, createScope, defineCollection, defineGroup, entryScope, escapeHtml, f, getActiveBundle, getBuildBundle, getClient, getEntries, getEntry, getLinkMarkAttrs, getMissingFieldWarnings, getPreviewData, initCmsClient, isBundleReady, isCdnTransformableUrl, isDraftMode, markBundleReady, parseRichTextDoc, recordMissingField, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml, resolveEditorOrigins, runWithDraftBundle, setActiveDraftBundle, setBuildBundle, setClient, signPreviewToken, updateBundleFieldValue, verifyPreviewToken };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { mintDevPreviewToken } from './chunk-7LMUFCWX.js';
|
|
2
2
|
export { signPreviewToken, verifyPreviewToken } from './chunk-7LMUFCWX.js';
|
|
3
|
-
import { collectionPaths, defineCollection, getEntry, getEntries, markBundleReady } from './chunk-
|
|
4
|
-
export { bundleReady, collectionPaths, defineCollection, getEntries, getEntry, isBundleReady, markBundleReady } from './chunk-
|
|
5
|
-
import { initCmsClient, buildBridgeScript, getClient } from './chunk-
|
|
6
|
-
export { createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient } from './chunk-
|
|
3
|
+
import { collectionAttrs, collectionPaths, defineCollection, getEntry, getEntries, markBundleReady, cmsEntryAttr, cmsGroupAttr } from './chunk-SGHAANOW.js';
|
|
4
|
+
export { bundleReady, cmsCollectionAttr, cmsEntryAttr, cmsEntryFieldAttr, cmsFieldAttr, cmsGroupAttr, collectionAttrs, collectionPaths, defineCollection, getEntries, getEntry, isBundleReady, markBundleReady } from './chunk-SGHAANOW.js';
|
|
5
|
+
import { initCmsClient, buildBridgeScript, getClient } from './chunk-YCQMH2T7.js';
|
|
6
|
+
export { createCmsClient, createPreviewMiddleware, getClient, initCmsClient, setClient } from './chunk-YCQMH2T7.js';
|
|
7
7
|
import './chunk-B4YYLS7Y.js';
|
|
8
8
|
import { getActiveBundle, recordMissingField, getMissingFieldWarnings, clearMissingFieldWarnings } from './chunk-DMLOBKYE.js';
|
|
9
9
|
export { clearMissingFieldWarnings, getActiveBundle, getBuildBundle, getMissingFieldWarnings, isDraftMode, recordMissingField, runWithDraftBundle, setActiveDraftBundle, setBuildBundle, updateBundleFieldValue } from './chunk-DMLOBKYE.js';
|
|
@@ -185,26 +185,6 @@ function renderRichTextHtml(doc, options = {}) {
|
|
|
185
185
|
}
|
|
186
186
|
return renderNode(root);
|
|
187
187
|
}
|
|
188
|
-
|
|
189
|
-
// src/fields/attrs.ts
|
|
190
|
-
function cmsFieldAttr(key) {
|
|
191
|
-
return { "data-cms-field": key };
|
|
192
|
-
}
|
|
193
|
-
function cmsGroupAttr(groupName, prefix) {
|
|
194
|
-
return { "data-cms-group": `${groupName}:${prefix}` };
|
|
195
|
-
}
|
|
196
|
-
function cmsEntryAttr(collectionKey, slug) {
|
|
197
|
-
if (slug) {
|
|
198
|
-
return {
|
|
199
|
-
"data-cms-collection": collectionKey,
|
|
200
|
-
"data-cms-entry": slug
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
return { "data-cms-collection": collectionKey };
|
|
204
|
-
}
|
|
205
|
-
function cmsEntryFieldAttr(path2) {
|
|
206
|
-
return { "data-cms-entry-field": path2 };
|
|
207
|
-
}
|
|
208
188
|
var DEFAULT_TAGS = {
|
|
209
189
|
text: "span",
|
|
210
190
|
number: "span",
|
|
@@ -574,7 +554,8 @@ var f = {
|
|
|
574
554
|
entries: getEntries,
|
|
575
555
|
entry: getEntry,
|
|
576
556
|
defineCollection,
|
|
577
|
-
collectionPaths
|
|
557
|
+
collectionPaths,
|
|
558
|
+
collectionAttrs
|
|
578
559
|
};
|
|
579
560
|
|
|
580
561
|
// src/head.ts
|
|
@@ -792,22 +773,42 @@ function cmsAstro(options = {}) {
|
|
|
792
773
|
}
|
|
793
774
|
const activeClient = getClient();
|
|
794
775
|
if (activeClient) {
|
|
776
|
+
let bundle;
|
|
795
777
|
try {
|
|
796
778
|
const devPreviewToken = command === "dev" ? await mintDevPreviewToken(activeClient.siteId, effectivePreviewSecret) : null;
|
|
797
|
-
|
|
779
|
+
bundle = await activeClient.getBundle(
|
|
798
780
|
devPreviewToken ? { previewToken: devPreviewToken } : void 0
|
|
799
781
|
);
|
|
782
|
+
} catch (err) {
|
|
783
|
+
if (command === "build") {
|
|
784
|
+
const status = err?.status;
|
|
785
|
+
if (status === 404) {
|
|
786
|
+
logger.warn(
|
|
787
|
+
"CMS bundle not found (no published version yet); building without it."
|
|
788
|
+
);
|
|
789
|
+
} else if (status !== void 0) {
|
|
790
|
+
throw err;
|
|
791
|
+
} else {
|
|
792
|
+
const url = `${activeClient.contentUrl.replace(/\/+$/, "")}/content/${activeClient.siteId}/bundle`;
|
|
793
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
794
|
+
throw new Error(
|
|
795
|
+
`Failed to fetch CMS bundle from ${url} (unreachable): ${message}`,
|
|
796
|
+
{
|
|
797
|
+
cause: err
|
|
798
|
+
}
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
if (bundle) {
|
|
800
804
|
markBundleReady(bundle);
|
|
801
805
|
const cmsDir = path.resolve(process.cwd(), ".cms");
|
|
802
|
-
|
|
803
|
-
fs.mkdirSync(cmsDir, { recursive: true });
|
|
804
|
-
}
|
|
806
|
+
fs.mkdirSync(cmsDir, { recursive: true });
|
|
805
807
|
fs.writeFileSync(
|
|
806
808
|
path.join(cmsDir, "bundle.json"),
|
|
807
809
|
JSON.stringify(bundle, null, 2),
|
|
808
810
|
"utf-8"
|
|
809
811
|
);
|
|
810
|
-
} catch {
|
|
811
812
|
}
|
|
812
813
|
}
|
|
813
814
|
},
|
|
@@ -951,6 +952,6 @@ ${urlEntries.join("\n")}
|
|
|
951
952
|
`;
|
|
952
953
|
}
|
|
953
954
|
|
|
954
|
-
export { KNOWN_NODES, buildCdnImageUrl, buildHeadTags, buildSrcSet, cms, cmsAstro,
|
|
955
|
+
export { KNOWN_NODES, buildCdnImageUrl, buildHeadTags, buildSrcSet, cms, cmsAstro, createEntryDualCallableHelper, createEntryScope, createScope, defineGroup, entryScope, escapeHtml, f, getLinkMarkAttrs, getPreviewData, isCdnTransformableUrl, parseRichTextDoc, renderMarksOnly, renderRedirectsFile, renderRichTextHtml, renderRobotsTxt, renderSitemapXml };
|
|
955
956
|
//# sourceMappingURL=index.js.map
|
|
956
957
|
//# sourceMappingURL=index.js.map
|