@caretcms/core 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 (249) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +191 -0
  3. package/dist/browser-runtime.d.ts +12 -0
  4. package/dist/browser-runtime.d.ts.map +1 -0
  5. package/dist/browser-runtime.js +298 -0
  6. package/dist/browser-runtime.js.map +1 -0
  7. package/dist/index.d.ts +81 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +343 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/loader.d.ts +61 -0
  12. package/dist/loader.d.ts.map +1 -0
  13. package/dist/loader.js +80 -0
  14. package/dist/loader.js.map +1 -0
  15. package/dist/providers/storage/filesystem.d.ts +7 -0
  16. package/dist/providers/storage/filesystem.d.ts.map +1 -0
  17. package/dist/providers/storage/filesystem.js +6 -0
  18. package/dist/providers/storage/filesystem.js.map +1 -0
  19. package/dist/providers/uploads/local.d.ts +6 -0
  20. package/dist/providers/uploads/local.d.ts.map +1 -0
  21. package/dist/providers/uploads/local.js +6 -0
  22. package/dist/providers/uploads/local.js.map +1 -0
  23. package/dist/runtime/auth/cookie-utils.d.ts +3 -0
  24. package/dist/runtime/auth/cookie-utils.d.ts.map +1 -0
  25. package/dist/runtime/auth/cookie-utils.js +33 -0
  26. package/dist/runtime/auth/cookie-utils.js.map +1 -0
  27. package/dist/runtime/auth/demo-session.d.ts +24 -0
  28. package/dist/runtime/auth/demo-session.d.ts.map +1 -0
  29. package/dist/runtime/auth/demo-session.js +42 -0
  30. package/dist/runtime/auth/demo-session.js.map +1 -0
  31. package/dist/runtime/auth/rate-limiter.d.ts +26 -0
  32. package/dist/runtime/auth/rate-limiter.d.ts.map +1 -0
  33. package/dist/runtime/auth/rate-limiter.js +65 -0
  34. package/dist/runtime/auth/rate-limiter.js.map +1 -0
  35. package/dist/runtime/auth/session.d.ts +14 -0
  36. package/dist/runtime/auth/session.d.ts.map +1 -0
  37. package/dist/runtime/auth/session.js +128 -0
  38. package/dist/runtime/auth/session.js.map +1 -0
  39. package/dist/runtime/bind.d.ts +14 -0
  40. package/dist/runtime/bind.d.ts.map +1 -0
  41. package/dist/runtime/bind.js +19 -0
  42. package/dist/runtime/bind.js.map +1 -0
  43. package/dist/runtime/config.d.ts +20 -0
  44. package/dist/runtime/config.d.ts.map +1 -0
  45. package/dist/runtime/config.js +40 -0
  46. package/dist/runtime/config.js.map +1 -0
  47. package/dist/runtime/content.d.ts +28 -0
  48. package/dist/runtime/content.d.ts.map +1 -0
  49. package/dist/runtime/content.js +37 -0
  50. package/dist/runtime/content.js.map +1 -0
  51. package/dist/runtime/index.d.ts +14 -0
  52. package/dist/runtime/index.d.ts.map +1 -0
  53. package/dist/runtime/index.js +16 -0
  54. package/dist/runtime/index.js.map +1 -0
  55. package/dist/runtime/middleware.d.ts +14 -0
  56. package/dist/runtime/middleware.d.ts.map +1 -0
  57. package/dist/runtime/middleware.js +80 -0
  58. package/dist/runtime/middleware.js.map +1 -0
  59. package/dist/runtime/mutations/contracts.d.ts +91 -0
  60. package/dist/runtime/mutations/contracts.d.ts.map +1 -0
  61. package/dist/runtime/mutations/contracts.js +320 -0
  62. package/dist/runtime/mutations/contracts.js.map +1 -0
  63. package/dist/runtime/mutations/engine.d.ts +23 -0
  64. package/dist/runtime/mutations/engine.d.ts.map +1 -0
  65. package/dist/runtime/mutations/engine.js +255 -0
  66. package/dist/runtime/mutations/engine.js.map +1 -0
  67. package/dist/runtime/providers.d.ts +9 -0
  68. package/dist/runtime/providers.d.ts.map +1 -0
  69. package/dist/runtime/providers.js +44 -0
  70. package/dist/runtime/providers.js.map +1 -0
  71. package/dist/runtime/request-context.d.ts +11 -0
  72. package/dist/runtime/request-context.d.ts.map +1 -0
  73. package/dist/runtime/request-context.js +16 -0
  74. package/dist/runtime/request-context.js.map +1 -0
  75. package/dist/runtime/rewrite.d.ts +13 -0
  76. package/dist/runtime/rewrite.d.ts.map +1 -0
  77. package/dist/runtime/rewrite.js +253 -0
  78. package/dist/runtime/rewrite.js.map +1 -0
  79. package/dist/runtime/routes/_helpers.d.ts +17 -0
  80. package/dist/runtime/routes/_helpers.d.ts.map +1 -0
  81. package/dist/runtime/routes/_helpers.js +38 -0
  82. package/dist/runtime/routes/_helpers.js.map +1 -0
  83. package/dist/runtime/routes/admin-entry.d.ts +3 -0
  84. package/dist/runtime/routes/admin-entry.d.ts.map +1 -0
  85. package/dist/runtime/routes/admin-entry.js +170 -0
  86. package/dist/runtime/routes/admin-entry.js.map +1 -0
  87. package/dist/runtime/routes/admin.d.ts +3 -0
  88. package/dist/runtime/routes/admin.d.ts.map +1 -0
  89. package/dist/runtime/routes/admin.js +189 -0
  90. package/dist/runtime/routes/admin.js.map +1 -0
  91. package/dist/runtime/routes/auth-login.d.ts +4 -0
  92. package/dist/runtime/routes/auth-login.d.ts.map +1 -0
  93. package/dist/runtime/routes/auth-login.js +71 -0
  94. package/dist/runtime/routes/auth-login.js.map +1 -0
  95. package/dist/runtime/routes/auth-logout.d.ts +4 -0
  96. package/dist/runtime/routes/auth-logout.d.ts.map +1 -0
  97. package/dist/runtime/routes/auth-logout.js +47 -0
  98. package/dist/runtime/routes/auth-logout.js.map +1 -0
  99. package/dist/runtime/routes/auth-session.d.ts +3 -0
  100. package/dist/runtime/routes/auth-session.d.ts.map +1 -0
  101. package/dist/runtime/routes/auth-session.js +8 -0
  102. package/dist/runtime/routes/auth-session.js.map +1 -0
  103. package/dist/runtime/routes/collection-list.d.ts +3 -0
  104. package/dist/runtime/routes/collection-list.d.ts.map +1 -0
  105. package/dist/runtime/routes/collection-list.js +420 -0
  106. package/dist/runtime/routes/collection-list.js.map +1 -0
  107. package/dist/runtime/routes/collections-metadata.d.ts +3 -0
  108. package/dist/runtime/routes/collections-metadata.d.ts.map +1 -0
  109. package/dist/runtime/routes/collections-metadata.js +17 -0
  110. package/dist/runtime/routes/collections-metadata.js.map +1 -0
  111. package/dist/runtime/routes/editor-assets.d.ts +3 -0
  112. package/dist/runtime/routes/editor-assets.d.ts.map +1 -0
  113. package/dist/runtime/routes/editor-assets.js +73 -0
  114. package/dist/runtime/routes/editor-assets.js.map +1 -0
  115. package/dist/runtime/routes/entries.d.ts +3 -0
  116. package/dist/runtime/routes/entries.d.ts.map +1 -0
  117. package/dist/runtime/routes/entries.js +96 -0
  118. package/dist/runtime/routes/entries.js.map +1 -0
  119. package/dist/runtime/routes/history.d.ts +4 -0
  120. package/dist/runtime/routes/history.d.ts.map +1 -0
  121. package/dist/runtime/routes/history.js +54 -0
  122. package/dist/runtime/routes/history.js.map +1 -0
  123. package/dist/runtime/routes/mutate.d.ts +4 -0
  124. package/dist/runtime/routes/mutate.d.ts.map +1 -0
  125. package/dist/runtime/routes/mutate.js +38 -0
  126. package/dist/runtime/routes/mutate.js.map +1 -0
  127. package/dist/runtime/routes/schema.d.ts +3 -0
  128. package/dist/runtime/routes/schema.d.ts.map +1 -0
  129. package/dist/runtime/routes/schema.js +58 -0
  130. package/dist/runtime/routes/schema.js.map +1 -0
  131. package/dist/runtime/routes/studio-home.d.ts +3 -0
  132. package/dist/runtime/routes/studio-home.d.ts.map +1 -0
  133. package/dist/runtime/routes/studio-home.js +99 -0
  134. package/dist/runtime/routes/studio-home.js.map +1 -0
  135. package/dist/runtime/routes/theme-stylesheet.d.ts +3 -0
  136. package/dist/runtime/routes/theme-stylesheet.d.ts.map +1 -0
  137. package/dist/runtime/routes/theme-stylesheet.js +32 -0
  138. package/dist/runtime/routes/theme-stylesheet.js.map +1 -0
  139. package/dist/runtime/routes/upload.d.ts +3 -0
  140. package/dist/runtime/routes/upload.d.ts.map +1 -0
  141. package/dist/runtime/routes/upload.js +33 -0
  142. package/dist/runtime/routes/upload.js.map +1 -0
  143. package/dist/runtime/sanitize-html.d.ts +8 -0
  144. package/dist/runtime/sanitize-html.d.ts.map +1 -0
  145. package/dist/runtime/sanitize-html.js +86 -0
  146. package/dist/runtime/sanitize-html.js.map +1 -0
  147. package/dist/runtime/schema/template.d.ts +15 -0
  148. package/dist/runtime/schema/template.d.ts.map +1 -0
  149. package/dist/runtime/schema/template.js +38 -0
  150. package/dist/runtime/schema/template.js.map +1 -0
  151. package/dist/runtime/schema-registry.d.ts +17 -0
  152. package/dist/runtime/schema-registry.d.ts.map +1 -0
  153. package/dist/runtime/schema-registry.js +16 -0
  154. package/dist/runtime/schema-registry.js.map +1 -0
  155. package/dist/runtime/storage/filesystem-adapter.d.ts +36 -0
  156. package/dist/runtime/storage/filesystem-adapter.d.ts.map +1 -0
  157. package/dist/runtime/storage/filesystem-adapter.js +291 -0
  158. package/dist/runtime/storage/filesystem-adapter.js.map +1 -0
  159. package/dist/runtime/storage/filesystem-upload-handler.d.ts +11 -0
  160. package/dist/runtime/storage/filesystem-upload-handler.d.ts.map +1 -0
  161. package/dist/runtime/storage/filesystem-upload-handler.js +20 -0
  162. package/dist/runtime/storage/filesystem-upload-handler.js.map +1 -0
  163. package/dist/runtime/storage/image-validation.d.ts +28 -0
  164. package/dist/runtime/storage/image-validation.d.ts.map +1 -0
  165. package/dist/runtime/storage/image-validation.js +94 -0
  166. package/dist/runtime/storage/image-validation.js.map +1 -0
  167. package/dist/runtime/storage/in-memory-adapter.d.ts +29 -0
  168. package/dist/runtime/storage/in-memory-adapter.d.ts.map +1 -0
  169. package/dist/runtime/storage/in-memory-adapter.js +110 -0
  170. package/dist/runtime/storage/in-memory-adapter.js.map +1 -0
  171. package/dist/runtime/storage/quota-upload-handler.d.ts +27 -0
  172. package/dist/runtime/storage/quota-upload-handler.d.ts.map +1 -0
  173. package/dist/runtime/storage/quota-upload-handler.js +34 -0
  174. package/dist/runtime/storage/quota-upload-handler.js.map +1 -0
  175. package/dist/runtime/storage/session-overlay-adapter.d.ts +33 -0
  176. package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -0
  177. package/dist/runtime/storage/session-overlay-adapter.js +121 -0
  178. package/dist/runtime/storage/session-overlay-adapter.js.map +1 -0
  179. package/dist/runtime/themes/preset-tokens.d.ts +17 -0
  180. package/dist/runtime/themes/preset-tokens.d.ts.map +1 -0
  181. package/dist/runtime/themes/preset-tokens.js +47 -0
  182. package/dist/runtime/themes/preset-tokens.js.map +1 -0
  183. package/dist/runtime/utils.d.ts +6 -0
  184. package/dist/runtime/utils.d.ts.map +1 -0
  185. package/dist/runtime/utils.js +29 -0
  186. package/dist/runtime/utils.js.map +1 -0
  187. package/dist/runtime/views/studio-layout.d.ts +25 -0
  188. package/dist/runtime/views/studio-layout.d.ts.map +1 -0
  189. package/dist/runtime/views/studio-layout.js +108 -0
  190. package/dist/runtime/views/studio-layout.js.map +1 -0
  191. package/dist/schema-utils.d.ts +16 -0
  192. package/dist/schema-utils.d.ts.map +1 -0
  193. package/dist/schema-utils.js +62 -0
  194. package/dist/schema-utils.js.map +1 -0
  195. package/dist/types.d.ts +76 -0
  196. package/dist/types.d.ts.map +1 -0
  197. package/dist/types.js +2 -0
  198. package/dist/types.js.map +1 -0
  199. package/editor-runtime.d.ts +6 -0
  200. package/editor-runtime.js +2 -0
  201. package/package.json +88 -0
  202. package/static/cms/admin-entry.css +207 -0
  203. package/static/cms/admin-entry.js +1083 -0
  204. package/static/cms/editor/config.js +118 -0
  205. package/static/cms/editor/content-map.css +141 -0
  206. package/static/cms/editor/content-map.js +172 -0
  207. package/static/cms/editor/guards.js +72 -0
  208. package/static/cms/editor/helpers.js +51 -0
  209. package/static/cms/editor/image-edit.js +151 -0
  210. package/static/cms/editor/image-utils.js +84 -0
  211. package/static/cms/editor/image.css +133 -0
  212. package/static/cms/editor/link-follow.js +144 -0
  213. package/static/cms/editor/link-ui.css +199 -0
  214. package/static/cms/editor/linkify.js +55 -0
  215. package/static/cms/editor/panel.css +91 -0
  216. package/static/cms/editor/panel.js +70 -0
  217. package/static/cms/editor/rich-toolbar.css +67 -0
  218. package/static/cms/editor/rich-toolbar.js +200 -0
  219. package/static/cms/editor/sanitize.js +89 -0
  220. package/static/cms/editor/save-queue.js +166 -0
  221. package/static/cms/editor/section-controls/activation.js +10 -0
  222. package/static/cms/editor/section-controls/api.js +87 -0
  223. package/static/cms/editor/section-controls/constants.js +24 -0
  224. package/static/cms/editor/section-controls/index.js +622 -0
  225. package/static/cms/editor/section-controls/model.js +76 -0
  226. package/static/cms/editor/section-controls/mutations.js +112 -0
  227. package/static/cms/editor/section-controls/page-context.js +34 -0
  228. package/static/cms/editor/section-controls/pickers.js +196 -0
  229. package/static/cms/editor/section-controls/reorder.js +92 -0
  230. package/static/cms/editor/section-controls/selection.js +54 -0
  231. package/static/cms/editor/section-controls/spacing-drag.js +83 -0
  232. package/static/cms/editor/section-controls/ui-elements.js +54 -0
  233. package/static/cms/editor/section-controls/utils.js +35 -0
  234. package/static/cms/editor/section-controls.css +349 -0
  235. package/static/cms/editor/section-controls.js +1 -0
  236. package/static/cms/editor/security.js +48 -0
  237. package/static/cms/editor/sync.js +72 -0
  238. package/static/cms/editor/text-edit.js +151 -0
  239. package/static/cms/editor/text-link-interactions.js +254 -0
  240. package/static/cms/editor/toast.css +50 -0
  241. package/static/cms/editor/toast.js +29 -0
  242. package/static/cms/editor/tokens-and-text.css +93 -0
  243. package/static/cms/editor/toolbar.css +249 -0
  244. package/static/cms/editor/toolbar.js +117 -0
  245. package/static/cms/editor.css +12 -0
  246. package/static/cms/editor.js +116 -0
  247. package/static/cms/studio-login.css +300 -0
  248. package/static/cms/studio-tokens.css +85 -0
  249. package/static/cms/studio.css +437 -0
@@ -0,0 +1,8 @@
1
+ import { isEditorAuthenticated } from "../auth/session.js";
2
+ import { json } from "./_helpers.js";
3
+ export async function GET(context) {
4
+ return json({
5
+ authenticated: isEditorAuthenticated(context),
6
+ });
7
+ }
8
+ //# sourceMappingURL=auth-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-session.js","sourceRoot":"","sources":["../../../src/runtime/routes/auth-session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,OAAO,IAAI,CAAC;QACV,aAAa,EAAE,qBAAqB,CAAC,OAAO,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { APIContext } from "astro";
2
+ export declare function GET(context: APIContext): Promise<Response>;
3
+ //# sourceMappingURL=collection-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-list.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/collection-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAexC,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqahE"}
@@ -0,0 +1,420 @@
1
+ import { isEditorAuthenticated } from "../auth/session.js";
2
+ import { getRuntimeConfig } from "../config.js";
3
+ import { getAdapter } from "./_helpers.js";
4
+ import { escapeHtml, htmlResponse, redirectResponse, renderStudioPage, } from "../views/studio-layout.js";
5
+ function humanize(name) {
6
+ return name.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
7
+ }
8
+ export async function GET(context) {
9
+ const runtime = getRuntimeConfig();
10
+ const collection = (context.params.collection ?? "").toString();
11
+ const loginRedirect = `${runtime.mountPath}?redirect=${encodeURIComponent(context.url.pathname)}`;
12
+ if (!isEditorAuthenticated(context)) {
13
+ return redirectResponse(loginRedirect);
14
+ }
15
+ if (!collection) {
16
+ return redirectResponse(`${runtime.mountPath}/cms`);
17
+ }
18
+ const adapter = getAdapter();
19
+ const known = await adapter.discoverCollections();
20
+ if (!known.includes(collection)) {
21
+ return redirectResponse(`${runtime.mountPath}/cms`);
22
+ }
23
+ const label = humanize(collection);
24
+ const safeCollection = escapeHtml(collection);
25
+ const extraStyles = `
26
+ .entry-card {
27
+ transition: transform 0.2s, border-color 0.2s, background 0.2s;
28
+ }
29
+ .entry-card:hover {
30
+ transform: translateY(-2px);
31
+ border-color: var(--studio-accent-strong, rgba(59, 130, 246, 0.3));
32
+ }
33
+ .entry-thumb {
34
+ aspect-ratio: 1;
35
+ background: rgba(0, 0, 0, 0.2);
36
+ overflow: hidden;
37
+ display: block;
38
+ }
39
+ .entry-thumb img {
40
+ width: 100%;
41
+ height: 100%;
42
+ object-fit: cover;
43
+ display: block;
44
+ }
45
+ .reorder-item {
46
+ display: flex;
47
+ align-items: center;
48
+ gap: 12px;
49
+ padding: 12px 16px;
50
+ border: 1px solid var(--studio-border);
51
+ background: var(--studio-surface);
52
+ cursor: grab;
53
+ transition: border-color 0.15s, opacity 0.15s, transform 0.15s;
54
+ user-select: none;
55
+ }
56
+ .reorder-item:active { cursor: grabbing; }
57
+ .reorder-item.dragging { opacity: 0.4; border-color: var(--studio-accent); }
58
+ .reorder-item.drag-over { border-color: var(--studio-accent); transform: scale(1.01); }
59
+ .reorder-handle { color: var(--studio-text-dim); font-size: 16px; line-height: 1; flex-shrink: 0; }
60
+ .reorder-label { flex: 1; font-size: 14px; color: var(--studio-text); }
61
+ .reorder-order { font-size: 11px; color: var(--studio-text-dim); font-variant-numeric: tabular-nums; min-width: 24px; text-align: right; }
62
+ .modal-backdrop {
63
+ position: fixed;
64
+ inset: 0;
65
+ background: rgba(0, 0, 0, 0.6);
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ z-index: 1000;
70
+ padding: 1rem;
71
+ }
72
+ .modal-backdrop[hidden] { display: none; }
73
+ .modal-card {
74
+ width: 100%;
75
+ max-width: 28rem;
76
+ background: var(--studio-bg);
77
+ border: 1px solid var(--studio-border);
78
+ }
79
+ .modal-header {
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: space-between;
83
+ padding: 1rem 1.5rem;
84
+ border-bottom: 1px solid var(--studio-border);
85
+ font-size: 11px;
86
+ font-weight: 600;
87
+ letter-spacing: 0.1em;
88
+ text-transform: uppercase;
89
+ color: var(--studio-text);
90
+ }
91
+ .modal-body { padding: 1.5rem; }
92
+ `;
93
+ const body = `<div class="studio-fade-in" style="max-width:80rem;margin:0 auto;" id="collection-page" data-collection="${safeCollection}">
94
+ <div style="display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:1.5rem;">
95
+ <div>
96
+ <h2 style="font-family:var(--studio-font-heading);font-size:1.25rem;margin:0;color:var(--studio-text);">${escapeHtml(label)}</h2>
97
+ <p id="entry-count" style="font-size:0.7rem;margin:0.25rem 0 0;color:var(--studio-text-dim);">Loading…</p>
98
+ </div>
99
+ <div style="display:flex;align-items:center;gap:0.75rem;flex-wrap:wrap;">
100
+ <input id="search-input" type="text" placeholder="Search…" class="studio-input" style="max-width:240px;" />
101
+ <button id="btn-reorder" class="studio-btn-ghost">Reorder</button>
102
+ <button id="btn-new" class="studio-btn-primary">+ New</button>
103
+ </div>
104
+ </div>
105
+
106
+ <div id="loading" style="display:flex;justify-content:center;padding:5rem 0;">
107
+ <div class="studio-spinner" style="width:24px;height:24px;"></div>
108
+ </div>
109
+
110
+ <div id="empty" hidden style="text-align:center;padding:5rem 0;color:var(--studio-text-dim);">
111
+ <p style="font-size:0.875rem;margin:0 0 0.75rem;">No entries yet.</p>
112
+ <button id="btn-empty-create" class="studio-btn-primary">Create First Entry</button>
113
+ </div>
114
+
115
+ <div id="error-state" hidden style="text-align:center;padding:5rem 0;">
116
+ <p style="font-size:0.875rem;margin:0 0 0.75rem;color:var(--studio-red);">Failed to load entries.</p>
117
+ <button id="retry-btn" class="studio-btn-ghost">Retry</button>
118
+ </div>
119
+
120
+ <div id="entries-grid" hidden style="display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));"></div>
121
+
122
+ <div id="reorder-container" hidden>
123
+ <div id="reorder-list" style="display:flex;flex-direction:column;gap:0.25rem;"></div>
124
+ <div style="display:flex;justify-content:flex-end;gap:0.75rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--studio-border);">
125
+ <button id="btn-reorder-cancel" class="studio-btn-ghost">Cancel</button>
126
+ <button id="btn-reorder-save" class="studio-btn-primary">Save Order</button>
127
+ </div>
128
+ </div>
129
+ </div>
130
+
131
+ <div id="create-dialog" class="modal-backdrop" hidden>
132
+ <div class="modal-card">
133
+ <div class="modal-header">
134
+ <span>New Entry</span>
135
+ <button id="btn-create-close" class="studio-btn-ghost" style="padding:4px 10px;">Close</button>
136
+ </div>
137
+ <div class="modal-body">
138
+ <label for="create-id-input" class="studio-label">Entry ID (slug)</label>
139
+ <input id="create-id-input" type="text" class="studio-input" placeholder="e.g. my-first-entry" autocomplete="off" spellcheck="false" />
140
+ <p id="create-hint" style="font-size:10px;margin:0.5rem 0 1rem;color:var(--studio-text-dim);">Lowercase letters, numbers, and hyphens only.</p>
141
+ <p id="create-error" class="studio-error-text" hidden></p>
142
+ <div style="display:flex;justify-content:flex-end;gap:0.75rem;">
143
+ <button id="btn-create-cancel" class="studio-btn-ghost">Cancel</button>
144
+ <button id="btn-create-confirm" class="studio-btn-primary" disabled>Create</button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>`;
149
+ const inlineScript = `(function () {
150
+ var COLLECTION = ${JSON.stringify(collection)};
151
+ var API = ${JSON.stringify(runtime.apiBasePath)};
152
+ var MOUNT = ${JSON.stringify(runtime.mountPath)};
153
+ var ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
154
+ var allEntries = [];
155
+
156
+ var grid = document.getElementById('entries-grid');
157
+ var loading = document.getElementById('loading');
158
+ var empty = document.getElementById('empty');
159
+ var errorState = document.getElementById('error-state');
160
+ var retryBtn = document.getElementById('retry-btn');
161
+ var countEl = document.getElementById('entry-count');
162
+ var searchInput = document.getElementById('search-input');
163
+ var newBtn = document.getElementById('btn-new');
164
+ var emptyCreateBtn = document.getElementById('btn-empty-create');
165
+ var reorderBtn = document.getElementById('btn-reorder');
166
+ var reorderContainer = document.getElementById('reorder-container');
167
+ var reorderList = document.getElementById('reorder-list');
168
+ var reorderSave = document.getElementById('btn-reorder-save');
169
+ var reorderCancel = document.getElementById('btn-reorder-cancel');
170
+ var dialog = document.getElementById('create-dialog');
171
+ var idInput = document.getElementById('create-id-input');
172
+ var errorEl = document.getElementById('create-error');
173
+ var confirmBtn = document.getElementById('btn-create-confirm');
174
+
175
+ function htmlEsc(s) { return String(s).replace(/[&<>"']/g, function (c) {
176
+ return { '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c]; });
177
+ }
178
+
179
+ function getTitle(d) {
180
+ if (!d) return 'Untitled';
181
+ for (var i = 0; i < ['name','title','question','company_name','headline','label'].length; i++) {
182
+ var k = ['name','title','question','company_name','headline','label'][i];
183
+ if (typeof d[k] === 'string' && d[k]) return d[k];
184
+ }
185
+ return 'Untitled';
186
+ }
187
+ function getThumb(d) {
188
+ if (!d) return null;
189
+ if (Array.isArray(d.images) && typeof d.images[0] === 'string') return d.images[0];
190
+ if (typeof d.image === 'string' && d.image) return d.image;
191
+ if (typeof d.thumbnail === 'string' && d.thumbnail) return d.thumbnail;
192
+ if (typeof d.bg_image === 'string' && d.bg_image) return d.bg_image;
193
+ return null;
194
+ }
195
+ function getSubtitle(d) {
196
+ if (!d) return '';
197
+ if (typeof d.category === 'string') return d.category;
198
+ if (typeof d.price === 'number') return '$' + d.price.toLocaleString();
199
+ if (typeof d.date === 'string') return d.date;
200
+ if (typeof d.order === 'number') return 'Order: ' + d.order;
201
+ return '';
202
+ }
203
+
204
+ function renderEntries(entries) {
205
+ grid.innerHTML = '';
206
+ if (entries.length === 0) {
207
+ grid.hidden = true;
208
+ empty.hidden = false;
209
+ return;
210
+ }
211
+ empty.hidden = true;
212
+ grid.hidden = false;
213
+ for (var i = 0; i < entries.length; i++) {
214
+ var entry = entries[i];
215
+ var title = getTitle(entry.data);
216
+ var thumb = getThumb(entry.data);
217
+ var subtitle = getSubtitle(entry.data);
218
+ var card = document.createElement('a');
219
+ card.href = MOUNT + '/cms/' + encodeURIComponent(COLLECTION) + '/' + encodeURIComponent(entry.id);
220
+ card.className = 'entry-card studio-card';
221
+ card.style.display = 'block';
222
+ card.style.overflow = 'hidden';
223
+ card.style.textDecoration = 'none';
224
+ card.innerHTML =
225
+ (thumb ? '<div class="entry-thumb"><img src="' + htmlEsc(thumb) + '" alt="' + htmlEsc(title) + '" loading="lazy" /></div>' : '') +
226
+ '<div style="padding:1rem;">' +
227
+ '<h3 style="font-size:0.875rem;font-weight:500;margin:0 0 0.25rem;color:var(--studio-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">' + htmlEsc(title) + '</h3>' +
228
+ (subtitle ? '<p style="font-size:0.7rem;margin:0 0 0.25rem;color:var(--studio-text-dim);text-transform:capitalize;">' + htmlEsc(subtitle) + '</p>' : '') +
229
+ '<p style="font-size:0.65rem;margin:0;color:var(--studio-text-dim);font-family:var(--studio-font-mono);">' + htmlEsc(entry.id) + '</p>' +
230
+ '</div>';
231
+ grid.appendChild(card);
232
+ }
233
+ }
234
+
235
+ function loadEntries() {
236
+ loading.hidden = false;
237
+ errorState.hidden = true;
238
+ empty.hidden = true;
239
+ grid.hidden = true;
240
+ fetch(API + '/entries?collection=' + encodeURIComponent(COLLECTION))
241
+ .then(function (res) {
242
+ if (res.status === 401) {
243
+ window.location.href = MOUNT + '?redirect=' + encodeURIComponent(window.location.pathname);
244
+ return null;
245
+ }
246
+ if (!res.ok) throw new Error('failed');
247
+ return res.json();
248
+ })
249
+ .then(function (json) {
250
+ if (!json) return;
251
+ allEntries = Array.isArray(json.entries) ? json.entries : [];
252
+ loading.hidden = true;
253
+ countEl.textContent = allEntries.length + ' ' + (allEntries.length === 1 ? 'entry' : 'entries');
254
+ renderEntries(allEntries);
255
+ })
256
+ .catch(function () {
257
+ loading.hidden = true;
258
+ countEl.textContent = 'Error';
259
+ errorState.hidden = false;
260
+ });
261
+ }
262
+
263
+ loadEntries();
264
+ retryBtn.addEventListener('click', loadEntries);
265
+
266
+ searchInput.addEventListener('input', function () {
267
+ var q = searchInput.value.toLowerCase();
268
+ if (!q) { renderEntries(allEntries); return; }
269
+ var filtered = allEntries.filter(function (e) {
270
+ var t = getTitle(e.data).toLowerCase();
271
+ return t.indexOf(q) >= 0 || e.id.toLowerCase().indexOf(q) >= 0;
272
+ });
273
+ renderEntries(filtered);
274
+ });
275
+
276
+ /* ─── Create dialog ─────────────────────────────────────────────── */
277
+ function openDialog() {
278
+ dialog.hidden = false;
279
+ idInput.value = '';
280
+ errorEl.hidden = true;
281
+ confirmBtn.disabled = true;
282
+ idInput.focus();
283
+ }
284
+ function closeDialog() { dialog.hidden = true; }
285
+ function validate() {
286
+ var v = idInput.value.trim();
287
+ if (!v) { confirmBtn.disabled = true; errorEl.hidden = true; return; }
288
+ if (!ID_RE.test(v)) { errorEl.textContent = 'Use lowercase letters, numbers, and hyphens only.'; errorEl.hidden = false; confirmBtn.disabled = true; return; }
289
+ if (allEntries.some(function (e) { return e.id === v; })) { errorEl.textContent = 'An entry with this ID already exists.'; errorEl.hidden = false; confirmBtn.disabled = true; return; }
290
+ errorEl.hidden = true; confirmBtn.disabled = false;
291
+ }
292
+ function createEntry() {
293
+ var entryId = idInput.value.trim();
294
+ if (!entryId || !ID_RE.test(entryId)) return;
295
+ confirmBtn.disabled = true;
296
+ confirmBtn.textContent = 'Creating…';
297
+ fetch(API + '/schema?collection=' + encodeURIComponent(COLLECTION))
298
+ .then(function (res) { return res.ok ? res.json() : { template: {} }; })
299
+ .then(function (info) {
300
+ var template = (info && info.template) || {};
301
+ if ('slug' in template) template.slug = entryId;
302
+ if ('id' in template) template.id = entryId;
303
+ return fetch(API + '/mutate', {
304
+ method: 'POST',
305
+ headers: { 'Content-Type': 'application/json', 'x-caret-request': '1' },
306
+ credentials: 'same-origin',
307
+ body: JSON.stringify({ type: 'put_entry', collection: COLLECTION, id: entryId, data: template }),
308
+ });
309
+ })
310
+ .then(function (res) {
311
+ if (!res) return;
312
+ if (res.status === 401) { window.location.href = MOUNT + '?redirect=' + encodeURIComponent(window.location.pathname); return; }
313
+ if (!res.ok) throw new Error('mutate failed');
314
+ window.location.href = MOUNT + '/cms/' + encodeURIComponent(COLLECTION) + '/' + encodeURIComponent(entryId);
315
+ })
316
+ .catch(function () {
317
+ errorEl.textContent = 'Failed to create entry. Try again.';
318
+ errorEl.hidden = false;
319
+ confirmBtn.disabled = false;
320
+ confirmBtn.textContent = 'Create';
321
+ });
322
+ }
323
+ newBtn.addEventListener('click', openDialog);
324
+ emptyCreateBtn.addEventListener('click', openDialog);
325
+ document.getElementById('btn-create-close').addEventListener('click', closeDialog);
326
+ document.getElementById('btn-create-cancel').addEventListener('click', closeDialog);
327
+ confirmBtn.addEventListener('click', createEntry);
328
+ idInput.addEventListener('input', validate);
329
+ idInput.addEventListener('keydown', function (e) { if (e.key === 'Enter' && !confirmBtn.disabled) createEntry(); });
330
+ dialog.addEventListener('click', function (e) { if (e.target === dialog) closeDialog(); });
331
+ document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !dialog.hidden) closeDialog(); });
332
+
333
+ /* ─── Reorder mode ──────────────────────────────────────────────── */
334
+ var reorderMode = false;
335
+ var ordered = [];
336
+ function enterReorder() {
337
+ reorderMode = true;
338
+ ordered = allEntries.slice().sort(function (a, b) {
339
+ var ao = (a.data && typeof a.data.order === 'number') ? a.data.order : 0;
340
+ var bo = (b.data && typeof b.data.order === 'number') ? b.data.order : 0;
341
+ return ao - bo;
342
+ });
343
+ grid.hidden = true; empty.hidden = true;
344
+ searchInput.style.display = 'none'; newBtn.style.display = 'none';
345
+ reorderBtn.textContent = 'Reordering…'; reorderBtn.disabled = true;
346
+ reorderContainer.hidden = false;
347
+ renderReorderList();
348
+ }
349
+ function exitReorder() {
350
+ reorderMode = false;
351
+ reorderContainer.hidden = true;
352
+ searchInput.style.display = ''; newBtn.style.display = '';
353
+ reorderBtn.textContent = 'Reorder'; reorderBtn.disabled = false;
354
+ renderEntries(allEntries);
355
+ }
356
+ function renderReorderList() {
357
+ reorderList.innerHTML = '';
358
+ var dragIdx = null;
359
+ ordered.forEach(function (entry, idx) {
360
+ var item = document.createElement('div');
361
+ item.className = 'reorder-item';
362
+ item.draggable = true;
363
+ item.dataset.idx = String(idx);
364
+ item.innerHTML =
365
+ '<span class="reorder-handle">&#9776;</span>' +
366
+ '<span class="reorder-label">' + htmlEsc(getTitle(entry.data)) + '</span>' +
367
+ '<span class="reorder-order">' + (idx + 1) + '</span>';
368
+ item.addEventListener('dragstart', function () { dragIdx = idx; item.classList.add('dragging'); });
369
+ item.addEventListener('dragend', function () {
370
+ dragIdx = null; item.classList.remove('dragging');
371
+ reorderList.querySelectorAll('.reorder-item').forEach(function (el) { el.classList.remove('drag-over'); });
372
+ });
373
+ item.addEventListener('dragover', function (e) { e.preventDefault(); if (dragIdx !== null && dragIdx !== idx) item.classList.add('drag-over'); });
374
+ item.addEventListener('dragleave', function () { item.classList.remove('drag-over'); });
375
+ item.addEventListener('drop', function (e) {
376
+ e.preventDefault(); item.classList.remove('drag-over');
377
+ if (dragIdx !== null && dragIdx !== idx) {
378
+ var moved = ordered.splice(dragIdx, 1)[0];
379
+ ordered.splice(idx, 0, moved);
380
+ renderReorderList();
381
+ }
382
+ });
383
+ reorderList.appendChild(item);
384
+ });
385
+ }
386
+ function saveOrder() {
387
+ reorderSave.disabled = true; reorderSave.textContent = 'Saving…';
388
+ var items = ordered.map(function (entry, idx) {
389
+ return { id: entry.id, order: idx, expectedRevision: entry.revision };
390
+ });
391
+ var reorderReq = fetch(API + '/mutate', {
392
+ method: 'POST',
393
+ headers: { 'Content-Type': 'application/json', 'x-caret-request': '1' },
394
+ credentials: 'same-origin',
395
+ body: JSON.stringify({ type: 'reorder_entries', collection: COLLECTION, items: items }),
396
+ });
397
+ Promise.all([reorderReq])
398
+ .then(function (responses) {
399
+ for (var i = 0; i < responses.length; i++) {
400
+ if (!responses[i].ok) throw new Error('save failed');
401
+ }
402
+ ordered.forEach(function (entry, idx) { if (entry.data) entry.data.order = idx; });
403
+ exitReorder();
404
+ })
405
+ .catch(function () { reorderSave.disabled = false; reorderSave.textContent = 'Retry'; });
406
+ }
407
+ reorderBtn.addEventListener('click', enterReorder);
408
+ reorderCancel.addEventListener('click', exitReorder);
409
+ reorderSave.addEventListener('click', saveOrder);
410
+ })();`;
411
+ return htmlResponse(renderStudioPage({
412
+ runtime,
413
+ title: label,
414
+ breadcrumb: [{ label }],
415
+ body,
416
+ extraStyles,
417
+ inlineScript,
418
+ }));
419
+ }
420
+ //# sourceMappingURL=collection-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-list.js","sourceRoot":"","sources":["../../../src/runtime/routes/collection-list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAChE,MAAM,aAAa,GAAG,GAAG,OAAO,CAAC,SAAS,aAAa,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IAElG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,gBAAgB,CAAC,GAAG,OAAO,CAAC,SAAS,MAAM,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAClD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,gBAAgB,CAAC,GAAG,OAAO,CAAC,SAAS,MAAM,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAE9C,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEnB,CAAC;IAEF,MAAM,IAAI,GAAG,4GAA4G,cAAc;;;kHAGvB,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAoD1H,CAAC;IAER,MAAM,YAAY,GAAG;uBACA,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;gBACjC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC;kBACjC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkQ3C,CAAC;IAEP,OAAO,YAAY,CACjB,gBAAgB,CAAC;QACf,OAAO;QACP,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;QACvB,IAAI;QACJ,WAAW;QACX,YAAY;KACb,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { APIContext } from "astro";
2
+ export declare function GET(context: APIContext): Promise<Response>;
3
+ //# sourceMappingURL=collections-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collections-metadata.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/collections-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAIxC,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAchE"}
@@ -0,0 +1,17 @@
1
+ import { isEditorAuthenticated } from "../auth/session.js";
2
+ import { json, getAdapter } from "./_helpers.js";
3
+ export async function GET(context) {
4
+ if (!isEditorAuthenticated(context)) {
5
+ return json({ error: "Unauthorized" }, 401);
6
+ }
7
+ const adapter = getAdapter();
8
+ try {
9
+ const collections = await adapter.listCollectionMetadata();
10
+ return json({ collections });
11
+ }
12
+ catch (error) {
13
+ const message = error instanceof Error ? error.message : "Failed to load collections";
14
+ return json({ error: message }, 500);
15
+ }
16
+ }
17
+ //# sourceMappingURL=collections-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collections-metadata.js","sourceRoot":"","sources":["../../../src/runtime/routes/collections-metadata.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,sBAAsB,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC;QACtF,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { APIContext } from "astro";
2
+ export declare function GET(context: APIContext): Promise<Response>;
3
+ //# sourceMappingURL=editor-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-assets.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/editor-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA0DxC,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2BhE"}
@@ -0,0 +1,73 @@
1
+ let _assetModules = null;
2
+ function getAssetModules() {
3
+ if (_assetModules)
4
+ return _assetModules;
5
+ try {
6
+ // @ts-expect-error Vite injects `glob` on import.meta at build time.
7
+ _assetModules = import.meta.glob("../../../static/cms/**/*.{js,css,json,svg}", { eager: true, query: "?raw", import: "default" });
8
+ }
9
+ catch {
10
+ _assetModules = {};
11
+ }
12
+ return _assetModules;
13
+ }
14
+ const ASSET_KEY_PREFIX = "../../../static/cms/";
15
+ let _assets = null;
16
+ function getAssets() {
17
+ if (_assets)
18
+ return _assets;
19
+ const built = {};
20
+ for (const [path, body] of Object.entries(getAssetModules())) {
21
+ if (typeof body !== "string")
22
+ continue;
23
+ const key = path.startsWith(ASSET_KEY_PREFIX)
24
+ ? path.slice(ASSET_KEY_PREFIX.length)
25
+ : path;
26
+ built[key] = body;
27
+ }
28
+ _assets = built;
29
+ return _assets;
30
+ }
31
+ const MIME_TYPES = {
32
+ ".js": "text/javascript; charset=utf-8",
33
+ ".css": "text/css; charset=utf-8",
34
+ ".json": "application/json; charset=utf-8",
35
+ ".svg": "image/svg+xml",
36
+ };
37
+ function getMimeType(path) {
38
+ const ext = path.slice(path.lastIndexOf("."));
39
+ return MIME_TYPES[ext] ?? "application/octet-stream";
40
+ }
41
+ function sanitizePath(raw) {
42
+ const normalized = raw.replace(/\\/g, "/");
43
+ if (normalized.includes("..") || normalized.includes("\0"))
44
+ return null;
45
+ if (/[^a-zA-Z0-9_./-]/.test(normalized))
46
+ return null;
47
+ return normalized;
48
+ }
49
+ export async function GET(context) {
50
+ const rawPath = (context.params.path ?? "").toString();
51
+ const safePath = sanitizePath(rawPath);
52
+ if (!safePath) {
53
+ return new Response("Not found", { status: 404 });
54
+ }
55
+ const body = getAssets()[safePath];
56
+ if (body === undefined) {
57
+ return new Response("Not found", { status: 404 });
58
+ }
59
+ // In dev, never cache — editor source files change frequently and a cached
60
+ // copy hides edits. In prod, cache for an hour (these are static package
61
+ // files that only change on a package update).
62
+ const cacheControl = process.env.NODE_ENV === "development"
63
+ ? "no-cache, no-store, must-revalidate"
64
+ : "public, max-age=3600";
65
+ return new Response(body, {
66
+ status: 200,
67
+ headers: {
68
+ "Content-Type": getMimeType(safePath),
69
+ "Cache-Control": cacheControl,
70
+ },
71
+ });
72
+ }
73
+ //# sourceMappingURL=editor-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-assets.js","sourceRoot":"","sources":["../../../src/runtime/routes/editor-assets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { APIContext } from "astro";
2
+ export declare function GET(context: APIContext): Promise<Response>;
3
+ //# sourceMappingURL=entries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/entries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA8DxC,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyEhE"}