@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 techstacked
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # @caretcms/core
2
+
3
+ Inline editing and live content collections for Astro. Add one HTML attribute to make any element editable, and use Astro's live loaders to query CMS data with `getLiveEntry` / `getLiveCollection` (stable on Astro 6, experimental on Astro 5.10+).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @caretcms/core
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ```js
14
+ // astro.config.mjs
15
+ import { defineConfig } from 'astro/config';
16
+ import caret from '@caretcms/core';
17
+
18
+ export default defineConfig({
19
+ output: 'server',
20
+ integrations: [caret()],
21
+ });
22
+ ```
23
+
24
+ ## Inline editing
25
+
26
+ Add `data-caret` attributes to your templates:
27
+
28
+ ```html
29
+ <main data-caret-scope="pages::home">
30
+ <h1 data-caret="headline">Welcome to my site</h1>
31
+ <p data-caret="intro">This text is editable.</p>
32
+ <img data-caret="hero_image" src="/default.jpg" alt="Hero" />
33
+ </main>
34
+ ```
35
+
36
+ Set a password and start the dev server:
37
+
38
+ ```bash
39
+ CARET_EDIT_PASSWORD=devpass npm run dev
40
+ ```
41
+
42
+ Log in at `/admin`, then click any annotated element on the page to edit it.
43
+
44
+ The inline editor only bootstraps on pages that contain `data-caret` bindings and only after
45
+ `GET /api/cms/auth/session` confirms an authenticated editor session. Session cookies are issued
46
+ as `HttpOnly`, `SameSite=Lax`, and automatically add `Secure` on HTTPS requests.
47
+
48
+ ## Live content collections
49
+
50
+ You can also wire collections into Astro's native content layer using `caretLoader`. This lets you query CMS data with `getLiveEntry` and `getLiveCollection` from `astro:content` — the same API you use for any Astro live collection.
51
+
52
+ > **Astro 6:** stable, no flag required.
53
+ > **Astro 5.10+:** available behind `experimental.liveContentCollections: true` in `astro.config.*`.
54
+ > **Astro 5.0–5.9:** the live-loader API (`defineLiveCollection`, `getLiveEntry`, `getLiveCollection`) doesn't exist; use `data-caret` inline editing, `bindEntry()`, and `loadEntry()` instead.
55
+
56
+ ### 1. Define collections
57
+
58
+ Create `src/caret.config.ts`:
59
+
60
+ ```ts
61
+ import { defineLiveCollection } from 'astro:content';
62
+ import { caretLoader } from '@caretcms/core';
63
+
64
+ const pages = defineLiveCollection({
65
+ loader: caretLoader('pages'),
66
+ });
67
+
68
+ const site = defineLiveCollection({
69
+ loader: caretLoader('site'),
70
+ });
71
+
72
+ export const collections = { pages, site };
73
+ ```
74
+
75
+ ### 2. Query in pages
76
+
77
+ ```astro
78
+ ---
79
+ import { getLiveEntry } from 'astro:content';
80
+
81
+ const { entry: home } = await getLiveEntry('pages', 'home');
82
+ ---
83
+ <h1>{home?.data.headline}</h1>
84
+ ```
85
+
86
+ ### 3. Both approaches work together
87
+
88
+ Inline editing (`data-caret`) and live collections read from the same storage adapter. Edits made inline are immediately visible through `getLiveEntry` / `getLiveCollection`, and vice versa. Use whichever approach fits the context:
89
+
90
+ - `data-caret` for visual, in-place editing of rendered pages
91
+ - `getLiveEntry` / `getLiveCollection` for programmatic data access in frontmatter
92
+
93
+ ## Explicit schemas (optional)
94
+
95
+ By default, Studio infers field types from your stored data. For better field labels, validation, and widget hints, pass JSON Schemas via the integration config:
96
+
97
+ ```js
98
+ // astro.config.mjs
99
+ import { defineConfig } from 'astro/config';
100
+ import { z } from 'astro/zod';
101
+ import caret from '@caretcms/core';
102
+
103
+ const PageSchema = z.object({ headline: z.string(), intro: z.string() });
104
+
105
+ export default defineConfig({
106
+ output: 'server',
107
+ integrations: [
108
+ caret({
109
+ schemas: {
110
+ pages: z.toJSONSchema(PageSchema),
111
+ },
112
+ }),
113
+ ],
114
+ });
115
+ ```
116
+
117
+ When provided, Studio uses these for field names, types, and editor widgets instead of guessing from the first entry.
118
+
119
+ ## What you get
120
+
121
+ - **Inline editing** on any `data-caret` element (text and images)
122
+ - **Live content collections** via `caretLoader` for `getLiveEntry` / `getLiveCollection` (Astro 6 stable, Astro 5.10+ behind `experimental.liveContentCollections`)
123
+ - **Content Studio** at `/admin/cms` for structured CRUD
124
+ - **Section composer** for reordering and spacing page sections
125
+ - **Response rewriting** middleware — stored edits replace template defaults at render time
126
+ - **Scoped bindings** via `data-caret-scope` to reduce repetition
127
+ - **Revision safety** with optimistic locking and restore from history
128
+ - **Storage adapters** — filesystem (default), in-memory, or custom via `StorageAdapter` interface
129
+
130
+ ## Cloudflare deployment
131
+
132
+ ```bash
133
+ npm install @caretcms/cloudflare
134
+ ```
135
+
136
+ ```js
137
+ import caret from '@caretcms/core';
138
+ import { cloudflareStorage, r2Uploads } from '@caretcms/cloudflare';
139
+
140
+ export default defineConfig({
141
+ output: 'server',
142
+ integrations: [
143
+ caret({
144
+ storage: cloudflareStorage({ binding: 'CMS_KV' }),
145
+ uploads: r2Uploads({ binding: 'CMS_R2' }),
146
+ }),
147
+ ],
148
+ });
149
+ ```
150
+
151
+ ## API
152
+
153
+ All routes are under `/api/cms` by default (configurable via `apiBasePath`):
154
+
155
+ | Route | Method | Purpose |
156
+ |---|---|---|
157
+ | `/api/cms/entries` | GET | List entries by collection |
158
+ | `/api/cms/schema` | GET | Collection schema (explicit or inferred) |
159
+ | `/api/cms/mutate` | POST | Save content mutations |
160
+ | `/api/cms/history` | GET | Entry revision history |
161
+ | `/api/cms/upload` | POST | File uploads |
162
+ | `/api/cms/auth/login` | POST | Editor login |
163
+ | `/api/cms/auth/session` | GET | Editor session status |
164
+ | `/api/cms/auth/logout` | POST | Editor logout |
165
+
166
+ `/api/cms/auth/session` returns `{ authenticated: boolean }` and is what the inline editor uses to
167
+ decide whether it should mount on the current page.
168
+
169
+ ## Configuration
170
+
171
+ ```js
172
+ caret({
173
+ mountPath: '/admin', // Admin UI base path (default: /admin)
174
+ apiBasePath: '/api/cms', // API route prefix (default: /api/cms)
175
+ enableAdmin: true, // Inject admin pages (default: true)
176
+ enableInlineEditor: true, // Inject inline editor (default: true)
177
+ storage: filesystemStorage(), // Storage adapter (default: filesystem)
178
+ uploads: localUploads(), // Upload handler (default: local filesystem)
179
+ schemas: {}, // Optional JSON Schema map for Studio (default: inferred)
180
+ })
181
+ ```
182
+
183
+ ## Requirements
184
+
185
+ - Astro 5 or 6
186
+ - Node 20.19.1+ or 22.12.0+
187
+ - Server output mode (for embedded editing routes)
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,12 @@
1
+ export interface CloudCmsClientConfig {
2
+ endpoint: string;
3
+ projectId: string;
4
+ contentPath?: string;
5
+ publicToken?: string;
6
+ sessionToken?: string;
7
+ environment?: string;
8
+ }
9
+ export declare function bootstrapCloudCms(config: CloudCmsClientConfig, root?: ParentNode): Promise<void>;
10
+ export declare function hasCloudCmsSession(config: CloudCmsClientConfig): boolean;
11
+ export declare function redirectToCloudCmsLogin(config: CloudCmsClientConfig, redirectTo?: string): void;
12
+ //# sourceMappingURL=browser-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-runtime.d.ts","sourceRoot":"","sources":["../src/browser-runtime.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA8UD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,GAAE,UAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAGxE;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CAMN"}
@@ -0,0 +1,298 @@
1
+ function getSessionStorageKey(config) {
2
+ return `caretcms:cloud-session:${config.endpoint}:${config.projectId}`;
3
+ }
4
+ function readStoredSessionToken(config) {
5
+ if (typeof window === "undefined")
6
+ return undefined;
7
+ try {
8
+ const value = window.localStorage.getItem(getSessionStorageKey(config));
9
+ return value && value.trim().length > 0 ? value.trim() : undefined;
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ }
15
+ function writeStoredSessionToken(config, token) {
16
+ if (typeof window === "undefined")
17
+ return;
18
+ try {
19
+ window.localStorage.setItem(getSessionStorageKey(config), token);
20
+ }
21
+ catch {
22
+ // Ignore localStorage failures.
23
+ }
24
+ }
25
+ function clearStoredSessionToken(config) {
26
+ if (typeof window === "undefined")
27
+ return;
28
+ try {
29
+ window.localStorage.removeItem(getSessionStorageKey(config));
30
+ }
31
+ catch {
32
+ // Ignore localStorage failures.
33
+ }
34
+ }
35
+ function normalizeConfig(input) {
36
+ const endpoint = input.endpoint.trim().replace(/\/$/, "");
37
+ const projectId = input.projectId.trim();
38
+ if (!endpoint) {
39
+ throw new Error("[caretcms] Cloud runtime requires an endpoint.");
40
+ }
41
+ if (!projectId) {
42
+ throw new Error("[caretcms] Cloud runtime requires a projectId.");
43
+ }
44
+ return {
45
+ endpoint,
46
+ projectId,
47
+ contentPath: input.contentPath?.trim() || "/content",
48
+ publicToken: input.publicToken?.trim() || undefined,
49
+ sessionToken: input.sessionToken?.trim() ||
50
+ readStoredSessionToken({
51
+ ...input,
52
+ endpoint,
53
+ projectId,
54
+ }),
55
+ environment: input.environment?.trim() || undefined,
56
+ };
57
+ }
58
+ function readHashSessionToken() {
59
+ if (typeof window === "undefined")
60
+ return undefined;
61
+ const hash = window.location.hash.startsWith("#")
62
+ ? window.location.hash.slice(1)
63
+ : window.location.hash;
64
+ if (!hash)
65
+ return undefined;
66
+ const params = new URLSearchParams(hash);
67
+ const token = params.get("cms-session");
68
+ return token && token.trim().length > 0 ? token.trim() : undefined;
69
+ }
70
+ function clearHashSessionToken() {
71
+ if (typeof window === "undefined")
72
+ return;
73
+ const url = new URL(window.location.href);
74
+ url.hash = "";
75
+ window.history.replaceState({}, document.title, url.toString());
76
+ }
77
+ function hydrateSessionFromUrl(config) {
78
+ const token = readHashSessionToken();
79
+ if (!token)
80
+ return config;
81
+ writeStoredSessionToken(config, token);
82
+ clearHashSessionToken();
83
+ return { ...config, sessionToken: token };
84
+ }
85
+ function parseScopeValue(value) {
86
+ if (!value)
87
+ return null;
88
+ const [collection, id] = value.split("::");
89
+ if (!collection || !id)
90
+ return null;
91
+ return { collection, id };
92
+ }
93
+ function getNearestScope(element) {
94
+ const scopeElement = element.closest("[data-caret-scope]");
95
+ if (!scopeElement)
96
+ return null;
97
+ return parseScopeValue(scopeElement.getAttribute("data-caret-scope"));
98
+ }
99
+ function resolveBindingValue(value, scope) {
100
+ const parts = value.split("::");
101
+ if (parts.length === 3) {
102
+ return {
103
+ collection: parts[0],
104
+ id: parts[1],
105
+ field: parts[2],
106
+ };
107
+ }
108
+ if (parts.length === 1 && scope) {
109
+ return {
110
+ collection: scope.collection,
111
+ id: scope.id,
112
+ field: value,
113
+ };
114
+ }
115
+ return null;
116
+ }
117
+ function hasChildMarkup(element) {
118
+ return Array.from(element.childNodes).some((node) => node.nodeType === Node.ELEMENT_NODE);
119
+ }
120
+ function collectBindings(root = document) {
121
+ const nodes = Array.from(root.querySelectorAll("[data-caret]"));
122
+ const bindings = [];
123
+ for (const element of nodes) {
124
+ const raw = element.getAttribute("data-caret");
125
+ if (!raw)
126
+ continue;
127
+ const resolved = resolveBindingValue(raw, getNearestScope(element));
128
+ if (!resolved)
129
+ continue;
130
+ const tagName = element.tagName.toLowerCase();
131
+ const isRich = tagName !== "img" && element.hasAttribute("data-caret-rich");
132
+ bindings.push({
133
+ element,
134
+ ...resolved,
135
+ isImage: tagName === "img",
136
+ isRich,
137
+ hasChildMarkup: tagName !== "img" && hasChildMarkup(element),
138
+ });
139
+ }
140
+ return bindings;
141
+ }
142
+ // --- Browser-side HTML sanitizer for rich text ---
143
+ const RICH_ALLOWED_TAGS = new Set([
144
+ "b", "strong", "i", "em", "u", "s", "a", "br", "sub", "sup",
145
+ ]);
146
+ const RICH_ALLOWED_ATTRS = {
147
+ a: new Set(["href", "target", "rel"]),
148
+ };
149
+ const SAFE_HREF_RE = /^(?:https?:|mailto:|tel:|\/)/i;
150
+ function sanitizeHtmlBrowser(html) {
151
+ if (!html)
152
+ return "";
153
+ const doc = new DOMParser().parseFromString(`<body>${html}</body>`, "text/html");
154
+ sanitizeNode(doc.body);
155
+ return doc.body.innerHTML;
156
+ }
157
+ function sanitizeNode(parent) {
158
+ const children = Array.from(parent.childNodes);
159
+ for (const node of children) {
160
+ if (node.nodeType === Node.TEXT_NODE)
161
+ continue;
162
+ if (node.nodeType !== Node.ELEMENT_NODE) {
163
+ parent.removeChild(node);
164
+ continue;
165
+ }
166
+ const el = node;
167
+ const tag = el.tagName.toLowerCase();
168
+ if (!RICH_ALLOWED_TAGS.has(tag)) {
169
+ const frag = document.createDocumentFragment();
170
+ while (el.firstChild)
171
+ frag.appendChild(el.firstChild);
172
+ parent.replaceChild(frag, el);
173
+ sanitizeNode(parent);
174
+ return;
175
+ }
176
+ const allowed = RICH_ALLOWED_ATTRS[tag];
177
+ const attrs = Array.from(el.attributes);
178
+ for (const attr of attrs) {
179
+ if (!allowed || !allowed.has(attr.name)) {
180
+ el.removeAttribute(attr.name);
181
+ }
182
+ }
183
+ if (tag === "a") {
184
+ const href = el.getAttribute("href") || "";
185
+ if (!SAFE_HREF_RE.test(href)) {
186
+ el.removeAttribute("href");
187
+ }
188
+ if (href && /^https?:/i.test(href)) {
189
+ el.setAttribute("target", "_blank");
190
+ el.setAttribute("rel", "noopener noreferrer");
191
+ }
192
+ }
193
+ sanitizeNode(el);
194
+ }
195
+ }
196
+ function getNestedString(data, path) {
197
+ const keys = path.split(".");
198
+ let current = data;
199
+ for (const key of keys) {
200
+ if (!current || typeof current !== "object" || Array.isArray(current)) {
201
+ return undefined;
202
+ }
203
+ current = current[key];
204
+ }
205
+ return typeof current === "string" ? current : undefined;
206
+ }
207
+ function applyBindingValue(binding, value) {
208
+ if (binding.isImage) {
209
+ binding.element.setAttribute("src", value);
210
+ return;
211
+ }
212
+ if (binding.isRich) {
213
+ binding.element.innerHTML = sanitizeHtmlBrowser(value);
214
+ return;
215
+ }
216
+ if (binding.hasChildMarkup)
217
+ return;
218
+ binding.element.textContent = value;
219
+ }
220
+ function buildContentUrl(config, path = "") {
221
+ const contentPath = config.contentPath ?? "/content";
222
+ const normalizedPath = contentPath.endsWith("/") ? contentPath.slice(0, -1) : contentPath;
223
+ return new URL(`${normalizedPath}${path}`, `${config.endpoint}/`);
224
+ }
225
+ function buildAuthHeaders(config, includePublicToken = false) {
226
+ const headers = {};
227
+ if (includePublicToken && config.publicToken) {
228
+ headers["x-caret-token"] = config.publicToken;
229
+ }
230
+ if (config.sessionToken) {
231
+ headers.Authorization = `Bearer ${config.sessionToken}`;
232
+ }
233
+ return headers;
234
+ }
235
+ async function fetchEntries(config, keys) {
236
+ if (keys.length === 0)
237
+ return {};
238
+ const url = new URL(config.contentPath ?? "/content", `${config.endpoint}/`);
239
+ url.searchParams.set("projectId", config.projectId);
240
+ url.searchParams.set("keys", keys.join(","));
241
+ if (config.environment) {
242
+ url.searchParams.set("environment", config.environment);
243
+ }
244
+ const headers = buildAuthHeaders(config, true);
245
+ const response = await fetch(url.toString(), { headers });
246
+ if (!response.ok) {
247
+ throw new Error(`[caretcms] Cloud content request failed (${response.status}).`);
248
+ }
249
+ const body = (await response.json());
250
+ if (!body?.entries)
251
+ return {};
252
+ if (Array.isArray(body.entries)) {
253
+ return body.entries.reduce((acc, entry) => {
254
+ if (entry && typeof entry.key === "string" && entry.data && typeof entry.data === "object") {
255
+ acc[entry.key] = entry.data;
256
+ }
257
+ return acc;
258
+ }, {});
259
+ }
260
+ return body.entries;
261
+ }
262
+ async function runCloudOverlay(config, root = document) {
263
+ const bindings = collectBindings(root);
264
+ if (bindings.length === 0)
265
+ return;
266
+ const entryKeys = [...new Set(bindings.map((binding) => `${binding.collection}::${binding.id}`))];
267
+ const entries = await fetchEntries(config, entryKeys);
268
+ for (const binding of bindings) {
269
+ const entry = entries[`${binding.collection}::${binding.id}`];
270
+ if (!entry)
271
+ continue;
272
+ const value = getNestedString(entry, binding.field);
273
+ if (value === undefined)
274
+ continue;
275
+ applyBindingValue(binding, value);
276
+ }
277
+ }
278
+ export async function bootstrapCloudCms(config, root = document) {
279
+ const normalized = hydrateSessionFromUrl(normalizeConfig(config));
280
+ if (document.readyState === "loading") {
281
+ await new Promise((resolve) => {
282
+ document.addEventListener("DOMContentLoaded", () => resolve(), { once: true });
283
+ });
284
+ }
285
+ await runCloudOverlay(normalized, root);
286
+ }
287
+ export function hasCloudCmsSession(config) {
288
+ const normalized = normalizeConfig(config);
289
+ return typeof normalized.sessionToken === "string" && normalized.sessionToken.length > 0;
290
+ }
291
+ export function redirectToCloudCmsLogin(config, redirectTo) {
292
+ const normalized = normalizeConfig(config);
293
+ const url = buildContentUrl(normalized, "/admin");
294
+ url.searchParams.set("projectId", normalized.projectId);
295
+ url.searchParams.set("redirect", redirectTo ?? window.location.href);
296
+ window.location.href = url.toString();
297
+ }
298
+ //# sourceMappingURL=browser-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-runtime.js","sourceRoot":"","sources":["../src/browser-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { AstroIntegration } from "astro";
2
+ import type { CaretStorageProvider, CaretUploadProvider } from "./types.js";
3
+ export type { StorageAdapter, UploadHandler, UploadContext, EntryData, HistoryEntry, CollectionMetadata, CollectionSchema, CaretMode, CaretStorageProvider, CaretUploadProvider, RuntimeProviderReference, } from "./types.js";
4
+ export { FilesystemAdapter } from "./runtime/storage/filesystem-adapter.js";
5
+ export { InMemoryAdapter } from "./runtime/storage/in-memory-adapter.js";
6
+ export { FilesystemUploadHandler } from "./runtime/storage/filesystem-upload-handler.js";
7
+ export { bindEntry } from "./runtime/bind.js";
8
+ export { caretLoader, CaretLoaderError } from "./loader.js";
9
+ export type { CaretLiveLoader } from "./loader.js";
10
+ type ProviderDefinitionOptions = {
11
+ entrypoint: string;
12
+ exportName?: string;
13
+ options?: Record<string, unknown> | null;
14
+ };
15
+ export interface CaretCloudOptions extends Record<string, unknown> {
16
+ endpoint: string;
17
+ projectId: string;
18
+ contentPath?: string;
19
+ publicToken?: string;
20
+ environment?: string;
21
+ }
22
+ type JsonSchemaDefinition = Record<string, unknown>;
23
+ export type CaretThemeOption = string | {
24
+ preset?: string;
25
+ tokens?: Record<string, string>;
26
+ };
27
+ export type CaretBrandOption = {
28
+ name?: string;
29
+ logo?: string;
30
+ faviconUrl?: string;
31
+ };
32
+ type BaseCaretOptions = {
33
+ mountPath?: string;
34
+ apiBasePath?: string;
35
+ enableAdmin?: boolean;
36
+ enableInlineEditor?: boolean;
37
+ /**
38
+ * Optional collection schemas as JSON Schema objects. When provided, Studio
39
+ * uses these for field labels, types, and validation instead of inferring
40
+ * schema from the first entry.
41
+ *
42
+ * Keys are collection names, values are JSON Schema objects (e.g. produced
43
+ * by z.toJSONSchema() from a Zod schema).
44
+ */
45
+ schemas?: Record<string, JsonSchemaDefinition>;
46
+ /**
47
+ * Studio chrome theme. Defaults to 'studio' — a neutral dark chrome that
48
+ * matches the inline editor's "click to edit" blue. Currently the only
49
+ * built-in preset; pass `{ tokens: { ... } }` to override individual
50
+ * `--color-theme-*` / `--font-theme-*` values without forking the preset.
51
+ */
52
+ theme?: CaretThemeOption;
53
+ /**
54
+ * Branding shown in the studio chrome (header brand mark, login title,
55
+ * favicon).
56
+ */
57
+ brand?: CaretBrandOption;
58
+ };
59
+ export type CaretOptions = (BaseCaretOptions & {
60
+ mode?: "embedded";
61
+ storage?: CaretStorageProvider;
62
+ uploads?: CaretUploadProvider;
63
+ cloud?: never;
64
+ }) | (BaseCaretOptions & {
65
+ mode: "cloud";
66
+ cloud: CaretCloudOptions;
67
+ storage?: never;
68
+ uploads?: never;
69
+ });
70
+ export declare function defineStorageProvider(options: ProviderDefinitionOptions): CaretStorageProvider;
71
+ export declare function defineUploadProvider(options: ProviderDefinitionOptions): CaretUploadProvider;
72
+ export declare function filesystemStorage(options?: {
73
+ dataRoot?: string;
74
+ metaRoot?: string;
75
+ }): CaretStorageProvider;
76
+ export declare function localUploads(options?: {
77
+ uploadsDir?: string;
78
+ }): CaretUploadProvider;
79
+ export declare function caret(options?: CaretOptions): AstroIntegration;
80
+ export default caret;
81
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}