@jini-ai/cms 0.5.2 → 0.5.4

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 (261) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +14 -8
  3. package/dist/comments/errors.d.ts +23 -0
  4. package/dist/comments/errors.js +25 -0
  5. package/dist/comments/express/index.d.ts +2 -0
  6. package/dist/comments/express/index.js +2 -0
  7. package/dist/comments/express/submit-handler.d.ts +30 -0
  8. package/dist/comments/express/submit-handler.js +85 -0
  9. package/dist/comments/hooks.d.ts +39 -0
  10. package/dist/comments/hooks.js +41 -0
  11. package/dist/comments/index.d.ts +11 -0
  12. package/dist/comments/index.js +11 -0
  13. package/dist/comments/ingress.d.ts +57 -0
  14. package/dist/comments/ingress.js +173 -0
  15. package/dist/comments/module.d.ts +94 -0
  16. package/dist/comments/module.js +73 -0
  17. package/dist/comments/ports.d.ts +184 -0
  18. package/dist/comments/ports.js +2 -0
  19. package/dist/comments/repo.memory.d.ts +70 -0
  20. package/dist/comments/repo.memory.js +120 -0
  21. package/dist/comments/sanitize.d.ts +15 -0
  22. package/dist/comments/sanitize.js +31 -0
  23. package/dist/comments/spam.heuristic.d.ts +8 -0
  24. package/dist/comments/spam.heuristic.js +54 -0
  25. package/dist/comments/sql/index.d.ts +3 -0
  26. package/dist/comments/sql/index.js +3 -0
  27. package/dist/comments/sql/repo.d.ts +77 -0
  28. package/dist/comments/sql/repo.js +190 -0
  29. package/dist/comments/sql/repo.rows.d.ts +49 -0
  30. package/dist/comments/sql/repo.rows.js +71 -0
  31. package/dist/comments/types.d.ts +187 -0
  32. package/dist/comments/types.js +39 -0
  33. package/dist/comments/write-service.d.ts +121 -0
  34. package/dist/comments/write-service.js +144 -0
  35. package/dist/core/commands/command.d.ts +2 -9
  36. package/dist/core/commands/command.js +2 -9
  37. package/dist/core/index.d.ts +2 -1
  38. package/dist/core/index.js +1 -0
  39. package/dist/core/keyset-cursor.d.ts +25 -0
  40. package/dist/core/keyset-cursor.js +20 -0
  41. package/dist/core/ports.d.ts +30 -0
  42. package/dist/core/ports.js +0 -1
  43. package/dist/core/tools/args.d.ts +1 -46
  44. package/dist/core/tools/args.js +1 -44
  45. package/dist/forms/delete-submission.d.ts +38 -0
  46. package/dist/forms/delete-submission.js +25 -0
  47. package/dist/forms/duplicate-slug.d.ts +81 -0
  48. package/dist/forms/duplicate-slug.js +115 -0
  49. package/dist/forms/errors.d.ts +53 -0
  50. package/dist/forms/errors.js +25 -0
  51. package/dist/forms/express/handler.d.ts +59 -0
  52. package/dist/forms/express/handler.js +217 -0
  53. package/dist/forms/express/index.d.ts +2 -0
  54. package/dist/forms/express/index.js +2 -0
  55. package/dist/forms/fields-json.d.ts +14 -0
  56. package/dist/forms/fields-json.js +11 -0
  57. package/dist/forms/forms.d.ts +59 -0
  58. package/dist/forms/forms.js +213 -0
  59. package/dist/forms/html/authoring-adapter.d.ts +34 -0
  60. package/dist/forms/html/authoring-adapter.js +48 -0
  61. package/dist/forms/html/html-authoring.d.ts +12 -0
  62. package/dist/forms/html/html-authoring.js +133 -0
  63. package/dist/forms/html/html-submission-adapter.d.ts +10 -0
  64. package/dist/forms/html/html-submission-adapter.js +15 -0
  65. package/dist/forms/html/index.d.ts +4 -0
  66. package/dist/forms/html/index.js +4 -0
  67. package/dist/forms/html-render.d.ts +33 -0
  68. package/dist/forms/html-render.js +31 -0
  69. package/dist/forms/index.d.ts +17 -0
  70. package/dist/forms/index.js +17 -0
  71. package/dist/forms/notify-subscriber.d.ts +32 -0
  72. package/dist/forms/notify-subscriber.js +60 -0
  73. package/dist/forms/ports.d.ts +168 -0
  74. package/dist/forms/ports.js +2 -0
  75. package/dist/forms/rate-limit-key.d.ts +8 -0
  76. package/dist/forms/rate-limit-key.js +7 -0
  77. package/dist/forms/repo.memory.d.ts +120 -0
  78. package/dist/forms/repo.memory.js +188 -0
  79. package/dist/forms/sql/index.d.ts +5 -0
  80. package/dist/forms/sql/index.js +5 -0
  81. package/dist/forms/sql/repo.d.ts +94 -0
  82. package/dist/forms/sql/repo.js +175 -0
  83. package/dist/forms/sql/repo.rows.d.ts +33 -0
  84. package/dist/forms/sql/repo.rows.js +64 -0
  85. package/dist/forms/sql/submission-ip-retention-repo.d.ts +9 -0
  86. package/dist/forms/sql/submission-ip-retention-repo.js +40 -0
  87. package/dist/forms/sql/tables.d.ts +32 -0
  88. package/dist/forms/sql/tables.js +2 -0
  89. package/dist/forms/submission-attempts.d.ts +70 -0
  90. package/dist/forms/submission-attempts.js +70 -0
  91. package/dist/forms/submission-email-validation.d.ts +8 -0
  92. package/dist/forms/submission-email-validation.js +34 -0
  93. package/dist/forms/submission-ip-retention.d.ts +30 -0
  94. package/dist/forms/submission-ip-retention.js +27 -0
  95. package/dist/forms/submit-service.d.ts +78 -0
  96. package/dist/forms/submit-service.js +109 -0
  97. package/dist/forms/types.d.ts +49 -0
  98. package/dist/forms/types.js +2 -0
  99. package/dist/forms/write-service.d.ts +83 -0
  100. package/dist/forms/write-service.js +271 -0
  101. package/dist/media/index.d.ts +0 -3
  102. package/dist/media/index.js +1 -4
  103. package/dist/media/node.d.ts +5 -0
  104. package/dist/media/node.js +6 -0
  105. package/dist/redirects/capture.d.ts +80 -0
  106. package/dist/redirects/capture.js +66 -0
  107. package/dist/redirects/express/index.d.ts +27 -0
  108. package/dist/redirects/express/index.js +40 -0
  109. package/dist/redirects/hit-sink.d.ts +56 -0
  110. package/dist/redirects/hit-sink.js +44 -0
  111. package/dist/redirects/host-config/index.d.ts +40 -0
  112. package/dist/redirects/host-config/index.js +145 -0
  113. package/dist/redirects/index.d.ts +14 -0
  114. package/dist/redirects/index.js +14 -0
  115. package/dist/redirects/matcher.d.ts +58 -0
  116. package/dist/redirects/matcher.js +144 -0
  117. package/dist/redirects/order.d.ts +30 -0
  118. package/dist/redirects/order.js +26 -0
  119. package/dist/redirects/ports.d.ts +242 -0
  120. package/dist/redirects/ports.internal.d.ts +57 -0
  121. package/dist/redirects/ports.internal.js +14 -0
  122. package/dist/redirects/ports.js +2 -0
  123. package/dist/redirects/redirects.d.ts +226 -0
  124. package/dist/redirects/redirects.js +590 -0
  125. package/dist/redirects/referrer-alias.d.ts +31 -0
  126. package/dist/redirects/referrer-alias.js +33 -0
  127. package/dist/redirects/repo.memory.d.ts +51 -0
  128. package/dist/redirects/repo.memory.js +98 -0
  129. package/dist/redirects/reserved-destination.d.ts +58 -0
  130. package/dist/redirects/reserved-destination.js +59 -0
  131. package/dist/redirects/resolver.d.ts +100 -0
  132. package/dist/redirects/resolver.js +87 -0
  133. package/dist/redirects/spa/index.d.ts +30 -0
  134. package/dist/redirects/spa/index.js +27 -0
  135. package/dist/redirects/sql/index.d.ts +4 -0
  136. package/dist/redirects/sql/index.js +4 -0
  137. package/dist/redirects/sql/repo.d.ts +82 -0
  138. package/dist/redirects/sql/repo.js +143 -0
  139. package/dist/redirects/sql/repo.rows.d.ts +49 -0
  140. package/dist/redirects/sql/repo.rows.js +79 -0
  141. package/dist/redirects/sql/row-types.d.ts +34 -0
  142. package/dist/redirects/sql/row-types.js +2 -0
  143. package/dist/redirects/target-gate.d.ts +30 -0
  144. package/dist/redirects/target-gate.js +85 -0
  145. package/dist/redirects/types.d.ts +213 -0
  146. package/dist/redirects/types.js +42 -0
  147. package/dist/seo/absolute-url.d.ts +58 -0
  148. package/dist/seo/absolute-url.js +117 -0
  149. package/dist/seo/dom/index.d.ts +14 -0
  150. package/dist/seo/dom/index.js +52 -0
  151. package/dist/seo/errors.d.ts +35 -0
  152. package/dist/seo/errors.js +35 -0
  153. package/dist/seo/feed.d.ts +49 -0
  154. package/dist/seo/feed.js +61 -0
  155. package/dist/seo/index.d.ts +13 -0
  156. package/dist/seo/index.js +13 -0
  157. package/dist/seo/media.d.ts +57 -0
  158. package/dist/seo/media.js +134 -0
  159. package/dist/seo/page-head.d.ts +18 -0
  160. package/dist/seo/page-head.js +114 -0
  161. package/dist/seo/ports.d.ts +221 -0
  162. package/dist/seo/ports.js +27 -0
  163. package/dist/seo/seo.d.ts +73 -0
  164. package/dist/seo/seo.js +230 -0
  165. package/dist/seo/sitemap.d.ts +139 -0
  166. package/dist/seo/sitemap.js +217 -0
  167. package/dist/seo/types.d.ts +278 -0
  168. package/dist/seo/types.js +2 -0
  169. package/dist/seo/write-service.d.ts +79 -0
  170. package/dist/seo/write-service.js +273 -0
  171. package/dist/seo/xml-escape.d.ts +16 -0
  172. package/dist/seo/xml-escape.js +19 -0
  173. package/dist/settings/express/cms-adapter.d.ts +20 -0
  174. package/dist/settings/express/cms-adapter.js +124 -0
  175. package/dist/settings/express/contracts.d.ts +135 -0
  176. package/dist/settings/express/contracts.js +2 -0
  177. package/dist/settings/express/http.d.ts +10 -0
  178. package/dist/settings/express/http.js +211 -0
  179. package/dist/settings/express/index.d.ts +5 -0
  180. package/dist/settings/express/index.js +5 -0
  181. package/dist/settings/express/shared.d.ts +68 -0
  182. package/dist/settings/express/shared.js +54 -0
  183. package/dist/settings/express/stream.d.ts +24 -0
  184. package/dist/settings/express/stream.js +147 -0
  185. package/dist/settings/index.d.ts +3 -38
  186. package/dist/settings/index.js +3 -35
  187. package/dist/taxonomy/write-service.d.ts +2 -30
  188. package/dist/widgets/authorize-helper.d.ts +42 -0
  189. package/dist/widgets/authorize-helper.js +16 -0
  190. package/dist/widgets/concurrency.d.ts +12 -0
  191. package/dist/widgets/concurrency.js +44 -0
  192. package/dist/widgets/config-validation.d.ts +34 -0
  193. package/dist/widgets/config-validation.js +125 -0
  194. package/dist/widgets/embed-service.d.ts +133 -0
  195. package/dist/widgets/embed-service.js +460 -0
  196. package/dist/widgets/embed-validation.d.ts +23 -0
  197. package/dist/widgets/embed-validation.js +38 -0
  198. package/dist/widgets/entry-payload.d.ts +103 -0
  199. package/dist/widgets/entry-payload.js +160 -0
  200. package/dist/widgets/errors.d.ts +136 -0
  201. package/dist/widgets/errors.js +136 -0
  202. package/dist/widgets/host-ports.d.ts +149 -0
  203. package/dist/widgets/host-ports.js +2 -0
  204. package/dist/widgets/html/html-embeds.d.ts +247 -0
  205. package/dist/widgets/html/html-embeds.js +408 -0
  206. package/dist/widgets/html/index.d.ts +5 -0
  207. package/dist/widgets/html/index.js +4 -0
  208. package/dist/widgets/html/legacy-widget-markers.d.ts +8 -0
  209. package/dist/widgets/html/legacy-widget-markers.js +45 -0
  210. package/dist/widgets/html/resolve-html-page-embeds.d.ts +42 -0
  211. package/dist/widgets/html/resolve-html-page-embeds.js +57 -0
  212. package/dist/widgets/index.d.ts +20 -0
  213. package/dist/widgets/index.js +19 -0
  214. package/dist/widgets/markers/html-attributes.d.ts +98 -0
  215. package/dist/widgets/markers/html-attributes.js +216 -0
  216. package/dist/widgets/markers/index.d.ts +3 -0
  217. package/dist/widgets/markers/index.js +3 -0
  218. package/dist/widgets/markers/marker.d.ts +496 -0
  219. package/dist/widgets/markers/marker.js +780 -0
  220. package/dist/widgets/page-embed-types.d.ts +42 -0
  221. package/dist/widgets/page-embed-types.js +42 -0
  222. package/dist/widgets/ports.d.ts +142 -0
  223. package/dist/widgets/ports.js +2 -0
  224. package/dist/widgets/read-service.d.ts +81 -0
  225. package/dist/widgets/read-service.js +79 -0
  226. package/dist/widgets/region-area-service.d.ts +110 -0
  227. package/dist/widgets/region-area-service.js +180 -0
  228. package/dist/widgets/registry.d.ts +217 -0
  229. package/dist/widgets/registry.js +172 -0
  230. package/dist/widgets/repo.memory.d.ts +41 -0
  231. package/dist/widgets/repo.memory.js +48 -0
  232. package/dist/widgets/resolver-service.d.ts +209 -0
  233. package/dist/widgets/resolver-service.js +909 -0
  234. package/dist/widgets/resolvers/contact-form.d.ts +26 -0
  235. package/dist/widgets/resolvers/contact-form.js +54 -0
  236. package/dist/widgets/resolvers/create-core-resolvers.d.ts +34 -0
  237. package/dist/widgets/resolvers/create-core-resolvers.js +11 -0
  238. package/dist/widgets/resolvers/index.d.ts +65 -0
  239. package/dist/widgets/resolvers/index.js +155 -0
  240. package/dist/widgets/resolvers/menu.d.ts +42 -0
  241. package/dist/widgets/resolvers/menu.js +43 -0
  242. package/dist/widgets/resolvers/ports.d.ts +82 -0
  243. package/dist/widgets/resolvers/ports.js +2 -0
  244. package/dist/widgets/resolvers/recent-entries.d.ts +71 -0
  245. package/dist/widgets/resolvers/recent-entries.js +165 -0
  246. package/dist/widgets/resolvers/taxonomy.d.ts +12 -0
  247. package/dist/widgets/resolvers/taxonomy.js +34 -0
  248. package/dist/widgets/sql/index.d.ts +3 -0
  249. package/dist/widgets/sql/index.js +3 -0
  250. package/dist/widgets/sql/repo.d.ts +41 -0
  251. package/dist/widgets/sql/repo.js +82 -0
  252. package/dist/widgets/sql/tables.d.ts +13 -0
  253. package/dist/widgets/sql/tables.js +2 -0
  254. package/dist/widgets/types.d.ts +213 -0
  255. package/dist/widgets/types.js +17 -0
  256. package/dist/widgets/where-used.d.ts +41 -0
  257. package/dist/widgets/where-used.js +11 -0
  258. package/dist/widgets/write-service.d.ts +204 -0
  259. package/dist/widgets/write-service.js +332 -0
  260. package/dist/workspace/delete.d.ts +1 -1
  261. package/package.json +220 -12
@@ -0,0 +1,209 @@
1
+ /**
2
+ * @file `resolvePageWidgets` — the batch-first page-render resolution orchestrator (SPEC-043
3
+ * REQ-23..28; ADR-047 Debate Fold-In Amendment 2).
4
+ *
5
+ * Purpose:
6
+ * The single seam that turns "a page's widget references" (region-bound + inline-embedded) into
7
+ * data the theme can render — one batched entry-load query, grouped by type, at most one
8
+ * `resolveWidgetType` call per type present on the page (REQ-24). Mirrors the `render.ts` "theme is
9
+ * data, core resolves" stance — the theme never calls this directly or resolves a reference itself.
10
+ *
11
+ * `EntryRepoPort` (this task's frozen, real chokepoint contract) has no `findByIds`/batch-by-id
12
+ * primitive — only `findById` (one row) and `EntryListPort.listByWorkspace` (a full-type scan).
13
+ * REQ-24's "one batched query" is satisfied here via ONE `listByWorkspace({workspaceId}, {type: 'widget'})` call
14
+ * per render (not one query per placement/type), which is the batching guarantee AC-16 actually
15
+ * tests (via `resolveWidgetType`'s single-`resolveMany`-call assertion) — a literal `WHERE id IN
16
+ * (...)` primitive does not exist on the real, frozen `EntryRepoPort` this task must compose
17
+ * against without modifying `features/entries`.
18
+ *
19
+ * Architectural role:
20
+ * `widgets` domain logic (implementation outline C-004).
21
+ */
22
+ import type { JsonObject, UUID } from "@jini-ai/core/primitives";
23
+ import type { EntryListPort, EntryRepoPort } from "../entries/index.js";
24
+ import type { WidgetHostPorts, PostRepoPort, MediaContentTypeStorePort } from "./host-ports.js";
25
+ import type { MediaRepoPort, TransformDefinitionRepoPort } from "../media/index.js";
26
+ import type { TaxonomyListPort, TermListPort } from "../taxonomy/index.js";
27
+ import type { PageHtmlEmbedRef } from "./html/html-embeds.js";
28
+ import type { WidgetRegionBindingRepoPort } from "./ports.js";
29
+ import type { WidgetRegionKey, WidgetRenderIR, WidgetResolveContext } from "./types.js";
30
+ export interface ResolvePageWidgetsDeps {
31
+ bindingRepo: WidgetRegionBindingRepoPort;
32
+ entryRepo: EntryRepoPort & EntryListPort;
33
+ }
34
+ /**
35
+ * The narrower dependency slice widget-instance resolution alone needs — `resolveWidgetInstances`
36
+ * and `resolveHtmlPageEmbeds` (below) never touch `bindingRepo` (that repo only backs region
37
+ * placements, which an `"html"`-format Page has no concept of). `ResolvePageWidgetsDeps` remains a
38
+ * structural supertype of this, so `resolvePageWidgets` passes its own full deps through unchanged.
39
+ */
40
+ type WidgetInstanceResolutionDeps = Pick<ResolvePageWidgetsDeps, "entryRepo">;
41
+ export interface ResolvePageWidgetsInput {
42
+ readonly workspaceId: UUID;
43
+ /**
44
+ * The already-fetched host document's `bodyJson`, when the caller has one to scan for inline
45
+ * `widgetEmbed` nodes (REQ-21) — e.g. a `PostRecord.bodyJson` on the `home`/`post` site routes.
46
+ * Passed as content rather than an id-to-fetch (unlike the old `pageEntryId` this replaces)
47
+ * because the only real callers already hold the document: `PostRecord` (`features/post`) is a
48
+ * separate, pre-ADR-022 table an `EntryRepoPort.findById` call can never resolve, which is why
49
+ * `pageEntryId` had no real caller and every `widgetEmbed` node in a post body rendered the
50
+ * REQ-28 placeholder forever, never real content. `undefined` when there is no host document
51
+ * (the home route) or nothing to scan.
52
+ */
53
+ readonly pageBodyJson?: unknown;
54
+ /** Region keys the current theme/template declares for this page. */
55
+ readonly resolvedRegions: readonly WidgetRegionKey[];
56
+ }
57
+ export interface ResolvePageWidgetsRequired {
58
+ deps: ResolvePageWidgetsDeps;
59
+ input: ResolvePageWidgetsInput;
60
+ }
61
+ export interface ResolvePageWidgetsResult {
62
+ readonly regions: Readonly<Record<WidgetRegionKey, readonly WidgetRenderIR[]>>;
63
+ /** Keyed by `placementId` — one entry per `widgetEmbed` node in the page's `bodyJson`. */
64
+ readonly inlineResolved: ReadonlyMap<UUID, WidgetRenderIR>;
65
+ }
66
+ export declare function resolvePageWidgets(required: ResolvePageWidgetsRequired, _optional?: Record<string, never>): Promise<ResolvePageWidgetsResult>;
67
+ /**
68
+ * One embed type's resolver: given every {@link PageHtmlEmbedRef} of that type found on the page,
69
+ * resolve as many as possible into a map keyed by the referenced id. A ref whose `id` is `null`
70
+ * (missing or out-of-bounds `id` key in the marker config) can never be resolved — a resolver skips it and should
71
+ * log a resolver-internal miss (see `HTML_EMBED_RESOLVERS`'s own doc for why this is a DIFFERENT log
72
+ * line from "unknown embed type"). The returned map's "present-with-placeholder-vs-absent" shape
73
+ * (a genuinely nonexistent target is ABSENT; a found-but-broken target is PRESENT with a placeholder
74
+ * IR) mirrors {@link resolveWidgetInstances}'s own convention — both render identically via
75
+ * `render.ts`'s `renderHtmlPageBody`, so this is not a behavior bug, same as the pre-restructuring
76
+ * `widgetResolved`/`formResolved` shape this replaces.
77
+ */
78
+ /**
79
+ * `resolveHtmlPageEmbeds`'s full dependency set — a structural superset of
80
+ * {@link WidgetInstanceResolutionDeps} (the `widget` resolver's own narrower need) plus the
81
+ * OPTIONAL `mediaRepo`/`transformRepo` pair the `media` resolver needs. Optional, not required
82
+ * (mirrors `PagesHtmlDocumentStoreDeps.entryRefsRepo`'s own "optional dependency" precedent), so
83
+ * every pre-existing widget-only call site and test keeps compiling and behaving unchanged; a
84
+ * `media` embed present with no `mediaRepo`/`transformRepo` supplied simply cannot resolve (logged,
85
+ * degrades to the REQ-28 placeholder like any other unresolved reference) rather than forcing every
86
+ * call site that never touches media to thread media dependencies through anyway.
87
+ */
88
+ export interface ResolveHtmlPageEmbedsDeps extends WidgetInstanceResolutionDeps {
89
+ readonly host: Pick<WidgetHostPorts, "media" | "posts">;
90
+ readonly mediaRepo?: MediaRepoPort;
91
+ readonly transformRepo?: TransformDefinitionRepoPort;
92
+ readonly postRepo?: PostRepoPort;
93
+ readonly taxonomyRepo?: TaxonomyListPort;
94
+ readonly termRepo?: TermListPort;
95
+ /**
96
+ * Video/embed capability (2026-08-24) — optional, same "degrade gracefully when absent" contract
97
+ * `mediaRepo`/`transformRepo` already have. When present, {@link resolveMediaTypeEmbeds} uses it
98
+ * to tell a video asset from an image one (keyed by `MediaRecord.source.sha256`, the same key
99
+ * `routes/admin/media/upload.ts` already records under). Absent (every pre-existing call site
100
+ * before this feature, and any future one that never touches media) means every asset resolves as
101
+ * an image exactly as it always has — this is additive, not a behavior change for images.
102
+ */
103
+ readonly mediaContentTypeStore?: MediaContentTypeStorePort;
104
+ /**
105
+ * Template-preview pending-body fix (2026-08-12) — an explicitly-passed, per-call override for
106
+ * exactly one entity id's content, consulted ONLY by {@link resolveContentTypeEmbeds}. Lets
107
+ * `routes/admin/posts/template-preview.ts` preview the operator's unsaved, in-editor `bodyJson`
108
+ * through the real render pipeline: without this, the current entity's own `{"type":"content"}`
109
+ * slot (`injectCurrentEntityContentId`) always re-fetches by id via {@link findPublishedPostById},
110
+ * which returns the last-SAVED row and silently discards any in-memory override the caller built
111
+ * (`ADS-memory/reports/implementation/2026-08-11-template-preview-render-bug.md` documents the
112
+ * sibling `templateChoice`-only bug this closes the `bodyJson` half of).
113
+ *
114
+ * Deliberately per-call, never a shared/global/module-level cache — threaded fresh through this
115
+ * `deps` object on every `resolveHtmlPageEmbeds` call, so two concurrent preview requests for
116
+ * different posts (or the same post from two browser tabs) can never observe each other's pending
117
+ * body. `undefined` for every pre-existing call site; behavior for those is byte-identical to
118
+ * before this field existed.
119
+ *
120
+ * `title`/`slug`/`updatedAt` are carried alongside `bodyJson` because {@link resolveContentTypeEmbeds}'s
121
+ * resolved `"post-content"` IR needs all four regardless of source — this is the same shape a real
122
+ * `findPublishedPostById` result already provides, just supplied directly instead of fetched.
123
+ */
124
+ readonly pendingContentOverride?: {
125
+ readonly id: UUID;
126
+ readonly title: string;
127
+ readonly slug: string;
128
+ readonly updatedAt: string;
129
+ /** The row's go-live time — the date line shows it over `updatedAt` (`postDisplayDateIso`). */
130
+ readonly publishAt?: string | null;
131
+ readonly bodyJson: JsonObject;
132
+ };
133
+ }
134
+ type HtmlEmbedResolver = (refs: readonly PageHtmlEmbedRef[], deps: ResolveHtmlPageEmbedsDeps, context: WidgetResolveContext) => Promise<ReadonlyMap<string, WidgetRenderIR>>;
135
+ /**
136
+ * Registry of known embed types (SPEC-047, generalized 2026-08-07). Adding a new embed type is
137
+ * registering one more entry here — no other file in `resolveHtmlPageEmbeds`'s call chain changes,
138
+ * and `html-embeds.ts`'s scanner already reports any type token it finds regardless of whether an
139
+ * entry exists here (see that file's own doc). A type ABSENT from this registry is the "unknown
140
+ * embed type" log path in {@link resolveHtmlPageEmbeds}; a type PRESENT here whose resolver still
141
+ * can't find a given id/name is the "resolver-internal miss" log path inside that resolver
142
+ * (`resolveWidgetTypeEmbeds`/`resolveMediaTypeEmbeds` above) — DECIDED (2026-08-07) to keep these
143
+ * two distinguishable in logs even though both render the identical REQ-28 placeholder externally:
144
+ * an author's markup typo (unknown type) and an author's stale reference (known type, dead id) are
145
+ * different problems needing different fixes.
146
+ *
147
+ * Historically `form` was removed (2026-08-10) because it was shorthand for a synthetic
148
+ * contact-form widget. The owner explicitly restores both spellings (2026-10-04): keep that
149
+ * synthetic instance on the SAME registered contact-form resolver so the two cannot drift.
150
+ */
151
+ export declare const HTML_EMBED_RESOLVERS: Readonly<Record<string, HtmlEmbedResolver>>;
152
+ /**
153
+ * Marker types that exist in the shared `data-embed-config` vocabulary (`core/embeds/marker.ts`) but
154
+ * are deliberately absent from {@link HTML_EMBED_RESOLVERS} — a theme's own structural markers, owned
155
+ * end-to-end by `features/theme/static-render.ts`'s `resolveSlots` (`"partial"`) and
156
+ * `injectMenuEmbeds` (`"menu"`), which run AFTER this stage on every static-tier page render
157
+ * (`routes/site/pages.ts`'s `renderViaTemplate`: `resolveHtmlPageEmbeds` first, then
158
+ * `renderStaticPage`). `isPageEmbedType`'s own doc already tells `render.ts`'s `renderHtmlPageBody` to
159
+ * leave these two untouched rather than substitute a placeholder over the nav — that fixed the
160
+ * SUBSTITUTION half of "this stage sees markers it does not own" (2026-08-10). This constant fixes the
161
+ * matching LOGGING half, which that earlier fix did not touch.
162
+ *
163
+ * Without this, {@link resolveHtmlPageEmbeds}'s "unknown embed type" warning fired for `menu`/`partial`
164
+ * on every single static-tier render — confirmed live during the 2026-08-16 GitHub Pages export
165
+ * (`gh-pages` commit `c0e52de2`, https://leonaburime-ucla.github.io/tovu-demo/): the log claimed "every
166
+ * occurrence degrades to the placeholder," which was false — curling the published page showed real,
167
+ * resolved `<a href>` links in both the nav and footer, zero placeholder markup anywhere. The page was
168
+ * never broken; only the diagnostic was. Left uncorrected, that false alarm fires on every render and
169
+ * trains a reader to ignore this log line, burying the ONE case it exists to catch: an author's actual
170
+ * markup typo (`HTML_EMBED_RESOLVERS`'s own doc on why "unknown type" and "known type, dead id" must
171
+ * stay distinguishable applies equally to "known-and-owned-elsewhere" vs. "owned nowhere").
172
+ *
173
+ * A type in this set must stay absent from `HTML_EMBED_RESOLVERS` — do not "fix" the warning by adding
174
+ * a resolver entry instead; see `isPageEmbedType`'s own doc for why that would reintroduce the
175
+ * substitution bug this file already fixed once.
176
+ *
177
+ * **Why this isn't just `!isPageEmbedType(type)`.** `isPageEmbedType` is membership in `PAGE_EMBED_TYPES`,
178
+ * which the compiler holds equal to `HTML_EMBED_RESOLVERS`'s keys — exactly the same fact this loop's own
179
+ * `HTML_EMBED_RESOLVERS[type]` lookup already tests, one
180
+ * bit: "is this resolver-service's own type." That bit is `false` for `partial`/`menu` AND for a genuine
181
+ * unregistered/typo type alike, so it cannot distinguish "known, owned by a later stage" from "owned
182
+ * nowhere" — using it to gate the warning would silence the ONE case the warning exists for, not just
183
+ * the two it shouldn't fire for. This set names the missing fact directly instead. It intentionally
184
+ * duplicates `static-render.ts`'s own `marker.type !== "menu"`/`!== "partial"` literals rather than
185
+ * importing them (that file is a different feature's territory in this change's dispatch) — the real
186
+ * fix, hoisting a shared constant into `core/embeds/marker.ts` for both files to import, is proposed but
187
+ * not yet authorized; see `ADS-memory/reports/2026-08-16-embed-placeholder-gap.md`'s "Reuse decision"
188
+ * section. Keep this set's members in sync with those two literals, not with `isPageEmbedType`.
189
+ *
190
+ * `"post-previews"` (2026-09-03) joins the set for the identical reason: it is resolved by
191
+ * `static-render.ts`'s `injectPostPreviewsEmbeds`, AFTER this stage, on every static-tier page
192
+ * render that reaches `renderStaticPage` — same duplicated-literal debt as the other two entries
193
+ * (see `POST_PREVIEWS_MARKER_TYPE`, `core/embeds/marker.ts`), not yet hoisted for the same reason.
194
+ *
195
+ * `"collection"` (2026-09-23) joins the set for the identical reason: it is resolved by
196
+ * `static-render.ts`'s `injectCollectionEmbeds`, AFTER this stage — same duplicated-literal debt as
197
+ * the other three entries (see `COLLECTION_MARKER_TYPE`, `core/embeds/marker.ts`).
198
+ *
199
+ * `"featured-image"` (2026-10-05) joins for the identical reason: `static-render.ts`'s
200
+ * `injectFeaturedImage` resolves it (see `FEATURED_IMAGE_MARKER_TYPE`, `core/embeds/marker.ts`).
201
+ */
202
+ export declare const THEME_OWNED_MARKER_TYPES: ReadonlySet<string>;
203
+ /**
204
+ * `isPageEmbedType` (the "does this stage OWN the marker type" question, with its own doc) lives in
205
+ * the dependency-free `page-embed-types.ts` so `render.ts` and the theme render workers can ask it
206
+ * without loading this file's service graph. Re-exported so existing importers keep working.
207
+ */
208
+ export { isPageEmbedType } from "./page-embed-types.js";
209
+ //# sourceMappingURL=resolver-service.d.ts.map