@caretcms/core 0.1.2 → 0.3.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 (190) hide show
  1. package/README.md +109 -13
  2. package/dist/contracts.d.ts +1 -0
  3. package/dist/contracts.d.ts.map +1 -1
  4. package/dist/contracts.js +1 -0
  5. package/dist/contracts.js.map +1 -1
  6. package/dist/index.d.ts +31 -9
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +146 -30
  9. package/dist/index.js.map +1 -1
  10. package/dist/loader.d.ts +17 -6
  11. package/dist/loader.d.ts.map +1 -1
  12. package/dist/loader.js +57 -14
  13. package/dist/loader.js.map +1 -1
  14. package/dist/markdown/block-context.d.ts +21 -0
  15. package/dist/markdown/block-context.d.ts.map +1 -0
  16. package/dist/markdown/block-context.js +27 -0
  17. package/dist/markdown/block-context.js.map +1 -0
  18. package/dist/markdown/canonical-body.d.ts +30 -0
  19. package/dist/markdown/canonical-body.d.ts.map +1 -0
  20. package/dist/markdown/canonical-body.js +54 -0
  21. package/dist/markdown/canonical-body.js.map +1 -0
  22. package/dist/markdown/contracts.d.ts +66 -0
  23. package/dist/markdown/contracts.d.ts.map +1 -0
  24. package/dist/markdown/contracts.js +102 -0
  25. package/dist/markdown/contracts.js.map +1 -0
  26. package/dist/markdown/html-to-snodes.d.ts +26 -0
  27. package/dist/markdown/html-to-snodes.d.ts.map +1 -0
  28. package/dist/markdown/html-to-snodes.js +118 -0
  29. package/dist/markdown/html-to-snodes.js.map +1 -0
  30. package/dist/markdown/remark.d.ts +35 -0
  31. package/dist/markdown/remark.d.ts.map +1 -0
  32. package/dist/markdown/remark.js +66 -0
  33. package/dist/markdown/remark.js.map +1 -0
  34. package/dist/markdown/satteri.d.ts +19 -0
  35. package/dist/markdown/satteri.d.ts.map +1 -0
  36. package/dist/markdown/satteri.js +144 -0
  37. package/dist/markdown/satteri.js.map +1 -0
  38. package/dist/markdown/serialize.d.ts +60 -0
  39. package/dist/markdown/serialize.d.ts.map +1 -0
  40. package/dist/markdown/serialize.js +264 -0
  41. package/dist/markdown/serialize.js.map +1 -0
  42. package/dist/markdown/splice.d.ts +32 -0
  43. package/dist/markdown/splice.d.ts.map +1 -0
  44. package/dist/markdown/splice.js +44 -0
  45. package/dist/markdown/splice.js.map +1 -0
  46. package/dist/markdown/stamp.d.ts +68 -0
  47. package/dist/markdown/stamp.d.ts.map +1 -0
  48. package/dist/markdown/stamp.js +131 -0
  49. package/dist/markdown/stamp.js.map +1 -0
  50. package/dist/runtime/auth/rate-limiter.d.ts.map +1 -1
  51. package/dist/runtime/auth/rate-limiter.js +5 -0
  52. package/dist/runtime/auth/rate-limiter.js.map +1 -1
  53. package/dist/runtime/auth/session.d.ts +3 -3
  54. package/dist/runtime/auth/session.d.ts.map +1 -1
  55. package/dist/runtime/auth/session.js +68 -21
  56. package/dist/runtime/auth/session.js.map +1 -1
  57. package/dist/runtime/config.d.ts +3 -0
  58. package/dist/runtime/config.d.ts.map +1 -1
  59. package/dist/runtime/config.js +4 -1
  60. package/dist/runtime/config.js.map +1 -1
  61. package/dist/runtime/content.d.ts.map +1 -1
  62. package/dist/runtime/content.js +4 -2
  63. package/dist/runtime/content.js.map +1 -1
  64. package/dist/runtime/i18n.d.ts +86 -0
  65. package/dist/runtime/i18n.d.ts.map +1 -0
  66. package/dist/runtime/i18n.js +168 -0
  67. package/dist/runtime/i18n.js.map +1 -0
  68. package/dist/runtime/middleware.d.ts.map +1 -1
  69. package/dist/runtime/middleware.js +61 -6
  70. package/dist/runtime/middleware.js.map +1 -1
  71. package/dist/runtime/mutations/contracts.d.ts +28 -1
  72. package/dist/runtime/mutations/contracts.d.ts.map +1 -1
  73. package/dist/runtime/mutations/contracts.js +76 -0
  74. package/dist/runtime/mutations/contracts.js.map +1 -1
  75. package/dist/runtime/mutations/engine.d.ts +6 -1
  76. package/dist/runtime/mutations/engine.d.ts.map +1 -1
  77. package/dist/runtime/mutations/engine.js +271 -51
  78. package/dist/runtime/mutations/engine.js.map +1 -1
  79. package/dist/runtime/providers.d.ts +2 -1
  80. package/dist/runtime/providers.d.ts.map +1 -1
  81. package/dist/runtime/providers.js +7 -1
  82. package/dist/runtime/providers.js.map +1 -1
  83. package/dist/runtime/publish.d.ts +13 -1
  84. package/dist/runtime/publish.d.ts.map +1 -1
  85. package/dist/runtime/publish.js +80 -4
  86. package/dist/runtime/publish.js.map +1 -1
  87. package/dist/runtime/request-context.d.ts +14 -2
  88. package/dist/runtime/request-context.d.ts.map +1 -1
  89. package/dist/runtime/request-context.js +7 -1
  90. package/dist/runtime/request-context.js.map +1 -1
  91. package/dist/runtime/rewrite.d.ts.map +1 -1
  92. package/dist/runtime/rewrite.js +109 -3
  93. package/dist/runtime/rewrite.js.map +1 -1
  94. package/dist/runtime/rich-allowlist.d.ts.map +1 -1
  95. package/dist/runtime/rich-allowlist.js +5 -1
  96. package/dist/runtime/rich-allowlist.js.map +1 -1
  97. package/dist/runtime/routes/admin-entry.d.ts.map +1 -1
  98. package/dist/runtime/routes/admin-entry.js +114 -18
  99. package/dist/runtime/routes/admin-entry.js.map +1 -1
  100. package/dist/runtime/routes/admin.d.ts.map +1 -1
  101. package/dist/runtime/routes/admin.js +33 -15
  102. package/dist/runtime/routes/admin.js.map +1 -1
  103. package/dist/runtime/routes/auth-login.d.ts.map +1 -1
  104. package/dist/runtime/routes/auth-login.js +4 -0
  105. package/dist/runtime/routes/auth-login.js.map +1 -1
  106. package/dist/runtime/routes/auth-logout.d.ts.map +1 -1
  107. package/dist/runtime/routes/auth-logout.js +7 -2
  108. package/dist/runtime/routes/auth-logout.js.map +1 -1
  109. package/dist/runtime/routes/auth-session.d.ts.map +1 -1
  110. package/dist/runtime/routes/auth-session.js +4 -2
  111. package/dist/runtime/routes/auth-session.js.map +1 -1
  112. package/dist/runtime/routes/collection-list.d.ts.map +1 -1
  113. package/dist/runtime/routes/collection-list.js +64 -41
  114. package/dist/runtime/routes/collection-list.js.map +1 -1
  115. package/dist/runtime/routes/entries.d.ts.map +1 -1
  116. package/dist/runtime/routes/entries.js +16 -6
  117. package/dist/runtime/routes/entries.js.map +1 -1
  118. package/dist/runtime/routes/history.d.ts.map +1 -1
  119. package/dist/runtime/routes/history.js +50 -22
  120. package/dist/runtime/routes/history.js.map +1 -1
  121. package/dist/runtime/routes/mutate.d.ts.map +1 -1
  122. package/dist/runtime/routes/mutate.js +40 -6
  123. package/dist/runtime/routes/mutate.js.map +1 -1
  124. package/dist/runtime/routes/publish.d.ts.map +1 -1
  125. package/dist/runtime/routes/publish.js +5 -2
  126. package/dist/runtime/routes/publish.js.map +1 -1
  127. package/dist/runtime/routes/schema.d.ts.map +1 -1
  128. package/dist/runtime/routes/schema.js +11 -3
  129. package/dist/runtime/routes/schema.js.map +1 -1
  130. package/dist/runtime/routes/studio-home.d.ts.map +1 -1
  131. package/dist/runtime/routes/studio-home.js +38 -19
  132. package/dist/runtime/routes/studio-home.js.map +1 -1
  133. package/dist/runtime/routes/theme-stylesheet.d.ts.map +1 -1
  134. package/dist/runtime/routes/theme-stylesheet.js +11 -1
  135. package/dist/runtime/routes/theme-stylesheet.js.map +1 -1
  136. package/dist/runtime/schema-registry.d.ts +8 -1
  137. package/dist/runtime/schema-registry.d.ts.map +1 -1
  138. package/dist/runtime/schema-registry.js +47 -3
  139. package/dist/runtime/schema-registry.js.map +1 -1
  140. package/dist/runtime/storage/atomic-write.d.ts.map +1 -1
  141. package/dist/runtime/storage/atomic-write.js +8 -3
  142. package/dist/runtime/storage/atomic-write.js.map +1 -1
  143. package/dist/runtime/storage/markdown-adapter.d.ts +19 -0
  144. package/dist/runtime/storage/markdown-adapter.d.ts.map +1 -1
  145. package/dist/runtime/storage/markdown-adapter.js +41 -0
  146. package/dist/runtime/storage/markdown-adapter.js.map +1 -1
  147. package/dist/runtime/storage/session-overlay-adapter.d.ts +8 -0
  148. package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -1
  149. package/dist/runtime/storage/session-overlay-adapter.js +24 -2
  150. package/dist/runtime/storage/session-overlay-adapter.js.map +1 -1
  151. package/dist/runtime/themes/preset-tokens.js +4 -4
  152. package/dist/runtime/themes/preset-tokens.js.map +1 -1
  153. package/dist/runtime/utils.d.ts +10 -0
  154. package/dist/runtime/utils.d.ts.map +1 -1
  155. package/dist/runtime/utils.js +16 -0
  156. package/dist/runtime/utils.js.map +1 -1
  157. package/dist/runtime/views/studio-layout.d.ts +3 -0
  158. package/dist/runtime/views/studio-layout.d.ts.map +1 -1
  159. package/dist/runtime/views/studio-layout.js +36 -13
  160. package/dist/runtime/views/studio-layout.js.map +1 -1
  161. package/dist/schema-utils.d.ts +7 -0
  162. package/dist/schema-utils.d.ts.map +1 -1
  163. package/dist/schema-utils.js +143 -0
  164. package/dist/schema-utils.js.map +1 -1
  165. package/dist/types.d.ts +83 -1
  166. package/dist/types.d.ts.map +1 -1
  167. package/package.json +2 -2
  168. package/static/cms/admin-entry.css +135 -13
  169. package/static/cms/admin-entry.js +509 -86
  170. package/static/cms/editor/guards.js +1 -1
  171. package/static/cms/editor/image-edit.js +42 -11
  172. package/static/cms/editor/image.css +7 -1
  173. package/static/cms/editor/md-block-edit.js +176 -0
  174. package/static/cms/editor/md-serialize.js +301 -0
  175. package/static/cms/editor/panel.css +69 -25
  176. package/static/cms/editor/panel.js +58 -1
  177. package/static/cms/editor/rich-toolbar.js +4 -3
  178. package/static/cms/editor/sanitize.js +2 -1
  179. package/static/cms/editor/sync.js +277 -56
  180. package/static/cms/editor/text-edit.js +68 -17
  181. package/static/cms/editor/text-link-interactions.js +4 -4
  182. package/static/cms/editor/toast.css +114 -2
  183. package/static/cms/editor/toast.js +121 -22
  184. package/static/cms/editor/tokens-and-text.css +73 -3
  185. package/static/cms/editor/toolbar.css +19 -6
  186. package/static/cms/editor/toolbar.js +64 -23
  187. package/static/cms/editor.css +1 -1
  188. package/static/cms/editor.js +14 -3
  189. package/static/cms/studio-tokens.css +4 -4
  190. package/static/cms/studio.css +24 -0
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Derive a block's serialization context from its SOURCE, not from client
3
+ * claims. A forged context could change a block's type (paragraph -> heading)
4
+ * or smuggle a hard break into a container-nested block (corrupting `> `/list
5
+ * structure on publish), so both facts are read off the canonical body at the
6
+ * verified source range instead of being accepted from the request.
7
+ */
8
+ import type { BlockContext } from "./serialize.js";
9
+ import type { MdSrc } from "./contracts.js";
10
+ /**
11
+ * Block context for the range `src` in `canonical` (the canonical body the
12
+ * range was hash-verified against):
13
+ *
14
+ * - Heading when the slice starts with ATX markers — the level comes from the
15
+ * marker count (heading ranges include their `#`s).
16
+ * - Otherwise a paragraph; `nested` is true when anything (a `> ` marker, list
17
+ * indent) precedes the range on its line — nested blocks are single-line by
18
+ * the stamping contract, and `nested` makes the serializer refuse `<br>`.
19
+ */
20
+ export declare function deriveBlockContext(canonical: string, src: MdSrc): BlockContext;
21
+ //# sourceMappingURL=block-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-context.d.ts","sourceRoot":"","sources":["../../src/markdown/block-context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAI5C;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,YAAY,CAO9E"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Derive a block's serialization context from its SOURCE, not from client
3
+ * claims. A forged context could change a block's type (paragraph -> heading)
4
+ * or smuggle a hard break into a container-nested block (corrupting `> `/list
5
+ * structure on publish), so both facts are read off the canonical body at the
6
+ * verified source range instead of being accepted from the request.
7
+ */
8
+ const HEADING_RE = /^(#{1,6})[ \t]/;
9
+ /**
10
+ * Block context for the range `src` in `canonical` (the canonical body the
11
+ * range was hash-verified against):
12
+ *
13
+ * - Heading when the slice starts with ATX markers — the level comes from the
14
+ * marker count (heading ranges include their `#`s).
15
+ * - Otherwise a paragraph; `nested` is true when anything (a `> ` marker, list
16
+ * indent) precedes the range on its line — nested blocks are single-line by
17
+ * the stamping contract, and `nested` makes the serializer refuse `<br>`.
18
+ */
19
+ export function deriveBlockContext(canonical, src) {
20
+ const slice = canonical.slice(src.start, src.end);
21
+ const heading = HEADING_RE.exec(slice);
22
+ if (heading)
23
+ return { block: "heading", level: heading[1].length };
24
+ const lineStart = canonical.lastIndexOf("\n", src.start - 1) + 1;
25
+ return { block: "paragraph", nested: lineStart < src.start };
26
+ }
27
+ //# sourceMappingURL=block-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-context.js","sourceRoot":"","sources":["../../src/markdown/block-context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,UAAU,GAAG,gBAAgB,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,GAAU;IAC9D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAEnE,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Canonical body base for markdown block offsets.
3
+ *
4
+ * Astro feeds the markdown processor a DIFFERENT source string per render path
5
+ * (verified against Astro 7.0.6): direct `.md` imports blank the frontmatter
6
+ * with equal-length whitespace, while content collections strip the
7
+ * frontmatter and `.trim()` the body. Raw mdast offsets are therefore not
8
+ * portable. Every `data-caret-md-src` offset is instead defined against ONE
9
+ * canonical base — the frontmatter-stripped, trimmed body — so the stamping
10
+ * plugin (any pipeline) and the server splicer agree on coordinates.
11
+ *
12
+ * Plugin side: `canonicalOffset = nodeOffset - (source.length - source.trimStart().length)`.
13
+ * Server side: this module maps canonical offsets back to file offsets for the
14
+ * publish splice.
15
+ */
16
+ export interface CanonicalBody {
17
+ /** The frontmatter-stripped, trimmed body — the offset base. */
18
+ body: string;
19
+ /** Map a canonical body offset to an absolute offset in the source file. */
20
+ fileOffsetOf: (canonicalOffset: number) => number;
21
+ }
22
+ /**
23
+ * Derive the canonical body and its offset mapping from a full source file.
24
+ *
25
+ * `body === fileSource.slice(bodyStart).trim()`, and `fileOffsetOf(0)` is the
26
+ * first non-whitespace byte after the frontmatter fence. Trailing-whitespace
27
+ * trimming does not affect the mapping (it only shortens `body`).
28
+ */
29
+ export declare function canonicalBody(fileSource: string): CanonicalBody;
30
+ //# sourceMappingURL=canonical-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-body.d.ts","sourceRoot":"","sources":["../../src/markdown/canonical-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,YAAY,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD;AAwBD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAS/D"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Canonical body base for markdown block offsets.
3
+ *
4
+ * Astro feeds the markdown processor a DIFFERENT source string per render path
5
+ * (verified against Astro 7.0.6): direct `.md` imports blank the frontmatter
6
+ * with equal-length whitespace, while content collections strip the
7
+ * frontmatter and `.trim()` the body. Raw mdast offsets are therefore not
8
+ * portable. Every `data-caret-md-src` offset is instead defined against ONE
9
+ * canonical base — the frontmatter-stripped, trimmed body — so the stamping
10
+ * plugin (any pipeline) and the server splicer agree on coordinates.
11
+ *
12
+ * Plugin side: `canonicalOffset = nodeOffset - (source.length - source.trimStart().length)`.
13
+ * Server side: this module maps canonical offsets back to file offsets for the
14
+ * publish splice.
15
+ */
16
+ /**
17
+ * Frontmatter fence matcher, MIRRORING Astro's own
18
+ * (`@astrojs/internal-helpers/dist/frontmatter.js` `frontmatterRE`) byte for
19
+ * byte. This must agree with what Astro strips before rendering — a stricter
20
+ * hand-rolled detector diverged on three legal shapes (UTF-8 BOM before the
21
+ * fence, blank lines before the fence, a `----` close line whose first three
22
+ * chars satisfy Astro's close) and every body save on such files 409'd as
23
+ * "stale" because plugin-side and server-side offsets disagreed.
24
+ */
25
+ const ASTRO_FRONTMATTER_RE = /(?:^\uFEFF?|^\s*\n)(?:---|\+\+\+)([\s\S]*?\n)(?:---|\+\+\+)/;
26
+ /**
27
+ * Byte offset where the markdown body begins (0 when there is no frontmatter
28
+ * fence) — everything Astro's stripper would remove, including any BOM or
29
+ * leading blank lines consumed by its match.
30
+ */
31
+ function bodyOffset(source) {
32
+ const match = ASTRO_FRONTMATTER_RE.exec(source);
33
+ if (!match)
34
+ return 0;
35
+ return match.index + match[0].length;
36
+ }
37
+ /**
38
+ * Derive the canonical body and its offset mapping from a full source file.
39
+ *
40
+ * `body === fileSource.slice(bodyStart).trim()`, and `fileOffsetOf(0)` is the
41
+ * first non-whitespace byte after the frontmatter fence. Trailing-whitespace
42
+ * trimming does not affect the mapping (it only shortens `body`).
43
+ */
44
+ export function canonicalBody(fileSource) {
45
+ const start = bodyOffset(fileSource);
46
+ const afterFm = fileSource.slice(start);
47
+ const leading = afterFm.length - afterFm.trimStart().length;
48
+ const base = start + leading;
49
+ return {
50
+ body: afterFm.trim(),
51
+ fileOffsetOf: (canonicalOffset) => base + canonicalOffset,
52
+ };
53
+ }
54
+ //# sourceMappingURL=canonical-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-body.js","sourceRoot":"","sources":["../../src/markdown/canonical-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAAG,6DAA6D,CAAC;AAE3F;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAc;IAChC,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;IAC5D,MAAM,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC;IAC7B,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;QACpB,YAAY,EAAE,CAAC,eAAuB,EAAE,EAAE,CAAC,IAAI,GAAG,eAAe;KAClE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Contract surface for markdown BODY inline editing (v0.3.0).
3
+ *
4
+ * These identifiers gate a security- and correctness-critical path: the
5
+ * `data-caret-md` attribute binds a rendered block back to a byte range in a
6
+ * source `.md` file, and a Publish splices edited markdown into that range.
7
+ * The grammar, the source-hint format, and the content hash are therefore a
8
+ * compatibility promise shared across the render-time stamping plugins, the
9
+ * mutation engine, the publish splicer, and the browser editor.
10
+ *
11
+ * Zero-dependency by policy (core ships no runtime deps). The browser editor
12
+ * ships as raw unbundled JS and hand-mirrors the pieces it needs
13
+ * (`static/cms/editor/md-serialize.js`); a parity test holds the mirror to
14
+ * this source of truth.
15
+ */
16
+ /** Attribute carrying the block binding (`collection::id::body::blockPath`). */
17
+ export declare const CARET_MD_ATTR = "data-caret-md";
18
+ /** Attribute carrying the source hint (`start:end:hash`). */
19
+ export declare const CARET_MD_SRC_ATTR = "data-caret-md-src";
20
+ /**
21
+ * Reserved field name for the body-draft map inside an entry's draft overlay
22
+ * `data`. Read boundaries strip it so it never surfaces to schema/loader
23
+ * consumers.
24
+ */
25
+ export declare const BODY_OVERLAY_KEY = "__body";
26
+ /** The synthetic field segment identifying a body binding (vs a `data-caret` field). */
27
+ export declare const BODY_FIELD = "body";
28
+ /**
29
+ * A block path: dot-joined child indexes from the mdast root to the block node
30
+ * (`"4"` = fifth top-level block; `"6.2"` = third child of the seventh block).
31
+ * Stable identity for the block within an entry across edits.
32
+ */
33
+ export declare const BLOCK_PATH_RE: RegExp;
34
+ export interface MdBinding {
35
+ collection: string;
36
+ id: string;
37
+ blockPath: string;
38
+ }
39
+ /** Format a block path from root-to-node child indexes. */
40
+ export declare function formatBlockPath(indexes: readonly number[]): string;
41
+ /** Parse a block path into its child indexes, or `null` if malformed. */
42
+ export declare function parseBlockPath(raw: string): number[] | null;
43
+ /** Format a `data-caret-md` binding value. */
44
+ export declare function formatMdBinding(b: MdBinding): string;
45
+ /** Parse a `data-caret-md` binding value, or `null` if it fails the grammar. */
46
+ export declare function parseMdBinding(raw: string): MdBinding | null;
47
+ export interface MdSrc {
48
+ /** Start offset in the canonical body (see `canonical-body.ts`). */
49
+ start: number;
50
+ /** End offset (exclusive) in the canonical body. */
51
+ end: number;
52
+ /** `fnv1a32` of the canonical body slice `[start, end)`. */
53
+ hash: string;
54
+ }
55
+ /** Format a `data-caret-md-src` hint value. */
56
+ export declare function formatMdSrc(s: MdSrc): string;
57
+ /** Parse a `data-caret-md-src` hint, validating bounds and hash shape. */
58
+ export declare function parseMdSrc(raw: string): MdSrc | null;
59
+ /**
60
+ * FNV-1a (32-bit) hash as an 8-char lowercase hex string. Not cryptographic —
61
+ * a staleness fingerprint over a source slice, chosen for a dependency-free,
62
+ * byte-identical implementation on both the TS and browser-JS sides. Iterates
63
+ * UTF-16 code units, so the two sides must hash the same string form.
64
+ */
65
+ export declare function fnv1a32(str: string): string;
66
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/markdown/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,gFAAgF;AAChF,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,wFAAwF;AACxF,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAoB,CAAC;AAE/C,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAElE;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAG3D;AAED,8CAA8C;AAC9C,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAEpD;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAS5D;AAED,MAAM,WAAW,KAAK;IACpB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;CACd;AAID,+CAA+C;AAC/C,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAE5C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAWpD;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO3C"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Contract surface for markdown BODY inline editing (v0.3.0).
3
+ *
4
+ * These identifiers gate a security- and correctness-critical path: the
5
+ * `data-caret-md` attribute binds a rendered block back to a byte range in a
6
+ * source `.md` file, and a Publish splices edited markdown into that range.
7
+ * The grammar, the source-hint format, and the content hash are therefore a
8
+ * compatibility promise shared across the render-time stamping plugins, the
9
+ * mutation engine, the publish splicer, and the browser editor.
10
+ *
11
+ * Zero-dependency by policy (core ships no runtime deps). The browser editor
12
+ * ships as raw unbundled JS and hand-mirrors the pieces it needs
13
+ * (`static/cms/editor/md-serialize.js`); a parity test holds the mirror to
14
+ * this source of truth.
15
+ */
16
+ import { COLLECTION_NAME_RE, ENTRY_ID_RE } from "../runtime/storage/id-contracts.js";
17
+ /** Attribute carrying the block binding (`collection::id::body::blockPath`). */
18
+ export const CARET_MD_ATTR = "data-caret-md";
19
+ /** Attribute carrying the source hint (`start:end:hash`). */
20
+ export const CARET_MD_SRC_ATTR = "data-caret-md-src";
21
+ /**
22
+ * Reserved field name for the body-draft map inside an entry's draft overlay
23
+ * `data`. Read boundaries strip it so it never surfaces to schema/loader
24
+ * consumers.
25
+ */
26
+ export const BODY_OVERLAY_KEY = "__body";
27
+ /** The synthetic field segment identifying a body binding (vs a `data-caret` field). */
28
+ export const BODY_FIELD = "body";
29
+ /**
30
+ * A block path: dot-joined child indexes from the mdast root to the block node
31
+ * (`"4"` = fifth top-level block; `"6.2"` = third child of the seventh block).
32
+ * Stable identity for the block within an entry across edits.
33
+ */
34
+ export const BLOCK_PATH_RE = /^\d+(?:\.\d+)*$/;
35
+ /** Format a block path from root-to-node child indexes. */
36
+ export function formatBlockPath(indexes) {
37
+ return indexes.join(".");
38
+ }
39
+ /** Parse a block path into its child indexes, or `null` if malformed. */
40
+ export function parseBlockPath(raw) {
41
+ if (!BLOCK_PATH_RE.test(raw))
42
+ return null;
43
+ return raw.split(".").map(Number);
44
+ }
45
+ /** Format a `data-caret-md` binding value. */
46
+ export function formatMdBinding(b) {
47
+ return `${b.collection}::${b.id}::${BODY_FIELD}::${b.blockPath}`;
48
+ }
49
+ /** Parse a `data-caret-md` binding value, or `null` if it fails the grammar. */
50
+ export function parseMdBinding(raw) {
51
+ const parts = raw.split("::");
52
+ if (parts.length !== 4)
53
+ return null;
54
+ const [collection, id, field, blockPath] = parts;
55
+ if (field !== BODY_FIELD)
56
+ return null;
57
+ if (!COLLECTION_NAME_RE.test(collection))
58
+ return null;
59
+ if (!ENTRY_ID_RE.test(id))
60
+ return null;
61
+ if (!BLOCK_PATH_RE.test(blockPath))
62
+ return null;
63
+ return { collection, id, blockPath };
64
+ }
65
+ const HASH_RE = /^[0-9a-f]{8}$/;
66
+ /** Format a `data-caret-md-src` hint value. */
67
+ export function formatMdSrc(s) {
68
+ return `${s.start}:${s.end}:${s.hash}`;
69
+ }
70
+ /** Parse a `data-caret-md-src` hint, validating bounds and hash shape. */
71
+ export function parseMdSrc(raw) {
72
+ const parts = raw.split(":");
73
+ if (parts.length !== 3)
74
+ return null;
75
+ const [startStr, endStr, hash] = parts;
76
+ if (!/^\d+$/.test(startStr) || !/^\d+$/.test(endStr))
77
+ return null;
78
+ if (!HASH_RE.test(hash))
79
+ return null;
80
+ const start = Number(startStr);
81
+ const end = Number(endStr);
82
+ if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end))
83
+ return null;
84
+ if (start >= end)
85
+ return null;
86
+ return { start, end, hash };
87
+ }
88
+ /**
89
+ * FNV-1a (32-bit) hash as an 8-char lowercase hex string. Not cryptographic —
90
+ * a staleness fingerprint over a source slice, chosen for a dependency-free,
91
+ * byte-identical implementation on both the TS and browser-JS sides. Iterates
92
+ * UTF-16 code units, so the two sides must hash the same string form.
93
+ */
94
+ export function fnv1a32(str) {
95
+ let h = 0x811c9dc5;
96
+ for (let i = 0; i < str.length; i++) {
97
+ h ^= str.charCodeAt(i);
98
+ h = Math.imul(h, 0x01000193);
99
+ }
100
+ return (h >>> 0).toString(16).padStart(8, "0");
101
+ }
102
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/markdown/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Server-side inline-HTML → SNode parser for the markdown body write path.
3
+ *
4
+ * Exists so the server NEVER trusts client-supplied markdown: an `md_block`
5
+ * mutation carries only HTML, which is re-sanitized against the rich allowlist
6
+ * and then converted here into the same minimal tree `serializeBlock` consumes.
7
+ * The markdown that eventually gets spliced into a source file is therefore
8
+ * always derived server-side, and anything outside the closed set hard-fails
9
+ * in the serializer.
10
+ *
11
+ * Deliberately tiny and strict — this only needs to parse the SANITIZER'S
12
+ * output (balanced inline tags, double-quoted attributes, standard entities),
13
+ * not arbitrary HTML. Malformed input throws; the mutation returns 400.
14
+ */
15
+ import type { SNode } from "./serialize.js";
16
+ export declare class HtmlParseError extends Error {
17
+ constructor(message: string);
18
+ }
19
+ /**
20
+ * Parse a sanitized inline-HTML fragment into SNodes. Throws
21
+ * {@link HtmlParseError} on anything structurally unexpected (unbalanced tags,
22
+ * malformed tag syntax, comments/doctypes/CDATA) — the sanitizer never emits
23
+ * those, so their presence means the input didn't come through it.
24
+ */
25
+ export declare function htmlToSNodes(html: string): SNode[];
26
+ //# sourceMappingURL=html-to-snodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-to-snodes.d.ts","sourceRoot":"","sources":["../../src/markdown/html-to-snodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAiCD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,CA+DlD"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Server-side inline-HTML → SNode parser for the markdown body write path.
3
+ *
4
+ * Exists so the server NEVER trusts client-supplied markdown: an `md_block`
5
+ * mutation carries only HTML, which is re-sanitized against the rich allowlist
6
+ * and then converted here into the same minimal tree `serializeBlock` consumes.
7
+ * The markdown that eventually gets spliced into a source file is therefore
8
+ * always derived server-side, and anything outside the closed set hard-fails
9
+ * in the serializer.
10
+ *
11
+ * Deliberately tiny and strict — this only needs to parse the SANITIZER'S
12
+ * output (balanced inline tags, double-quoted attributes, standard entities),
13
+ * not arbitrary HTML. Malformed input throws; the mutation returns 400.
14
+ */
15
+ export class HtmlParseError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = "HtmlParseError";
19
+ }
20
+ }
21
+ const NAMED_ENTITIES = {
22
+ amp: "&",
23
+ lt: "<",
24
+ gt: ">",
25
+ quot: '"',
26
+ apos: "'",
27
+ nbsp: " ",
28
+ };
29
+ function decodeEntities(text) {
30
+ return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (whole, body) => {
31
+ if (body.startsWith("#x") || body.startsWith("#X")) {
32
+ const cp = Number.parseInt(body.slice(2), 16);
33
+ return Number.isNaN(cp) ? whole : safeFromCodePoint(cp, whole);
34
+ }
35
+ if (body.startsWith("#")) {
36
+ const cp = Number.parseInt(body.slice(1), 10);
37
+ return Number.isNaN(cp) ? whole : safeFromCodePoint(cp, whole);
38
+ }
39
+ return NAMED_ENTITIES[body.toLowerCase()] ?? whole;
40
+ });
41
+ }
42
+ function safeFromCodePoint(cp, fallback) {
43
+ if (cp < 0 || cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff))
44
+ return fallback;
45
+ return String.fromCodePoint(cp);
46
+ }
47
+ const TAG_NAME_RE = /^[a-zA-Z][a-zA-Z0-9]*$/;
48
+ const VOID_TAGS = new Set(["br"]);
49
+ /**
50
+ * Parse a sanitized inline-HTML fragment into SNodes. Throws
51
+ * {@link HtmlParseError} on anything structurally unexpected (unbalanced tags,
52
+ * malformed tag syntax, comments/doctypes/CDATA) — the sanitizer never emits
53
+ * those, so their presence means the input didn't come through it.
54
+ */
55
+ export function htmlToSNodes(html) {
56
+ const roots = [];
57
+ const stack = [];
58
+ const push = (node) => {
59
+ if (stack.length > 0)
60
+ stack[stack.length - 1].children.push(node);
61
+ else
62
+ roots.push(node);
63
+ };
64
+ let i = 0;
65
+ while (i < html.length) {
66
+ if (html[i] !== "<") {
67
+ const next = html.indexOf("<", i);
68
+ const end = next === -1 ? html.length : next;
69
+ push({ type: "text", value: decodeEntities(html.slice(i, end)) });
70
+ i = end;
71
+ continue;
72
+ }
73
+ const gt = html.indexOf(">", i);
74
+ if (gt === -1)
75
+ throw new HtmlParseError("unterminated tag");
76
+ const raw = html.slice(i + 1, gt);
77
+ i = gt + 1;
78
+ if (raw.startsWith("/")) {
79
+ const name = raw.slice(1).trim().toLowerCase();
80
+ const top = stack.pop();
81
+ if (!top || top.tag !== name) {
82
+ throw new HtmlParseError(`unbalanced closing tag </${name}>`);
83
+ }
84
+ push({ type: "element", tag: top.tag, attrs: top.attrs, children: top.children });
85
+ continue;
86
+ }
87
+ if (raw.startsWith("!") || raw.startsWith("?")) {
88
+ throw new HtmlParseError("comments and declarations are not allowed");
89
+ }
90
+ const selfClosing = raw.endsWith("/");
91
+ const tagBody = selfClosing ? raw.slice(0, -1) : raw;
92
+ const spaceIdx = tagBody.search(/[\s]/);
93
+ const name = (spaceIdx === -1 ? tagBody : tagBody.slice(0, spaceIdx)).toLowerCase();
94
+ if (!TAG_NAME_RE.test(name))
95
+ throw new HtmlParseError(`malformed tag <${raw}>`);
96
+ const attrs = {};
97
+ const attrSrc = spaceIdx === -1 ? "" : tagBody.slice(spaceIdx);
98
+ const attrRe = /([a-zA-Z-]+)(?:="([^"]*)")?/g;
99
+ for (let m; (m = attrRe.exec(attrSrc));) {
100
+ // Only carry href — the sole attribute the closed set represents. Other
101
+ // sanitizer-permitted attributes (target/rel/class) don't round-trip to
102
+ // markdown and are regenerated at render time.
103
+ if (m[1].toLowerCase() === "href")
104
+ attrs.href = decodeEntities(m[2] ?? "");
105
+ }
106
+ if (VOID_TAGS.has(name) || selfClosing) {
107
+ push({ type: "element", tag: name, attrs, children: [] });
108
+ }
109
+ else {
110
+ stack.push({ tag: name, attrs, children: [] });
111
+ }
112
+ }
113
+ if (stack.length > 0) {
114
+ throw new HtmlParseError(`unclosed tag <${stack[stack.length - 1].tag}>`);
115
+ }
116
+ return roots;
117
+ }
118
+ //# sourceMappingURL=html-to-snodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-to-snodes.js","sourceRoot":"","sources":["../../src/markdown/html-to-snodes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Remark plugin that stamps `data-caret-md` bindings (Astro 6 / unified
3
+ * holdouts). Behaviour-identical to the Sätteri frontend — both call the shared
4
+ * `computeStamp`/`planParagraph`, and a parity test runs the two over the same
5
+ * trees. A tiny internal walker avoids a `unist-util-visit` dependency.
6
+ */
7
+ interface CaretRemarkOptions {
8
+ contentRoot: string;
9
+ }
10
+ interface Pos {
11
+ start?: {
12
+ offset?: number;
13
+ };
14
+ end?: {
15
+ offset?: number;
16
+ };
17
+ }
18
+ interface MdNode {
19
+ type: string;
20
+ position?: Pos;
21
+ children?: MdNode[];
22
+ data?: Record<string, unknown> & {
23
+ hProperties?: Record<string, unknown>;
24
+ };
25
+ }
26
+ interface VFileLike {
27
+ value?: unknown;
28
+ path?: string;
29
+ toString(): string;
30
+ }
31
+ /** Remark transformer (returned by the attacher). Exposed for direct testing. */
32
+ export declare function transformCaretRemark(tree: MdNode, file: VFileLike, contentRoot: string): void;
33
+ export declare function caretRemarkPlugin(options: CaretRemarkOptions): () => (tree: MdNode, file: VFileLike) => void;
34
+ export {};
35
+ //# sourceMappingURL=remark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remark.d.ts","sourceRoot":"","sources":["../../src/markdown/remark.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,GAAG;IACX,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,GAAG,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B;AACD,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAC5E;AACD,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,IAAI,MAAM,CAAC;CACpB;AAOD,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAoD7F;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,UAG/B,MAAM,MAAM,EAAE,MAAM,SAAS,KAAG,IAAI,CAIjE"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Remark plugin that stamps `data-caret-md` bindings (Astro 6 / unified
3
+ * holdouts). Behaviour-identical to the Sätteri frontend — both call the shared
4
+ * `computeStamp`/`planParagraph`, and a parity test runs the two over the same
5
+ * trees. A tiny internal walker avoids a `unist-util-visit` dependency.
6
+ */
7
+ import { computeStamp, planParagraph } from "./stamp.js";
8
+ function setData(target, attrs) {
9
+ target.data ??= {};
10
+ target.data.hProperties = { ...target.data.hProperties, ...attrs };
11
+ }
12
+ /** Remark transformer (returned by the attacher). Exposed for direct testing. */
13
+ export function transformCaretRemark(tree, file, contentRoot) {
14
+ const source = typeof file.value === "string" ? file.value : file.toString();
15
+ const fileURL = file.path;
16
+ const base = (node) => ({
17
+ source,
18
+ fileURL,
19
+ contentRoot,
20
+ start: node.position?.start?.offset,
21
+ end: node.position?.end?.offset,
22
+ });
23
+ const walk = (node, parent, ancestorTypes, idxPath) => {
24
+ if (node.type === "heading") {
25
+ const parentType = ancestorTypes[0] ?? "root";
26
+ const attrs = computeStamp({
27
+ ...base(node),
28
+ blockPath: idxPath,
29
+ ancestorTypes,
30
+ nested: parentType !== "root",
31
+ blockType: "heading",
32
+ });
33
+ if (attrs)
34
+ setData(node, attrs);
35
+ }
36
+ else if (node.type === "paragraph") {
37
+ const parentType = ancestorTypes[0] ?? "root";
38
+ const plan = planParagraph(parentType, idxPath[idxPath.length - 1]);
39
+ if (plan.action !== "skip") {
40
+ const toParent = plan.action === "parent";
41
+ const target = toParent ? parent : node;
42
+ const attrs = computeStamp({
43
+ ...base(node), // the paragraph's (marker-free) offsets
44
+ blockPath: toParent ? idxPath.slice(0, -1) : idxPath,
45
+ ancestorTypes: toParent ? ancestorTypes.slice(1) : ancestorTypes,
46
+ nested: toParent ? true : plan.nested,
47
+ });
48
+ if (attrs)
49
+ setData(target, attrs);
50
+ }
51
+ }
52
+ if (Array.isArray(node.children)) {
53
+ node.children.forEach((child, i) => walk(child, node, [node.type, ...ancestorTypes], [...idxPath, i]));
54
+ }
55
+ };
56
+ walk(tree, undefined, [], []);
57
+ }
58
+ export function caretRemarkPlugin(options) {
59
+ const { contentRoot } = options;
60
+ return function attacher() {
61
+ return function transform(tree, file) {
62
+ transformCaretRemark(tree, file, contentRoot);
63
+ };
64
+ };
65
+ }
66
+ //# sourceMappingURL=remark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remark.js","sourceRoot":"","sources":["../../src/markdown/remark.ts"],"names":[],"mappings":"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"}