@407dev/cms-astro 0.1.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.
Files changed (212) hide show
  1. package/README.md +69 -0
  2. package/dist/chunk-2TKIQIOE.js +118 -0
  3. package/dist/chunk-2TKIQIOE.js.map +1 -0
  4. package/dist/chunk-53OQ5RXJ.js +912 -0
  5. package/dist/chunk-53OQ5RXJ.js.map +1 -0
  6. package/dist/chunk-56OMNQLH.js +1013 -0
  7. package/dist/chunk-56OMNQLH.js.map +1 -0
  8. package/dist/chunk-5AOOMQ7K.js +1031 -0
  9. package/dist/chunk-5AOOMQ7K.js.map +1 -0
  10. package/dist/chunk-5XRUCFDC.js +743 -0
  11. package/dist/chunk-5XRUCFDC.js.map +1 -0
  12. package/dist/chunk-62ZHCOLZ.js +25 -0
  13. package/dist/chunk-62ZHCOLZ.js.map +1 -0
  14. package/dist/chunk-6AZLRSYA.js +126 -0
  15. package/dist/chunk-6AZLRSYA.js.map +1 -0
  16. package/dist/chunk-6L3ZTCFB.js +14 -0
  17. package/dist/chunk-6L3ZTCFB.js.map +1 -0
  18. package/dist/chunk-6O7ZNNDT.js +697 -0
  19. package/dist/chunk-6O7ZNNDT.js.map +1 -0
  20. package/dist/chunk-6PQIXTMK.js +697 -0
  21. package/dist/chunk-6PQIXTMK.js.map +1 -0
  22. package/dist/chunk-7AW6M7QW.js +1013 -0
  23. package/dist/chunk-7AW6M7QW.js.map +1 -0
  24. package/dist/chunk-7E3XJLKX.js +73 -0
  25. package/dist/chunk-7E3XJLKX.js.map +1 -0
  26. package/dist/chunk-7LM54OTA.js +1031 -0
  27. package/dist/chunk-7LM54OTA.js.map +1 -0
  28. package/dist/chunk-7LMUFCWX.js +126 -0
  29. package/dist/chunk-7LMUFCWX.js.map +1 -0
  30. package/dist/chunk-A3OGL4OX.js +706 -0
  31. package/dist/chunk-A3OGL4OX.js.map +1 -0
  32. package/dist/chunk-AO4UAWOV.js +1030 -0
  33. package/dist/chunk-AO4UAWOV.js.map +1 -0
  34. package/dist/chunk-B4YYLS7Y.js +14 -0
  35. package/dist/chunk-B4YYLS7Y.js.map +1 -0
  36. package/dist/chunk-BDFVGXM2.js +697 -0
  37. package/dist/chunk-BDFVGXM2.js.map +1 -0
  38. package/dist/chunk-CXM7NZVX.js +1031 -0
  39. package/dist/chunk-CXM7NZVX.js.map +1 -0
  40. package/dist/chunk-DMLOBKYE.js +96 -0
  41. package/dist/chunk-DMLOBKYE.js.map +1 -0
  42. package/dist/chunk-DXJSYGS6.js +743 -0
  43. package/dist/chunk-DXJSYGS6.js.map +1 -0
  44. package/dist/chunk-EFUSAQZM.js +72 -0
  45. package/dist/chunk-EFUSAQZM.js.map +1 -0
  46. package/dist/chunk-F7KDGPBN.js +1013 -0
  47. package/dist/chunk-F7KDGPBN.js.map +1 -0
  48. package/dist/chunk-FBSQT45X.js +126 -0
  49. package/dist/chunk-FBSQT45X.js.map +1 -0
  50. package/dist/chunk-FEPDOMVH.js +697 -0
  51. package/dist/chunk-FEPDOMVH.js.map +1 -0
  52. package/dist/chunk-FQDOL2QW.js +25 -0
  53. package/dist/chunk-FQDOL2QW.js.map +1 -0
  54. package/dist/chunk-GB3LGQJM.js +109 -0
  55. package/dist/chunk-GB3LGQJM.js.map +1 -0
  56. package/dist/chunk-HCNP6R3P.js +736 -0
  57. package/dist/chunk-HCNP6R3P.js.map +1 -0
  58. package/dist/chunk-J6WEJDRI.js +743 -0
  59. package/dist/chunk-J6WEJDRI.js.map +1 -0
  60. package/dist/chunk-JHEAPNJ2.js +117 -0
  61. package/dist/chunk-JHEAPNJ2.js.map +1 -0
  62. package/dist/chunk-JOJDJ6GW.js +25 -0
  63. package/dist/chunk-JOJDJ6GW.js.map +1 -0
  64. package/dist/chunk-KTDV6WYB.js +202 -0
  65. package/dist/chunk-KTDV6WYB.js.map +1 -0
  66. package/dist/chunk-KZWJBKPC.js +734 -0
  67. package/dist/chunk-KZWJBKPC.js.map +1 -0
  68. package/dist/chunk-LEAQBGL6.js +109 -0
  69. package/dist/chunk-LEAQBGL6.js.map +1 -0
  70. package/dist/chunk-LGZJL2Q7.js +697 -0
  71. package/dist/chunk-LGZJL2Q7.js.map +1 -0
  72. package/dist/chunk-LQPBU46R.js +109 -0
  73. package/dist/chunk-LQPBU46R.js.map +1 -0
  74. package/dist/chunk-M55NNUTY.js +1013 -0
  75. package/dist/chunk-M55NNUTY.js.map +1 -0
  76. package/dist/chunk-M6NCYCC3.js +1013 -0
  77. package/dist/chunk-M6NCYCC3.js.map +1 -0
  78. package/dist/chunk-MGN7OZAU.js +109 -0
  79. package/dist/chunk-MGN7OZAU.js.map +1 -0
  80. package/dist/chunk-MGYZOX4K.js +1013 -0
  81. package/dist/chunk-MGYZOX4K.js.map +1 -0
  82. package/dist/chunk-MY4IEKJS.js +1031 -0
  83. package/dist/chunk-MY4IEKJS.js.map +1 -0
  84. package/dist/chunk-NCQRGAB4.js +705 -0
  85. package/dist/chunk-NCQRGAB4.js.map +1 -0
  86. package/dist/chunk-NI4NHXI4.js +697 -0
  87. package/dist/chunk-NI4NHXI4.js.map +1 -0
  88. package/dist/chunk-NPI5N7AU.js +14 -0
  89. package/dist/chunk-NPI5N7AU.js.map +1 -0
  90. package/dist/chunk-QN4CPMJF.js +126 -0
  91. package/dist/chunk-QN4CPMJF.js.map +1 -0
  92. package/dist/chunk-QYUVAKMC.js +1013 -0
  93. package/dist/chunk-QYUVAKMC.js.map +1 -0
  94. package/dist/chunk-RAAT6PDT.js +25 -0
  95. package/dist/chunk-RAAT6PDT.js.map +1 -0
  96. package/dist/chunk-RDPO5VPS.js +1013 -0
  97. package/dist/chunk-RDPO5VPS.js.map +1 -0
  98. package/dist/chunk-RQHIW2PF.js +25 -0
  99. package/dist/chunk-RQHIW2PF.js.map +1 -0
  100. package/dist/chunk-RREVHA52.js +722 -0
  101. package/dist/chunk-RREVHA52.js.map +1 -0
  102. package/dist/chunk-S7PT4PZN.js +25 -0
  103. package/dist/chunk-S7PT4PZN.js.map +1 -0
  104. package/dist/chunk-SUXV5M32.js +109 -0
  105. package/dist/chunk-SUXV5M32.js.map +1 -0
  106. package/dist/chunk-SZEORUY6.js +696 -0
  107. package/dist/chunk-SZEORUY6.js.map +1 -0
  108. package/dist/chunk-T7NGGWGY.js +25 -0
  109. package/dist/chunk-T7NGGWGY.js.map +1 -0
  110. package/dist/chunk-UEVWP5VE.js +696 -0
  111. package/dist/chunk-UEVWP5VE.js.map +1 -0
  112. package/dist/chunk-UJNKNP7U.js +748 -0
  113. package/dist/chunk-UJNKNP7U.js.map +1 -0
  114. package/dist/chunk-V4XVFWFI.js +1013 -0
  115. package/dist/chunk-V4XVFWFI.js.map +1 -0
  116. package/dist/chunk-VJU2CIKZ.js +729 -0
  117. package/dist/chunk-VJU2CIKZ.js.map +1 -0
  118. package/dist/chunk-VRQUP5L3.js +202 -0
  119. package/dist/chunk-VRQUP5L3.js.map +1 -0
  120. package/dist/chunk-WBJ5E7CL.js +742 -0
  121. package/dist/chunk-WBJ5E7CL.js.map +1 -0
  122. package/dist/chunk-XJPVYMZM.js +24 -0
  123. package/dist/chunk-XJPVYMZM.js.map +1 -0
  124. package/dist/chunk-Y3Q65C7R.js +14 -0
  125. package/dist/chunk-Y3Q65C7R.js.map +1 -0
  126. package/dist/chunk-YHEGFPTR.js +1030 -0
  127. package/dist/chunk-YHEGFPTR.js.map +1 -0
  128. package/dist/chunk-ZDLBN46C.js +697 -0
  129. package/dist/chunk-ZDLBN46C.js.map +1 -0
  130. package/dist/dev/index.d.ts +122 -0
  131. package/dist/dev/index.js +662 -0
  132. package/dist/dev/index.js.map +1 -0
  133. package/dist/fields/collections.d.ts +18 -0
  134. package/dist/fields/collections.js +37 -0
  135. package/dist/fields/collections.js.map +1 -0
  136. package/dist/index.d.ts +235 -0
  137. package/dist/index.js +956 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/middleware/index.d.ts +8 -0
  140. package/dist/middleware/index.js +13 -0
  141. package/dist/middleware/index.js.map +1 -0
  142. package/dist/preview-BEkLMD6N.d.ts +23 -0
  143. package/dist/preview-D9yewK8x.d.ts +24 -0
  144. package/dist/preview-DJEA4fj7.d.ts +23 -0
  145. package/dist/preview-DeD1Jn7U.d.ts +23 -0
  146. package/dist/toolbar/app.d.ts +28 -0
  147. package/dist/toolbar/app.js +1176 -0
  148. package/dist/toolbar/app.js.map +1 -0
  149. package/dist/types-15jfCQKb.d.ts +141 -0
  150. package/dist/types-BREdL9Gx.d.ts +140 -0
  151. package/dist/types-C6sUZNa2.d.ts +104 -0
  152. package/dist/types-CEYS5Fzc.d.ts +112 -0
  153. package/dist/types-DpeHpobR.d.ts +104 -0
  154. package/dist/types-NaKJe6Pg.d.ts +140 -0
  155. package/package.json +90 -0
  156. package/src/CmsHead.astro +25 -0
  157. package/src/CmsImage.astro +62 -0
  158. package/src/CmsVideo.astro +185 -0
  159. package/src/RichText.astro +32 -0
  160. package/src/client.test.ts +227 -0
  161. package/src/client.ts +164 -0
  162. package/src/dev/config.test.ts +258 -0
  163. package/src/dev/config.ts +319 -0
  164. package/src/dev/index.ts +5 -0
  165. package/src/dev/preview-token.ts +39 -0
  166. package/src/dev/routes.test.ts +354 -0
  167. package/src/dev/routes.ts +245 -0
  168. package/src/dev/token.test.ts +280 -0
  169. package/src/dev/token.ts +201 -0
  170. package/src/dev/verifier.test.ts +63 -0
  171. package/src/dev/verifier.ts +161 -0
  172. package/src/fields/attrs.ts +24 -0
  173. package/src/fields/collection.ts +72 -0
  174. package/src/fields/collections.ts +35 -0
  175. package/src/fields/entryScope.test.ts +62 -0
  176. package/src/fields/entryScope.ts +240 -0
  177. package/src/fields/group.ts +51 -0
  178. package/src/fields/helpers.test.ts +51 -0
  179. package/src/fields/helpers.ts +214 -0
  180. package/src/fields/index.ts +46 -0
  181. package/src/fields/scope.ts +21 -0
  182. package/src/fields/types.ts +119 -0
  183. package/src/head.test.ts +74 -0
  184. package/src/head.ts +123 -0
  185. package/src/image.test.ts +42 -0
  186. package/src/image.ts +64 -0
  187. package/src/index.test.ts +76 -0
  188. package/src/index.ts +13 -0
  189. package/src/integration.ts +218 -0
  190. package/src/jwt.ts +131 -0
  191. package/src/middleware/index.ts +4 -0
  192. package/src/middleware/preview.test.ts +184 -0
  193. package/src/middleware/preview.ts +206 -0
  194. package/src/preview/bridge-script.test.ts +683 -0
  195. package/src/preview/bridge-script.ts +763 -0
  196. package/src/preview/origins.ts +29 -0
  197. package/src/preview.ts +49 -0
  198. package/src/richtext/RichTextNode.astro +130 -0
  199. package/src/richtext/render.ts +248 -0
  200. package/src/richtext.test.ts +139 -0
  201. package/src/runtime/bundle.ts +28 -0
  202. package/src/runtime/store.ts +130 -0
  203. package/src/siteFiles.test.ts +93 -0
  204. package/src/siteFiles.ts +111 -0
  205. package/src/toolbar/app.test.ts +191 -0
  206. package/src/toolbar/app.ts +1091 -0
  207. package/src/toolbar/icon.ts +5 -0
  208. package/src/toolbar/widgets.test.ts +153 -0
  209. package/src/toolbar/widgets.ts +365 -0
  210. package/src/types.test.ts +154 -0
  211. package/src/types.ts +163 -0
  212. package/src/version.ts +3 -0
@@ -0,0 +1,1176 @@
1
+ import { chromeTokens } from '../chunk-2TKIQIOE.js';
2
+ import { DEFAULT_EDITOR_ORIGINS } from '../chunk-XJPVYMZM.js';
3
+ import { defineToolbarApp } from 'astro/toolbar';
4
+
5
+ // src/toolbar/widgets.ts
6
+ function extractRichTextSummary(value) {
7
+ if (!value) return "(empty)";
8
+ if (typeof value === "string") {
9
+ const trimmed = value.replace(/<[^>]*>/g, "").trim();
10
+ return trimmed ? trimmed.length > 50 ? `${trimmed.slice(0, 47)}...` : trimmed : "(empty)";
11
+ }
12
+ if (typeof value === "object" && value !== null) {
13
+ let walk2 = function(node) {
14
+ if (!node || typeof node !== "object") return;
15
+ nodeCount++;
16
+ const n = node;
17
+ if (typeof n.text === "string" && n.text.trim()) {
18
+ textRuns.push(n.text.trim());
19
+ }
20
+ if (Array.isArray(n.content)) {
21
+ for (const child of n.content) {
22
+ walk2(child);
23
+ }
24
+ }
25
+ };
26
+ const doc = value;
27
+ let nodeCount = 0;
28
+ const textRuns = [];
29
+ walk2(doc);
30
+ const firstRun = textRuns[0] || "";
31
+ const snippet = firstRun.length > 40 ? `${firstRun.slice(0, 37)}...` : firstRun;
32
+ return snippet ? `"${snippet}" (${nodeCount} ${nodeCount === 1 ? "node" : "nodes"})` : `(${nodeCount} ${nodeCount === 1 ? "node" : "nodes"})`;
33
+ }
34
+ return String(value);
35
+ }
36
+ function extractImageSummary(value) {
37
+ if (!value) return "(no image)";
38
+ if (typeof value === "string") {
39
+ try {
40
+ const u = new URL(value, "https://placeholder.local");
41
+ const filename = u.pathname.split("/").pop() || value;
42
+ return filename.length > 40 ? `${filename.slice(0, 37)}...` : filename;
43
+ } catch {
44
+ return value.length > 40 ? `${value.slice(0, 37)}...` : value;
45
+ }
46
+ }
47
+ if (typeof value === "object" && value !== null) {
48
+ const img = value;
49
+ const name = img.url ? img.url.split("/").pop() || "image" : "image";
50
+ const dim = img.width && img.height ? ` (${img.width}\xD7${img.height})` : "";
51
+ const alt = img.alt ? ` \u2014 "${img.alt}"` : "";
52
+ const combined = `${name}${dim}${alt}`;
53
+ return combined.length > 50 ? `${combined.slice(0, 47)}...` : combined;
54
+ }
55
+ return String(value);
56
+ }
57
+ function createTextWidget(ctx) {
58
+ const container = document.createElement("div");
59
+ container.className = "cms-widget-container";
60
+ const form = document.createElement("form");
61
+ form.className = "cms-widget-form";
62
+ const input = document.createElement("input");
63
+ input.type = "text";
64
+ input.className = "cms-widget-input";
65
+ input.value = ctx.value !== void 0 && ctx.value !== null ? String(ctx.value) : "";
66
+ input.placeholder = ctx.defaultValue !== void 0 && ctx.defaultValue !== null ? String(ctx.defaultValue) : "";
67
+ input.disabled = Boolean(ctx.disabled);
68
+ const saveBtn = document.createElement("button");
69
+ saveBtn.type = "submit";
70
+ saveBtn.className = "cms-widget-save-btn";
71
+ saveBtn.textContent = "Save";
72
+ saveBtn.disabled = Boolean(ctx.disabled);
73
+ const errorBox = document.createElement("div");
74
+ errorBox.className = "cms-widget-error";
75
+ errorBox.style.display = "none";
76
+ form.appendChild(input);
77
+ form.appendChild(saveBtn);
78
+ container.appendChild(form);
79
+ container.appendChild(errorBox);
80
+ form.addEventListener("submit", async (e) => {
81
+ e.preventDefault();
82
+ if (!ctx.onSave || ctx.disabled) return;
83
+ saveBtn.disabled = true;
84
+ saveBtn.textContent = "Saving...";
85
+ errorBox.style.display = "none";
86
+ try {
87
+ const res = await ctx.onSave(input.value);
88
+ if (!res.ok) {
89
+ errorBox.textContent = res.error || "Failed to save field";
90
+ errorBox.style.display = "block";
91
+ }
92
+ } finally {
93
+ saveBtn.disabled = Boolean(ctx.disabled);
94
+ saveBtn.textContent = "Save";
95
+ }
96
+ });
97
+ return container;
98
+ }
99
+ function createNumberWidget(ctx) {
100
+ const container = document.createElement("div");
101
+ container.className = "cms-widget-container";
102
+ const form = document.createElement("form");
103
+ form.className = "cms-widget-form";
104
+ const input = document.createElement("input");
105
+ input.type = "number";
106
+ input.className = "cms-widget-input";
107
+ input.value = ctx.value !== void 0 && ctx.value !== null ? String(ctx.value) : "";
108
+ input.placeholder = ctx.defaultValue !== void 0 && ctx.defaultValue !== null ? String(ctx.defaultValue) : "";
109
+ input.disabled = Boolean(ctx.disabled);
110
+ if (ctx.constraints?.min !== void 0) input.min = String(ctx.constraints.min);
111
+ if (ctx.constraints?.max !== void 0) input.max = String(ctx.constraints.max);
112
+ if (ctx.constraints?.step !== void 0) input.step = String(ctx.constraints.step);
113
+ const saveBtn = document.createElement("button");
114
+ saveBtn.type = "submit";
115
+ saveBtn.className = "cms-widget-save-btn";
116
+ saveBtn.textContent = "Save";
117
+ saveBtn.disabled = Boolean(ctx.disabled);
118
+ const errorBox = document.createElement("div");
119
+ errorBox.className = "cms-widget-error";
120
+ errorBox.style.display = "none";
121
+ form.appendChild(input);
122
+ form.appendChild(saveBtn);
123
+ container.appendChild(form);
124
+ container.appendChild(errorBox);
125
+ form.addEventListener("submit", async (e) => {
126
+ e.preventDefault();
127
+ if (!ctx.onSave || ctx.disabled) return;
128
+ saveBtn.disabled = true;
129
+ saveBtn.textContent = "Saving...";
130
+ errorBox.style.display = "none";
131
+ const numVal = input.value === "" ? null : Number(input.value);
132
+ try {
133
+ const res = await ctx.onSave(numVal);
134
+ if (!res.ok) {
135
+ errorBox.textContent = res.error || "Failed to save field";
136
+ errorBox.style.display = "block";
137
+ }
138
+ } finally {
139
+ saveBtn.disabled = Boolean(ctx.disabled);
140
+ saveBtn.textContent = "Save";
141
+ }
142
+ });
143
+ return container;
144
+ }
145
+ function createToggleWidget(ctx) {
146
+ const container = document.createElement("div");
147
+ container.className = "cms-widget-container cms-widget-toggle-row";
148
+ const label = document.createElement("label");
149
+ label.className = "cms-widget-toggle-label";
150
+ const input = document.createElement("input");
151
+ input.type = "checkbox";
152
+ input.className = "cms-widget-checkbox";
153
+ input.checked = Boolean(ctx.value ?? ctx.defaultValue ?? false);
154
+ input.disabled = Boolean(ctx.disabled);
155
+ const statusText = document.createElement("span");
156
+ statusText.className = "cms-widget-toggle-text";
157
+ statusText.textContent = input.checked ? "True" : "False";
158
+ const errorBox = document.createElement("div");
159
+ errorBox.className = "cms-widget-error";
160
+ errorBox.style.display = "none";
161
+ label.appendChild(input);
162
+ label.appendChild(statusText);
163
+ container.appendChild(label);
164
+ container.appendChild(errorBox);
165
+ input.addEventListener("change", async () => {
166
+ statusText.textContent = input.checked ? "True" : "False";
167
+ if (!ctx.onSave || ctx.disabled) return;
168
+ input.disabled = true;
169
+ errorBox.style.display = "none";
170
+ try {
171
+ const res = await ctx.onSave(input.checked);
172
+ if (!res.ok) {
173
+ errorBox.textContent = res.error || "Failed to save field";
174
+ errorBox.style.display = "block";
175
+ input.checked = !input.checked;
176
+ statusText.textContent = input.checked ? "True" : "False";
177
+ }
178
+ } finally {
179
+ input.disabled = Boolean(ctx.disabled);
180
+ }
181
+ });
182
+ return container;
183
+ }
184
+ function createSelectWidget(ctx) {
185
+ const container = document.createElement("div");
186
+ container.className = "cms-widget-container";
187
+ const select = document.createElement("select");
188
+ select.className = "cms-widget-select";
189
+ select.disabled = Boolean(ctx.disabled);
190
+ const emptyOpt = document.createElement("option");
191
+ emptyOpt.value = "";
192
+ emptyOpt.textContent = "(select value)";
193
+ select.appendChild(emptyOpt);
194
+ const rawOptions = ctx.constraints?.options;
195
+ if (Array.isArray(rawOptions)) {
196
+ for (const opt of rawOptions) {
197
+ const optEl = document.createElement("option");
198
+ if (typeof opt === "string") {
199
+ optEl.value = opt;
200
+ optEl.textContent = opt;
201
+ } else if (typeof opt === "object" && opt !== null) {
202
+ const o = opt;
203
+ optEl.value = o.value || "";
204
+ optEl.textContent = o.label || o.value || "";
205
+ }
206
+ select.appendChild(optEl);
207
+ }
208
+ }
209
+ const currentVal = ctx.value !== void 0 && ctx.value !== null ? String(ctx.value) : "";
210
+ select.value = currentVal;
211
+ const errorBox = document.createElement("div");
212
+ errorBox.className = "cms-widget-error";
213
+ errorBox.style.display = "none";
214
+ container.appendChild(select);
215
+ container.appendChild(errorBox);
216
+ select.addEventListener("change", async () => {
217
+ if (!ctx.onSave || ctx.disabled) return;
218
+ select.disabled = true;
219
+ errorBox.style.display = "none";
220
+ try {
221
+ const res = await ctx.onSave(select.value);
222
+ if (!res.ok) {
223
+ errorBox.textContent = res.error || "Failed to save field";
224
+ errorBox.style.display = "block";
225
+ select.value = currentVal;
226
+ }
227
+ } finally {
228
+ select.disabled = Boolean(ctx.disabled);
229
+ }
230
+ });
231
+ return container;
232
+ }
233
+ function createSummaryWidget(ctx) {
234
+ const container = document.createElement("div");
235
+ container.className = "cms-widget-summary-row";
236
+ const summary = document.createElement("div");
237
+ summary.className = "cms-widget-summary-text";
238
+ const normType = (ctx.typeId || "").toLowerCase();
239
+ if (normType === "richtext") {
240
+ summary.textContent = extractRichTextSummary(ctx.value ?? ctx.defaultValue);
241
+ } else if (normType === "image") {
242
+ summary.textContent = extractImageSummary(ctx.value ?? ctx.defaultValue);
243
+ } else {
244
+ const v = ctx.value ?? ctx.defaultValue;
245
+ summary.textContent = v !== void 0 && v !== null ? JSON.stringify(v) : "(no value)";
246
+ }
247
+ const cleanOrigin = (ctx.editorOrigin || DEFAULT_EDITOR_ORIGINS[0]).replace(/\/$/, "");
248
+ const editorUrl = `${cleanOrigin}/sites/${encodeURIComponent(ctx.siteId)}/editor?path=${encodeURIComponent(ctx.routePath || "/")}&field=${encodeURIComponent(ctx.key)}`;
249
+ const link = document.createElement("a");
250
+ link.href = editorUrl;
251
+ link.target = "_blank";
252
+ link.rel = "noopener noreferrer";
253
+ link.className = "cms-widget-editor-link";
254
+ link.innerHTML = "Open in Editor \u2197";
255
+ container.appendChild(summary);
256
+ container.appendChild(link);
257
+ return container;
258
+ }
259
+ var widgetRegistry = /* @__PURE__ */ new Map([
260
+ ["text", createTextWidget],
261
+ ["number", createNumberWidget],
262
+ ["toggle", createToggleWidget],
263
+ ["select", createSelectWidget]
264
+ ]);
265
+ function resolveToolbarWidget(typeId) {
266
+ const normalized = typeId.toLowerCase();
267
+ return widgetRegistry.get(normalized) || createSummaryWidget;
268
+ }
269
+
270
+ // src/toolbar/app.ts
271
+ var app_default = defineToolbarApp({
272
+ init(canvas, app, server) {
273
+ let isEmbedded = false;
274
+ try {
275
+ isEmbedded = window.self !== window.top || window.parent !== window;
276
+ } catch {
277
+ isEmbedded = true;
278
+ }
279
+ if (isEmbedded) {
280
+ const hideToolbar = () => {
281
+ const toolbar = document.querySelector("astro-dev-toolbar");
282
+ if (toolbar instanceof HTMLElement) {
283
+ toolbar.style.setProperty("display", "none", "important");
284
+ }
285
+ };
286
+ hideToolbar();
287
+ document.addEventListener("astro:page-load", hideToolbar);
288
+ document.addEventListener("astro:after-swap", hideToolbar);
289
+ }
290
+ let devStatus = null;
291
+ let fieldDefinitions = /* @__PURE__ */ new Map();
292
+ let bundleFieldsMap = {};
293
+ let renderedFieldsList = [];
294
+ const style = document.createElement("style");
295
+ style.textContent = `
296
+ :host {
297
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
298
+ color: ${chromeTokens.foreground};
299
+ font-size: 12px;
300
+ line-height: 1.4;
301
+ }
302
+ * {
303
+ box-sizing: border-box;
304
+ }
305
+ astro-dev-toolbar-window {
306
+ position: fixed !important;
307
+ top: 0 !important;
308
+ right: 0 !important;
309
+ bottom: 0 !important;
310
+ left: auto !important;
311
+ transform: none !important;
312
+ width: 440px !important;
313
+ max-width: 100vw !important;
314
+ height: 100vh !important;
315
+ height: 100dvh !important;
316
+ max-height: 100vh !important;
317
+ max-height: 100dvh !important;
318
+ border-radius: 0 !important;
319
+ border: none !important;
320
+ border-left: 1px solid ${chromeTokens.border} !important;
321
+ padding: 0 !important;
322
+ margin: 0 !important;
323
+ background: ${chromeTokens.background} !important;
324
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.5) !important;
325
+ z-index: 999999999 !important;
326
+ overflow: hidden !important;
327
+ display: flex !important;
328
+ flex-direction: column !important;
329
+ }
330
+ .toolbar-container {
331
+ display: flex;
332
+ flex-direction: column;
333
+ gap: 12px;
334
+ padding: 16px 16px 56px 16px;
335
+ width: 100%;
336
+ height: 100%;
337
+ max-height: 100vh;
338
+ max-height: 100dvh;
339
+ min-height: 0;
340
+ flex: 1 1 auto;
341
+ overflow-y: auto;
342
+ overflow-x: hidden;
343
+ overscroll-behavior: contain;
344
+ scrollbar-gutter: stable;
345
+ scrollbar-width: thin;
346
+ scrollbar-color: ${chromeTokens.border} transparent;
347
+ background: ${chromeTokens.background};
348
+ border: none;
349
+ border-radius: 0;
350
+ box-shadow: none;
351
+ box-sizing: border-box;
352
+ }
353
+ .toolbar-container > * {
354
+ flex-shrink: 0;
355
+ }
356
+ .toolbar-container::-webkit-scrollbar {
357
+ width: 6px;
358
+ }
359
+ .toolbar-container::-webkit-scrollbar-track {
360
+ background: transparent;
361
+ }
362
+ .toolbar-container::-webkit-scrollbar-thumb {
363
+ background: ${chromeTokens.border};
364
+ border-radius: 3px;
365
+ }
366
+ .toolbar-container::-webkit-scrollbar-thumb:hover {
367
+ background: ${chromeTokens.borderStrong};
368
+ }
369
+ .header-card {
370
+ background: ${chromeTokens.card};
371
+ border: 1px solid ${chromeTokens.border};
372
+ border-radius: 6px;
373
+ padding: 12px;
374
+ display: flex;
375
+ flex-direction: column;
376
+ gap: 8px;
377
+ flex-shrink: 0;
378
+ }
379
+ .header-top {
380
+ display: flex;
381
+ justify-content: space-between;
382
+ align-items: center;
383
+ }
384
+ .title-area {
385
+ display: flex;
386
+ align-items: center;
387
+ gap: 8px;
388
+ }
389
+ .app-title {
390
+ font-weight: 600;
391
+ font-size: 13px;
392
+ color: ${chromeTokens.cardForeground};
393
+ }
394
+ .meta-row {
395
+ display: flex;
396
+ align-items: center;
397
+ justify-content: space-between;
398
+ font-size: 11px;
399
+ color: ${chromeTokens.mutedForeground};
400
+ }
401
+ .meta-chips {
402
+ display: flex;
403
+ align-items: center;
404
+ gap: 6px;
405
+ flex-wrap: wrap;
406
+ }
407
+ .chip {
408
+ display: inline-flex;
409
+ align-items: center;
410
+ padding: 2px 6px;
411
+ border-radius: 4px;
412
+ font-size: 10px;
413
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
414
+ }
415
+ .chip-site {
416
+ background: ${chromeTokens.muted};
417
+ color: ${chromeTokens.foregroundSecondary};
418
+ }
419
+ .chip-fresh {
420
+ background: rgba(16, 185, 129, 0.15);
421
+ color: ${chromeTokens.successText};
422
+ border: 1px solid rgba(16, 185, 129, 0.3);
423
+ }
424
+ .chip-unpushed {
425
+ background: rgba(234, 179, 8, 0.15);
426
+ color: ${chromeTokens.warningText};
427
+ border: 1px solid rgba(234, 179, 8, 0.3);
428
+ }
429
+ .toggle-wrap {
430
+ display: flex;
431
+ align-items: center;
432
+ gap: 6px;
433
+ font-size: 11px;
434
+ cursor: pointer;
435
+ user-select: none;
436
+ }
437
+ .toggle-input {
438
+ cursor: pointer;
439
+ }
440
+ .banner {
441
+ border-radius: 6px;
442
+ padding: 10px 12px;
443
+ font-size: 11px;
444
+ flex-shrink: 0;
445
+ }
446
+ .banner-error {
447
+ background: rgba(239, 68, 68, 0.15);
448
+ border: 1px solid rgba(239, 68, 68, 0.4);
449
+ color: ${chromeTokens.destructiveText};
450
+ }
451
+ .banner-warning {
452
+ background: rgba(234, 179, 8, 0.15);
453
+ border: 1px solid rgba(234, 179, 8, 0.4);
454
+ color: ${chromeTokens.warningText};
455
+ }
456
+ .banner-info {
457
+ background: rgba(59, 130, 246, 0.15);
458
+ border: 1px solid rgba(59, 130, 246, 0.4);
459
+ color: ${chromeTokens.infoText};
460
+ }
461
+ .section-title {
462
+ font-size: 11px;
463
+ font-weight: 600;
464
+ text-transform: uppercase;
465
+ letter-spacing: 0.05em;
466
+ color: ${chromeTokens.foregroundSubtle};
467
+ margin-top: 4px;
468
+ display: flex;
469
+ align-items: center;
470
+ justify-content: space-between;
471
+ flex-shrink: 0;
472
+ }
473
+ .diag-list {
474
+ display: flex;
475
+ flex-direction: column;
476
+ gap: 6px;
477
+ flex-shrink: 0;
478
+ }
479
+ .diag-item {
480
+ background: ${chromeTokens.card};
481
+ border: 1px solid ${chromeTokens.border};
482
+ border-radius: 6px;
483
+ padding: 8px 10px;
484
+ display: flex;
485
+ flex-direction: column;
486
+ gap: 4px;
487
+ flex-shrink: 0;
488
+ }
489
+ .diag-item-error {
490
+ border-left: 3px solid ${chromeTokens.destructive};
491
+ }
492
+ .diag-item-warning {
493
+ border-left: 3px solid ${chromeTokens.warning};
494
+ }
495
+ .diag-loc {
496
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
497
+ font-size: 10px;
498
+ color: ${chromeTokens.infoText};
499
+ text-decoration: none;
500
+ }
501
+ .diag-loc:hover {
502
+ text-decoration: underline;
503
+ }
504
+ .diag-msg {
505
+ color: ${chromeTokens.foregroundSecondary};
506
+ font-size: 11px;
507
+ }
508
+ .group-card {
509
+ background: ${chromeTokens.card};
510
+ border: 1px solid ${chromeTokens.border};
511
+ border-radius: 6px;
512
+ overflow: hidden;
513
+ flex-shrink: 0;
514
+ }
515
+ .group-header {
516
+ background: ${chromeTokens.muted};
517
+ padding: 6px 10px;
518
+ font-weight: 600;
519
+ font-size: 11px;
520
+ color: ${chromeTokens.foregroundSecondary};
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: space-between;
524
+ flex-shrink: 0;
525
+ }
526
+ .field-list {
527
+ display: flex;
528
+ flex-direction: column;
529
+ flex-shrink: 0;
530
+ }
531
+ .field-row {
532
+ padding: 8px 10px;
533
+ border-top: 1px solid ${chromeTokens.border};
534
+ display: flex;
535
+ flex-direction: column;
536
+ gap: 6px;
537
+ transition: background-color 0.3s ease;
538
+ flex-shrink: 0;
539
+ }
540
+ @keyframes fieldHighlightPulse {
541
+ 0% {
542
+ background: rgba(99, 102, 241, 0.35);
543
+ box-shadow: inset 0 0 0 1px ${chromeTokens.primary};
544
+ }
545
+ 70% {
546
+ background: rgba(99, 102, 241, 0.15);
547
+ box-shadow: inset 0 0 0 1px rgba(99, 102, 241, 0.4);
548
+ }
549
+ 100% {
550
+ background: transparent;
551
+ box-shadow: none;
552
+ }
553
+ }
554
+ .field-row-highlighted {
555
+ animation: fieldHighlightPulse 2s ease-out;
556
+ }
557
+ .field-meta {
558
+ display: flex;
559
+ align-items: center;
560
+ justify-content: space-between;
561
+ gap: 6px;
562
+ }
563
+ .field-key {
564
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
565
+ font-size: 11px;
566
+ font-weight: 500;
567
+ color: ${chromeTokens.foregroundSecondary};
568
+ }
569
+ .badge-group {
570
+ display: flex;
571
+ align-items: center;
572
+ gap: 4px;
573
+ }
574
+ .badge {
575
+ font-size: 9px;
576
+ padding: 1px 4px;
577
+ border-radius: 3px;
578
+ font-weight: 500;
579
+ text-transform: lowercase;
580
+ }
581
+ .badge-no-value {
582
+ background: rgba(239, 68, 68, 0.2);
583
+ color: ${chromeTokens.destructiveText};
584
+ }
585
+ .badge-no-default {
586
+ background: rgba(234, 179, 8, 0.2);
587
+ color: ${chromeTokens.warningText};
588
+ }
589
+ .badge-orphaned {
590
+ background: rgba(168, 85, 247, 0.2);
591
+ color: ${chromeTokens.primaryText};
592
+ }
593
+ .badge-type {
594
+ background: ${chromeTokens.muted};
595
+ color: ${chromeTokens.mutedForeground};
596
+ }
597
+ /* Widget inputs */
598
+ .cms-widget-container {
599
+ display: flex;
600
+ flex-direction: column;
601
+ gap: 4px;
602
+ }
603
+ .cms-widget-form {
604
+ display: flex;
605
+ gap: 6px;
606
+ align-items: center;
607
+ }
608
+ .cms-widget-input {
609
+ flex: 1;
610
+ background: ${chromeTokens.sunken};
611
+ border: 1px solid ${chromeTokens.borderStrong};
612
+ border-radius: 4px;
613
+ color: ${chromeTokens.foreground};
614
+ padding: 4px 8px;
615
+ font-size: 11px;
616
+ outline: none;
617
+ }
618
+ .cms-widget-input:focus {
619
+ border-color: ${chromeTokens.ring};
620
+ }
621
+ .cms-widget-input:disabled {
622
+ opacity: 0.5;
623
+ cursor: not-allowed;
624
+ }
625
+ .cms-widget-save-btn {
626
+ background: ${chromeTokens.primary};
627
+ color: ${chromeTokens.primaryForeground};
628
+ border: none;
629
+ border-radius: 4px;
630
+ padding: 4px 10px;
631
+ font-size: 11px;
632
+ font-weight: 500;
633
+ cursor: pointer;
634
+ }
635
+ .cms-widget-save-btn:hover:not(:disabled) {
636
+ background: color-mix(in srgb, ${chromeTokens.primary} 85%, black);
637
+ }
638
+ .cms-widget-save-btn:disabled {
639
+ opacity: 0.5;
640
+ cursor: not-allowed;
641
+ }
642
+ .cms-widget-select {
643
+ width: 100%;
644
+ background: ${chromeTokens.sunken};
645
+ border: 1px solid ${chromeTokens.borderStrong};
646
+ border-radius: 4px;
647
+ color: ${chromeTokens.foreground};
648
+ padding: 4px 8px;
649
+ font-size: 11px;
650
+ outline: none;
651
+ }
652
+ .cms-widget-toggle-row {
653
+ display: flex;
654
+ align-items: center;
655
+ gap: 6px;
656
+ }
657
+ .cms-widget-toggle-label {
658
+ display: flex;
659
+ align-items: center;
660
+ gap: 6px;
661
+ cursor: pointer;
662
+ }
663
+ .cms-widget-checkbox {
664
+ cursor: pointer;
665
+ }
666
+ .cms-widget-toggle-text {
667
+ font-size: 11px;
668
+ color: ${chromeTokens.foregroundSecondary};
669
+ }
670
+ .cms-widget-summary-row {
671
+ display: flex;
672
+ align-items: center;
673
+ justify-content: space-between;
674
+ gap: 8px;
675
+ background: ${chromeTokens.sunken};
676
+ border: 1px solid ${chromeTokens.border};
677
+ border-radius: 4px;
678
+ padding: 4px 8px;
679
+ }
680
+ .cms-widget-summary-text {
681
+ font-size: 11px;
682
+ color: ${chromeTokens.mutedForeground};
683
+ overflow: hidden;
684
+ text-overflow: ellipsis;
685
+ white-space: nowrap;
686
+ max-width: 260px;
687
+ }
688
+ .cms-widget-editor-link {
689
+ font-size: 11px;
690
+ color: ${chromeTokens.primaryText};
691
+ text-decoration: none;
692
+ white-space: nowrap;
693
+ }
694
+ .cms-widget-editor-link:hover {
695
+ text-decoration: underline;
696
+ }
697
+ .cms-widget-error {
698
+ font-size: 10px;
699
+ color: ${chromeTokens.destructiveText};
700
+ margin-top: 2px;
701
+ }
702
+ .empty-notice {
703
+ font-size: 11px;
704
+ color: ${chromeTokens.foregroundSubtle};
705
+ font-style: italic;
706
+ padding: 8px 0;
707
+ flex-shrink: 0;
708
+ }
709
+ `;
710
+ canvas.appendChild(style);
711
+ const windowEl = document.createElement("astro-dev-toolbar-window");
712
+ windowEl.style.position = "fixed";
713
+ windowEl.style.top = "0";
714
+ windowEl.style.right = "0";
715
+ windowEl.style.bottom = "0";
716
+ windowEl.style.left = "auto";
717
+ windowEl.style.transform = "none";
718
+ windowEl.style.width = "440px";
719
+ windowEl.style.maxWidth = "100vw";
720
+ windowEl.style.height = "100vh";
721
+ windowEl.style.maxHeight = "100vh";
722
+ windowEl.style.borderRadius = "0";
723
+ windowEl.style.border = "none";
724
+ windowEl.style.borderLeft = `1px solid ${chromeTokens.border}`;
725
+ windowEl.style.padding = "0";
726
+ windowEl.style.margin = "0";
727
+ windowEl.style.background = chromeTokens.background;
728
+ windowEl.style.boxShadow = "-4px 0 24px rgba(0, 0, 0, 0.5)";
729
+ windowEl.style.zIndex = "999999999";
730
+ windowEl.style.display = "flex";
731
+ windowEl.style.flexDirection = "column";
732
+ windowEl.style.overflow = "hidden";
733
+ const container = document.createElement("div");
734
+ container.className = "toolbar-container";
735
+ container.style.height = "100%";
736
+ container.style.minHeight = "0";
737
+ container.style.flex = "1 1 auto";
738
+ container.style.overflowY = "auto";
739
+ container.style.boxSizing = "border-box";
740
+ windowEl.appendChild(container);
741
+ canvas.appendChild(windowEl);
742
+ function patchDomElement(key, kind, value, entryRef) {
743
+ let selector;
744
+ const eRef = entryRef;
745
+ const fPath = eRef?.path || key;
746
+ if (eRef && (eRef.collection || eRef.slug)) {
747
+ const colAttr = eRef.collection ? `[data-cms-collection="${eRef.collection}"]` : "";
748
+ const entryAttr = eRef.slug ? `[data-cms-entry="${eRef.slug}"]` : "";
749
+ const scopeSel = `${colAttr}${entryAttr}`;
750
+ selector = `${scopeSel} [data-cms-entry-field="${fPath}"], ${scopeSel}[data-cms-entry-field="${fPath}"]`;
751
+ } else if (eRef) {
752
+ selector = `[data-cms-entry-field="${fPath}"]`;
753
+ } else {
754
+ selector = `[data-cms-field="${key}"]`;
755
+ }
756
+ const els = document.querySelectorAll(selector);
757
+ for (let i = 0; i < els.length; i++) {
758
+ const el = els[i];
759
+ if (kind === "image" || el.tagName.toLowerCase() === "img") {
760
+ if (value && typeof value === "object") {
761
+ const imgVal = value;
762
+ if (imgVal.url) el.setAttribute("src", imgVal.url);
763
+ if (imgVal.alt !== void 0) el.setAttribute("alt", imgVal.alt);
764
+ } else if (typeof value === "string") {
765
+ el.setAttribute("src", value);
766
+ }
767
+ } else {
768
+ el.textContent = value !== null && value !== void 0 ? String(value) : "";
769
+ }
770
+ }
771
+ }
772
+ async function handleSaveValue(key, val, kind, entryRef) {
773
+ try {
774
+ const res = await fetch("/_cms/dev/value", {
775
+ method: "PATCH",
776
+ headers: {
777
+ "Content-Type": "application/json"
778
+ },
779
+ body: JSON.stringify({ key, value: val })
780
+ });
781
+ if (res.ok) {
782
+ bundleFieldsMap[key] = val;
783
+ const def = fieldDefinitions.get(key);
784
+ if (def) {
785
+ def.value = val;
786
+ }
787
+ patchDomElement(key, kind, val, entryRef);
788
+ const w = window;
789
+ w.__CMS_RESCAN__?.();
790
+ render();
791
+ return { ok: true };
792
+ }
793
+ const data = await res.json().catch(() => ({}));
794
+ const errorMsg = data.errors?.map((e) => e.message).join(", ") || data.error || `Save failed (HTTP ${res.status})`;
795
+ return { ok: false, error: errorMsg };
796
+ } catch (err) {
797
+ const msg = err instanceof Error ? err.message : String(err);
798
+ return { ok: false, error: msg };
799
+ }
800
+ }
801
+ function render() {
802
+ container.innerHTML = "";
803
+ if (!devStatus) {
804
+ const loadingDiv = document.createElement("div");
805
+ loadingDiv.className = "empty-notice";
806
+ loadingDiv.textContent = "Loading CMS dev status...";
807
+ container.appendChild(loadingDiv);
808
+ return;
809
+ }
810
+ const isReadOnly = devStatus.status === "read-only";
811
+ const isRefused = devStatus.status === "refused";
812
+ const isUnconfigured = devStatus.status === "unconfigured";
813
+ const disabled = isReadOnly || isRefused || isUnconfigured;
814
+ const headerCard = document.createElement("div");
815
+ headerCard.className = "header-card";
816
+ const headerTop = document.createElement("div");
817
+ headerTop.className = "header-top";
818
+ const titleArea = document.createElement("div");
819
+ titleArea.className = "title-area";
820
+ const titleSpan = document.createElement("span");
821
+ titleSpan.className = "app-title";
822
+ titleSpan.textContent = "CMS Content";
823
+ titleArea.appendChild(titleSpan);
824
+ const toggleWrap = document.createElement("label");
825
+ toggleWrap.className = "toggle-wrap";
826
+ const toggleCheckbox = document.createElement("input");
827
+ toggleCheckbox.type = "checkbox";
828
+ toggleCheckbox.className = "toggle-input";
829
+ toggleCheckbox.checked = document.documentElement.hasAttribute("data-cms-edit-mode");
830
+ toggleCheckbox.addEventListener("change", () => {
831
+ if (toggleCheckbox.checked) {
832
+ document.documentElement.setAttribute("data-cms-edit-mode", "true");
833
+ } else {
834
+ document.documentElement.removeAttribute("data-cms-edit-mode");
835
+ }
836
+ });
837
+ const toggleLabel = document.createElement("span");
838
+ toggleLabel.textContent = "Outlines";
839
+ toggleWrap.appendChild(toggleCheckbox);
840
+ toggleWrap.appendChild(toggleLabel);
841
+ headerTop.appendChild(titleArea);
842
+ headerTop.appendChild(toggleWrap);
843
+ headerCard.appendChild(headerTop);
844
+ const metaRow = document.createElement("div");
845
+ metaRow.className = "meta-row";
846
+ const chips = document.createElement("div");
847
+ chips.className = "meta-chips";
848
+ const siteChip = document.createElement("span");
849
+ siteChip.className = "chip chip-site";
850
+ siteChip.textContent = devStatus.siteId || "No Site";
851
+ chips.appendChild(siteChip);
852
+ if (devStatus.identity?.email || devStatus.identity?.sub) {
853
+ const userChip = document.createElement("span");
854
+ userChip.className = "chip chip-site";
855
+ userChip.textContent = devStatus.identity.email || devStatus.identity.sub;
856
+ chips.appendChild(userChip);
857
+ }
858
+ if (devStatus.verifier?.available) {
859
+ const freshChip = document.createElement("span");
860
+ if (devStatus.manifest?.fresh) {
861
+ freshChip.className = "chip chip-fresh";
862
+ freshChip.textContent = "\u25CF Fresh";
863
+ } else {
864
+ freshChip.className = "chip chip-unpushed";
865
+ freshChip.textContent = "\u25B2 Unpushed";
866
+ }
867
+ chips.appendChild(freshChip);
868
+ }
869
+ metaRow.appendChild(chips);
870
+ headerCard.appendChild(metaRow);
871
+ container.appendChild(headerCard);
872
+ if (isReadOnly && devStatus.mismatch) {
873
+ const banner = document.createElement("div");
874
+ banner.className = "banner banner-error";
875
+ banner.textContent = `Toolbar is READ-ONLY: ${devStatus.mismatch.source} (${devStatus.mismatch.actual}) \u2260 site rendered by this dev server (${devStatus.mismatch.expected})`;
876
+ container.appendChild(banner);
877
+ } else if (isRefused) {
878
+ const banner = document.createElement("div");
879
+ banner.className = "banner banner-error";
880
+ banner.textContent = `CMS dev routes disabled: ${devStatus.error || "Access refused"}`;
881
+ container.appendChild(banner);
882
+ } else if (isUnconfigured) {
883
+ const banner = document.createElement("div");
884
+ banner.className = "banner banner-info";
885
+ banner.textContent = devStatus.error || "Not logged in. Run `cms login` to enable dev-time editing.";
886
+ container.appendChild(banner);
887
+ }
888
+ const errors = devStatus.verifier?.errors || [];
889
+ const warnings = devStatus.verifier?.warnings || [];
890
+ const allDiags = [...errors, ...warnings];
891
+ if (allDiags.length > 0) {
892
+ const diagSec = document.createElement("div");
893
+ diagSec.className = "section-title";
894
+ diagSec.textContent = `Diagnostics (${allDiags.length})`;
895
+ container.appendChild(diagSec);
896
+ const diagList = document.createElement("div");
897
+ diagList.className = "diag-list";
898
+ for (const diag of allDiags) {
899
+ const item = document.createElement("div");
900
+ item.className = `diag-item ${diag.type === "error" ? "diag-item-error" : "diag-item-warning"}`;
901
+ if (diag.file) {
902
+ const locLink = document.createElement("a");
903
+ locLink.className = "diag-loc";
904
+ locLink.href = `vscode://file/${diag.file}:${diag.line || 1}:${diag.column || 1}`;
905
+ locLink.textContent = `${diag.file}:${diag.line || 1}:${diag.column || 1}`;
906
+ item.appendChild(locLink);
907
+ }
908
+ const msg = document.createElement("div");
909
+ msg.className = "diag-msg";
910
+ msg.textContent = diag.message;
911
+ item.appendChild(msg);
912
+ diagList.appendChild(item);
913
+ }
914
+ container.appendChild(diagList);
915
+ }
916
+ const fieldsSecTitle = document.createElement("div");
917
+ fieldsSecTitle.className = "section-title";
918
+ fieldsSecTitle.textContent = `Rendered Fields (${renderedFieldsList.length})`;
919
+ container.appendChild(fieldsSecTitle);
920
+ if (renderedFieldsList.length === 0) {
921
+ const empty = document.createElement("div");
922
+ empty.className = "empty-notice";
923
+ empty.textContent = "No CMS fields detected on current page.";
924
+ container.appendChild(empty);
925
+ } else {
926
+ const groupsMap = /* @__PURE__ */ new Map();
927
+ for (const field of renderedFieldsList) {
928
+ let groupName = field.group;
929
+ if (!groupName) {
930
+ const parts = field.key.split(".");
931
+ if (parts.length > 1) {
932
+ groupName = parts.slice(0, -1).join(".");
933
+ } else {
934
+ groupName = "Ungrouped";
935
+ }
936
+ }
937
+ if (!groupsMap.has(groupName)) {
938
+ groupsMap.set(groupName, []);
939
+ }
940
+ groupsMap.get(groupName)?.push(field);
941
+ }
942
+ const currentRoute = window.location.pathname || "/";
943
+ const editorOrigin = devStatus.editorOrigins?.[0] || DEFAULT_EDITOR_ORIGINS[0];
944
+ for (const [groupName, groupFields] of groupsMap.entries()) {
945
+ const groupCard = document.createElement("div");
946
+ groupCard.className = "group-card";
947
+ const groupHeader = document.createElement("div");
948
+ groupHeader.className = "group-header";
949
+ groupHeader.textContent = groupName;
950
+ groupCard.appendChild(groupHeader);
951
+ const fieldList = document.createElement("div");
952
+ fieldList.className = "field-list";
953
+ for (const field of groupFields) {
954
+ const def = fieldDefinitions.get(field.key);
955
+ const rawVal = bundleFieldsMap[field.key] !== void 0 ? bundleFieldsMap[field.key] : def?.value !== void 0 ? def.value : def?.default_value;
956
+ const typeId = def?.type || field.kind || "text";
957
+ const isOrphaned = Boolean(def?.orphaned_at);
958
+ const hasNoValue = rawVal === void 0 || rawVal === null || rawVal === "";
959
+ const hasNoDefault = def?.default_value === void 0 || def?.default_value === null;
960
+ const row = document.createElement("div");
961
+ row.className = "field-row";
962
+ row.dataset.fieldKey = field.key;
963
+ row.setAttribute("data-field-key", field.key);
964
+ const meta = document.createElement("div");
965
+ meta.className = "field-meta";
966
+ const keySpan = document.createElement("span");
967
+ keySpan.className = "field-key";
968
+ keySpan.textContent = field.key;
969
+ meta.appendChild(keySpan);
970
+ const badgeGroup = document.createElement("div");
971
+ badgeGroup.className = "badge-group";
972
+ if (isOrphaned) {
973
+ const b = document.createElement("span");
974
+ b.className = "badge badge-orphaned";
975
+ b.textContent = "orphaned";
976
+ badgeGroup.appendChild(b);
977
+ }
978
+ if (hasNoValue) {
979
+ const b = document.createElement("span");
980
+ b.className = "badge badge-no-value";
981
+ b.textContent = "no value";
982
+ badgeGroup.appendChild(b);
983
+ }
984
+ if (hasNoDefault) {
985
+ const b = document.createElement("span");
986
+ b.className = "badge badge-no-default";
987
+ b.textContent = "no default";
988
+ badgeGroup.appendChild(b);
989
+ }
990
+ const typeBadge = document.createElement("span");
991
+ typeBadge.className = "badge badge-type";
992
+ typeBadge.textContent = typeId;
993
+ badgeGroup.appendChild(typeBadge);
994
+ meta.appendChild(badgeGroup);
995
+ row.appendChild(meta);
996
+ const renderer = resolveToolbarWidget(typeId);
997
+ const widgetEl = renderer({
998
+ key: field.key,
999
+ typeId,
1000
+ value: rawVal,
1001
+ defaultValue: def?.default_value,
1002
+ constraints: def?.constraints,
1003
+ disabled,
1004
+ siteId: devStatus.siteId,
1005
+ routePath: currentRoute,
1006
+ editorOrigin,
1007
+ onSave: async (v) => handleSaveValue(field.key, v, field.kind || typeId, field.entryRef)
1008
+ });
1009
+ row.appendChild(widgetEl);
1010
+ fieldList.appendChild(row);
1011
+ }
1012
+ groupCard.appendChild(fieldList);
1013
+ container.appendChild(groupCard);
1014
+ }
1015
+ }
1016
+ const renderedKeys = new Set(renderedFieldsList.map((f) => f.key));
1017
+ const orphanedDefs = [];
1018
+ for (const def of fieldDefinitions.values()) {
1019
+ if (def.orphaned_at || !renderedKeys.has(def.key)) {
1020
+ orphanedDefs.push(def);
1021
+ }
1022
+ }
1023
+ if (orphanedDefs.length > 0) {
1024
+ const orphanTitle = document.createElement("div");
1025
+ orphanTitle.className = "section-title";
1026
+ orphanTitle.textContent = `Unrendered / Orphaned Fields (${orphanedDefs.length})`;
1027
+ container.appendChild(orphanTitle);
1028
+ const orphanCard = document.createElement("div");
1029
+ orphanCard.className = "group-card";
1030
+ const orphanList = document.createElement("div");
1031
+ orphanList.className = "field-list";
1032
+ for (const o of orphanedDefs) {
1033
+ const row = document.createElement("div");
1034
+ row.className = "field-row";
1035
+ row.dataset.fieldKey = o.key;
1036
+ row.setAttribute("data-field-key", o.key);
1037
+ const meta = document.createElement("div");
1038
+ meta.className = "field-meta";
1039
+ const keySpan = document.createElement("span");
1040
+ keySpan.className = "field-key";
1041
+ keySpan.textContent = o.key;
1042
+ meta.appendChild(keySpan);
1043
+ const badgeGroup = document.createElement("div");
1044
+ badgeGroup.className = "badge-group";
1045
+ if (o.orphaned_at) {
1046
+ const b = document.createElement("span");
1047
+ b.className = "badge badge-orphaned";
1048
+ b.textContent = "orphaned";
1049
+ badgeGroup.appendChild(b);
1050
+ } else {
1051
+ const b = document.createElement("span");
1052
+ b.className = "badge badge-type";
1053
+ b.textContent = "unrendered";
1054
+ badgeGroup.appendChild(b);
1055
+ }
1056
+ meta.appendChild(badgeGroup);
1057
+ row.appendChild(meta);
1058
+ orphanList.appendChild(row);
1059
+ }
1060
+ orphanCard.appendChild(orphanList);
1061
+ container.appendChild(orphanCard);
1062
+ }
1063
+ }
1064
+ async function loadData() {
1065
+ try {
1066
+ const statusRes = await fetch("/_cms/dev/status");
1067
+ if (statusRes.ok) {
1068
+ devStatus = await statusRes.json();
1069
+ } else if (statusRes.status === 503) {
1070
+ const errData = await statusRes.json().catch(() => ({}));
1071
+ devStatus = {
1072
+ status: errData.status || "refused",
1073
+ siteId: "",
1074
+ apiUrl: "",
1075
+ manifest: { fresh: true, localHash: null, pushedHash: null },
1076
+ verifier: { available: false, errors: [], warnings: [] },
1077
+ error: errData.error
1078
+ };
1079
+ }
1080
+ if (devStatus?.verifier?.errors && devStatus.verifier.errors.length > 0) {
1081
+ app.toggleNotification({ state: true, level: "error" });
1082
+ } else if (devStatus?.verifier?.warnings && devStatus.verifier.warnings.length > 0) {
1083
+ app.toggleNotification({ state: true, level: "warning" });
1084
+ } else {
1085
+ app.toggleNotification({ state: false });
1086
+ }
1087
+ if (devStatus && devStatus.status !== "refused" && devStatus.status !== "unconfigured") {
1088
+ const bundleRes = await fetch("/_cms/dev/bundle");
1089
+ if (bundleRes.ok) {
1090
+ const bundleData = await bundleRes.json();
1091
+ if (bundleData.bundle?.fields) {
1092
+ bundleFieldsMap = bundleData.bundle.fields;
1093
+ }
1094
+ if (Array.isArray(bundleData.fields)) {
1095
+ fieldDefinitions = new Map(bundleData.fields.map((f) => [f.key, f]));
1096
+ }
1097
+ }
1098
+ }
1099
+ } catch (_err) {
1100
+ }
1101
+ const winFields = window.__CMS_FIELDS__;
1102
+ if (Array.isArray(winFields)) {
1103
+ renderedFieldsList = winFields;
1104
+ }
1105
+ render();
1106
+ }
1107
+ server.on("cms:diagnostics", (data) => {
1108
+ if (devStatus) {
1109
+ devStatus.verifier = {
1110
+ available: Boolean(data.available),
1111
+ errors: data.errors || [],
1112
+ warnings: data.warnings || []
1113
+ };
1114
+ if (data.fresh !== void 0) {
1115
+ devStatus.manifest.fresh = data.fresh;
1116
+ }
1117
+ if (data.errors && data.errors.length > 0) {
1118
+ app.toggleNotification({ state: true, level: "error" });
1119
+ } else if (data.warnings && data.warnings.length > 0) {
1120
+ app.toggleNotification({ state: true, level: "warning" });
1121
+ } else {
1122
+ app.toggleNotification({ state: false });
1123
+ }
1124
+ render();
1125
+ }
1126
+ });
1127
+ function escapeCssKey(str) {
1128
+ if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
1129
+ return CSS.escape(str);
1130
+ }
1131
+ return str.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g, "\\$1");
1132
+ }
1133
+ function focusFieldRow(key) {
1134
+ if (!key) return;
1135
+ const targetRow = container.querySelector(
1136
+ `[data-field-key="${escapeCssKey(key)}"]`
1137
+ );
1138
+ if (targetRow) {
1139
+ targetRow.scrollIntoView({ behavior: "smooth", block: "center" });
1140
+ targetRow.classList.remove("field-row-highlighted");
1141
+ void targetRow.offsetWidth;
1142
+ targetRow.classList.add("field-row-highlighted");
1143
+ const inputEl = targetRow.querySelector(
1144
+ 'input:not([type="checkbox"]), select, textarea, button, a'
1145
+ );
1146
+ if (inputEl) {
1147
+ setTimeout(() => {
1148
+ inputEl.focus();
1149
+ if (typeof inputEl.select === "function") {
1150
+ inputEl.select();
1151
+ }
1152
+ }, 150);
1153
+ }
1154
+ }
1155
+ }
1156
+ document.addEventListener("cms:fields-updated", ((e) => {
1157
+ if (Array.isArray(e.detail)) {
1158
+ renderedFieldsList = e.detail;
1159
+ render();
1160
+ }
1161
+ }));
1162
+ document.addEventListener("cms:field-selected", ((e) => {
1163
+ if (e.detail?.key) {
1164
+ focusFieldRow(e.detail.key);
1165
+ }
1166
+ }));
1167
+ document.addEventListener("astro:page-load", () => {
1168
+ loadData();
1169
+ });
1170
+ loadData();
1171
+ }
1172
+ });
1173
+
1174
+ export { app_default as default };
1175
+ //# sourceMappingURL=app.js.map
1176
+ //# sourceMappingURL=app.js.map