@krantho/api 0.0.0-stage → 1.0.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 (675) hide show
  1. package/LICENSE +21 -0
  2. package/dist/active-locales.d.ts +11 -0
  3. package/dist/active-locales.d.ts.map +1 -0
  4. package/dist/active-locales.js +31 -0
  5. package/dist/active-locales.js.map +1 -0
  6. package/dist/assistant/access.d.ts +25 -0
  7. package/dist/assistant/access.d.ts.map +1 -0
  8. package/dist/assistant/access.js +35 -0
  9. package/dist/assistant/access.js.map +1 -0
  10. package/dist/assistant/agent-loop.d.ts +31 -0
  11. package/dist/assistant/agent-loop.d.ts.map +1 -0
  12. package/dist/assistant/agent-loop.js +183 -0
  13. package/dist/assistant/agent-loop.js.map +1 -0
  14. package/dist/assistant/call-handler.d.ts +15 -0
  15. package/dist/assistant/call-handler.d.ts.map +1 -0
  16. package/dist/assistant/call-handler.js +24 -0
  17. package/dist/assistant/call-handler.js.map +1 -0
  18. package/dist/assistant/chat-handler.d.ts +8 -0
  19. package/dist/assistant/chat-handler.d.ts.map +1 -0
  20. package/dist/assistant/chat-handler.js +79 -0
  21. package/dist/assistant/chat-handler.js.map +1 -0
  22. package/dist/assistant/chat-request.d.ts +16 -0
  23. package/dist/assistant/chat-request.d.ts.map +1 -0
  24. package/dist/assistant/chat-request.js +59 -0
  25. package/dist/assistant/chat-request.js.map +1 -0
  26. package/dist/assistant/confirm-handler.d.ts +3 -0
  27. package/dist/assistant/confirm-handler.d.ts.map +1 -0
  28. package/dist/assistant/confirm-handler.js +39 -0
  29. package/dist/assistant/confirm-handler.js.map +1 -0
  30. package/dist/assistant/document-change.d.ts +22 -0
  31. package/dist/assistant/document-change.d.ts.map +1 -0
  32. package/dist/assistant/document-change.js +74 -0
  33. package/dist/assistant/document-change.js.map +1 -0
  34. package/dist/assistant/document-lock.d.ts +12 -0
  35. package/dist/assistant/document-lock.d.ts.map +1 -0
  36. package/dist/assistant/document-lock.js +14 -0
  37. package/dist/assistant/document-lock.js.map +1 -0
  38. package/dist/assistant/execute-action.d.ts +19 -0
  39. package/dist/assistant/execute-action.d.ts.map +1 -0
  40. package/dist/assistant/execute-action.js +167 -0
  41. package/dist/assistant/execute-action.js.map +1 -0
  42. package/dist/assistant/pending-action.d.ts +86 -0
  43. package/dist/assistant/pending-action.d.ts.map +1 -0
  44. package/dist/assistant/pending-action.js +104 -0
  45. package/dist/assistant/pending-action.js.map +1 -0
  46. package/dist/assistant/protocol.d.ts +120 -0
  47. package/dist/assistant/protocol.d.ts.map +1 -0
  48. package/dist/assistant/protocol.js +2 -0
  49. package/dist/assistant/protocol.js.map +1 -0
  50. package/dist/assistant/routes.d.ts +4 -0
  51. package/dist/assistant/routes.d.ts.map +1 -0
  52. package/dist/assistant/routes.js +10 -0
  53. package/dist/assistant/routes.js.map +1 -0
  54. package/dist/assistant/sse-stream.d.ts +15 -0
  55. package/dist/assistant/sse-stream.d.ts.map +1 -0
  56. package/dist/assistant/sse-stream.js +61 -0
  57. package/dist/assistant/sse-stream.js.map +1 -0
  58. package/dist/assistant/status-handler.d.ts +8 -0
  59. package/dist/assistant/status-handler.d.ts.map +1 -0
  60. package/dist/assistant/status-handler.js +39 -0
  61. package/dist/assistant/status-handler.js.map +1 -0
  62. package/dist/assistant/system-prompt.d.ts +18 -0
  63. package/dist/assistant/system-prompt.d.ts.map +1 -0
  64. package/dist/assistant/system-prompt.js +48 -0
  65. package/dist/assistant/system-prompt.js.map +1 -0
  66. package/dist/assistant/tool-registry.d.ts +19 -0
  67. package/dist/assistant/tool-registry.d.ts.map +1 -0
  68. package/dist/assistant/tool-registry.js +69 -0
  69. package/dist/assistant/tool-registry.js.map +1 -0
  70. package/dist/assistant/tools/action-tools.d.ts +4 -0
  71. package/dist/assistant/tools/action-tools.d.ts.map +1 -0
  72. package/dist/assistant/tools/action-tools.js +132 -0
  73. package/dist/assistant/tools/action-tools.js.map +1 -0
  74. package/dist/assistant/tools/aeo-tools.d.ts +4 -0
  75. package/dist/assistant/tools/aeo-tools.d.ts.map +1 -0
  76. package/dist/assistant/tools/aeo-tools.js +162 -0
  77. package/dist/assistant/tools/aeo-tools.js.map +1 -0
  78. package/dist/assistant/tools/define-tool.d.ts +55 -0
  79. package/dist/assistant/tools/define-tool.d.ts.map +1 -0
  80. package/dist/assistant/tools/define-tool.js +5 -0
  81. package/dist/assistant/tools/define-tool.js.map +1 -0
  82. package/dist/assistant/tools/draft-tools.d.ts +7 -0
  83. package/dist/assistant/tools/draft-tools.d.ts.map +1 -0
  84. package/dist/assistant/tools/draft-tools.js +105 -0
  85. package/dist/assistant/tools/draft-tools.js.map +1 -0
  86. package/dist/assistant/tools/draft-write.d.ts +49 -0
  87. package/dist/assistant/tools/draft-write.d.ts.map +1 -0
  88. package/dist/assistant/tools/draft-write.js +122 -0
  89. package/dist/assistant/tools/draft-write.js.map +1 -0
  90. package/dist/assistant/tools/faq-fit.d.ts +32 -0
  91. package/dist/assistant/tools/faq-fit.d.ts.map +1 -0
  92. package/dist/assistant/tools/faq-fit.js +96 -0
  93. package/dist/assistant/tools/faq-fit.js.map +1 -0
  94. package/dist/assistant/tools/read-tools.d.ts +13 -0
  95. package/dist/assistant/tools/read-tools.d.ts.map +1 -0
  96. package/dist/assistant/tools/read-tools.js +242 -0
  97. package/dist/assistant/tools/read-tools.js.map +1 -0
  98. package/dist/assistant/tools/seo-tools.d.ts +4 -0
  99. package/dist/assistant/tools/seo-tools.d.ts.map +1 -0
  100. package/dist/assistant/tools/seo-tools.js +152 -0
  101. package/dist/assistant/tools/seo-tools.js.map +1 -0
  102. package/dist/assistant/tools/support.d.ts +35 -0
  103. package/dist/assistant/tools/support.d.ts.map +1 -0
  104. package/dist/assistant/tools/support.js +63 -0
  105. package/dist/assistant/tools/support.js.map +1 -0
  106. package/dist/assistant/untrusted.d.ts +15 -0
  107. package/dist/assistant/untrusted.d.ts.map +1 -0
  108. package/dist/assistant/untrusted.js +27 -0
  109. package/dist/assistant/untrusted.js.map +1 -0
  110. package/dist/assistant/write-policy.d.ts +20 -0
  111. package/dist/assistant/write-policy.d.ts.map +1 -0
  112. package/dist/assistant/write-policy.js +32 -0
  113. package/dist/assistant/write-policy.js.map +1 -0
  114. package/dist/auth-tokens.d.ts +31 -0
  115. package/dist/auth-tokens.d.ts.map +1 -0
  116. package/dist/auth-tokens.js +35 -0
  117. package/dist/auth-tokens.js.map +1 -0
  118. package/dist/content-change.d.ts +16 -0
  119. package/dist/content-change.d.ts.map +1 -0
  120. package/dist/content-change.js +34 -0
  121. package/dist/content-change.js.map +1 -0
  122. package/dist/content-locks.d.ts +27 -0
  123. package/dist/content-locks.d.ts.map +1 -0
  124. package/dist/content-locks.js +40 -0
  125. package/dist/content-locks.js.map +1 -0
  126. package/dist/cookies.d.ts +19 -0
  127. package/dist/cookies.d.ts.map +1 -0
  128. package/dist/cookies.js +52 -0
  129. package/dist/cookies.js.map +1 -0
  130. package/dist/create-api-handlers.d.ts +128 -0
  131. package/dist/create-api-handlers.d.ts.map +1 -0
  132. package/dist/create-api-handlers.js +384 -0
  133. package/dist/create-api-handlers.js.map +1 -0
  134. package/dist/document-actions.d.ts +25 -0
  135. package/dist/document-actions.d.ts.map +1 -0
  136. package/dist/document-actions.js +157 -0
  137. package/dist/document-actions.js.map +1 -0
  138. package/dist/document-seo.d.ts +15 -0
  139. package/dist/document-seo.d.ts.map +1 -0
  140. package/dist/document-seo.js +41 -0
  141. package/dist/document-seo.js.map +1 -0
  142. package/dist/group-by-collection.d.ts +6 -0
  143. package/dist/group-by-collection.d.ts.map +1 -0
  144. package/dist/group-by-collection.js +11 -0
  145. package/dist/group-by-collection.js.map +1 -0
  146. package/dist/handlers/apply-metadata-defaults.d.ts +4 -0
  147. package/dist/handlers/apply-metadata-defaults.d.ts.map +1 -0
  148. package/dist/handlers/apply-metadata-defaults.js +108 -0
  149. package/dist/handlers/apply-metadata-defaults.js.map +1 -0
  150. package/dist/handlers/auth-callback.d.ts +4 -0
  151. package/dist/handlers/auth-callback.d.ts.map +1 -0
  152. package/dist/handlers/auth-callback.js +217 -0
  153. package/dist/handlers/auth-callback.js.map +1 -0
  154. package/dist/handlers/auth-capabilities.d.ts +4 -0
  155. package/dist/handlers/auth-capabilities.d.ts.map +1 -0
  156. package/dist/handlers/auth-capabilities.js +19 -0
  157. package/dist/handlers/auth-capabilities.js.map +1 -0
  158. package/dist/handlers/auth-login.d.ts +4 -0
  159. package/dist/handlers/auth-login.d.ts.map +1 -0
  160. package/dist/handlers/auth-login.js +60 -0
  161. package/dist/handlers/auth-login.js.map +1 -0
  162. package/dist/handlers/auth-logout.d.ts +4 -0
  163. package/dist/handlers/auth-logout.d.ts.map +1 -0
  164. package/dist/handlers/auth-logout.js +40 -0
  165. package/dist/handlers/auth-logout.js.map +1 -0
  166. package/dist/handlers/auth-me.d.ts +4 -0
  167. package/dist/handlers/auth-me.d.ts.map +1 -0
  168. package/dist/handlers/auth-me.js +54 -0
  169. package/dist/handlers/auth-me.js.map +1 -0
  170. package/dist/handlers/auth-oidc-login.d.ts +4 -0
  171. package/dist/handlers/auth-oidc-login.d.ts.map +1 -0
  172. package/dist/handlers/auth-oidc-login.js +51 -0
  173. package/dist/handlers/auth-oidc-login.js.map +1 -0
  174. package/dist/handlers/auth-refresh.d.ts +15 -0
  175. package/dist/handlers/auth-refresh.d.ts.map +1 -0
  176. package/dist/handlers/auth-refresh.js +82 -0
  177. package/dist/handlers/auth-refresh.js.map +1 -0
  178. package/dist/handlers/bulk-delete.d.ts +8 -0
  179. package/dist/handlers/bulk-delete.d.ts.map +1 -0
  180. package/dist/handlers/bulk-delete.js +72 -0
  181. package/dist/handlers/bulk-delete.js.map +1 -0
  182. package/dist/handlers/bulk-publish.d.ts +8 -0
  183. package/dist/handlers/bulk-publish.d.ts.map +1 -0
  184. package/dist/handlers/bulk-publish.js +48 -0
  185. package/dist/handlers/bulk-publish.js.map +1 -0
  186. package/dist/handlers/capabilities.d.ts +4 -0
  187. package/dist/handlers/capabilities.d.ts.map +1 -0
  188. package/dist/handlers/capabilities.js +44 -0
  189. package/dist/handlers/capabilities.js.map +1 -0
  190. package/dist/handlers/content-changes.d.ts +28 -0
  191. package/dist/handlers/content-changes.d.ts.map +1 -0
  192. package/dist/handlers/content-changes.js +160 -0
  193. package/dist/handlers/content-changes.js.map +1 -0
  194. package/dist/handlers/content-lock.d.ts +13 -0
  195. package/dist/handlers/content-lock.d.ts.map +1 -0
  196. package/dist/handlers/content-lock.js +109 -0
  197. package/dist/handlers/content-lock.js.map +1 -0
  198. package/dist/handlers/content-tree.d.ts +11 -0
  199. package/dist/handlers/content-tree.d.ts.map +1 -0
  200. package/dist/handlers/content-tree.js +28 -0
  201. package/dist/handlers/content-tree.js.map +1 -0
  202. package/dist/handlers/create-content.d.ts +4 -0
  203. package/dist/handlers/create-content.d.ts.map +1 -0
  204. package/dist/handlers/create-content.js +49 -0
  205. package/dist/handlers/create-content.js.map +1 -0
  206. package/dist/handlers/delete-content.d.ts +4 -0
  207. package/dist/handlers/delete-content.d.ts.map +1 -0
  208. package/dist/handlers/delete-content.js +17 -0
  209. package/dist/handlers/delete-content.js.map +1 -0
  210. package/dist/handlers/delete-runtime-field.d.ts +4 -0
  211. package/dist/handlers/delete-runtime-field.d.ts.map +1 -0
  212. package/dist/handlers/delete-runtime-field.js +43 -0
  213. package/dist/handlers/delete-runtime-field.js.map +1 -0
  214. package/dist/handlers/export-bundle.d.ts +13 -0
  215. package/dist/handlers/export-bundle.d.ts.map +1 -0
  216. package/dist/handlers/export-bundle.js +99 -0
  217. package/dist/handlers/export-bundle.js.map +1 -0
  218. package/dist/handlers/export-content.d.ts +7 -0
  219. package/dist/handlers/export-content.d.ts.map +1 -0
  220. package/dist/handlers/export-content.js +69 -0
  221. package/dist/handlers/export-content.js.map +1 -0
  222. package/dist/handlers/export-schema.d.ts +4 -0
  223. package/dist/handlers/export-schema.d.ts.map +1 -0
  224. package/dist/handlers/export-schema.js +13 -0
  225. package/dist/handlers/export-schema.js.map +1 -0
  226. package/dist/handlers/get-content.d.ts +4 -0
  227. package/dist/handlers/get-content.d.ts.map +1 -0
  228. package/dist/handlers/get-content.js +65 -0
  229. package/dist/handlers/get-content.js.map +1 -0
  230. package/dist/handlers/get-runtime-schema.d.ts +4 -0
  231. package/dist/handlers/get-runtime-schema.d.ts.map +1 -0
  232. package/dist/handlers/get-runtime-schema.js +17 -0
  233. package/dist/handlers/get-runtime-schema.js.map +1 -0
  234. package/dist/handlers/get-schema.d.ts +4 -0
  235. package/dist/handlers/get-schema.d.ts.map +1 -0
  236. package/dist/handlers/get-schema.js +87 -0
  237. package/dist/handlers/get-schema.js.map +1 -0
  238. package/dist/handlers/get-version.d.ts +4 -0
  239. package/dist/handlers/get-version.d.ts.map +1 -0
  240. package/dist/handlers/get-version.js +26 -0
  241. package/dist/handlers/get-version.js.map +1 -0
  242. package/dist/handlers/import-bundle.d.ts +4 -0
  243. package/dist/handlers/import-bundle.d.ts.map +1 -0
  244. package/dist/handlers/import-bundle.js +55 -0
  245. package/dist/handlers/import-bundle.js.map +1 -0
  246. package/dist/handlers/import-content.d.ts +4 -0
  247. package/dist/handlers/import-content.d.ts.map +1 -0
  248. package/dist/handlers/import-content.js +152 -0
  249. package/dist/handlers/import-content.js.map +1 -0
  250. package/dist/handlers/index.d.ts +87 -0
  251. package/dist/handlers/index.d.ts.map +1 -0
  252. package/dist/handlers/index.js +87 -0
  253. package/dist/handlers/index.js.map +1 -0
  254. package/dist/handlers/list-collection.d.ts +8 -0
  255. package/dist/handlers/list-collection.d.ts.map +1 -0
  256. package/dist/handlers/list-collection.js +14 -0
  257. package/dist/handlers/list-collection.js.map +1 -0
  258. package/dist/handlers/list-collections.d.ts +4 -0
  259. package/dist/handlers/list-collections.d.ts.map +1 -0
  260. package/dist/handlers/list-collections.js +17 -0
  261. package/dist/handlers/list-collections.js.map +1 -0
  262. package/dist/handlers/list-content.d.ts +8 -0
  263. package/dist/handlers/list-content.d.ts.map +1 -0
  264. package/dist/handlers/list-content.js +22 -0
  265. package/dist/handlers/list-content.js.map +1 -0
  266. package/dist/handlers/list-query.d.ts +7 -0
  267. package/dist/handlers/list-query.d.ts.map +1 -0
  268. package/dist/handlers/list-query.js +36 -0
  269. package/dist/handlers/list-query.js.map +1 -0
  270. package/dist/handlers/list-versions.d.ts +4 -0
  271. package/dist/handlers/list-versions.d.ts.map +1 -0
  272. package/dist/handlers/list-versions.js +19 -0
  273. package/dist/handlers/list-versions.js.map +1 -0
  274. package/dist/handlers/llm-credential.d.ts +46 -0
  275. package/dist/handlers/llm-credential.d.ts.map +1 -0
  276. package/dist/handlers/llm-credential.js +68 -0
  277. package/dist/handlers/llm-credential.js.map +1 -0
  278. package/dist/handlers/llm-resolve.d.ts +45 -0
  279. package/dist/handlers/llm-resolve.d.ts.map +1 -0
  280. package/dist/handlers/llm-resolve.js +126 -0
  281. package/dist/handlers/llm-resolve.js.map +1 -0
  282. package/dist/handlers/llm-settings.d.ts +19 -0
  283. package/dist/handlers/llm-settings.d.ts.map +1 -0
  284. package/dist/handlers/llm-settings.js +209 -0
  285. package/dist/handlers/llm-settings.js.map +1 -0
  286. package/dist/handlers/media-bulk-delete.d.ts +4 -0
  287. package/dist/handlers/media-bulk-delete.d.ts.map +1 -0
  288. package/dist/handlers/media-bulk-delete.js +19 -0
  289. package/dist/handlers/media-bulk-delete.js.map +1 -0
  290. package/dist/handlers/media-bulk-update.d.ts +4 -0
  291. package/dist/handlers/media-bulk-update.d.ts.map +1 -0
  292. package/dist/handlers/media-bulk-update.js +25 -0
  293. package/dist/handlers/media-bulk-update.js.map +1 -0
  294. package/dist/handlers/media-delete.d.ts +4 -0
  295. package/dist/handlers/media-delete.d.ts.map +1 -0
  296. package/dist/handlers/media-delete.js +27 -0
  297. package/dist/handlers/media-delete.js.map +1 -0
  298. package/dist/handlers/media-duplicate.d.ts +4 -0
  299. package/dist/handlers/media-duplicate.d.ts.map +1 -0
  300. package/dist/handlers/media-duplicate.js +20 -0
  301. package/dist/handlers/media-duplicate.js.map +1 -0
  302. package/dist/handlers/media-folders.d.ts +12 -0
  303. package/dist/handlers/media-folders.d.ts.map +1 -0
  304. package/dist/handlers/media-folders.js +119 -0
  305. package/dist/handlers/media-folders.js.map +1 -0
  306. package/dist/handlers/media-get.d.ts +4 -0
  307. package/dist/handlers/media-get.d.ts.map +1 -0
  308. package/dist/handlers/media-get.js +16 -0
  309. package/dist/handlers/media-get.js.map +1 -0
  310. package/dist/handlers/media-image-info.d.ts +4 -0
  311. package/dist/handlers/media-image-info.d.ts.map +1 -0
  312. package/dist/handlers/media-image-info.js +32 -0
  313. package/dist/handlers/media-image-info.js.map +1 -0
  314. package/dist/handlers/media-image.d.ts +11 -0
  315. package/dist/handlers/media-image.d.ts.map +1 -0
  316. package/dist/handlers/media-image.js +116 -0
  317. package/dist/handlers/media-image.js.map +1 -0
  318. package/dist/handlers/media-info.d.ts +4 -0
  319. package/dist/handlers/media-info.d.ts.map +1 -0
  320. package/dist/handlers/media-info.js +18 -0
  321. package/dist/handlers/media-info.js.map +1 -0
  322. package/dist/handlers/media-list.d.ts +4 -0
  323. package/dist/handlers/media-list.d.ts.map +1 -0
  324. package/dist/handlers/media-list.js +14 -0
  325. package/dist/handlers/media-list.js.map +1 -0
  326. package/dist/handlers/media-register.d.ts +4 -0
  327. package/dist/handlers/media-register.d.ts.map +1 -0
  328. package/dist/handlers/media-register.js +57 -0
  329. package/dist/handlers/media-register.js.map +1 -0
  330. package/dist/handlers/media-replace.d.ts +9 -0
  331. package/dist/handlers/media-replace.d.ts.map +1 -0
  332. package/dist/handlers/media-replace.js +53 -0
  333. package/dist/handlers/media-replace.js.map +1 -0
  334. package/dist/handlers/media-tags.d.ts +4 -0
  335. package/dist/handlers/media-tags.d.ts.map +1 -0
  336. package/dist/handlers/media-tags.js +9 -0
  337. package/dist/handlers/media-tags.js.map +1 -0
  338. package/dist/handlers/media-update.d.ts +4 -0
  339. package/dist/handlers/media-update.d.ts.map +1 -0
  340. package/dist/handlers/media-update.js +64 -0
  341. package/dist/handlers/media-update.js.map +1 -0
  342. package/dist/handlers/media-upload.d.ts +4 -0
  343. package/dist/handlers/media-upload.d.ts.map +1 -0
  344. package/dist/handlers/media-upload.js +26 -0
  345. package/dist/handlers/media-upload.js.map +1 -0
  346. package/dist/handlers/media-usage.d.ts +9 -0
  347. package/dist/handlers/media-usage.d.ts.map +1 -0
  348. package/dist/handlers/media-usage.js +36 -0
  349. package/dist/handlers/media-usage.js.map +1 -0
  350. package/dist/handlers/migration-conflicts.d.ts +13 -0
  351. package/dist/handlers/migration-conflicts.d.ts.map +1 -0
  352. package/dist/handlers/migration-conflicts.js +55 -0
  353. package/dist/handlers/migration-conflicts.js.map +1 -0
  354. package/dist/handlers/migration-status.d.ts +4 -0
  355. package/dist/handlers/migration-status.d.ts.map +1 -0
  356. package/dist/handlers/migration-status.js +34 -0
  357. package/dist/handlers/migration-status.js.map +1 -0
  358. package/dist/handlers/publish-content.d.ts +9 -0
  359. package/dist/handlers/publish-content.d.ts.map +1 -0
  360. package/dist/handlers/publish-content.js +47 -0
  361. package/dist/handlers/publish-content.js.map +1 -0
  362. package/dist/handlers/publish-impact.d.ts +11 -0
  363. package/dist/handlers/publish-impact.d.ts.map +1 -0
  364. package/dist/handlers/publish-impact.js +44 -0
  365. package/dist/handlers/publish-impact.js.map +1 -0
  366. package/dist/handlers/resolve-page.d.ts +9 -0
  367. package/dist/handlers/resolve-page.d.ts.map +1 -0
  368. package/dist/handlers/resolve-page.js +105 -0
  369. package/dist/handlers/resolve-page.js.map +1 -0
  370. package/dist/handlers/restore-version.d.ts +4 -0
  371. package/dist/handlers/restore-version.d.ts.map +1 -0
  372. package/dist/handlers/restore-version.js +69 -0
  373. package/dist/handlers/restore-version.js.map +1 -0
  374. package/dist/handlers/runtime-metadata.d.ts +6 -0
  375. package/dist/handlers/runtime-metadata.d.ts.map +1 -0
  376. package/dist/handlers/runtime-metadata.js +82 -0
  377. package/dist/handlers/runtime-metadata.js.map +1 -0
  378. package/dist/handlers/save-runtime-field.d.ts +4 -0
  379. package/dist/handlers/save-runtime-field.d.ts.map +1 -0
  380. package/dist/handlers/save-runtime-field.js +108 -0
  381. package/dist/handlers/save-runtime-field.js.map +1 -0
  382. package/dist/handlers/search-content.d.ts +9 -0
  383. package/dist/handlers/search-content.d.ts.map +1 -0
  384. package/dist/handlers/search-content.js +40 -0
  385. package/dist/handlers/search-content.js.map +1 -0
  386. package/dist/handlers/seo-config.d.ts +16 -0
  387. package/dist/handlers/seo-config.d.ts.map +1 -0
  388. package/dist/handlers/seo-config.js +250 -0
  389. package/dist/handlers/seo-config.js.map +1 -0
  390. package/dist/handlers/seo-document.d.ts +24 -0
  391. package/dist/handlers/seo-document.d.ts.map +1 -0
  392. package/dist/handlers/seo-document.js +119 -0
  393. package/dist/handlers/seo-document.js.map +1 -0
  394. package/dist/handlers/seo-enrich-archetype.d.ts +71 -0
  395. package/dist/handlers/seo-enrich-archetype.d.ts.map +1 -0
  396. package/dist/handlers/seo-enrich-archetype.js +250 -0
  397. package/dist/handlers/seo-enrich-archetype.js.map +1 -0
  398. package/dist/handlers/seo-enrich-meta.d.ts +40 -0
  399. package/dist/handlers/seo-enrich-meta.d.ts.map +1 -0
  400. package/dist/handlers/seo-enrich-meta.js +121 -0
  401. package/dist/handlers/seo-enrich-meta.js.map +1 -0
  402. package/dist/handlers/seo-enrich-runner.d.ts +65 -0
  403. package/dist/handlers/seo-enrich-runner.d.ts.map +1 -0
  404. package/dist/handlers/seo-enrich-runner.js +192 -0
  405. package/dist/handlers/seo-enrich-runner.js.map +1 -0
  406. package/dist/handlers/seo-enrich.d.ts +10 -0
  407. package/dist/handlers/seo-enrich.d.ts.map +1 -0
  408. package/dist/handlers/seo-enrich.js +166 -0
  409. package/dist/handlers/seo-enrich.js.map +1 -0
  410. package/dist/handlers/seo-generate.d.ts +4 -0
  411. package/dist/handlers/seo-generate.d.ts.map +1 -0
  412. package/dist/handlers/seo-generate.js +31 -0
  413. package/dist/handlers/seo-generate.js.map +1 -0
  414. package/dist/handlers/seo-impact.d.ts +36 -0
  415. package/dist/handlers/seo-impact.d.ts.map +1 -0
  416. package/dist/handlers/seo-impact.js +137 -0
  417. package/dist/handlers/seo-impact.js.map +1 -0
  418. package/dist/handlers/seo-indexnow.d.ts +11 -0
  419. package/dist/handlers/seo-indexnow.d.ts.map +1 -0
  420. package/dist/handlers/seo-indexnow.js +15 -0
  421. package/dist/handlers/seo-indexnow.js.map +1 -0
  422. package/dist/handlers/seo-llms-txt.d.ts +26 -0
  423. package/dist/handlers/seo-llms-txt.d.ts.map +1 -0
  424. package/dist/handlers/seo-llms-txt.js +99 -0
  425. package/dist/handlers/seo-llms-txt.js.map +1 -0
  426. package/dist/handlers/seo-preview.d.ts +8 -0
  427. package/dist/handlers/seo-preview.d.ts.map +1 -0
  428. package/dist/handlers/seo-preview.js +49 -0
  429. package/dist/handlers/seo-preview.js.map +1 -0
  430. package/dist/handlers/seo-robots.d.ts +22 -0
  431. package/dist/handlers/seo-robots.d.ts.map +1 -0
  432. package/dist/handlers/seo-robots.js +48 -0
  433. package/dist/handlers/seo-robots.js.map +1 -0
  434. package/dist/handlers/seo-sitemap.d.ts +68 -0
  435. package/dist/handlers/seo-sitemap.d.ts.map +1 -0
  436. package/dist/handlers/seo-sitemap.js +178 -0
  437. package/dist/handlers/seo-sitemap.js.map +1 -0
  438. package/dist/handlers/seo-status.d.ts +4 -0
  439. package/dist/handlers/seo-status.d.ts.map +1 -0
  440. package/dist/handlers/seo-status.js +61 -0
  441. package/dist/handlers/seo-status.js.map +1 -0
  442. package/dist/handlers/seo-structured-data.d.ts +4 -0
  443. package/dist/handlers/seo-structured-data.d.ts.map +1 -0
  444. package/dist/handlers/seo-structured-data.js +18 -0
  445. package/dist/handlers/seo-structured-data.js.map +1 -0
  446. package/dist/handlers/site-config.d.ts +8 -0
  447. package/dist/handlers/site-config.d.ts.map +1 -0
  448. package/dist/handlers/site-config.js +26 -0
  449. package/dist/handlers/site-config.js.map +1 -0
  450. package/dist/handlers/site-preview.d.ts +10 -0
  451. package/dist/handlers/site-preview.d.ts.map +1 -0
  452. package/dist/handlers/site-preview.js +54 -0
  453. package/dist/handlers/site-preview.js.map +1 -0
  454. package/dist/handlers/site-settings.d.ts +17 -0
  455. package/dist/handlers/site-settings.d.ts.map +1 -0
  456. package/dist/handlers/site-settings.js +75 -0
  457. package/dist/handlers/site-settings.js.map +1 -0
  458. package/dist/handlers/snapshot-create.d.ts +4 -0
  459. package/dist/handlers/snapshot-create.d.ts.map +1 -0
  460. package/dist/handlers/snapshot-create.js +15 -0
  461. package/dist/handlers/snapshot-create.js.map +1 -0
  462. package/dist/handlers/snapshot-delete.d.ts +4 -0
  463. package/dist/handlers/snapshot-delete.d.ts.map +1 -0
  464. package/dist/handlers/snapshot-delete.js +21 -0
  465. package/dist/handlers/snapshot-delete.js.map +1 -0
  466. package/dist/handlers/snapshot-get.d.ts +4 -0
  467. package/dist/handlers/snapshot-get.d.ts.map +1 -0
  468. package/dist/handlers/snapshot-get.js +17 -0
  469. package/dist/handlers/snapshot-get.js.map +1 -0
  470. package/dist/handlers/snapshot-list.d.ts +4 -0
  471. package/dist/handlers/snapshot-list.d.ts.map +1 -0
  472. package/dist/handlers/snapshot-list.js +9 -0
  473. package/dist/handlers/snapshot-list.js.map +1 -0
  474. package/dist/handlers/snapshot-restore.d.ts +4 -0
  475. package/dist/handlers/snapshot-restore.d.ts.map +1 -0
  476. package/dist/handlers/snapshot-restore.js +27 -0
  477. package/dist/handlers/snapshot-restore.js.map +1 -0
  478. package/dist/handlers/translation-status.d.ts +9 -0
  479. package/dist/handlers/translation-status.d.ts.map +1 -0
  480. package/dist/handlers/translation-status.js +68 -0
  481. package/dist/handlers/translation-status.js.map +1 -0
  482. package/dist/handlers/update-content.d.ts +4 -0
  483. package/dist/handlers/update-content.d.ts.map +1 -0
  484. package/dist/handlers/update-content.js +66 -0
  485. package/dist/handlers/update-content.js.map +1 -0
  486. package/dist/handlers/user-create.d.ts +4 -0
  487. package/dist/handlers/user-create.d.ts.map +1 -0
  488. package/dist/handlers/user-create.js +38 -0
  489. package/dist/handlers/user-create.js.map +1 -0
  490. package/dist/handlers/user-delete.d.ts +4 -0
  491. package/dist/handlers/user-delete.d.ts.map +1 -0
  492. package/dist/handlers/user-delete.js +25 -0
  493. package/dist/handlers/user-delete.js.map +1 -0
  494. package/dist/handlers/user-get.d.ts +4 -0
  495. package/dist/handlers/user-get.d.ts.map +1 -0
  496. package/dist/handlers/user-get.js +22 -0
  497. package/dist/handlers/user-get.js.map +1 -0
  498. package/dist/handlers/user-list.d.ts +4 -0
  499. package/dist/handlers/user-list.d.ts.map +1 -0
  500. package/dist/handlers/user-list.js +28 -0
  501. package/dist/handlers/user-list.js.map +1 -0
  502. package/dist/handlers/user-permissions.d.ts +6 -0
  503. package/dist/handlers/user-permissions.d.ts.map +1 -0
  504. package/dist/handlers/user-permissions.js +42 -0
  505. package/dist/handlers/user-permissions.js.map +1 -0
  506. package/dist/handlers/user-update.d.ts +4 -0
  507. package/dist/handlers/user-update.d.ts.map +1 -0
  508. package/dist/handlers/user-update.js +54 -0
  509. package/dist/handlers/user-update.js.map +1 -0
  510. package/dist/handlers/validate-all.d.ts +4 -0
  511. package/dist/handlers/validate-all.d.ts.map +1 -0
  512. package/dist/handlers/validate-all.js +14 -0
  513. package/dist/handlers/validate-all.js.map +1 -0
  514. package/dist/handlers/version-retention.d.ts +6 -0
  515. package/dist/handlers/version-retention.d.ts.map +1 -0
  516. package/dist/handlers/version-retention.js +40 -0
  517. package/dist/handlers/version-retention.js.map +1 -0
  518. package/dist/handlers/webhook-deliveries.d.ts +4 -0
  519. package/dist/handlers/webhook-deliveries.d.ts.map +1 -0
  520. package/dist/handlers/webhook-deliveries.js +24 -0
  521. package/dist/handlers/webhook-deliveries.js.map +1 -0
  522. package/dist/handlers/webhook-retry.d.ts +11 -0
  523. package/dist/handlers/webhook-retry.d.ts.map +1 -0
  524. package/dist/handlers/webhook-retry.js +69 -0
  525. package/dist/handlers/webhook-retry.js.map +1 -0
  526. package/dist/head.d.ts +9 -0
  527. package/dist/head.d.ts.map +1 -0
  528. package/dist/head.js +28 -0
  529. package/dist/head.js.map +1 -0
  530. package/dist/hooks.d.ts +34 -0
  531. package/dist/hooks.d.ts.map +1 -0
  532. package/dist/hooks.js +19 -0
  533. package/dist/hooks.js.map +1 -0
  534. package/dist/image-cache.d.ts +47 -0
  535. package/dist/image-cache.d.ts.map +1 -0
  536. package/dist/image-cache.js +112 -0
  537. package/dist/image-cache.js.map +1 -0
  538. package/dist/image-dimensions.d.ts +12 -0
  539. package/dist/image-dimensions.d.ts.map +1 -0
  540. package/dist/image-dimensions.js +129 -0
  541. package/dist/image-dimensions.js.map +1 -0
  542. package/dist/image-optimizer.d.ts +86 -0
  543. package/dist/image-optimizer.d.ts.map +1 -0
  544. package/dist/image-optimizer.js +206 -0
  545. package/dist/image-optimizer.js.map +1 -0
  546. package/dist/image-presets.d.ts +17 -0
  547. package/dist/image-presets.d.ts.map +1 -0
  548. package/dist/image-presets.js +50 -0
  549. package/dist/image-presets.js.map +1 -0
  550. package/dist/image-url.d.ts +26 -0
  551. package/dist/image-url.d.ts.map +1 -0
  552. package/dist/image-url.js +47 -0
  553. package/dist/image-url.js.map +1 -0
  554. package/dist/index.d.ts +37 -0
  555. package/dist/index.d.ts.map +1 -0
  556. package/dist/index.js +23 -0
  557. package/dist/index.js.map +1 -0
  558. package/dist/jwt.d.ts +54 -0
  559. package/dist/jwt.d.ts.map +1 -0
  560. package/dist/jwt.js +114 -0
  561. package/dist/jwt.js.map +1 -0
  562. package/dist/locale-fallback.d.ts +18 -0
  563. package/dist/locale-fallback.d.ts.map +1 -0
  564. package/dist/locale-fallback.js +42 -0
  565. package/dist/locale-fallback.js.map +1 -0
  566. package/dist/media-library.d.ts +46 -0
  567. package/dist/media-library.d.ts.map +1 -0
  568. package/dist/media-library.js +231 -0
  569. package/dist/media-library.js.map +1 -0
  570. package/dist/media-reference-updater.d.ts +24 -0
  571. package/dist/media-reference-updater.d.ts.map +1 -0
  572. package/dist/media-reference-updater.js +124 -0
  573. package/dist/media-reference-updater.js.map +1 -0
  574. package/dist/media-references.d.ts +14 -0
  575. package/dist/media-references.d.ts.map +1 -0
  576. package/dist/media-references.js +25 -0
  577. package/dist/media-references.js.map +1 -0
  578. package/dist/merged-schema.d.ts +10 -0
  579. package/dist/merged-schema.d.ts.map +1 -0
  580. package/dist/merged-schema.js +21 -0
  581. package/dist/merged-schema.js.map +1 -0
  582. package/dist/middleware/auth.d.ts +21 -0
  583. package/dist/middleware/auth.d.ts.map +1 -0
  584. package/dist/middleware/auth.js +82 -0
  585. package/dist/middleware/auth.js.map +1 -0
  586. package/dist/oidc-state.d.ts +42 -0
  587. package/dist/oidc-state.d.ts.map +1 -0
  588. package/dist/oidc-state.js +72 -0
  589. package/dist/oidc-state.js.map +1 -0
  590. package/dist/oidc.d.ts +83 -0
  591. package/dist/oidc.d.ts.map +1 -0
  592. package/dist/oidc.js +226 -0
  593. package/dist/oidc.js.map +1 -0
  594. package/dist/openapi.d.ts +13 -0
  595. package/dist/openapi.d.ts.map +1 -0
  596. package/dist/openapi.js +133 -0
  597. package/dist/openapi.js.map +1 -0
  598. package/dist/permissions.d.ts +37 -0
  599. package/dist/permissions.d.ts.map +1 -0
  600. package/dist/permissions.js +69 -0
  601. package/dist/permissions.js.map +1 -0
  602. package/dist/plugins.d.ts +64 -0
  603. package/dist/plugins.d.ts.map +1 -0
  604. package/dist/plugins.js +73 -0
  605. package/dist/plugins.js.map +1 -0
  606. package/dist/preview-token.d.ts +13 -0
  607. package/dist/preview-token.d.ts.map +1 -0
  608. package/dist/preview-token.js +45 -0
  609. package/dist/preview-token.js.map +1 -0
  610. package/dist/public-cache.d.ts +8 -0
  611. package/dist/public-cache.d.ts.map +1 -0
  612. package/dist/public-cache.js +8 -0
  613. package/dist/public-cache.js.map +1 -0
  614. package/dist/reference-resolver.d.ts +21 -0
  615. package/dist/reference-resolver.d.ts.map +1 -0
  616. package/dist/reference-resolver.js +128 -0
  617. package/dist/reference-resolver.js.map +1 -0
  618. package/dist/return-to.d.ts +7 -0
  619. package/dist/return-to.d.ts.map +1 -0
  620. package/dist/return-to.js +15 -0
  621. package/dist/return-to.js.map +1 -0
  622. package/dist/router.d.ts +14 -0
  623. package/dist/router.d.ts.map +1 -0
  624. package/dist/router.js +51 -0
  625. package/dist/router.js.map +1 -0
  626. package/dist/runtime-field-checks.d.ts +11 -0
  627. package/dist/runtime-field-checks.d.ts.map +1 -0
  628. package/dist/runtime-field-checks.js +72 -0
  629. package/dist/runtime-field-checks.js.map +1 -0
  630. package/dist/save-document.d.ts +71 -0
  631. package/dist/save-document.d.ts.map +1 -0
  632. package/dist/save-document.js +213 -0
  633. package/dist/save-document.js.map +1 -0
  634. package/dist/seo-compose.d.ts +50 -0
  635. package/dist/seo-compose.d.ts.map +1 -0
  636. package/dist/seo-compose.js +104 -0
  637. package/dist/seo-compose.js.map +1 -0
  638. package/dist/seo-config-snapshot.d.ts +10 -0
  639. package/dist/seo-config-snapshot.d.ts.map +1 -0
  640. package/dist/seo-config-snapshot.js +16 -0
  641. package/dist/seo-config-snapshot.js.map +1 -0
  642. package/dist/seo-loader.d.ts +10 -0
  643. package/dist/seo-loader.d.ts.map +1 -0
  644. package/dist/seo-loader.js +14 -0
  645. package/dist/seo-loader.js.map +1 -0
  646. package/dist/seo-site-findings.d.ts +27 -0
  647. package/dist/seo-site-findings.d.ts.map +1 -0
  648. package/dist/seo-site-findings.js +87 -0
  649. package/dist/seo-site-findings.js.map +1 -0
  650. package/dist/seo-subsystem.d.ts +28 -0
  651. package/dist/seo-subsystem.d.ts.map +1 -0
  652. package/dist/seo-subsystem.js +62 -0
  653. package/dist/seo-subsystem.js.map +1 -0
  654. package/dist/seo-validation.d.ts +20 -0
  655. package/dist/seo-validation.d.ts.map +1 -0
  656. package/dist/seo-validation.js +96 -0
  657. package/dist/seo-validation.js.map +1 -0
  658. package/dist/types.d.ts +126 -0
  659. package/dist/types.d.ts.map +1 -0
  660. package/dist/types.js +6 -0
  661. package/dist/types.js.map +1 -0
  662. package/dist/validators.d.ts +107 -0
  663. package/dist/validators.d.ts.map +1 -0
  664. package/dist/validators.js +199 -0
  665. package/dist/validators.js.map +1 -0
  666. package/dist/webhooks.d.ts +29 -0
  667. package/dist/webhooks.d.ts.map +1 -0
  668. package/dist/webhooks.js +123 -0
  669. package/dist/webhooks.js.map +1 -0
  670. package/dist/workload-identity.d.ts +23 -0
  671. package/dist/workload-identity.d.ts.map +1 -0
  672. package/dist/workload-identity.js +145 -0
  673. package/dist/workload-identity.js.map +1 -0
  674. package/package.json +50 -3
  675. package/README.md +0 -3
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Collection impact analysis handler.
3
+ *
4
+ * Evaluates the impact of changing a collection's archetype by scanning
5
+ * all documents and identifying orphaned properties (currently set but
6
+ * unsupported under the new archetype) and missing required properties
7
+ * (required under the new archetype but not currently set).
8
+ *
9
+ * GET /api/seo/collection/:name/impact?archetype=preset-name
10
+ */
11
+ import type { ApiHandler } from '../types.js';
12
+ export interface ImpactResponse {
13
+ archetype: string;
14
+ totalDocuments: number;
15
+ affectedDocuments: Array<{
16
+ slug: string;
17
+ title: string;
18
+ orphanedProperties: Array<{
19
+ entityType: string;
20
+ property: string;
21
+ value: unknown;
22
+ }>;
23
+ missingRequired: Array<{
24
+ entityType: string;
25
+ property: string;
26
+ }>;
27
+ }>;
28
+ summary: {
29
+ documentsWithOrphans: number;
30
+ documentsWithMissingRequired: number;
31
+ totalOrphanedProperties: number;
32
+ totalMissingRequired: number;
33
+ };
34
+ }
35
+ export declare const seoCollectionImpact: ApiHandler;
36
+ //# sourceMappingURL=seo-impact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-impact.d.ts","sourceRoot":"","sources":["../../src/handlers/seo-impact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,KAAK,CAAC;QACvB,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,kBAAkB,EAAE,KAAK,CAAC;YACxB,UAAU,EAAE,MAAM,CAAA;YAClB,QAAQ,EAAE,MAAM,CAAA;YAChB,KAAK,EAAE,OAAO,CAAA;SACf,CAAC,CAAA;QACF,eAAe,EAAE,KAAK,CAAC;YACrB,UAAU,EAAE,MAAM,CAAA;YAClB,QAAQ,EAAE,MAAM,CAAA;SACjB,CAAC,CAAA;KACH,CAAC,CAAA;IACF,OAAO,EAAE;QACP,oBAAoB,EAAE,MAAM,CAAA;QAC5B,4BAA4B,EAAE,MAAM,CAAA;QACpC,uBAAuB,EAAE,MAAM,CAAA;QAC/B,oBAAoB,EAAE,MAAM,CAAA;KAC7B,CAAA;CACF;AAED,eAAO,MAAM,mBAAmB,EAAE,UA4IjC,CAAA"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Collection impact analysis handler.
3
+ *
4
+ * Evaluates the impact of changing a collection's archetype by scanning
5
+ * all documents and identifying orphaned properties (currently set but
6
+ * unsupported under the new archetype) and missing required properties
7
+ * (required under the new archetype but not currently set).
8
+ *
9
+ * GET /api/seo/collection/:name/impact?archetype=preset-name
10
+ */
11
+ import { canQuery } from '@krantho/persistence';
12
+ import { requireRole } from '../permissions.js';
13
+ import { loadSeoModule } from '../seo-loader.js';
14
+ import { loadSeo } from '../seo-subsystem.js';
15
+ export const seoCollectionImpact = async (req, ctx) => {
16
+ const denied = requireRole(ctx.auth, 'admin');
17
+ if (denied)
18
+ return denied;
19
+ if (!ctx.seoConfigAdapter) {
20
+ return { status: 501, body: { error: 'SEO configuration not available' } };
21
+ }
22
+ const collectionName = req.params['name'];
23
+ if (!collectionName) {
24
+ return { status: 400, body: { error: 'Collection name required' } };
25
+ }
26
+ const archetypeName = req.query['archetype'];
27
+ if (!archetypeName) {
28
+ return { status: 400, body: { error: 'Archetype query parameter required' } };
29
+ }
30
+ // Dynamically import to avoid bundling @krantho/seo in the API
31
+ const seo = await loadSeoModule();
32
+ const { readers } = await loadSeo(ctx.config);
33
+ // Build the set of entity types in the proposed archetype
34
+ // For now, accept a comma-separated list of types as the archetype parameter
35
+ const proposedTypes = archetypeName
36
+ .split(',')
37
+ .map((t) => t.trim())
38
+ .filter(Boolean);
39
+ if (proposedTypes.length === 0) {
40
+ return { status: 400, body: { error: 'No types specified in archetype' } };
41
+ }
42
+ const proposedTypeSet = new Set(proposedTypes);
43
+ // The properties any active reader's rule for each type requires
44
+ const requiredByType = new Map();
45
+ for (const type of proposedTypes) {
46
+ const required = new Set();
47
+ for (const id of readers) {
48
+ const profile = seo.getProfile(id);
49
+ const rule = profile ? seo.ruleFor(profile, type) : undefined;
50
+ if (rule?.status === 'active' || rule?.status === 'restricted') {
51
+ for (const property of rule.required ?? [])
52
+ required.add(property);
53
+ }
54
+ }
55
+ if (required.size > 0)
56
+ requiredByType.set(type, [...required]);
57
+ }
58
+ // List all documents in the collection
59
+ if (!canQuery(ctx.adapter)) {
60
+ return { status: 501, body: { error: 'Collection listing not available' } };
61
+ }
62
+ const { items: documents } = await ctx.adapter.query({
63
+ state: 'current',
64
+ status: 'published',
65
+ projection: 'summary',
66
+ collections: [collectionName],
67
+ });
68
+ // Batch-load all document SEO configs for this collection in a single query
69
+ const docConfigs = await ctx.seoConfigAdapter.listConfigsByPrefix(`doc:${collectionName}/`);
70
+ const configBySlug = new Map();
71
+ for (const config of docConfigs) {
72
+ // Extract slug from config id: "doc:pages/home" → "home"
73
+ const slug = config.id.slice(`doc:${collectionName}/`.length);
74
+ configBySlug.set(slug, config);
75
+ }
76
+ const affectedDocuments = [];
77
+ for (const doc of documents) {
78
+ const docConfig = configBySlug.get(doc.meta.slug);
79
+ if (!docConfig)
80
+ continue;
81
+ const orphanedProperties = [];
82
+ const missingRequired = [];
83
+ // Find orphaned properties: properties on entities whose @type is not in the proposed archetype
84
+ for (const entity of docConfig.config.entities) {
85
+ if (!proposedTypeSet.has(entity['@type'])) {
86
+ // Entire entity is orphaned — list all its populated properties
87
+ for (const [prop, val] of Object.entries(entity.properties)) {
88
+ if (val !== undefined && val !== null && val !== '') {
89
+ orphanedProperties.push({
90
+ entityType: entity['@type'],
91
+ property: prop,
92
+ value: val,
93
+ });
94
+ }
95
+ }
96
+ }
97
+ }
98
+ // Find missing required: required properties under the proposed types that are not set
99
+ for (const type of proposedTypes) {
100
+ const required = requiredByType.get(type);
101
+ if (!required)
102
+ continue;
103
+ // Find matching entity in the doc's config
104
+ const docEntity = docConfig.config.entities.find((e) => e['@type'] === type);
105
+ for (const prop of required) {
106
+ const value = docEntity?.properties[prop];
107
+ if (value === undefined || value === null || value === '') {
108
+ missingRequired.push({ entityType: type, property: prop });
109
+ }
110
+ }
111
+ }
112
+ if (orphanedProperties.length > 0 || missingRequired.length > 0) {
113
+ const title = typeof doc.fields['title'] === 'string' ? doc.fields['title'] : doc.meta.slug;
114
+ affectedDocuments.push({
115
+ slug: doc.meta.slug,
116
+ title,
117
+ orphanedProperties,
118
+ missingRequired,
119
+ });
120
+ }
121
+ }
122
+ const summary = {
123
+ documentsWithOrphans: affectedDocuments.filter((d) => d.orphanedProperties.length > 0).length,
124
+ documentsWithMissingRequired: affectedDocuments.filter((d) => d.missingRequired.length > 0)
125
+ .length,
126
+ totalOrphanedProperties: affectedDocuments.reduce((sum, d) => sum + d.orphanedProperties.length, 0),
127
+ totalMissingRequired: affectedDocuments.reduce((sum, d) => sum + d.missingRequired.length, 0),
128
+ };
129
+ const response = {
130
+ archetype: archetypeName,
131
+ totalDocuments: documents.length,
132
+ affectedDocuments,
133
+ summary,
134
+ };
135
+ return { status: 200, body: response };
136
+ };
137
+ //# sourceMappingURL=seo-impact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-impact.js","sourceRoot":"","sources":["../../src/handlers/seo-impact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ApiHandler } from '../types.js';
2
+ /** The API path of the IndexNow key file; a site serves it at `/<key>.txt` */
3
+ export declare const SEO_INDEXNOW_KEY_PATH = "/api/seo/indexnow/:key";
4
+ /**
5
+ * GET /api/seo/indexnow/:key — the IndexNow key file. IndexNow reads it at
6
+ * `<site.baseUrl>/<key>.txt` to confirm the site owns the key, so the site
7
+ * routes that address here. Answers the key as plain text when it matches
8
+ * `seo.indexNow.key`, and 404 otherwise.
9
+ */
10
+ export declare const seoIndexNowKey: ApiHandler;
11
+ //# sourceMappingURL=seo-indexnow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-indexnow.d.ts","sourceRoot":"","sources":["../../src/handlers/seo-indexnow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,2BAA2B,CAAA;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,UAI5B,CAAA"}
@@ -0,0 +1,15 @@
1
+ /** The API path of the IndexNow key file; a site serves it at `/<key>.txt` */
2
+ export const SEO_INDEXNOW_KEY_PATH = '/api/seo/indexnow/:key';
3
+ /**
4
+ * GET /api/seo/indexnow/:key — the IndexNow key file. IndexNow reads it at
5
+ * `<site.baseUrl>/<key>.txt` to confirm the site owns the key, so the site
6
+ * routes that address here. Answers the key as plain text when it matches
7
+ * `seo.indexNow.key`, and 404 otherwise.
8
+ */
9
+ export const seoIndexNowKey = async (req, ctx) => {
10
+ const key = ctx.config.seo.indexNow.key;
11
+ if (!key || req.params['key'] !== key)
12
+ return { status: 404, body: { error: 'Not found' } };
13
+ return { status: 200, body: key, headers: { 'content-type': 'text/plain; charset=utf-8' } };
14
+ };
15
+ //# sourceMappingURL=seo-indexnow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-indexnow.js","sourceRoot":"","sources":["../../src/handlers/seo-indexnow.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,wBAAwB,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAe,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAA;IACvC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAA;IAC3F,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,EAAE,CAAA;AAC7F,CAAC,CAAA"}
@@ -0,0 +1,26 @@
1
+ import type { ApiContext, ApiHandler } from '../types.js';
2
+ /** The route serving the site's llms.txt */
3
+ export declare const SEO_LLMS_TXT_PATH = "/api/seo/llms.txt";
4
+ /** Site settings key holding the saved llms.txt snapshot */
5
+ export declare const LLMS_TXT_SETTING = "seo.llmsTxt";
6
+ /** Text that replaces the generated summary and link descriptions */
7
+ export interface LlmsTxtOverrides {
8
+ summary?: string | undefined;
9
+ /** Link descriptions keyed by `collection/slug` */
10
+ descriptions?: ReadonlyMap<string, string> | undefined;
11
+ }
12
+ /**
13
+ * Build llms.txt (llmstxt.org) from the live documents: the site name, its
14
+ * summary, then one section per collection with pages (`rendersPages()`) listing each live,
15
+ * indexable document with its URL and description.
16
+ */
17
+ export declare function buildLlmsTxt(ctx: ApiContext, overrides?: LlmsTxtOverrides): Promise<string>;
18
+ /** The saved llms.txt snapshot, or null when none is saved */
19
+ export declare function loadLlmsTxtSnapshot(ctx: ApiContext): Promise<string | null>;
20
+ /**
21
+ * GET /api/seo/llms.txt — the saved snapshot when there is one, else generated
22
+ * from the live documents, as text/plain. The `x-krantho-llms-origin` header
23
+ * says which: `snapshot` or `generated`.
24
+ */
25
+ export declare const seoLlmsTxt: ApiHandler;
26
+ //# sourceMappingURL=seo-llms-txt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-llms-txt.d.ts","sourceRoot":"","sources":["../../src/handlers/seo-llms-txt.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGzD,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,sBAAsB,CAAA;AAEpD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,gBAAgB,CAAA;AAE7C,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,mDAAmD;IACnD,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CACvD;AAsDD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,UAAU,EACf,SAAS,GAAE,gBAAqB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED,8DAA8D;AAC9D,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGjF;AAKD;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,UAcxB,CAAA"}
@@ -0,0 +1,99 @@
1
+ import { documentPath, rendersPages } from '@krantho/core';
2
+ import { canReadPublished } from '@krantho/persistence';
3
+ import { buildSeoFieldMap, resolveSeoField } from '@krantho/seo-shared';
4
+ import { PUBLIC_MACHINE_READ_CACHE_CONTROL } from '../public-cache.js';
5
+ import { isNoindex } from './seo-sitemap.js';
6
+ /** The route serving the site's llms.txt */
7
+ export const SEO_LLMS_TXT_PATH = '/api/seo/llms.txt';
8
+ /** Site settings key holding the saved llms.txt snapshot */
9
+ export const LLMS_TXT_SETTING = 'seo.llmsTxt';
10
+ /** One line of text: runs of whitespace, newlines included, become one space */
11
+ function oneLine(text) {
12
+ return text.replace(/\s+/g, ' ').trim();
13
+ }
14
+ /** The site summary: the override, else the site SEO config's primary entity description */
15
+ async function siteSummary(ctx, overrides) {
16
+ if (overrides.summary !== undefined)
17
+ return oneLine(overrides.summary);
18
+ const config = await ctx.seoConfigAdapter?.getConfig('site');
19
+ const description = config?.config.entities[0]?.properties['description'];
20
+ return typeof description === 'string' ? oneLine(description) : '';
21
+ }
22
+ /** `- [title](url): description` for one live document, or null when it is not listed */
23
+ function documentLine(ctx, collection, doc, overrides) {
24
+ if (isNoindex(doc.fields))
25
+ return null;
26
+ const path = documentPath(collection, doc.meta.slug);
27
+ if (path === null)
28
+ return null;
29
+ const fieldMap = buildSeoFieldMap(Object.keys(doc.fields));
30
+ const title = oneLine(resolveSeoField(fieldMap, 'title', doc.fields)) || doc.meta.slug;
31
+ const override = overrides.descriptions?.get(`${collection.name}/${doc.meta.slug}`);
32
+ const description = oneLine(override ?? resolveSeoField(fieldMap, 'description', doc.fields));
33
+ const baseUrl = ctx.config.site.baseUrl.replace(/\/$/, '');
34
+ const link = `- [${title}](${baseUrl}${path})`;
35
+ return description ? `${link}: ${description}` : link;
36
+ }
37
+ /** The `## collection` block of one collection, or null when it lists nothing */
38
+ async function collectionBlock(ctx, adapter, collection, overrides) {
39
+ const { items: docs } = await adapter.query({
40
+ state: 'published',
41
+ projection: 'summary',
42
+ collections: [collection.name],
43
+ });
44
+ const lines = docs
45
+ .map((doc) => documentLine(ctx, collection, doc, overrides))
46
+ .filter((line) => line !== null);
47
+ if (lines.length === 0)
48
+ return null;
49
+ return [`## ${collection.name}`, '', ...lines].join('\n');
50
+ }
51
+ /**
52
+ * Build llms.txt (llmstxt.org) from the live documents: the site name, its
53
+ * summary, then one section per collection with pages (`rendersPages()`) listing each live,
54
+ * indexable document with its URL and description.
55
+ */
56
+ export async function buildLlmsTxt(ctx, overrides = {}) {
57
+ const blocks = [`# ${oneLine(ctx.config.site.name)}`];
58
+ const summary = await siteSummary(ctx, overrides);
59
+ if (summary)
60
+ blocks.push(`> ${summary}`);
61
+ if (canReadPublished(ctx.adapter)) {
62
+ for (const collection of ctx.contentConfig.collections.values()) {
63
+ if (!rendersPages(collection))
64
+ continue;
65
+ const block = await collectionBlock(ctx, ctx.adapter, collection, overrides);
66
+ if (block)
67
+ blocks.push(block);
68
+ }
69
+ }
70
+ return `${blocks.join('\n\n')}\n`;
71
+ }
72
+ /** The saved llms.txt snapshot, or null when none is saved */
73
+ export async function loadLlmsTxtSnapshot(ctx) {
74
+ const saved = await ctx.siteSettingsAdapter?.getSetting(LLMS_TXT_SETTING);
75
+ return saved ? saved : null;
76
+ }
77
+ /** The response header naming where the served llms.txt comes from */
78
+ const LLMS_TXT_ORIGIN_HEADER = 'x-krantho-llms-origin';
79
+ /**
80
+ * GET /api/seo/llms.txt — the saved snapshot when there is one, else generated
81
+ * from the live documents, as text/plain. The `x-krantho-llms-origin` header
82
+ * says which: `snapshot` or `generated`.
83
+ */
84
+ export const seoLlmsTxt = async (_req, ctx) => {
85
+ if (!canReadPublished(ctx.adapter)) {
86
+ return { status: 501, body: { error: 'Adapter does not support reading published content' } };
87
+ }
88
+ const snapshot = await loadLlmsTxtSnapshot(ctx);
89
+ return {
90
+ status: 200,
91
+ body: snapshot ?? (await buildLlmsTxt(ctx)),
92
+ headers: {
93
+ 'content-type': 'text/plain; charset=utf-8',
94
+ 'cache-control': PUBLIC_MACHINE_READ_CACHE_CONTROL,
95
+ [LLMS_TXT_ORIGIN_HEADER]: snapshot === null ? 'generated' : 'snapshot',
96
+ },
97
+ };
98
+ };
99
+ //# sourceMappingURL=seo-llms-txt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-llms-txt.js","sourceRoot":"","sources":["../../src/handlers/seo-llms-txt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ApiHandler } from '../types.js';
2
+ /**
3
+ * GET /api/seo/preview/:collection/:slug — compose the JSON-LD of the
4
+ * document's current version in its collection and locale (`?locale=`, the
5
+ * site's default when absent; 400 when it is not a locale code)
6
+ */
7
+ export declare const seoPreview: ApiHandler;
8
+ //# sourceMappingURL=seo-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-preview.d.ts","sourceRoot":"","sources":["../../src/handlers/seo-preview.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,UAuCxB,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { documentPath } from '@krantho/core';
2
+ import { canGetContent } from '@krantho/persistence';
3
+ import { composePageJsonLd } from '../seo-compose.js';
4
+ import { parseLocaleParam, requireParam, validateCollectionParam } from '../validators.js';
5
+ /**
6
+ * GET /api/seo/preview/:collection/:slug — compose the JSON-LD of the
7
+ * document's current version in its collection and locale (`?locale=`, the
8
+ * site's default when absent; 400 when it is not a locale code)
9
+ */
10
+ export const seoPreview = async (req, ctx) => {
11
+ const validated = validateCollectionParam(req.params['collection'], ctx);
12
+ if (!validated.isValid)
13
+ return validated.response;
14
+ const slugResult = requireParam(req.params, 'slug');
15
+ if (!slugResult.isValid)
16
+ return slugResult.response;
17
+ const slug = slugResult.value;
18
+ const collection = validated.collection;
19
+ const requestedLocale = req.query['locale'];
20
+ const locale = parseLocaleParam(requestedLocale);
21
+ if (requestedLocale !== undefined && locale === undefined) {
22
+ return {
23
+ status: 400,
24
+ body: { error: '"locale" must be a locale code, such as "en" or "nb-NO"' },
25
+ };
26
+ }
27
+ if (!canGetContent(ctx.adapter)) {
28
+ return { status: 501, body: { error: 'Adapter does not support reading a document' } };
29
+ }
30
+ const current = await ctx.adapter.getContent(collection, slug, locale);
31
+ if (!current) {
32
+ return {
33
+ status: 404,
34
+ body: { error: `Content "${slug}" not found in "${collection}"` },
35
+ };
36
+ }
37
+ const graph = await composePageJsonLd({
38
+ collection,
39
+ slug,
40
+ path: documentPath(validated.collectionDef, slug),
41
+ fields: current.fields,
42
+ metadata: current.metadata,
43
+ documentMeta: current.meta,
44
+ config: ctx.config,
45
+ seoConfigs: ctx.seoConfigAdapter,
46
+ });
47
+ return { status: 200, body: graph };
48
+ };
49
+ //# sourceMappingURL=seo-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-preview.js","sourceRoot":"","sources":["../../src/handlers/seo-preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE1F;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAe,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACvD,MAAM,SAAS,GAAG,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,CAAA;IACxE,IAAI,CAAC,SAAS,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC,QAAQ,CAAA;IAEjD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnD,IAAI,CAAC,UAAU,CAAC,OAAO;QAAE,OAAO,UAAU,CAAC,QAAQ,CAAA;IACnD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAA;IAC7B,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAA;IACvC,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,MAAM,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAA;IAChD,IAAI,eAAe,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1D,OAAO;YACL,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,yDAAyD,EAAE;SAC3E,CAAA;IACH,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,6CAA6C,EAAE,EAAE,CAAA;IACxF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IACtE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,IAAI,mBAAmB,UAAU,GAAG,EAAE;SAClE,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC;QACpC,UAAU;QACV,IAAI;QACJ,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC;QACjD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,IAAI;QAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,UAAU,EAAE,GAAG,CAAC,gBAAgB;KACjC,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACrC,CAAC,CAAA"}
@@ -0,0 +1,22 @@
1
+ import type { ApiContext, ApiHandler } from '../types.js';
2
+ /**
3
+ * The seo_config id whose `robotsTxt` holds a saved robots.txt override: the
4
+ * site scope's configuration, beside its entities and never among them. An
5
+ * admin saves it through `PUT /api/seo/config/site`; while set, the handler
6
+ * serves it verbatim, otherwise the generated body.
7
+ */
8
+ export declare const robotsOverrideConfigId: "site";
9
+ /** Build the default robots.txt body, naming the sitemap at the site's root (`/sitemap.xml`) */
10
+ export declare function buildDefaultRobotsBody(baseUrl: string): string;
11
+ /** Read a saved robots override from the site's seo_config, or null if none exists */
12
+ export declare function loadRobotsOverride(ctx: ApiContext): Promise<string | null>;
13
+ /**
14
+ * GET /api/seo/robots.txt — generate robots.txt with sitemap reference.
15
+ *
16
+ * If an override is stored in seo_config (the site scope's `robotsTxt`), it
17
+ * is returned verbatim. Otherwise a standard robots.txt that
18
+ * allows all crawlers and points to the sitemap is generated dynamically
19
+ * from the handler's site.baseUrl.
20
+ */
21
+ export declare const seoRobots: ApiHandler;
22
+ //# sourceMappingURL=seo-robots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-robots.d.ts","sourceRoot":"","sources":["../../src/handlers/seo-robots.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGzD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAG,MAAe,CAAA;AAErD,gGAAgG;AAChG,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,sFAAsF;AACtF,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAShF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,UAYvB,CAAA"}
@@ -0,0 +1,48 @@
1
+ import { PUBLIC_MACHINE_READ_CACHE_CONTROL } from '../public-cache.js';
2
+ import { SITEMAP_PUBLIC_PATH } from './seo-sitemap.js';
3
+ /**
4
+ * The seo_config id whose `robotsTxt` holds a saved robots.txt override: the
5
+ * site scope's configuration, beside its entities and never among them. An
6
+ * admin saves it through `PUT /api/seo/config/site`; while set, the handler
7
+ * serves it verbatim, otherwise the generated body.
8
+ */
9
+ export const robotsOverrideConfigId = 'site';
10
+ /** Build the default robots.txt body, naming the sitemap at the site's root (`/sitemap.xml`) */
11
+ export function buildDefaultRobotsBody(baseUrl) {
12
+ const trimmed = baseUrl.replace(/\/$/, '');
13
+ return ['User-agent: *', 'Allow: /', '', `Sitemap: ${trimmed}${SITEMAP_PUBLIC_PATH}`].join('\n');
14
+ }
15
+ /** Read a saved robots override from the site's seo_config, or null if none exists */
16
+ export async function loadRobotsOverride(ctx) {
17
+ if (!ctx.seoConfigAdapter)
18
+ return null;
19
+ try {
20
+ const config = await ctx.seoConfigAdapter.getConfig(robotsOverrideConfigId);
21
+ const override = config?.config.robotsTxt;
22
+ return typeof override === 'string' && override.length > 0 ? override : null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ /**
29
+ * GET /api/seo/robots.txt — generate robots.txt with sitemap reference.
30
+ *
31
+ * If an override is stored in seo_config (the site scope's `robotsTxt`), it
32
+ * is returned verbatim. Otherwise a standard robots.txt that
33
+ * allows all crawlers and points to the sitemap is generated dynamically
34
+ * from the handler's site.baseUrl.
35
+ */
36
+ export const seoRobots = async (_req, ctx) => {
37
+ const override = await loadRobotsOverride(ctx);
38
+ const body = override ?? buildDefaultRobotsBody(ctx.config.site.baseUrl);
39
+ return {
40
+ status: 200,
41
+ body,
42
+ headers: {
43
+ 'content-type': 'text/plain; charset=utf-8',
44
+ 'cache-control': PUBLIC_MACHINE_READ_CACHE_CONTROL,
45
+ },
46
+ };
47
+ };
48
+ //# sourceMappingURL=seo-robots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-robots.js","sourceRoot":"","sources":["../../src/handlers/seo-robots.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAA;AAEtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAe,CAAA;AAErD,gGAAgG;AAChG,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC1C,OAAO,CAAC,eAAe,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,OAAO,GAAG,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAClG,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAe;IACtD,IAAI,CAAC,GAAG,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAA;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAA;QAC3E,MAAM,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,SAAS,CAAA;QACzC,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAe,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACvD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,QAAQ,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAExE,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI;QACJ,OAAO,EAAE;YACP,cAAc,EAAE,2BAA2B;YAC3C,eAAe,EAAE,iCAAiC;SACnD;KACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,68 @@
1
+ import type { ApiContext, ApiHandler } from '../types.js';
2
+ /**
3
+ * Canonical paths for the SEO routes registered in `create-api-handlers.ts`.
4
+ *
5
+ * Exported as constants so callers (e.g., the robots.txt handler) reference
6
+ * the same path the router registers, preventing drift if a route is renamed.
7
+ */
8
+ export declare const SEO_SITEMAP_PATH = "/api/seo/sitemap";
9
+ /** Where a site serves the sitemap — the address robots.txt names; the site routes it to SEO_SITEMAP_PATH */
10
+ export declare const SITEMAP_PUBLIC_PATH = "/sitemap.xml";
11
+ export declare const SEO_SITEMAP_JSON_PATH = "/api/seo/sitemap.json";
12
+ export declare const SEO_ROBOTS_PATH = "/api/seo/robots.txt";
13
+ /** A single URL entry in the sitemap output */
14
+ export interface SitemapUrl {
15
+ loc: string;
16
+ /** When the page last changed, as a W3C Datetime in UTC (`2026-09-30T22:17:06.000Z`) */
17
+ lastmod?: string | undefined;
18
+ changefreq: string;
19
+ priority: string;
20
+ }
21
+ /**
22
+ * Whether a document asks not to be indexed. The field name is resolved
23
+ * dynamically so CMS schemas with different conventions (e.g. `robots-index`
24
+ * vs `noindex`) all work.
25
+ */
26
+ export declare function isNoindex(fields: Record<string, unknown>): boolean;
27
+ /**
28
+ * Build the list of sitemap URLs from the handler's content config.
29
+ *
30
+ * Pure: reads from the context, returns an array. No side effects. This is
31
+ * the shared core used by both `seoSitemap` (XML output) and `seoSitemapJson`
32
+ * (JSON output for the Studio preview), plus any future consumer that needs
33
+ * the url list.
34
+ *
35
+ * Iterates every published item in every collection that renders pages
36
+ * (`rendersPages()`), skips noindex pages (resolved via the dynamic field map
37
+ * so CMS field names can differ), and derives the URL with `documentPath()`
38
+ * from the collection's `path` — or, without one, `pages` items at the site
39
+ * root (the `home` page is the homepage) and other collections under their
40
+ * name (`/{name}/slug`). A path is listed once: the homepage, and a fixed-path
41
+ * collection whose documents share one page.
42
+ */
43
+ export declare function buildSitemapUrls(ctx: ApiContext): Promise<SitemapUrl[]>;
44
+ /**
45
+ * Serialize a list of sitemap URLs to XML.
46
+ *
47
+ * Exported so tests can drive the serializer directly without needing to
48
+ * stub the full ApiContext. Also used by the XML handler below.
49
+ */
50
+ export declare function serializeSitemapXml(urls: readonly SitemapUrl[]): string;
51
+ /**
52
+ * GET /api/seo/sitemap — generate sitemap XML dynamically from all collections.
53
+ *
54
+ * Lists all published content across the collections that render pages, at
55
+ * site.baseUrl + `documentPath()`. Excludes collections without pages and
56
+ * noindex pages.
57
+ */
58
+ export declare const seoSitemap: ApiHandler;
59
+ /**
60
+ * GET /api/seo/sitemap.json — same url list as the XML handler, served as JSON.
61
+ *
62
+ * Used by Studio's Structure → Sitemap & Robots tab to render a sortable table
63
+ * without parsing XML client-side. Not intended as a public SEO endpoint —
64
+ * search engines consume the XML at `/api/seo/sitemap` (or wherever your
65
+ * framework rewrites it, e.g. `/sitemap.xml`).
66
+ */
67
+ export declare const seoSitemapJson: ApiHandler;
68
+ //# sourceMappingURL=seo-sitemap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-sitemap.d.ts","sourceRoot":"","sources":["../../src/handlers/seo-sitemap.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAClD,6GAA6G;AAC7G,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,qBAAqB,0BAA0B,CAAA;AAC5D,eAAO,MAAM,eAAe,wBAAwB,CAAA;AAEpD,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CASlE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CA2C7E;AAyBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAYvE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,UAUxB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,UAM5B,CAAA"}