@caretcms/core 0.2.0 → 0.4.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 (256) hide show
  1. package/README.md +195 -12
  2. package/dist/index.d.ts +26 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +113 -12
  5. package/dist/index.js.map +1 -1
  6. package/dist/loader.d.ts.map +1 -1
  7. package/dist/loader.js +35 -3
  8. package/dist/loader.js.map +1 -1
  9. package/dist/markdown/paragraphs.d.ts +14 -0
  10. package/dist/markdown/paragraphs.d.ts.map +1 -0
  11. package/dist/markdown/paragraphs.js +61 -0
  12. package/dist/markdown/paragraphs.js.map +1 -0
  13. package/dist/markdown/remark.d.ts.map +1 -1
  14. package/dist/markdown/remark.js +1 -0
  15. package/dist/markdown/remark.js.map +1 -1
  16. package/dist/markdown/satteri.d.ts.map +1 -1
  17. package/dist/markdown/satteri.js +35 -9
  18. package/dist/markdown/satteri.js.map +1 -1
  19. package/dist/markdown/stamp.d.ts +0 -9
  20. package/dist/markdown/stamp.d.ts.map +1 -1
  21. package/dist/markdown/stamp.js +6 -0
  22. package/dist/markdown/stamp.js.map +1 -1
  23. package/dist/providers/deployment/github.d.ts +27 -0
  24. package/dist/providers/deployment/github.d.ts.map +1 -0
  25. package/dist/providers/deployment/github.js +180 -0
  26. package/dist/providers/deployment/github.js.map +1 -0
  27. package/dist/providers/deployment/simulated.d.ts +10 -0
  28. package/dist/providers/deployment/simulated.d.ts.map +1 -0
  29. package/dist/providers/deployment/simulated.js +29 -0
  30. package/dist/providers/deployment/simulated.js.map +1 -0
  31. package/dist/runtime/auth/session.d.ts +1 -0
  32. package/dist/runtime/auth/session.d.ts.map +1 -1
  33. package/dist/runtime/auth/session.js +16 -0
  34. package/dist/runtime/auth/session.js.map +1 -1
  35. package/dist/runtime/authorization.d.ts +11 -0
  36. package/dist/runtime/authorization.d.ts.map +1 -0
  37. package/dist/runtime/authorization.js +29 -0
  38. package/dist/runtime/authorization.js.map +1 -0
  39. package/dist/runtime/collection-policy.d.ts +11 -0
  40. package/dist/runtime/collection-policy.d.ts.map +1 -0
  41. package/dist/runtime/collection-policy.js +44 -0
  42. package/dist/runtime/collection-policy.js.map +1 -0
  43. package/dist/runtime/config.d.ts +3 -0
  44. package/dist/runtime/config.d.ts.map +1 -1
  45. package/dist/runtime/config.js +4 -1
  46. package/dist/runtime/config.js.map +1 -1
  47. package/dist/runtime/content-errors.d.ts +9 -0
  48. package/dist/runtime/content-errors.d.ts.map +1 -0
  49. package/dist/runtime/content-errors.js +17 -0
  50. package/dist/runtime/content-errors.js.map +1 -0
  51. package/dist/runtime/content.d.ts.map +1 -1
  52. package/dist/runtime/content.js +13 -4
  53. package/dist/runtime/content.js.map +1 -1
  54. package/dist/runtime/deployment-status.d.ts +14 -0
  55. package/dist/runtime/deployment-status.d.ts.map +1 -0
  56. package/dist/runtime/deployment-status.js +57 -0
  57. package/dist/runtime/deployment-status.js.map +1 -0
  58. package/dist/runtime/draft-state.d.ts +16 -0
  59. package/dist/runtime/draft-state.d.ts.map +1 -0
  60. package/dist/runtime/draft-state.js +29 -0
  61. package/dist/runtime/draft-state.js.map +1 -0
  62. package/dist/runtime/i18n.d.ts +97 -0
  63. package/dist/runtime/i18n.d.ts.map +1 -0
  64. package/dist/runtime/i18n.js +190 -0
  65. package/dist/runtime/i18n.js.map +1 -0
  66. package/dist/runtime/index.d.ts +1 -0
  67. package/dist/runtime/index.d.ts.map +1 -1
  68. package/dist/runtime/index.js +1 -0
  69. package/dist/runtime/index.js.map +1 -1
  70. package/dist/runtime/middleware.d.ts.map +1 -1
  71. package/dist/runtime/middleware.js +61 -4
  72. package/dist/runtime/middleware.js.map +1 -1
  73. package/dist/runtime/mutations/contracts.d.ts +12 -0
  74. package/dist/runtime/mutations/contracts.d.ts.map +1 -1
  75. package/dist/runtime/mutations/contracts.js +54 -4
  76. package/dist/runtime/mutations/contracts.js.map +1 -1
  77. package/dist/runtime/mutations/engine.d.ts +2 -0
  78. package/dist/runtime/mutations/engine.d.ts.map +1 -1
  79. package/dist/runtime/mutations/engine.js +220 -57
  80. package/dist/runtime/mutations/engine.js.map +1 -1
  81. package/dist/runtime/providers.d.ts +4 -1
  82. package/dist/runtime/providers.d.ts.map +1 -1
  83. package/dist/runtime/providers.js +18 -1
  84. package/dist/runtime/providers.js.map +1 -1
  85. package/dist/runtime/publish-recovery.d.ts +32 -0
  86. package/dist/runtime/publish-recovery.d.ts.map +1 -0
  87. package/dist/runtime/publish-recovery.js +98 -0
  88. package/dist/runtime/publish-recovery.js.map +1 -0
  89. package/dist/runtime/publish.d.ts +10 -4
  90. package/dist/runtime/publish.d.ts.map +1 -1
  91. package/dist/runtime/publish.js +105 -63
  92. package/dist/runtime/publish.js.map +1 -1
  93. package/dist/runtime/rebuild-webhook.d.ts +4 -0
  94. package/dist/runtime/rebuild-webhook.d.ts.map +1 -1
  95. package/dist/runtime/rebuild-webhook.js +12 -2
  96. package/dist/runtime/rebuild-webhook.js.map +1 -1
  97. package/dist/runtime/request-context.d.ts +7 -1
  98. package/dist/runtime/request-context.d.ts.map +1 -1
  99. package/dist/runtime/request-context.js +7 -1
  100. package/dist/runtime/request-context.js.map +1 -1
  101. package/dist/runtime/rewrite.d.ts.map +1 -1
  102. package/dist/runtime/rewrite.js +28 -2
  103. package/dist/runtime/rewrite.js.map +1 -1
  104. package/dist/runtime/rich-allowlist.js +1 -1
  105. package/dist/runtime/rich-allowlist.js.map +1 -1
  106. package/dist/runtime/routes/admin-entry.d.ts.map +1 -1
  107. package/dist/runtime/routes/admin-entry.js +129 -21
  108. package/dist/runtime/routes/admin-entry.js.map +1 -1
  109. package/dist/runtime/routes/admin.d.ts.map +1 -1
  110. package/dist/runtime/routes/admin.js +28 -14
  111. package/dist/runtime/routes/admin.js.map +1 -1
  112. package/dist/runtime/routes/auth-login.d.ts.map +1 -1
  113. package/dist/runtime/routes/auth-login.js +4 -0
  114. package/dist/runtime/routes/auth-login.js.map +1 -1
  115. package/dist/runtime/routes/auth-logout.d.ts.map +1 -1
  116. package/dist/runtime/routes/auth-logout.js +7 -2
  117. package/dist/runtime/routes/auth-logout.js.map +1 -1
  118. package/dist/runtime/routes/auth-session.d.ts.map +1 -1
  119. package/dist/runtime/routes/auth-session.js +10 -2
  120. package/dist/runtime/routes/auth-session.js.map +1 -1
  121. package/dist/runtime/routes/collection-list.d.ts.map +1 -1
  122. package/dist/runtime/routes/collection-list.js +213 -66
  123. package/dist/runtime/routes/collection-list.js.map +1 -1
  124. package/dist/runtime/routes/deployment.d.ts +5 -0
  125. package/dist/runtime/routes/deployment.d.ts.map +1 -0
  126. package/dist/runtime/routes/deployment.js +38 -0
  127. package/dist/runtime/routes/deployment.js.map +1 -0
  128. package/dist/runtime/routes/draft.d.ts.map +1 -1
  129. package/dist/runtime/routes/draft.js +10 -3
  130. package/dist/runtime/routes/draft.js.map +1 -1
  131. package/dist/runtime/routes/entries.d.ts.map +1 -1
  132. package/dist/runtime/routes/entries.js +87 -43
  133. package/dist/runtime/routes/entries.js.map +1 -1
  134. package/dist/runtime/routes/history.d.ts.map +1 -1
  135. package/dist/runtime/routes/history.js +40 -21
  136. package/dist/runtime/routes/history.js.map +1 -1
  137. package/dist/runtime/routes/mutate.d.ts.map +1 -1
  138. package/dist/runtime/routes/mutate.js +4 -1
  139. package/dist/runtime/routes/mutate.js.map +1 -1
  140. package/dist/runtime/routes/publish.d.ts.map +1 -1
  141. package/dist/runtime/routes/publish.js +127 -33
  142. package/dist/runtime/routes/publish.js.map +1 -1
  143. package/dist/runtime/routes/schema.d.ts.map +1 -1
  144. package/dist/runtime/routes/schema.js +11 -2
  145. package/dist/runtime/routes/schema.js.map +1 -1
  146. package/dist/runtime/routes/studio-home.d.ts.map +1 -1
  147. package/dist/runtime/routes/studio-home.js +41 -20
  148. package/dist/runtime/routes/studio-home.js.map +1 -1
  149. package/dist/runtime/routes/upload.d.ts.map +1 -1
  150. package/dist/runtime/routes/upload.js +3 -0
  151. package/dist/runtime/routes/upload.js.map +1 -1
  152. package/dist/runtime/schema-registry.d.ts +8 -1
  153. package/dist/runtime/schema-registry.d.ts.map +1 -1
  154. package/dist/runtime/schema-registry.js +49 -3
  155. package/dist/runtime/schema-registry.js.map +1 -1
  156. package/dist/runtime/storage/entry-commit.d.ts +8 -0
  157. package/dist/runtime/storage/entry-commit.d.ts.map +1 -0
  158. package/dist/runtime/storage/entry-commit.js +45 -0
  159. package/dist/runtime/storage/entry-commit.js.map +1 -0
  160. package/dist/runtime/storage/filesystem-adapter.d.ts +5 -0
  161. package/dist/runtime/storage/filesystem-adapter.d.ts.map +1 -1
  162. package/dist/runtime/storage/filesystem-adapter.js +12 -3
  163. package/dist/runtime/storage/filesystem-adapter.js.map +1 -1
  164. package/dist/runtime/storage/frontmatter-codec.d.ts +5 -23
  165. package/dist/runtime/storage/frontmatter-codec.d.ts.map +1 -1
  166. package/dist/runtime/storage/frontmatter-codec.js +156 -13
  167. package/dist/runtime/storage/frontmatter-codec.js.map +1 -1
  168. package/dist/runtime/storage/in-memory-adapter.d.ts +7 -0
  169. package/dist/runtime/storage/in-memory-adapter.d.ts.map +1 -1
  170. package/dist/runtime/storage/in-memory-adapter.js +6 -0
  171. package/dist/runtime/storage/in-memory-adapter.js.map +1 -1
  172. package/dist/runtime/storage/markdown-adapter.d.ts.map +1 -1
  173. package/dist/runtime/storage/markdown-adapter.js +18 -20
  174. package/dist/runtime/storage/markdown-adapter.js.map +1 -1
  175. package/dist/runtime/storage/session-overlay-adapter.d.ts +12 -4
  176. package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -1
  177. package/dist/runtime/storage/session-overlay-adapter.js +100 -13
  178. package/dist/runtime/storage/session-overlay-adapter.js.map +1 -1
  179. package/dist/runtime/storage/sidecar-meta-store.d.ts +5 -0
  180. package/dist/runtime/storage/sidecar-meta-store.d.ts.map +1 -1
  181. package/dist/runtime/storage/sidecar-meta-store.js +48 -5
  182. package/dist/runtime/storage/sidecar-meta-store.js.map +1 -1
  183. package/dist/runtime/themes/preset-tokens.js +4 -4
  184. package/dist/runtime/themes/preset-tokens.js.map +1 -1
  185. package/dist/runtime/utils.d.ts.map +1 -1
  186. package/dist/runtime/utils.js +3 -4
  187. package/dist/runtime/utils.js.map +1 -1
  188. package/dist/runtime/views/studio-layout.d.ts +3 -0
  189. package/dist/runtime/views/studio-layout.d.ts.map +1 -1
  190. package/dist/runtime/views/studio-layout.js +36 -13
  191. package/dist/runtime/views/studio-layout.js.map +1 -1
  192. package/dist/schema-utils.d.ts +7 -0
  193. package/dist/schema-utils.d.ts.map +1 -1
  194. package/dist/schema-utils.js +143 -0
  195. package/dist/schema-utils.js.map +1 -1
  196. package/dist/types.d.ts +165 -1
  197. package/dist/types.d.ts.map +1 -1
  198. package/package.json +12 -3
  199. package/static/cms/admin-entry.css +144 -13
  200. package/static/cms/admin-entry.js +539 -586
  201. package/static/cms/dev-toolbar/app.js +78 -19
  202. package/static/cms/editor/config.js +35 -15
  203. package/static/cms/editor/content-map.css +8 -1
  204. package/static/cms/editor/content-map.js +62 -23
  205. package/static/cms/editor/deployment-status.js +66 -0
  206. package/static/cms/editor/draft-client.js +87 -0
  207. package/static/cms/editor/guards.js +20 -0
  208. package/static/cms/editor/helpers.js +30 -1
  209. package/static/cms/editor/highlight.js +1 -0
  210. package/static/cms/editor/image-edit.js +44 -1
  211. package/static/cms/editor/image-utils.js +23 -7
  212. package/static/cms/editor/link-follow.js +122 -41
  213. package/static/cms/editor/link-ui.css +10 -1
  214. package/static/cms/editor/linkify.js +2 -0
  215. package/static/cms/editor/md-block-edit.js +140 -37
  216. package/static/cms/editor/md-paragraphs.js +98 -0
  217. package/static/cms/editor/md-serialize.js +1 -1
  218. package/static/cms/editor/panel.js +53 -7
  219. package/static/cms/editor/preview-mode.js +44 -0
  220. package/static/cms/editor/publish-result.js +100 -0
  221. package/static/cms/editor/rich-toolbar.js +58 -15
  222. package/static/cms/editor/sanitize.js +6 -2
  223. package/static/cms/editor/save-queue.js +75 -17
  224. package/static/cms/editor/section-controls/activation.js +3 -0
  225. package/static/cms/editor/section-controls/api.js +25 -7
  226. package/static/cms/editor/section-controls/index.js +60 -8
  227. package/static/cms/editor/section-controls/model.js +39 -4
  228. package/static/cms/editor/section-controls/mutations.js +15 -0
  229. package/static/cms/editor/section-controls/page-context.js +9 -0
  230. package/static/cms/editor/section-controls/pickers.js +53 -2
  231. package/static/cms/editor/section-controls/reorder.js +23 -0
  232. package/static/cms/editor/section-controls/selection.js +6 -0
  233. package/static/cms/editor/section-controls/spacing-drag.js +16 -0
  234. package/static/cms/editor/section-controls/ui-elements.js +7 -0
  235. package/static/cms/editor/section-controls/utils.js +7 -0
  236. package/static/cms/editor/section-controls.css +18 -3
  237. package/static/cms/editor/security.js +13 -2
  238. package/static/cms/editor/stega-hydrate.js +17 -4
  239. package/static/cms/editor/sync.js +475 -56
  240. package/static/cms/editor/text-edit.js +37 -3
  241. package/static/cms/editor/text-link-interactions.js +59 -17
  242. package/static/cms/editor/toast.js +23 -9
  243. package/static/cms/editor/tokens-and-text.css +9 -0
  244. package/static/cms/editor/toolbar.css +5 -0
  245. package/static/cms/editor/toolbar.js +91 -101
  246. package/static/cms/editor.css +1 -1
  247. package/static/cms/editor.js +1 -0
  248. package/static/cms/studio/entry-loader.js +102 -0
  249. package/static/cms/studio/field-model.js +110 -0
  250. package/static/cms/studio/fields.js +319 -0
  251. package/static/cms/studio/history-client.js +74 -0
  252. package/static/cms/studio/mutation-client.js +74 -0
  253. package/static/cms/studio/sync-client.js +107 -0
  254. package/static/cms/studio/upload-client.js +109 -0
  255. package/static/cms/studio-tokens.css +4 -4
  256. package/static/cms/studio.css +24 -0
@@ -1,9 +1,17 @@
1
+ import { getRequestContext } from "../request-context.js";
2
+ import { canPerform } from "../authorization.js";
1
3
  export const prerender = false;
2
- import { isEditorAuthenticated } from "../auth/session.js";
4
+ import { getEditorIdentity, isEditorAuthenticated } from "../auth/session.js";
3
5
  import { json } from "./_helpers.js";
4
6
  export async function GET(context) {
7
+ const authenticated = isEditorAuthenticated(context);
5
8
  return json({
6
- authenticated: isEditorAuthenticated(context),
9
+ ...(authenticated && getRequestContext()?.authorize ? {
10
+ draftMode: true,
11
+ permissions: Object.fromEntries(await Promise.all(["edit", "publish", "delete", "manageCollections", "upload"].map(async (action) => [action, await canPerform(action, context.url?.searchParams.get("collection") ?? undefined, context.url?.searchParams.get("id") ?? undefined)]))),
12
+ } : {}),
13
+ authenticated,
14
+ identity: authenticated ? getEditorIdentity(context) : null,
7
15
  });
8
16
  }
9
17
  //# sourceMappingURL=auth-session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-session.js","sourceRoot":"","sources":["../../../src/runtime/routes/auth-session.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAG/B,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"}
1
+ {"version":3,"file":"auth-session.js","sourceRoot":"","sources":["../../../src/runtime/routes/auth-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAG/B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,MAAM,aAAa,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC;QACV,GAAG,CAAC,aAAa,IAAI,iBAAiB,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;YACpD,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,OAAO,CAAC,GAAG,CAC9C,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,QAAQ,CAAW,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,CACzF,CAAC,MAAM,EAAE,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAClJ,CAAC;SACH,CAAC,CAAC,CAAC,EAAE,CAAC;QACP,aAAa;QACb,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;KAC5D,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"collection-list.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/collection-list.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,QAAQ,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAexC,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqahE"}
1
+ {"version":3,"file":"collection-list.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/collection-list.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,SAAS,QAAQ,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAqBxC,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAujBhE"}
@@ -1,8 +1,11 @@
1
+ import { canPerform } from "../authorization.js";
1
2
  export const prerender = false;
2
3
  import { isEditorAuthenticated } from "../auth/session.js";
3
4
  import { getRuntimeConfig } from "../config.js";
4
5
  import { resolveAdapter } from "./_helpers.js";
5
- import { escapeHtml, htmlResponse, redirectResponse, renderStudioPage, } from "../views/studio-layout.js";
6
+ import { isKnownStudioCollection, resolveCollectionStudioConfig, } from "../schema-registry.js";
7
+ import { publicationField } from "../collection-policy.js";
8
+ import { escapeHtml, htmlResponse, redirectResponse, renderStudioPage, serializeJsonForScript, } from "../views/studio-layout.js";
6
9
  function humanize(name) {
7
10
  return name.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
8
11
  }
@@ -17,11 +20,18 @@ export async function GET(context) {
17
20
  return redirectResponse(`${runtime.mountPath}/cms`);
18
21
  }
19
22
  const adapter = await resolveAdapter();
20
- const known = await adapter.discoverCollections();
21
- if (!known.includes(collection)) {
23
+ if (!(await isKnownStudioCollection(adapter, collection))) {
22
24
  return redirectResponse(`${runtime.mountPath}/cms`);
23
25
  }
24
- const label = humanize(collection);
26
+ const collectionConfig = await resolveCollectionStudioConfig(adapter, collection);
27
+ if (collectionConfig.singletonId) {
28
+ return redirectResponse(`${runtime.mountPath}/cms/${encodeURIComponent(collection)}/${encodeURIComponent(collectionConfig.singletonId)}`);
29
+ }
30
+ const label = collectionConfig.label || humanize(collection);
31
+ const messages = runtime.messages;
32
+ const creatable = collectionConfig.creatable !== false && await canPerform("edit", collection);
33
+ const orderable = collectionConfig.orderable !== false && await canPerform("edit", collection);
34
+ const publicationFieldName = publicationField(collectionConfig);
25
35
  const safeCollection = escapeHtml(collection);
26
36
  const extraStyles = `
27
37
  .entry-card {
@@ -60,6 +70,8 @@ export async function GET(context) {
60
70
  .reorder-handle { color: var(--studio-text-dim); font-size: 16px; line-height: 1; flex-shrink: 0; }
61
71
  .reorder-label { flex: 1; font-size: 14px; color: var(--studio-text); }
62
72
  .reorder-order { font-size: 11px; color: var(--studio-text-dim); font-variant-numeric: tabular-nums; min-width: 24px; text-align: right; }
73
+ .reorder-controls { display: flex; gap: 0.35rem; flex-shrink: 0; }
74
+ .reorder-move { min-width: 32px; padding: 4px 8px; }
63
75
  .modal-backdrop {
64
76
  position: fixed;
65
77
  inset: 0;
@@ -94,13 +106,14 @@ export async function GET(context) {
94
106
  const body = `<div class="studio-fade-in" style="max-width:80rem;margin:0 auto;" id="collection-page" data-collection="${safeCollection}">
95
107
  <div style="display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:1.5rem;">
96
108
  <div>
97
- <h2 style="font-family:var(--studio-font-heading);font-size:1.25rem;margin:0;color:var(--studio-text);">${escapeHtml(label)}</h2>
98
- <p id="entry-count" style="font-size:0.7rem;margin:0.25rem 0 0;color:var(--studio-text-dim);">Loading…</p>
109
+ <h1 style="font-family:var(--studio-font-heading);font-size:1.25rem;margin:0;color:var(--studio-text);">${escapeHtml(label)}</h1>
110
+ <p id="entry-count" style="font-size:0.7rem;margin:0.25rem 0 0;color:var(--studio-text-dim);">${escapeHtml(messages["common.loading"])}</p>
99
111
  </div>
100
112
  <div style="display:flex;align-items:center;gap:0.75rem;flex-wrap:wrap;">
101
- <input id="search-input" type="text" placeholder="Search…" class="studio-input" style="max-width:240px;" />
102
- <button id="btn-reorder" class="studio-btn-ghost">Reorder</button>
103
- <button id="btn-new" class="studio-btn-primary">+ New</button>
113
+ <label for="search-input" style="font-size:0.7rem;color:var(--studio-text-dim);">${escapeHtml(messages["collection.search"])}</label>
114
+ <input id="search-input" name="search" type="search" placeholder="${escapeHtml(messages["collection.searchPlaceholder"])}" class="studio-input" style="max-width:240px;" />
115
+ ${orderable ? `<button id="btn-reorder" type="button" class="studio-btn-ghost" aria-controls="reorder-container" aria-expanded="false">${escapeHtml(messages["collection.reorder"])}</button>` : ""}
116
+ ${creatable ? `<button id="btn-new" class="studio-btn-primary">${escapeHtml(messages["collection.new"])}</button>` : ""}
104
117
  </div>
105
118
  </div>
106
119
 
@@ -109,50 +122,69 @@ export async function GET(context) {
109
122
  </div>
110
123
 
111
124
  <div id="empty" hidden style="text-align:center;padding:5rem 0;color:var(--studio-text-dim);">
112
- <p style="font-size:0.875rem;margin:0 0 0.75rem;">No entries yet.</p>
113
- <button id="btn-empty-create" class="studio-btn-primary">Create First Entry</button>
125
+ <p style="font-size:0.875rem;margin:0 0 0.75rem;">${escapeHtml(messages["collection.noEntries"])}</p>
126
+ ${creatable ? `<button id="btn-empty-create" class="studio-btn-primary">${escapeHtml(messages["collection.createFirst"])}</button>` : ""}
114
127
  </div>
115
128
 
116
129
  <div id="error-state" hidden style="text-align:center;padding:5rem 0;">
117
- <p style="font-size:0.875rem;margin:0 0 0.75rem;color:var(--studio-red);">Failed to load entries.</p>
118
- <button id="retry-btn" class="studio-btn-ghost">Retry</button>
130
+ <p style="font-size:0.875rem;margin:0 0 0.75rem;color:var(--studio-red);">${escapeHtml(messages["collection.failed"])}</p>
131
+ <button id="retry-btn" class="studio-btn-ghost">${escapeHtml(messages["common.retry"])}</button>
119
132
  </div>
120
133
 
121
134
  <div id="entries-grid" hidden style="display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));"></div>
122
135
 
123
- <div id="reorder-container" hidden>
124
- <div id="reorder-list" style="display:flex;flex-direction:column;gap:0.25rem;"></div>
136
+ <nav id="pagination" aria-label="${escapeHtml(messages["collection.pagination"])}" hidden style="display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:1rem;">
137
+ <button id="page-prev" type="button" class="studio-btn-ghost">${escapeHtml(messages["collection.previous"])}</button>
138
+ <span id="page-range" role="status" aria-live="polite"></span>
139
+ <button id="page-next" type="button" class="studio-btn-ghost">${escapeHtml(messages["collection.next"])}</button>
140
+ </nav>
141
+ <p id="reorder-scope" hidden style="font-size:0.8rem;color:var(--studio-text-dim);">${escapeHtml(messages["collection.reorderScope"])}</p>
142
+
143
+ <div id="reorder-container" role="region" aria-label="${escapeHtml(messages["collection.reorder"])}" hidden>
144
+ <div id="reorder-list" role="list" style="display:flex;flex-direction:column;gap:0.25rem;"></div>
125
145
  <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);">
126
- <button id="btn-reorder-cancel" class="studio-btn-ghost">Cancel</button>
127
- <button id="btn-reorder-save" class="studio-btn-primary">Save Order</button>
146
+ <button id="btn-reorder-cancel" type="button" class="studio-btn-ghost">${escapeHtml(messages["common.cancel"])}</button>
147
+ <button id="btn-reorder-save" type="button" class="studio-btn-primary">${escapeHtml(messages["collection.saveOrder"])}</button>
128
148
  </div>
129
149
  </div>
130
150
  </div>
131
151
 
132
- <div id="create-dialog" class="modal-backdrop" hidden>
152
+ <div id="create-dialog" class="modal-backdrop" role="dialog" aria-modal="true" aria-labelledby="create-dialog-title" aria-describedby="create-hint" hidden>
133
153
  <div class="modal-card">
134
154
  <div class="modal-header">
135
- <span>New Entry</span>
136
- <button id="btn-create-close" class="studio-btn-ghost" style="padding:4px 10px;">Close</button>
155
+ <h2 id="create-dialog-title" style="font:inherit;letter-spacing:inherit;text-transform:inherit;margin:0;">${escapeHtml(messages["collection.newEntry"])}</h2>
156
+ <button id="btn-create-close" type="button" class="studio-btn-ghost" style="padding:4px 10px;">${escapeHtml(messages["common.close"])}</button>
137
157
  </div>
138
158
  <div class="modal-body">
139
- <label for="create-id-input" class="studio-label">Entry ID (slug)</label>
140
- <input id="create-id-input" type="text" class="studio-input" placeholder="e.g. my-first-entry" autocomplete="off" spellcheck="false" />
141
- <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>
159
+ <label for="create-id-input" class="studio-label">${escapeHtml(messages["collection.entryId"])}</label>
160
+ <input id="create-id-input" type="text" class="studio-input" placeholder="${escapeHtml(messages["collection.entryIdPlaceholder"])}" autocomplete="off" spellcheck="false" />
161
+ <p id="create-hint" style="font-size:10px;margin:0.5rem 0 0.35rem;color:var(--studio-text-dim);">${escapeHtml(messages["collection.idHint"])}</p>
162
+ ${publicationFieldName ? `<p style="font-size:10px;margin:0 0 1rem;color:var(--studio-text-dim);">${escapeHtml(messages["collection.publishHint"])}</p>` : ""}
142
163
  <p id="create-error" class="studio-error-text" hidden></p>
143
164
  <div style="display:flex;justify-content:flex-end;gap:0.75rem;">
144
- <button id="btn-create-cancel" class="studio-btn-ghost">Cancel</button>
145
- <button id="btn-create-confirm" class="studio-btn-primary" disabled>Create</button>
165
+ <button id="btn-create-cancel" type="button" class="studio-btn-ghost">${escapeHtml(messages["common.cancel"])}</button>
166
+ <button id="btn-create-confirm" type="button" class="studio-btn-primary" disabled>${escapeHtml(messages["collection.create"])}</button>
146
167
  </div>
147
168
  </div>
148
169
  </div>
149
170
  </div>`;
150
171
  const inlineScript = `(function () {
151
- var COLLECTION = ${JSON.stringify(collection)};
152
- var API = ${JSON.stringify(runtime.apiBasePath)};
153
- var MOUNT = ${JSON.stringify(runtime.mountPath)};
172
+ var COLLECTION = ${serializeJsonForScript(collection)};
173
+ var API = ${serializeJsonForScript(runtime.apiBasePath)};
174
+ var MOUNT = ${serializeJsonForScript(runtime.mountPath)};
175
+ var MSG = ${serializeJsonForScript(messages)};
176
+ var PUBLICATION_FIELD = ${serializeJsonForScript(publicationFieldName)};
154
177
  var ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
155
178
  var allEntries = [];
179
+ var currentPage = 1;
180
+ var query = '';
181
+ var requestVersion = 0;
182
+ var searchTimer;
183
+ var pagination = document.getElementById('pagination');
184
+ var previousPage = document.getElementById('page-prev');
185
+ var nextPage = document.getElementById('page-next');
186
+ var pageRange = document.getElementById('page-range');
187
+ var reorderScope = document.getElementById('reorder-scope');
156
188
 
157
189
  var grid = document.getElementById('entries-grid');
158
190
  var loading = document.getElementById('loading');
@@ -172,23 +204,30 @@ export async function GET(context) {
172
204
  var idInput = document.getElementById('create-id-input');
173
205
  var errorEl = document.getElementById('create-error');
174
206
  var confirmBtn = document.getElementById('btn-create-confirm');
207
+ var createCloseBtn = document.getElementById('btn-create-close');
208
+ var createCancelBtn = document.getElementById('btn-create-cancel');
209
+ var dialogTrigger = null;
210
+ var knownDuplicateIds = new Set();
175
211
 
176
212
  function htmlEsc(s) { return String(s).replace(/[&<>"']/g, function (c) {
177
213
  return { '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c]; });
178
214
  }
179
215
 
180
216
  function getTitle(d) {
181
- if (!d) return 'Untitled';
217
+ if (!d) return MSG['collection.untitled'];
182
218
  for (var i = 0; i < ['name','title','question','company_name','headline','label'].length; i++) {
183
219
  var k = ['name','title','question','company_name','headline','label'][i];
184
220
  if (typeof d[k] === 'string' && d[k]) return d[k];
185
221
  }
186
- return 'Untitled';
222
+ return MSG['collection.untitled'];
187
223
  }
188
224
  function getThumb(d) {
189
225
  if (!d) return null;
190
226
  if (Array.isArray(d.images) && typeof d.images[0] === 'string') return d.images[0];
227
+ if (Array.isArray(d.images) && d.images[0] && typeof d.images[0].src === 'string') return d.images[0].src;
191
228
  if (typeof d.image === 'string' && d.image) return d.image;
229
+ if (typeof d.coverImage === 'string' && d.coverImage) return d.coverImage;
230
+ if (typeof d.portrait === 'string' && d.portrait) return d.portrait;
192
231
  if (typeof d.thumbnail === 'string' && d.thumbnail) return d.thumbnail;
193
232
  if (typeof d.bg_image === 'string' && d.bg_image) return d.bg_image;
194
233
  return null;
@@ -213,9 +252,17 @@ export async function GET(context) {
213
252
  grid.hidden = false;
214
253
  for (var i = 0; i < entries.length; i++) {
215
254
  var entry = entries[i];
216
- var title = getTitle(entry.data);
255
+ var title = entry.readError ? entry.id : getTitle(entry.data);
217
256
  var thumb = getThumb(entry.data);
218
257
  var subtitle = getSubtitle(entry.data);
258
+ var publication = PUBLICATION_FIELD && entry.data && typeof entry.data[PUBLICATION_FIELD] === 'boolean'
259
+ ? (entry.data[PUBLICATION_FIELD]
260
+ ? '<span style="font-size:0.62rem;color:var(--studio-green);">' + htmlEsc(MSG['collection.published']) + '</span>'
261
+ : '<span style="font-size:0.62rem;color:var(--studio-text-dim);">' + htmlEsc(MSG['collection.unpublished']) + '</span>')
262
+ : '';
263
+ var invalid = Array.isArray(entry.validationIssues) && entry.validationIssues.length
264
+ ? '<span style="display:block;font-size:0.62rem;color:var(--studio-red);margin-bottom:0.25rem;">' + htmlEsc(MSG['collection.invalid']) + '</span>'
265
+ : '';
219
266
  var card = document.createElement('a');
220
267
  card.href = MOUNT + '/cms/' + encodeURIComponent(COLLECTION) + '/' + encodeURIComponent(entry.id);
221
268
  card.className = 'entry-card studio-card';
@@ -225,8 +272,10 @@ export async function GET(context) {
225
272
  card.innerHTML =
226
273
  (thumb ? '<div class="entry-thumb"><img src="' + htmlEsc(thumb) + '" alt="' + htmlEsc(title) + '" loading="lazy" /></div>' : '') +
227
274
  '<div style="padding:1rem;">' +
228
- '<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>' +
275
+ '<h2 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) + '</h2>' +
229
276
  (subtitle ? '<p style="font-size:0.7rem;margin:0 0 0.25rem;color:var(--studio-text-dim);text-transform:capitalize;">' + htmlEsc(subtitle) + '</p>' : '') +
277
+ (entry.readError ? '<p role="note">' + htmlEsc(MSG['collection.unreadable']) + '</p>' : invalid) +
278
+ publication +
230
279
  '<p style="font-size:0.65rem;margin:0;color:var(--studio-text-dim);font-family:var(--studio-font-mono);">' + htmlEsc(entry.id) + '</p>' +
231
280
  '</div>';
232
281
  grid.appendChild(card);
@@ -234,11 +283,14 @@ export async function GET(context) {
234
283
  }
235
284
 
236
285
  function loadEntries() {
286
+ var version = ++requestVersion;
287
+ pagination.hidden = true;
288
+ if (reorderBtn) reorderBtn.disabled = true;
237
289
  loading.hidden = false;
238
290
  errorState.hidden = true;
239
291
  empty.hidden = true;
240
292
  grid.hidden = true;
241
- fetch(API + '/entries?collection=' + encodeURIComponent(COLLECTION))
293
+ return fetch(API + '/entries?collection=' + encodeURIComponent(COLLECTION) + '&page=' + currentPage + '&q=' + encodeURIComponent(query))
242
294
  .then(function (res) {
243
295
  if (res.status === 401) {
244
296
  window.location.href = MOUNT + '?redirect=' + encodeURIComponent(window.location.pathname);
@@ -248,15 +300,27 @@ export async function GET(context) {
248
300
  return res.json();
249
301
  })
250
302
  .then(function (json) {
251
- if (!json) return;
303
+ if (!json || version !== requestVersion) return;
252
304
  allEntries = Array.isArray(json.entries) ? json.entries : [];
253
305
  loading.hidden = true;
254
- countEl.textContent = allEntries.length + ' ' + (allEntries.length === 1 ? 'entry' : 'entries');
306
+ var paging = json.pagination;
307
+ currentPage = paging.page;
308
+ countEl.textContent = paging.total + ' ' + (paging.total === 1 ? MSG['count.entry'] : MSG['count.entries']);
309
+ previousPage.disabled = !paging.hasPrev;
310
+ nextPage.disabled = !paging.hasNext;
311
+ pageRange.textContent = MSG['collection.range'].replace('{start}', paging.total ? (paging.page - 1) * paging.pageSize + 1 : 0).replace('{end}', Math.min(paging.page * paging.pageSize, paging.total)).replace('{total}', paging.total);
312
+ pagination.hidden = paging.total === 0;
313
+ empty.querySelector('p').textContent = query ? MSG['collection.noResults'] : MSG['collection.noEntries'];
314
+ if (emptyCreateBtn) emptyCreateBtn.hidden = Boolean(query);
315
+ var limited = Boolean(query) || paging.totalPages > 1 || allEntries.some(function (entry) { return entry.readError; });
316
+ if (reorderBtn) { reorderBtn.disabled = limited; reorderScope.hidden = !limited; }
317
+
255
318
  renderEntries(allEntries);
256
319
  })
257
320
  .catch(function () {
321
+ if (version !== requestVersion) return;
258
322
  loading.hidden = true;
259
- countEl.textContent = 'Error';
323
+ countEl.textContent = MSG['common.error'];
260
324
  errorState.hidden = false;
261
325
  });
262
326
  }
@@ -264,30 +328,39 @@ export async function GET(context) {
264
328
  loadEntries();
265
329
  retryBtn.addEventListener('click', loadEntries);
266
330
 
331
+ previousPage.addEventListener('click', function () { currentPage--; loadEntries(); });
332
+ nextPage.addEventListener('click', function () { currentPage++; loadEntries(); });
267
333
  searchInput.addEventListener('input', function () {
268
- var q = searchInput.value.toLowerCase();
269
- if (!q) { renderEntries(allEntries); return; }
270
- var filtered = allEntries.filter(function (e) {
271
- var t = getTitle(e.data).toLowerCase();
272
- return t.indexOf(q) >= 0 || e.id.toLowerCase().indexOf(q) >= 0;
273
- });
274
- renderEntries(filtered);
334
+ clearTimeout(searchTimer);
335
+ ++requestVersion; // ignore older responses immediately, including during debounce
336
+ if (reorderBtn) reorderBtn.disabled = true;
337
+ previousPage.disabled = true; nextPage.disabled = true;
338
+ searchTimer = setTimeout(function () {
339
+ query = searchInput.value.trim(); currentPage = 1; loadEntries();
340
+ }, 180);
275
341
  });
276
342
 
277
343
  /* ─── Create dialog ─────────────────────────────────────────────── */
278
344
  function openDialog() {
345
+ dialogTrigger = document.activeElement instanceof HTMLElement ? document.activeElement : null;
279
346
  dialog.hidden = false;
280
347
  idInput.value = '';
281
348
  errorEl.hidden = true;
282
349
  confirmBtn.disabled = true;
283
350
  idInput.focus();
284
351
  }
285
- function closeDialog() { dialog.hidden = true; }
352
+ function closeDialog() {
353
+ if (dialog.hidden) return;
354
+ dialog.hidden = true;
355
+ var trigger = dialogTrigger;
356
+ dialogTrigger = null;
357
+ if (trigger && trigger.isConnected) trigger.focus();
358
+ }
286
359
  function validate() {
287
360
  var v = idInput.value.trim();
288
361
  if (!v) { confirmBtn.disabled = true; errorEl.hidden = true; return; }
289
- if (!ID_RE.test(v)) { errorEl.textContent = 'Use lowercase letters, numbers, and hyphens only.'; errorEl.hidden = false; confirmBtn.disabled = true; return; }
290
- 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; }
362
+ if (!ID_RE.test(v)) { errorEl.textContent = MSG['collection.invalidId']; errorEl.hidden = false; confirmBtn.disabled = true; return; }
363
+ if (knownDuplicateIds.has(v) || allEntries.some(function (e) { return e.id === v; })) { errorEl.textContent = MSG['collection.duplicateId']; errorEl.hidden = false; confirmBtn.disabled = true; return; }
291
364
  errorEl.hidden = true; confirmBtn.disabled = false;
292
365
  }
293
366
  function createEntry() {
@@ -305,36 +378,78 @@ export async function GET(context) {
305
378
  method: 'POST',
306
379
  headers: { 'Content-Type': 'application/json', 'x-caret-request': '1' },
307
380
  credentials: 'same-origin',
308
- body: JSON.stringify({ type: 'put_entry', collection: COLLECTION, id: entryId, data: template }),
381
+ body: JSON.stringify({ type: 'put_entry', collection: COLLECTION, id: entryId, data: template, createOnly: true }),
309
382
  });
310
383
  })
311
384
  .then(function (res) {
312
385
  if (!res) return;
313
386
  if (res.status === 401) { window.location.href = MOUNT + '?redirect=' + encodeURIComponent(window.location.pathname); return; }
387
+ if (res.status === 409) {
388
+ knownDuplicateIds.add(entryId);
389
+ errorEl.textContent = MSG['collection.duplicateId'];
390
+ errorEl.hidden = false;
391
+ confirmBtn.disabled = true;
392
+ confirmBtn.textContent = MSG['collection.create'];
393
+ idInput.focus();
394
+ idInput.select();
395
+ return;
396
+ }
314
397
  if (!res.ok) throw new Error('mutate failed');
315
- window.location.href = MOUNT + '/cms/' + encodeURIComponent(COLLECTION) + '/' + encodeURIComponent(entryId);
398
+ window.location.href = MOUNT + '/cms/' + encodeURIComponent(COLLECTION) + '/' + encodeURIComponent(entryId) + '?new=1';
316
399
  })
317
400
  .catch(function () {
318
- errorEl.textContent = 'Failed to create entry. Try again.';
401
+ errorEl.textContent = MSG['collection.createFailed'];
319
402
  errorEl.hidden = false;
320
403
  confirmBtn.disabled = false;
321
- confirmBtn.textContent = 'Create';
404
+ confirmBtn.textContent = MSG['collection.create'];
322
405
  });
323
406
  }
324
- newBtn.addEventListener('click', openDialog);
325
- emptyCreateBtn.addEventListener('click', openDialog);
326
- document.getElementById('btn-create-close').addEventListener('click', closeDialog);
327
- document.getElementById('btn-create-cancel').addEventListener('click', closeDialog);
407
+ if (newBtn) newBtn.addEventListener('click', openDialog);
408
+ if (emptyCreateBtn) emptyCreateBtn.addEventListener('click', openDialog);
409
+ createCloseBtn.addEventListener('click', closeDialog);
410
+ createCancelBtn.addEventListener('click', closeDialog);
328
411
  confirmBtn.addEventListener('click', createEntry);
329
412
  idInput.addEventListener('input', validate);
330
413
  idInput.addEventListener('keydown', function (e) { if (e.key === 'Enter' && !confirmBtn.disabled) createEntry(); });
331
414
  dialog.addEventListener('click', function (e) { if (e.target === dialog) closeDialog(); });
332
- document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !dialog.hidden) closeDialog(); });
415
+ document.addEventListener('keydown', function (e) {
416
+ if (!dialog.hidden) {
417
+ if (e.key === 'Escape') {
418
+ e.preventDefault();
419
+ e.stopPropagation();
420
+ closeDialog();
421
+ return;
422
+ }
423
+ if (e.key !== 'Tab') return;
424
+ var focusable = [createCloseBtn, idInput, createCancelBtn, confirmBtn].filter(function (element) {
425
+ return !element.disabled && !element.hidden;
426
+ });
427
+ var first = focusable[0];
428
+ var last = focusable[focusable.length - 1];
429
+ if (e.shiftKey && document.activeElement === first) {
430
+ e.preventDefault();
431
+ last.focus();
432
+ } else if (!e.shiftKey && document.activeElement === last) {
433
+ e.preventDefault();
434
+ first.focus();
435
+ }
436
+ return;
437
+ }
438
+ if (e.key === 'Escape' && reorderMode) {
439
+ e.preventDefault();
440
+ e.stopPropagation();
441
+ exitReorder();
442
+ }
443
+ }, true);
333
444
 
334
445
  /* ─── Reorder mode ──────────────────────────────────────────────── */
335
446
  var reorderMode = false;
336
447
  var ordered = [];
448
+ var reorderTrigger = null;
337
449
  function enterReorder() {
450
+ if (reorderBtn.disabled) return;
451
+ reorderTrigger = document.activeElement instanceof HTMLElement ? document.activeElement : reorderBtn;
452
+ pagination.hidden = true;
338
453
  reorderMode = true;
339
454
  ordered = allEntries.slice().sort(function (a, b) {
340
455
  var ao = (a.data && typeof a.data.order === 'number') ? a.data.order : 0;
@@ -342,17 +457,38 @@ export async function GET(context) {
342
457
  return ao - bo;
343
458
  });
344
459
  grid.hidden = true; empty.hidden = true;
345
- searchInput.style.display = 'none'; newBtn.style.display = 'none';
346
- reorderBtn.textContent = 'Reordering…'; reorderBtn.disabled = true;
460
+ searchInput.style.display = 'none'; if (newBtn) newBtn.style.display = 'none';
461
+ reorderBtn.textContent = MSG['collection.reordering']; reorderBtn.disabled = true;
462
+ reorderBtn.setAttribute('aria-expanded', 'true');
347
463
  reorderContainer.hidden = false;
348
464
  renderReorderList();
465
+ var firstMove = reorderList.querySelector('button:not(:disabled)');
466
+ (firstMove || reorderCancel).focus();
349
467
  }
350
468
  function exitReorder() {
351
469
  reorderMode = false;
352
470
  reorderContainer.hidden = true;
353
- searchInput.style.display = ''; newBtn.style.display = '';
354
- reorderBtn.textContent = 'Reorder'; reorderBtn.disabled = false;
355
- renderEntries(allEntries);
471
+ searchInput.style.display = ''; if (newBtn) newBtn.style.display = '';
472
+ reorderBtn.textContent = MSG['collection.reorder']; reorderBtn.disabled = false;
473
+ reorderBtn.setAttribute('aria-expanded', 'false');
474
+ var trigger = reorderTrigger;
475
+ reorderTrigger = null;
476
+ loadEntries().then(function () {
477
+ if (trigger && trigger.isConnected) trigger.focus();
478
+ });
479
+ }
480
+ function moveReorderEntry(index, direction) {
481
+ var target = index + direction;
482
+ if (target < 0 || target >= ordered.length) return;
483
+ var moved = ordered.splice(index, 1)[0];
484
+ if (!moved) return;
485
+ ordered.splice(target, 0, moved);
486
+ renderReorderList();
487
+ var nextItem = reorderList.children[target];
488
+ var sameDirection = nextItem && nextItem.querySelector('[data-move="' + direction + '"]');
489
+ var oppositeDirection = nextItem && nextItem.querySelector('[data-move="' + (-direction) + '"]');
490
+ var focusTarget = sameDirection && !sameDirection.disabled ? sameDirection : oppositeDirection;
491
+ if (focusTarget) focusTarget.focus();
356
492
  }
357
493
  function renderReorderList() {
358
494
  reorderList.innerHTML = '';
@@ -360,12 +496,23 @@ export async function GET(context) {
360
496
  ordered.forEach(function (entry, idx) {
361
497
  var item = document.createElement('div');
362
498
  item.className = 'reorder-item';
499
+ item.setAttribute('role', 'listitem');
363
500
  item.draggable = true;
364
501
  item.dataset.idx = String(idx);
502
+ var title = getTitle(entry.data);
365
503
  item.innerHTML =
366
- '<span class="reorder-handle">&#9776;</span>' +
367
- '<span class="reorder-label">' + htmlEsc(getTitle(entry.data)) + '</span>' +
368
- '<span class="reorder-order">' + (idx + 1) + '</span>';
504
+ '<span class="reorder-handle" aria-hidden="true">&#9776;</span>' +
505
+ '<span class="reorder-label">' + htmlEsc(title) + '</span>' +
506
+ '<span class="reorder-order">' + (idx + 1) + '</span>' +
507
+ '<span class="reorder-controls">' +
508
+ '<button type="button" class="studio-btn-ghost reorder-move" data-move="-1" aria-label="' + htmlEsc(MSG['field.moveUp'] + ' ' + title) + '"' + (idx === 0 ? ' disabled' : '') + '>&uarr;</button>' +
509
+ '<button type="button" class="studio-btn-ghost reorder-move" data-move="1" aria-label="' + htmlEsc(MSG['field.moveDown'] + ' ' + title) + '"' + (idx === ordered.length - 1 ? ' disabled' : '') + '>&darr;</button>' +
510
+ '</span>';
511
+ item.querySelectorAll('[data-move]').forEach(function (button) {
512
+ button.addEventListener('click', function () {
513
+ moveReorderEntry(idx, Number(button.dataset.move));
514
+ });
515
+ });
369
516
  item.addEventListener('dragstart', function () { dragIdx = idx; item.classList.add('dragging'); });
370
517
  item.addEventListener('dragend', function () {
371
518
  dragIdx = null; item.classList.remove('dragging');
@@ -385,7 +532,7 @@ export async function GET(context) {
385
532
  });
386
533
  }
387
534
  function saveOrder() {
388
- reorderSave.disabled = true; reorderSave.textContent = 'Saving…';
535
+ reorderSave.disabled = true; reorderSave.textContent = MSG['common.saving'];
389
536
  var items = ordered.map(function (entry, idx) {
390
537
  return { id: entry.id, order: idx, expectedRevision: entry.revision };
391
538
  });
@@ -403,9 +550,9 @@ export async function GET(context) {
403
550
  ordered.forEach(function (entry, idx) { if (entry.data) entry.data.order = idx; });
404
551
  exitReorder();
405
552
  })
406
- .catch(function () { reorderSave.disabled = false; reorderSave.textContent = 'Retry'; });
553
+ .catch(function () { reorderSave.disabled = false; reorderSave.textContent = MSG['common.retry']; });
407
554
  }
408
- reorderBtn.addEventListener('click', enterReorder);
555
+ if (reorderBtn) reorderBtn.addEventListener('click', enterReorder);
409
556
  reorderCancel.addEventListener('click', exitReorder);
410
557
  reorderSave.addEventListener('click', saveOrder);
411
558
  })();`;
@@ -1 +1 @@
1
- {"version":3,"file":"collection-list.js","sourceRoot":"","sources":["../../../src/runtime/routes/collection-list.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAG/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,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,MAAM,cAAc,EAAE,CAAC;IACvC,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"}
1
+ {"version":3,"file":"collection-list.js","sourceRoot":"","sources":["../../../src/runtime/routes/collection-list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const prerender = false;
2
+ import type { APIContext } from "astro";
3
+ /** GET /api/cms/deployment — provider-backed status for the editor's latest deploy. */
4
+ export declare function GET(context: APIContext): Promise<Response>;
5
+ //# sourceMappingURL=deployment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/deployment.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,QAAQ,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAMxC,uFAAuF;AACvF,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6BhE"}
@@ -0,0 +1,38 @@
1
+ export const prerender = false;
2
+ import { getEditorId, isEditorAuthenticated } from "../auth/session.js";
3
+ import { normalizeDeploymentEvidence } from "../deployment-status.js";
4
+ import { getRuntimeServices } from "../providers.js";
5
+ import { json } from "./_helpers.js";
6
+ /** GET /api/cms/deployment — provider-backed status for the editor's latest deploy. */
7
+ export async function GET(context) {
8
+ if (!isEditorAuthenticated(context))
9
+ return json({ error: "Unauthorized" }, 401);
10
+ const editorId = getEditorId(context);
11
+ const services = await getRuntimeServices();
12
+ const provider = services.deploymentStatusProvider;
13
+ if (!provider)
14
+ return json({ configured: false, state: "unknown" });
15
+ if (!editorId || !services.adapter.makeEditorOverlay) {
16
+ return json({ configured: true, state: "unknown", target: null });
17
+ }
18
+ const overlay = await services.adapter.makeEditorOverlay(editorId);
19
+ const target = await overlay.getDeploymentTarget?.() ?? null;
20
+ if (!target)
21
+ return json({ configured: true, state: "unknown", target: null });
22
+ try {
23
+ const evidence = await provider.getDeploymentStatus({ target, request: context.request });
24
+ return json(normalizeDeploymentEvidence(target, evidence));
25
+ }
26
+ catch (error) {
27
+ console.error("[caretcms] Deployment status provider failed:", error);
28
+ return json({
29
+ configured: true,
30
+ state: "unknown",
31
+ buildId: null,
32
+ target,
33
+ checkedAt: Date.now(),
34
+ message: "Deployment status is temporarily unavailable",
35
+ });
36
+ }
37
+ }
38
+ //# sourceMappingURL=deployment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../../src/runtime/routes/deployment.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;IAEjF,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,wBAAwB,CAAC;IACnD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,EAAE,EAAE,IAAI,IAAI,CAAC;IAC7D,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,OAAO,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;YACV,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,IAAI;YACb,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,OAAO,EAAE,8CAA8C;SACxD,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/draft.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,QAAQ,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAMxC;;GAEG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYhE;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyBnE"}
1
+ {"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/draft.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS,QAAQ,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAMxC;;GAEG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYhE;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6BnE"}