@caretcms/core 0.1.0 → 0.1.2

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 (243) hide show
  1. package/README.md +182 -6
  2. package/dist/browser-runtime.d.ts +16 -0
  3. package/dist/browser-runtime.d.ts.map +1 -1
  4. package/dist/browser-runtime.js +42 -23
  5. package/dist/browser-runtime.js.map +1 -1
  6. package/dist/contracts.d.ts +14 -0
  7. package/dist/contracts.d.ts.map +1 -0
  8. package/dist/contracts.js +14 -0
  9. package/dist/contracts.js.map +1 -0
  10. package/dist/editable.d.ts +28 -0
  11. package/dist/editable.d.ts.map +1 -0
  12. package/dist/editable.js +122 -0
  13. package/dist/editable.js.map +1 -0
  14. package/dist/index.d.ts +53 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +274 -4
  17. package/dist/index.js.map +1 -1
  18. package/dist/loader.d.ts.map +1 -1
  19. package/dist/loader.js +45 -3
  20. package/dist/loader.js.map +1 -1
  21. package/dist/providers/storage/markdown.d.ts +7 -0
  22. package/dist/providers/storage/markdown.d.ts.map +1 -0
  23. package/dist/providers/storage/markdown.js +6 -0
  24. package/dist/providers/storage/markdown.js.map +1 -0
  25. package/dist/runtime/auth/cookie-utils.d.ts +1 -0
  26. package/dist/runtime/auth/cookie-utils.d.ts.map +1 -1
  27. package/dist/runtime/auth/cookie-utils.js +1 -1
  28. package/dist/runtime/auth/cookie-utils.js.map +1 -1
  29. package/dist/runtime/auth/rate-limiter.d.ts.map +1 -1
  30. package/dist/runtime/auth/rate-limiter.js +19 -13
  31. package/dist/runtime/auth/rate-limiter.js.map +1 -1
  32. package/dist/runtime/auth/session.d.ts +8 -0
  33. package/dist/runtime/auth/session.d.ts.map +1 -1
  34. package/dist/runtime/auth/session.js +72 -11
  35. package/dist/runtime/auth/session.js.map +1 -1
  36. package/dist/runtime/config.d.ts +1 -0
  37. package/dist/runtime/config.d.ts.map +1 -1
  38. package/dist/runtime/config.js +2 -1
  39. package/dist/runtime/config.js.map +1 -1
  40. package/dist/runtime/git-journal.d.ts +19 -0
  41. package/dist/runtime/git-journal.d.ts.map +1 -0
  42. package/dist/runtime/git-journal.js +64 -0
  43. package/dist/runtime/git-journal.js.map +1 -0
  44. package/dist/runtime/index.d.ts +1 -1
  45. package/dist/runtime/index.d.ts.map +1 -1
  46. package/dist/runtime/index.js +1 -1
  47. package/dist/runtime/index.js.map +1 -1
  48. package/dist/runtime/middleware.d.ts.map +1 -1
  49. package/dist/runtime/middleware.js +125 -8
  50. package/dist/runtime/middleware.js.map +1 -1
  51. package/dist/runtime/mutations/contracts.d.ts.map +1 -1
  52. package/dist/runtime/mutations/contracts.js +7 -4
  53. package/dist/runtime/mutations/contracts.js.map +1 -1
  54. package/dist/runtime/mutations/engine.d.ts +7 -0
  55. package/dist/runtime/mutations/engine.d.ts.map +1 -1
  56. package/dist/runtime/mutations/engine.js +30 -17
  57. package/dist/runtime/mutations/engine.js.map +1 -1
  58. package/dist/runtime/providers.d.ts +16 -0
  59. package/dist/runtime/providers.d.ts.map +1 -1
  60. package/dist/runtime/providers.js +16 -0
  61. package/dist/runtime/providers.js.map +1 -1
  62. package/dist/runtime/publish.d.ts +40 -0
  63. package/dist/runtime/publish.d.ts.map +1 -0
  64. package/dist/runtime/publish.js +75 -0
  65. package/dist/runtime/publish.js.map +1 -0
  66. package/dist/runtime/rebuild-webhook.d.ts +29 -0
  67. package/dist/runtime/rebuild-webhook.d.ts.map +1 -0
  68. package/dist/runtime/rebuild-webhook.js +37 -0
  69. package/dist/runtime/rebuild-webhook.js.map +1 -0
  70. package/dist/runtime/request-context.d.ts +19 -0
  71. package/dist/runtime/request-context.d.ts.map +1 -1
  72. package/dist/runtime/request-context.js.map +1 -1
  73. package/dist/runtime/rewrite.d.ts +29 -1
  74. package/dist/runtime/rewrite.d.ts.map +1 -1
  75. package/dist/runtime/rewrite.js +30 -16
  76. package/dist/runtime/rewrite.js.map +1 -1
  77. package/dist/runtime/rich-allowlist.d.ts +29 -0
  78. package/dist/runtime/rich-allowlist.d.ts.map +1 -0
  79. package/dist/runtime/rich-allowlist.js +49 -0
  80. package/dist/runtime/rich-allowlist.js.map +1 -0
  81. package/dist/runtime/routes/_helpers.d.ts +33 -0
  82. package/dist/runtime/routes/_helpers.d.ts.map +1 -1
  83. package/dist/runtime/routes/_helpers.js +117 -1
  84. package/dist/runtime/routes/_helpers.js.map +1 -1
  85. package/dist/runtime/routes/admin-entry.d.ts +1 -0
  86. package/dist/runtime/routes/admin-entry.d.ts.map +1 -1
  87. package/dist/runtime/routes/admin-entry.js +3 -2
  88. package/dist/runtime/routes/admin-entry.js.map +1 -1
  89. package/dist/runtime/routes/admin.d.ts +1 -0
  90. package/dist/runtime/routes/admin.d.ts.map +1 -1
  91. package/dist/runtime/routes/admin.js +61 -9
  92. package/dist/runtime/routes/admin.js.map +1 -1
  93. package/dist/runtime/routes/auth-login.d.ts +1 -0
  94. package/dist/runtime/routes/auth-login.d.ts.map +1 -1
  95. package/dist/runtime/routes/auth-login.js +26 -8
  96. package/dist/runtime/routes/auth-login.js.map +1 -1
  97. package/dist/runtime/routes/auth-logout.d.ts +1 -0
  98. package/dist/runtime/routes/auth-logout.d.ts.map +1 -1
  99. package/dist/runtime/routes/auth-logout.js +5 -0
  100. package/dist/runtime/routes/auth-logout.js.map +1 -1
  101. package/dist/runtime/routes/auth-session.d.ts +1 -0
  102. package/dist/runtime/routes/auth-session.d.ts.map +1 -1
  103. package/dist/runtime/routes/auth-session.js +1 -0
  104. package/dist/runtime/routes/auth-session.js.map +1 -1
  105. package/dist/runtime/routes/collection-list.d.ts +1 -0
  106. package/dist/runtime/routes/collection-list.d.ts.map +1 -1
  107. package/dist/runtime/routes/collection-list.js +3 -2
  108. package/dist/runtime/routes/collection-list.js.map +1 -1
  109. package/dist/runtime/routes/collections-metadata.d.ts +1 -0
  110. package/dist/runtime/routes/collections-metadata.d.ts.map +1 -1
  111. package/dist/runtime/routes/collections-metadata.js +7 -4
  112. package/dist/runtime/routes/collections-metadata.js.map +1 -1
  113. package/dist/runtime/routes/draft.d.ts +13 -0
  114. package/dist/runtime/routes/draft.d.ts.map +1 -0
  115. package/dist/runtime/routes/draft.js +55 -0
  116. package/dist/runtime/routes/draft.js.map +1 -0
  117. package/dist/runtime/routes/editor-assets.d.ts +1 -0
  118. package/dist/runtime/routes/editor-assets.d.ts.map +1 -1
  119. package/dist/runtime/routes/editor-assets.js +1 -0
  120. package/dist/runtime/routes/editor-assets.js.map +1 -1
  121. package/dist/runtime/routes/entries.d.ts +1 -0
  122. package/dist/runtime/routes/entries.d.ts.map +1 -1
  123. package/dist/runtime/routes/entries.js +3 -2
  124. package/dist/runtime/routes/entries.js.map +1 -1
  125. package/dist/runtime/routes/history.d.ts +1 -0
  126. package/dist/runtime/routes/history.d.ts.map +1 -1
  127. package/dist/runtime/routes/history.js +24 -10
  128. package/dist/runtime/routes/history.js.map +1 -1
  129. package/dist/runtime/routes/mutate.d.ts +1 -0
  130. package/dist/runtime/routes/mutate.d.ts.map +1 -1
  131. package/dist/runtime/routes/mutate.js +7 -10
  132. package/dist/runtime/routes/mutate.js.map +1 -1
  133. package/dist/runtime/routes/publish.d.ts +10 -0
  134. package/dist/runtime/routes/publish.d.ts.map +1 -0
  135. package/dist/runtime/routes/publish.js +75 -0
  136. package/dist/runtime/routes/publish.js.map +1 -0
  137. package/dist/runtime/routes/schema.d.ts +1 -0
  138. package/dist/runtime/routes/schema.d.ts.map +1 -1
  139. package/dist/runtime/routes/schema.js +7 -4
  140. package/dist/runtime/routes/schema.js.map +1 -1
  141. package/dist/runtime/routes/studio-home.d.ts +1 -0
  142. package/dist/runtime/routes/studio-home.d.ts.map +1 -1
  143. package/dist/runtime/routes/studio-home.js +10 -9
  144. package/dist/runtime/routes/studio-home.js.map +1 -1
  145. package/dist/runtime/routes/theme-stylesheet.d.ts +1 -0
  146. package/dist/runtime/routes/theme-stylesheet.d.ts.map +1 -1
  147. package/dist/runtime/routes/theme-stylesheet.js +1 -0
  148. package/dist/runtime/routes/theme-stylesheet.js.map +1 -1
  149. package/dist/runtime/routes/upload.d.ts +1 -0
  150. package/dist/runtime/routes/upload.d.ts.map +1 -1
  151. package/dist/runtime/routes/upload.js +17 -3
  152. package/dist/runtime/routes/upload.js.map +1 -1
  153. package/dist/runtime/sanitize-html.d.ts +8 -2
  154. package/dist/runtime/sanitize-html.d.ts.map +1 -1
  155. package/dist/runtime/sanitize-html.js +57 -38
  156. package/dist/runtime/sanitize-html.js.map +1 -1
  157. package/dist/runtime/static-bake.d.ts +20 -0
  158. package/dist/runtime/static-bake.d.ts.map +1 -0
  159. package/dist/runtime/static-bake.js +58 -0
  160. package/dist/runtime/static-bake.js.map +1 -0
  161. package/dist/runtime/stega.d.ts +38 -0
  162. package/dist/runtime/stega.d.ts.map +1 -0
  163. package/dist/runtime/stega.js +98 -0
  164. package/dist/runtime/stega.js.map +1 -0
  165. package/dist/runtime/storage/atomic-write.d.ts +22 -0
  166. package/dist/runtime/storage/atomic-write.d.ts.map +1 -0
  167. package/dist/runtime/storage/atomic-write.js +44 -0
  168. package/dist/runtime/storage/atomic-write.js.map +1 -0
  169. package/dist/runtime/storage/filesystem-adapter.d.ts +14 -11
  170. package/dist/runtime/storage/filesystem-adapter.d.ts.map +1 -1
  171. package/dist/runtime/storage/filesystem-adapter.js +71 -201
  172. package/dist/runtime/storage/filesystem-adapter.js.map +1 -1
  173. package/dist/runtime/storage/frontmatter-codec.d.ts +47 -0
  174. package/dist/runtime/storage/frontmatter-codec.d.ts.map +1 -0
  175. package/dist/runtime/storage/frontmatter-codec.js +523 -0
  176. package/dist/runtime/storage/frontmatter-codec.js.map +1 -0
  177. package/dist/runtime/storage/fs-runtime.d.ts +8 -0
  178. package/dist/runtime/storage/fs-runtime.d.ts.map +1 -0
  179. package/dist/runtime/storage/fs-runtime.js +40 -0
  180. package/dist/runtime/storage/fs-runtime.js.map +1 -0
  181. package/dist/runtime/storage/id-contracts.d.ts +22 -0
  182. package/dist/runtime/storage/id-contracts.d.ts.map +1 -0
  183. package/dist/runtime/storage/id-contracts.js +27 -0
  184. package/dist/runtime/storage/id-contracts.js.map +1 -0
  185. package/dist/runtime/storage/image-validation.d.ts +10 -0
  186. package/dist/runtime/storage/image-validation.d.ts.map +1 -1
  187. package/dist/runtime/storage/image-validation.js +17 -4
  188. package/dist/runtime/storage/image-validation.js.map +1 -1
  189. package/dist/runtime/storage/in-memory-adapter.d.ts +4 -0
  190. package/dist/runtime/storage/in-memory-adapter.d.ts.map +1 -1
  191. package/dist/runtime/storage/in-memory-adapter.js +11 -0
  192. package/dist/runtime/storage/in-memory-adapter.js.map +1 -1
  193. package/dist/runtime/storage/markdown-adapter.d.ts +63 -0
  194. package/dist/runtime/storage/markdown-adapter.d.ts.map +1 -0
  195. package/dist/runtime/storage/markdown-adapter.js +227 -0
  196. package/dist/runtime/storage/markdown-adapter.js.map +1 -0
  197. package/dist/runtime/storage/quota-upload-handler.d.ts +2 -0
  198. package/dist/runtime/storage/quota-upload-handler.d.ts.map +1 -1
  199. package/dist/runtime/storage/quota-upload-handler.js +34 -8
  200. package/dist/runtime/storage/quota-upload-handler.js.map +1 -1
  201. package/dist/runtime/storage/session-overlay-adapter.d.ts +3 -0
  202. package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -1
  203. package/dist/runtime/storage/session-overlay-adapter.js +3 -1
  204. package/dist/runtime/storage/session-overlay-adapter.js.map +1 -1
  205. package/dist/runtime/storage/sidecar-meta-store.d.ts +51 -0
  206. package/dist/runtime/storage/sidecar-meta-store.d.ts.map +1 -0
  207. package/dist/runtime/storage/sidecar-meta-store.js +209 -0
  208. package/dist/runtime/storage/sidecar-meta-store.js.map +1 -0
  209. package/dist/runtime/themes/preset-tokens.d.ts +0 -1
  210. package/dist/runtime/themes/preset-tokens.d.ts.map +1 -1
  211. package/dist/runtime/themes/preset-tokens.js +1 -1
  212. package/dist/runtime/themes/preset-tokens.js.map +1 -1
  213. package/dist/runtime/utils.d.ts +9 -1
  214. package/dist/runtime/utils.d.ts.map +1 -1
  215. package/dist/runtime/utils.js +21 -1
  216. package/dist/runtime/utils.js.map +1 -1
  217. package/dist/runtime/views/studio-layout.d.ts.map +1 -1
  218. package/dist/runtime/views/studio-layout.js +11 -10
  219. package/dist/runtime/views/studio-layout.js.map +1 -1
  220. package/dist/schema-utils.d.ts.map +1 -1
  221. package/dist/schema-utils.js +1 -0
  222. package/dist/schema-utils.js.map +1 -1
  223. package/dist/types.d.ts +17 -0
  224. package/dist/types.d.ts.map +1 -1
  225. package/package.json +9 -1
  226. package/static/cms/dev-toolbar/app.js +265 -0
  227. package/static/cms/editor/config.js +10 -0
  228. package/static/cms/editor/helpers.js +5 -1
  229. package/static/cms/editor/highlight.js +44 -0
  230. package/static/cms/editor/sanitize.js +56 -9
  231. package/static/cms/editor/stega-hydrate.js +80 -0
  232. package/static/cms/editor/text-edit.js +22 -0
  233. package/static/cms/editor/tokens-and-text.css +1 -1
  234. package/static/cms/editor/toolbar.css +101 -4
  235. package/static/cms/editor/toolbar.js +171 -21
  236. package/static/cms/editor.js +18 -1
  237. package/static/cms/signin-hint.css +74 -0
  238. package/static/cms/studio-login.css +70 -0
  239. package/static/cms/studio.css +80 -13
  240. package/dist/runtime/schema/template.d.ts +0 -15
  241. package/dist/runtime/schema/template.d.ts.map +0 -1
  242. package/dist/runtime/schema/template.js +0 -38
  243. package/dist/runtime/schema/template.js.map +0 -1
@@ -0,0 +1,75 @@
1
+ import { withEntryLock } from "./mutations/engine.js";
2
+ import { TOMBSTONE_KEY } from "./storage/session-overlay-adapter.js";
3
+ function isTombstoneData(data) {
4
+ return Boolean(data && data[TOMBSTONE_KEY] === true);
5
+ }
6
+ /** The (collection, id) pairs that currently exist in the overlay within scope. */
7
+ async function overlayEntriesInScope(overlay, scope) {
8
+ const collections = scope.collection
9
+ ? [scope.collection]
10
+ : await overlay.discoverCollections();
11
+ const out = [];
12
+ for (const collection of collections) {
13
+ const ids = scope.collection && scope.id
14
+ ? [scope.id]
15
+ : await overlay.listEntryIds(collection);
16
+ for (const id of ids)
17
+ out.push({ collection, id });
18
+ }
19
+ return out;
20
+ }
21
+ /**
22
+ * Flush the overlay into the base. A tombstoned draft entry deletes from the
23
+ * base; any other draft entry is written, the base revision bumped, and a
24
+ * `"publish"` history entry (carrying the pre-publish base data) appended. Each
25
+ * published entry is then cleared from the overlay so it stops shadowing the
26
+ * base. Returns the new base revisions so the client can reconcile its cached
27
+ * revision map — without this, the first edit after a publish would 409.
28
+ *
29
+ * NOT atomic across multiple entries (per-entry locks only): on a partial
30
+ * failure the returned list reflects exactly what was committed. Callers that
31
+ * surface "publish all" should report that list.
32
+ */
33
+ export async function publishOverlay(base, overlay, scope = {}) {
34
+ const targets = await overlayEntriesInScope(overlay, scope);
35
+ const published = [];
36
+ for (const { collection, id } of targets) {
37
+ const result = await withEntryLock(collection, id, async () => {
38
+ const draft = await overlay.getEntry(collection, id);
39
+ if (!draft)
40
+ return null; // raced away; nothing to publish
41
+ if (isTombstoneData(draft.data)) {
42
+ await base.deleteEntry(collection, id);
43
+ await overlay.deleteEntry(collection, id);
44
+ return { collection, id, revision: await base.getRevision(collection, id), deleted: true };
45
+ }
46
+ const before = await base.getEntry(collection, id);
47
+ await base.writeEntry(collection, id, draft.data);
48
+ const revision = await base.bumpRevision(collection, id);
49
+ await base.appendHistory(collection, id, {
50
+ ts: Date.now(),
51
+ action: "publish",
52
+ data: before?.data ?? null,
53
+ });
54
+ await overlay.deleteEntry(collection, id);
55
+ return { collection, id, revision, deleted: false };
56
+ });
57
+ if (result)
58
+ published.push(result);
59
+ }
60
+ return published;
61
+ }
62
+ /** Count draft entries currently held in an editor overlay. */
63
+ export async function countOverlayDrafts(overlay, scope = {}) {
64
+ return (await overlayEntriesInScope(overlay, scope)).length;
65
+ }
66
+ /** Discard an editor's draft(s) within scope without touching the base. Returns
67
+ * the number of overlay entries cleared. */
68
+ export async function discardOverlay(overlay, scope = {}) {
69
+ const targets = await overlayEntriesInScope(overlay, scope);
70
+ for (const { collection, id } of targets) {
71
+ await withEntryLock(collection, id, () => overlay.deleteEntry(collection, id));
72
+ }
73
+ return targets.length;
74
+ }
75
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/runtime/publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface RebuildWebhookConfig {
2
+ webhookUrl: string | null;
3
+ method?: "POST" | "PUT";
4
+ headers?: Record<string, string>;
5
+ }
6
+ export interface RebuildWebhookPayload {
7
+ published: Array<{
8
+ collection: string;
9
+ id: string;
10
+ revision: number;
11
+ deleted: boolean;
12
+ }>;
13
+ commit: string | null;
14
+ }
15
+ export type RebuildWebhookResult = {
16
+ triggered: false;
17
+ ok: true;
18
+ } | {
19
+ triggered: true;
20
+ ok: true;
21
+ status: number;
22
+ } | {
23
+ triggered: true;
24
+ ok: false;
25
+ status?: number;
26
+ error: string;
27
+ };
28
+ export declare function triggerRebuildWebhook(config: RebuildWebhookConfig, payload: RebuildWebhookPayload): Promise<RebuildWebhookResult>;
29
+ //# sourceMappingURL=rebuild-webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuild-webhook.d.ts","sourceRoot":"","sources":["../../src/runtime/rebuild-webhook.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GAC9B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAoC/B"}
@@ -0,0 +1,37 @@
1
+ export async function triggerRebuildWebhook(config, payload) {
2
+ const webhookUrl = config.webhookUrl?.trim();
3
+ if (!webhookUrl)
4
+ return { triggered: false, ok: true };
5
+ try {
6
+ const response = await fetch(webhookUrl, {
7
+ method: config.method ?? "POST",
8
+ headers: {
9
+ "content-type": "application/json",
10
+ ...(config.headers ?? {}),
11
+ },
12
+ body: JSON.stringify({
13
+ source: "caretcms",
14
+ event: "publish",
15
+ published: payload.published,
16
+ commit: payload.commit,
17
+ }),
18
+ });
19
+ if (!response.ok) {
20
+ return {
21
+ triggered: true,
22
+ ok: false,
23
+ status: response.status,
24
+ error: `Rebuild webhook failed with status ${response.status}`,
25
+ };
26
+ }
27
+ return { triggered: true, ok: true, status: response.status };
28
+ }
29
+ catch (error) {
30
+ return {
31
+ triggered: true,
32
+ ok: false,
33
+ error: error instanceof Error ? error.message : "Rebuild webhook failed",
34
+ };
35
+ }
36
+ }
37
+ //# sourceMappingURL=rebuild-webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuild-webhook.js","sourceRoot":"","sources":["../../src/runtime/rebuild-webhook.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAA4B,EAC5B,OAA8B;IAE9B,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;YACvC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM;YAC/B,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;aAC1B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO;gBACL,SAAS,EAAE,IAAI;gBACf,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,KAAK,EAAE,sCAAsC,QAAQ,CAAC,MAAM,EAAE;aAC/D,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,SAAS,EAAE,IAAI;YACf,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -4,6 +4,25 @@ export interface CaretRequestContext {
4
4
  uploadHandler: UploadHandler;
5
5
  sessionId: string | null;
6
6
  demoMode: boolean;
7
+ /**
8
+ * True when this request is from an authenticated editor (or an active demo
9
+ * overlay). Gates draft-only behavior such as stega encoding in the live
10
+ * loaders. Set by the middleware after auth is resolved; absent means false.
11
+ */
12
+ editor?: boolean;
13
+ /**
14
+ * The authenticated editor's id (from the session cookie), when present. Keys
15
+ * the per-editor draft overlay so unpublished edits stay isolated per editor.
16
+ * Absent for anonymous/public requests and legacy sessions.
17
+ */
18
+ editorId?: string | null;
19
+ /**
20
+ * True only when a per-session storage overlay was actually installed for
21
+ * this demo request, guaranteeing writes are isolated from the shared base
22
+ * store. Demo editor rights are granted only when this holds — see
23
+ * `isEditorAuthenticated`. Absent/false means fail closed.
24
+ */
25
+ overlayActive?: boolean;
7
26
  }
8
27
  export declare function runWithRequestContext<T>(context: CaretRequestContext, fn: () => Promise<T>): Promise<T>;
9
28
  export declare function getRequestContext(): CaretRequestContext | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,mBAAmB,EAC5B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED,wBAAgB,iBAAiB,IAAI,mBAAmB,GAAG,SAAS,CAEnE;AAED,wBAAgB,qBAAqB,IAAI,mBAAmB,CAQ3D"}
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAID,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,mBAAmB,EAC5B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED,wBAAgB,iBAAiB,IAAI,mBAAmB,GAAG,SAAS,CAEnE;AAED,wBAAgB,qBAAqB,IAAI,mBAAmB,CAQ3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAUrD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAuB,CAAC;AAE7D,MAAM,UAAU,qBAAqB,CACnC,OAA4B,EAC5B,EAAoB;IAEpB,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,kIAAkI,CACnI,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/runtime/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA6BrD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAuB,CAAC;AAE7D,MAAM,UAAU,qBAAqB,CACnC,OAA4B,EAC5B,EAAoB;IAEpB,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,kIAAkI,CACnI,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -9,5 +9,33 @@
9
9
  * Elements with nested child markup are skipped (editor warns at runtime).
10
10
  */
11
11
  import type { StorageAdapter } from "../types.js";
12
- export declare function rewriteCaretAttributes(html: string, adapter: StorageAdapter): Promise<string>;
12
+ type ScopeMatch = {
13
+ collection: string;
14
+ id: string;
15
+ };
16
+ /**
17
+ * Tags whose text content the rewrite engine can swap (`data-caret` bindings).
18
+ * `<img>` (src swap) is handled separately. This list is a PUBLIC CONTRACT:
19
+ * caretize mirrors it as its candidate set (a parity test asserts equality) —
20
+ * a `data-caret` on any tag outside this list saves through the editor but is
21
+ * never injected into the public render (a silently inert binding).
22
+ */
23
+ export declare const REWRITABLE_TEXT_TAGS: readonly ["h1", "h2", "h3", "h4", "h5", "h6", "p", "span", "small", "strong", "em", "a", "li", "td", "th", "label", "button", "figcaption", "blockquote", "dt", "dd", "summary", "caption", "legend"];
24
+ /**
25
+ * CANONICAL data-caret value resolution (exported for the parser parity test):
26
+ * full triple as-is; bare field resolved against the nearest enclosing scope;
27
+ * anything else (2 or 4+ parts) is not a binding. The hand-mirrored copies in
28
+ * browser-runtime.ts, static/cms/editor/helpers.js, and
29
+ * static/cms/dev-toolbar/app.js are held to this behavior by
30
+ * tests/unit/caret-parser-parity.test.ts.
31
+ */
32
+ export declare function resolveBinding(caretValue: string, scope: ScopeMatch | null): {
33
+ collection: string;
34
+ id: string;
35
+ field: string;
36
+ } | null;
37
+ export declare function rewriteCaretAttributes(html: string, adapter: StorageAdapter, options?: {
38
+ allowedClasses?: Record<string, readonly string[]>;
39
+ }): Promise<string>;
40
+ export {};
13
41
  //# sourceMappingURL=rewrite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../src/runtime/rewrite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAyL7D,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAyHjB"}
1
+ {"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../src/runtime/rewrite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,aAAa,CAAC;AAkB7D,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AASF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,uMAKvB,CAAC;AAwGX;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,UAAU,GAAG,IAAI,GACvB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAW1D;AAmCD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAA;CAAE,GAC/D,OAAO,CAAC,MAAM,CAAC,CAyHjB"}
@@ -9,7 +9,21 @@
9
9
  * Elements with nested child markup are skipped (editor warns at runtime).
10
10
  */
11
11
  import { sanitizeHtml } from "./sanitize-html.js";
12
+ import { getNestedValue } from "./utils.js";
12
13
  // --- Patterns ---
14
+ /**
15
+ * Tags whose text content the rewrite engine can swap (`data-caret` bindings).
16
+ * `<img>` (src swap) is handled separately. This list is a PUBLIC CONTRACT:
17
+ * caretize mirrors it as its candidate set (a parity test asserts equality) —
18
+ * a `data-caret` on any tag outside this list saves through the editor but is
19
+ * never injected into the public render (a silently inert binding).
20
+ */
21
+ export const REWRITABLE_TEXT_TAGS = [
22
+ "h1", "h2", "h3", "h4", "h5", "h6",
23
+ "p", "span", "small", "strong", "em", "a", "li", "td", "th", "label",
24
+ "button", "figcaption", "blockquote", "dt", "dd", "summary", "caption",
25
+ "legend",
26
+ ];
13
27
  // Matches any element with data-caret attribute.
14
28
  // Captures: tag name, full opening tag, data-caret value, content between tags, closing tag
15
29
  //
@@ -19,7 +33,7 @@ import { sanitizeHtml } from "./sanitize-html.js";
19
33
  // capture the inner content. <img> is handled separately by IMG_ELEMENT_PATTERN
20
34
  // because it is a void element with no closing tag and (in standard HTML5
21
35
  // output) no self-closing slash — it would never match this pattern.
22
- const CARET_ELEMENT_PATTERN = /<(h[1-6]|p|span|small|strong|em|a|li|td|th|label|button|figcaption|blockquote|dt|dd|summary|caption|legend)\b([^>]*?\bdata-caret\s*=\s*"([^"]*)"[^>]*?)(?:\/>|>([\s\S]*?)<\/\1>)/;
36
+ const CARET_ELEMENT_PATTERN = new RegExp(`<(${REWRITABLE_TEXT_TAGS.join("|")})\\b([^>]*?\\bdata-caret\\s*=\\s*"([^"]*)"[^>]*?)(?:\\/>|>([\\s\\S]*?)<\\/\\1>)`);
23
37
  // Void <img> with a data-caret binding. Closes on a bare `>` or a self-closing
24
38
  // `/>` — never on a closing tag. Captures: 1 = attribute string, 2 = data-caret value.
25
39
  const IMG_ELEMENT_PATTERN = /<img\b([^>]*?\bdata-caret\s*=\s*"([^"]*)"[^>]*?)\/?>/;
@@ -93,7 +107,15 @@ function findNearestScope(stack) {
93
107
  }
94
108
  return null;
95
109
  }
96
- function resolveBinding(caretValue, scope) {
110
+ /**
111
+ * CANONICAL data-caret value resolution (exported for the parser parity test):
112
+ * full triple as-is; bare field resolved against the nearest enclosing scope;
113
+ * anything else (2 or 4+ parts) is not a binding. The hand-mirrored copies in
114
+ * browser-runtime.ts, static/cms/editor/helpers.js, and
115
+ * static/cms/dev-toolbar/app.js are held to this behavior by
116
+ * tests/unit/caret-parser-parity.test.ts.
117
+ */
118
+ export function resolveBinding(caretValue, scope) {
97
119
  const parts = caretValue.split("::");
98
120
  if (parts.length === 3) {
99
121
  return { collection: parts[0], id: parts[1], field: parts[2] };
@@ -123,20 +145,12 @@ async function batchLoadEntries(adapter, keys) {
123
145
  await Promise.all(promises);
124
146
  return entries;
125
147
  }
126
- function getNestedValue(data, path) {
127
- const keys = path.split(".");
128
- let current = data;
129
- for (const key of keys) {
130
- if (current === null || current === undefined)
131
- return undefined;
132
- if (typeof current !== "object")
133
- return undefined;
134
- current = current[key];
135
- }
136
- return typeof current === "string" ? current : undefined;
148
+ function getNestedString(data, path) {
149
+ const value = getNestedValue(data, path);
150
+ return typeof value === "string" ? value : undefined;
137
151
  }
138
152
  // --- Main rewrite ---
139
- export async function rewriteCaretAttributes(html, adapter) {
153
+ export async function rewriteCaretAttributes(html, adapter, options) {
140
154
  // 1. Find all data-caret bindings and collect unique entry keys
141
155
  const bindings = [];
142
156
  const entryKeys = new Set();
@@ -193,7 +207,7 @@ export async function rewriteCaretAttributes(html, adapter) {
193
207
  const entry = entries.get(entryKey);
194
208
  if (!entry)
195
209
  continue;
196
- const storedValue = getNestedValue(entry.data, binding.field);
210
+ const storedValue = getNestedString(entry.data, binding.field);
197
211
  if (storedValue === undefined)
198
212
  continue;
199
213
  if (binding.isImg) {
@@ -224,7 +238,7 @@ export async function rewriteCaretAttributes(html, adapter) {
224
238
  const before = binding.fullMatch.slice(0, openTagEnd);
225
239
  const after = binding.fullMatch.slice(closeTagStart);
226
240
  const injected = binding.isRich
227
- ? sanitizeHtml(storedValue)
241
+ ? sanitizeHtml(storedValue, { allowedClasses: options?.allowedClasses })
228
242
  : escapeHtml(storedValue);
229
243
  const newMatch = before + injected + after;
230
244
  result =
@@ -1 +1 @@
1
- {"version":3,"file":"rewrite.js","sourceRoot":"","sources":["../../src/runtime/rewrite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rewrite.js","sourceRoot":"","sources":["../../src/runtime/rewrite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared rich-text allowlist + class matcher.
3
+ *
4
+ * The single source of truth for what the rich-text sanitizers keep. Imported
5
+ * by the two TypeScript sanitizers — the server render path (sanitize-html.ts,
6
+ * regex-based, no DOM) and the cloud live-sync path (browser-runtime.ts, DOM).
7
+ *
8
+ * The editor-save sanitizer in static/cms/editor/sanitize.js is shipped as raw,
9
+ * unbundled JS, so it can't import this module — it MUST mirror these values
10
+ * and the classAllowed() logic by hand. That hand mirror is held in lockstep by
11
+ * tests/unit/contracts-parity.test.ts ("browser sanitizer parity"), which fails
12
+ * CI on any drift (W0). Keep all three sanitizers in lockstep.
13
+ */
14
+ export declare const RICH_ALLOWED_TAGS: Set<string>;
15
+ /** Attributes preserved per tag (class is gated separately, by allowedClasses). */
16
+ export declare const RICH_ALLOWED_ATTRS: Record<string, Set<string>>;
17
+ export declare const SAFE_HREF_RE: RegExp;
18
+ /**
19
+ * Per-tag class allowlist. Keys are tag names, values are allowed class names.
20
+ * A pattern ending in `*` is a prefix match (`text-*` allows `text-primary`);
21
+ * a lone `*` allows any class on that tag. Anything not matched is dropped.
22
+ * Mirrors the `allowedClasses` option of the `sanitize-html` package.
23
+ */
24
+ export type AllowedClasses = Record<string, readonly string[]>;
25
+ /** Does `cls` match any pattern in `patterns`? (exact, `prefix-*`, or lone `*`) */
26
+ export declare function classAllowed(cls: string, patterns: readonly string[]): boolean;
27
+ /** Filter a raw class attribute value to the tag's allowed patterns. */
28
+ export declare function filterClasses(value: string, patterns: readonly string[]): string;
29
+ //# sourceMappingURL=rich-allowlist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rich-allowlist.d.ts","sourceRoot":"","sources":["../../src/runtime/rich-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,eAAO,MAAM,iBAAiB,aAE5B,CAAC;AAEH,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAE1D,CAAC;AAEF,eAAO,MAAM,YAAY,QAAkC,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE/D,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAU9E;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAKhF"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Shared rich-text allowlist + class matcher.
3
+ *
4
+ * The single source of truth for what the rich-text sanitizers keep. Imported
5
+ * by the two TypeScript sanitizers — the server render path (sanitize-html.ts,
6
+ * regex-based, no DOM) and the cloud live-sync path (browser-runtime.ts, DOM).
7
+ *
8
+ * The editor-save sanitizer in static/cms/editor/sanitize.js is shipped as raw,
9
+ * unbundled JS, so it can't import this module — it MUST mirror these values
10
+ * and the classAllowed() logic by hand. That hand mirror is held in lockstep by
11
+ * tests/unit/contracts-parity.test.ts ("browser sanitizer parity"), which fails
12
+ * CI on any drift (W0). Keep all three sanitizers in lockstep.
13
+ */
14
+ // `span` (W4) lets styled inline runs (`<span class="gold">…</span>`, common in
15
+ // headings) survive in rich content — but it carries NO attributes of its own
16
+ // (see RICH_ALLOWED_ATTRS): its `class` is kept only when blessed via the per-tag
17
+ // `allowedClasses` config, and everything else (incl. on*=, style=) is stripped.
18
+ // Fuzzed in tests/unit/sanitize-html-properties.test.ts.
19
+ export const RICH_ALLOWED_TAGS = new Set([
20
+ "b", "strong", "i", "em", "u", "s", "a", "br", "sub", "sup", "span",
21
+ ]);
22
+ /** Attributes preserved per tag (class is gated separately, by allowedClasses). */
23
+ export const RICH_ALLOWED_ATTRS = {
24
+ a: new Set(["href", "target", "rel"]),
25
+ };
26
+ export const SAFE_HREF_RE = /^(?:https?:|mailto:|tel:|\/)/i;
27
+ /** Does `cls` match any pattern in `patterns`? (exact, `prefix-*`, or lone `*`) */
28
+ export function classAllowed(cls, patterns) {
29
+ for (const p of patterns) {
30
+ if (p === "*")
31
+ return true;
32
+ if (p.endsWith("*")) {
33
+ if (cls.startsWith(p.slice(0, -1)))
34
+ return true;
35
+ }
36
+ else if (cls === p) {
37
+ return true;
38
+ }
39
+ }
40
+ return false;
41
+ }
42
+ /** Filter a raw class attribute value to the tag's allowed patterns. */
43
+ export function filterClasses(value, patterns) {
44
+ return value
45
+ .split(/\s+/)
46
+ .filter((c) => c !== "" && classAllowed(c, patterns))
47
+ .join(" ");
48
+ }
49
+ //# sourceMappingURL=rich-allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rich-allowlist.js","sourceRoot":"","sources":["../../src/runtime/rich-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,gFAAgF;AAChF,8EAA8E;AAC9E,kFAAkF;AAClF,iFAAiF;AACjF,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM;CACpE,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,kBAAkB,GAAgC;IAC7D,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,+BAA+B,CAAC;AAU5D,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,QAA2B;IACnE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAC3B,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QAClD,CAAC;aAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,QAA2B;IACtE,OAAO,KAAK;SACT,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;SACpD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
@@ -1,5 +1,37 @@
1
1
  import type { StorageAdapter, UploadHandler } from "../../types.js";
2
+ /**
3
+ * Storage adapter for CMS API/Studio routes. Prefer the middleware ALS scope;
4
+ * fall back to the configured base adapter when injectRoute handlers run
5
+ * outside middleware (seen in Astro static dev after HMR or stale processes).
6
+ */
7
+ export declare function resolveAdapter(): Promise<StorageAdapter>;
8
+ export declare function resolveUploadHandler(): Promise<UploadHandler>;
2
9
  export declare function json(body: Record<string, unknown>, status?: number): Response;
10
+ /** Default cap for JSON command payloads (mutate/history/login). */
11
+ export declare const MAX_JSON_BODY_BYTES: number;
12
+ /** Default cap for multipart upload bodies before they're buffered. */
13
+ export declare const MAX_UPLOAD_BODY_BYTES: number;
14
+ /**
15
+ * Reject a request whose declared Content-Length exceeds `maxBytes`. Cheap
16
+ * first line of defense for bodies we must hand to a buffering parser (e.g.
17
+ * formData()): an honest client and most attacks announce their size. Returns
18
+ * a 413 response when over the cap, otherwise null. Absent/garbage
19
+ * Content-Length passes here — pair with a streaming cap where possible.
20
+ */
21
+ export declare function enforceContentLength(request: Request, maxBytes: number): Response | null;
22
+ type JsonBodyResult = {
23
+ ok: true;
24
+ value: unknown;
25
+ } | {
26
+ ok: false;
27
+ response: Response;
28
+ };
29
+ /**
30
+ * Read and JSON-parse a request body with a hard byte cap, streaming the body
31
+ * and aborting once the running total exceeds `maxBytes` so an attacker can't
32
+ * exhaust memory by omitting Content-Length and sending a chunked flood.
33
+ */
34
+ export declare function readJsonBody(request: Request, maxBytes?: number): Promise<JsonBodyResult>;
3
35
  /**
4
36
  * Lightweight CSRF defense for mutating endpoints.
5
37
  *
@@ -14,4 +46,5 @@ export declare function enforceCsrfHeader(request: Request): Response | null;
14
46
  export declare function getAdapter(): StorageAdapter;
15
47
  export declare function getUploadHandler(): UploadHandler;
16
48
  export declare function getSessionId(): string | null;
49
+ export {};
17
50
  //# sourceMappingURL=_helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMpE,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,SAAM,GAAG,QAAQ,CAK1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAWnE;AAED,wBAAgB,UAAU,IAAI,cAAc,CAE3C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C"}
1
+ {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../../src/runtime/routes/_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAyBpE;;;;GAIG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAI9D;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,aAAa,CAAC,CAInE;AAKD,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,SAAM,GAAG,QAAQ,CAK1E;AAED,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,QAAc,CAAC;AAC/C,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAEtD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,GACf,QAAQ,GAAG,IAAI,CAMjB;AAED,KAAK,cAAc,GACf;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEtC;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,QAAQ,GAAE,MAA4B,GACrC,OAAO,CAAC,cAAc,CAAC,CAmBzB;AA2CD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAWnE;AAED,wBAAgB,UAAU,IAAI,cAAc,CAE3C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C"}
@@ -1,4 +1,37 @@
1
- import { requireRequestContext } from "../request-context.js";
1
+ import { getRequestContext, requireRequestContext, } from "../request-context.js";
2
+ import { getRuntimeServices } from "../providers.js";
3
+ let bootstrapContext = null;
4
+ async function bootstrapRequestContext() {
5
+ if (!bootstrapContext) {
6
+ bootstrapContext = getRuntimeServices().then((services) => ({
7
+ adapter: services.adapter,
8
+ uploadHandler: services.uploadHandler,
9
+ sessionId: null,
10
+ editorId: null,
11
+ demoMode: false,
12
+ overlayActive: false,
13
+ editor: false,
14
+ }));
15
+ }
16
+ return bootstrapContext;
17
+ }
18
+ /**
19
+ * Storage adapter for CMS API/Studio routes. Prefer the middleware ALS scope;
20
+ * fall back to the configured base adapter when injectRoute handlers run
21
+ * outside middleware (seen in Astro static dev after HMR or stale processes).
22
+ */
23
+ export async function resolveAdapter() {
24
+ const ctx = getRequestContext();
25
+ if (ctx)
26
+ return ctx.adapter;
27
+ return (await bootstrapRequestContext()).adapter;
28
+ }
29
+ export async function resolveUploadHandler() {
30
+ const ctx = getRequestContext();
31
+ if (ctx)
32
+ return ctx.uploadHandler;
33
+ return (await bootstrapRequestContext()).uploadHandler;
34
+ }
2
35
  const CSRF_HEADER = "x-caret-request";
3
36
  const CSRF_HEADER_VALUE = "1";
4
37
  export function json(body, status = 200) {
@@ -7,6 +40,89 @@ export function json(body, status = 200) {
7
40
  headers: { "Content-Type": "application/json; charset=utf-8" },
8
41
  });
9
42
  }
43
+ /** Default cap for JSON command payloads (mutate/history/login). */
44
+ export const MAX_JSON_BODY_BYTES = 1024 * 1024; // 1 MB
45
+ /** Default cap for multipart upload bodies before they're buffered. */
46
+ export const MAX_UPLOAD_BODY_BYTES = 25 * 1024 * 1024; // 25 MB
47
+ /**
48
+ * Reject a request whose declared Content-Length exceeds `maxBytes`. Cheap
49
+ * first line of defense for bodies we must hand to a buffering parser (e.g.
50
+ * formData()): an honest client and most attacks announce their size. Returns
51
+ * a 413 response when over the cap, otherwise null. Absent/garbage
52
+ * Content-Length passes here — pair with a streaming cap where possible.
53
+ */
54
+ export function enforceContentLength(request, maxBytes) {
55
+ const declared = Number(request.headers.get("content-length") ?? "");
56
+ if (Number.isFinite(declared) && declared > maxBytes) {
57
+ return json({ error: "Payload too large" }, 413);
58
+ }
59
+ return null;
60
+ }
61
+ /**
62
+ * Read and JSON-parse a request body with a hard byte cap, streaming the body
63
+ * and aborting once the running total exceeds `maxBytes` so an attacker can't
64
+ * exhaust memory by omitting Content-Length and sending a chunked flood.
65
+ */
66
+ export async function readJsonBody(request, maxBytes = MAX_JSON_BODY_BYTES) {
67
+ const tooLarge = enforceContentLength(request, maxBytes);
68
+ if (tooLarge)
69
+ return { ok: false, response: tooLarge };
70
+ let text;
71
+ try {
72
+ text = await readBodyTextCapped(request, maxBytes);
73
+ }
74
+ catch (error) {
75
+ if (error instanceof BodyTooLargeError) {
76
+ return { ok: false, response: json({ error: "Payload too large" }, 413) };
77
+ }
78
+ return { ok: false, response: json({ error: "Invalid body" }, 400) };
79
+ }
80
+ try {
81
+ return { ok: true, value: JSON.parse(text) };
82
+ }
83
+ catch {
84
+ return { ok: false, response: json({ error: "Invalid JSON" }, 400) };
85
+ }
86
+ }
87
+ class BodyTooLargeError extends Error {
88
+ }
89
+ async function readBodyTextCapped(request, maxBytes) {
90
+ const body = request.body;
91
+ if (!body) {
92
+ const text = await request.text();
93
+ if (text.length > maxBytes)
94
+ throw new BodyTooLargeError();
95
+ return text;
96
+ }
97
+ const reader = body.getReader();
98
+ const chunks = [];
99
+ let total = 0;
100
+ try {
101
+ for (;;) {
102
+ const { done, value } = await reader.read();
103
+ if (done)
104
+ break;
105
+ if (!value)
106
+ continue;
107
+ total += value.byteLength;
108
+ if (total > maxBytes) {
109
+ await reader.cancel().catch(() => { });
110
+ throw new BodyTooLargeError();
111
+ }
112
+ chunks.push(value);
113
+ }
114
+ }
115
+ finally {
116
+ reader.releaseLock();
117
+ }
118
+ const merged = new Uint8Array(total);
119
+ let offset = 0;
120
+ for (const chunk of chunks) {
121
+ merged.set(chunk, offset);
122
+ offset += chunk.byteLength;
123
+ }
124
+ return new TextDecoder().decode(merged);
125
+ }
10
126
  /**
11
127
  * Lightweight CSRF defense for mutating endpoints.
12
128
  *