@orthacms/content-server 0.0.0-reserve.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 (396) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/define.d.ts +17 -0
  4. package/dist/define.d.ts.map +1 -0
  5. package/dist/define.js +28 -0
  6. package/dist/index.d.ts +48 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +109 -0
  9. package/dist/lib/collection/define.d.ts +35 -0
  10. package/dist/lib/collection/define.d.ts.map +1 -0
  11. package/dist/lib/collection/define.js +217 -0
  12. package/dist/lib/collection/table-builder.d.ts +28 -0
  13. package/dist/lib/collection/table-builder.d.ts.map +1 -0
  14. package/dist/lib/collection/table-builder.js +306 -0
  15. package/dist/lib/content-types/controllers/get-content-schema.controller.d.ts +24 -0
  16. package/dist/lib/content-types/controllers/get-content-schema.controller.d.ts.map +1 -0
  17. package/dist/lib/content-types/controllers/get-content-schema.controller.js +58 -0
  18. package/dist/lib/content-types/controllers/get-filter-fields.controller.d.ts +35 -0
  19. package/dist/lib/content-types/controllers/get-filter-fields.controller.d.ts.map +1 -0
  20. package/dist/lib/content-types/controllers/get-filter-fields.controller.js +74 -0
  21. package/dist/lib/content-types/controllers/list-content-schema.controller.d.ts +15 -0
  22. package/dist/lib/content-types/controllers/list-content-schema.controller.d.ts.map +1 -0
  23. package/dist/lib/content-types/controllers/list-content-schema.controller.js +38 -0
  24. package/dist/lib/content-types/queries/workspace-grants.query.d.ts +25 -0
  25. package/dist/lib/content-types/queries/workspace-grants.query.d.ts.map +1 -0
  26. package/dist/lib/content-types/queries/workspace-grants.query.js +45 -0
  27. package/dist/lib/content.module.d.ts +21 -0
  28. package/dist/lib/content.module.d.ts.map +1 -0
  29. package/dist/lib/content.module.js +264 -0
  30. package/dist/lib/content.tokens.d.ts +5 -0
  31. package/dist/lib/content.tokens.d.ts.map +1 -0
  32. package/dist/lib/content.tokens.js +9 -0
  33. package/dist/lib/copilot/content-tool.provider.d.ts +64 -0
  34. package/dist/lib/copilot/content-tool.provider.d.ts.map +1 -0
  35. package/dist/lib/copilot/content-tool.provider.js +309 -0
  36. package/dist/lib/copilot/diff-snapshots.d.ts +42 -0
  37. package/dist/lib/copilot/diff-snapshots.d.ts.map +1 -0
  38. package/dist/lib/copilot/diff-snapshots.js +77 -0
  39. package/dist/lib/copilot/entry-proposal.applier.d.ts +89 -0
  40. package/dist/lib/copilot/entry-proposal.applier.d.ts.map +1 -0
  41. package/dist/lib/copilot/entry-proposal.applier.js +245 -0
  42. package/dist/lib/copilot/entry-proposal.provider.d.ts +157 -0
  43. package/dist/lib/copilot/entry-proposal.provider.d.ts.map +1 -0
  44. package/dist/lib/copilot/entry-proposal.provider.js +619 -0
  45. package/dist/lib/copilot/filter-schema.d.ts +61 -0
  46. package/dist/lib/copilot/filter-schema.d.ts.map +1 -0
  47. package/dist/lib/copilot/filter-schema.js +139 -0
  48. package/dist/lib/copilot/project-entry.d.ts +23 -0
  49. package/dist/lib/copilot/project-entry.d.ts.map +1 -0
  50. package/dist/lib/copilot/project-entry.js +36 -0
  51. package/dist/lib/copilot/proposal-kinds.d.ts +30 -0
  52. package/dist/lib/copilot/proposal-kinds.d.ts.map +1 -0
  53. package/dist/lib/copilot/proposal-kinds.js +32 -0
  54. package/dist/lib/copilot/revision-tool.provider.d.ts +56 -0
  55. package/dist/lib/copilot/revision-tool.provider.d.ts.map +1 -0
  56. package/dist/lib/copilot/revision-tool.provider.js +215 -0
  57. package/dist/lib/docs/content-schemas.d.ts +34 -0
  58. package/dist/lib/docs/content-schemas.d.ts.map +1 -0
  59. package/dist/lib/docs/content-schemas.js +617 -0
  60. package/dist/lib/docs/describe-content-api.d.ts +22 -0
  61. package/dist/lib/docs/describe-content-api.d.ts.map +1 -0
  62. package/dist/lib/docs/describe-content-api.js +173 -0
  63. package/dist/lib/docs/field-schema.d.ts +28 -0
  64. package/dist/lib/docs/field-schema.d.ts.map +1 -0
  65. package/dist/lib/docs/field-schema.js +214 -0
  66. package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts +23 -0
  67. package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts.map +1 -0
  68. package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.js +77 -0
  69. package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts +23 -0
  70. package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts.map +1 -0
  71. package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.js +66 -0
  72. package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts +43 -0
  73. package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts.map +1 -0
  74. package/dist/lib/entries/application/use-cases/publish-entry.use-case.js +106 -0
  75. package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts +30 -0
  76. package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts.map +1 -0
  77. package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.js +70 -0
  78. package/dist/lib/entries/controllers/bulk-entries.controller.d.ts +26 -0
  79. package/dist/lib/entries/controllers/bulk-entries.controller.d.ts.map +1 -0
  80. package/dist/lib/entries/controllers/create-entry.controller.d.ts +20 -0
  81. package/dist/lib/entries/controllers/create-entry.controller.d.ts.map +1 -0
  82. package/dist/lib/entries/controllers/delete-entry.controller.d.ts +24 -0
  83. package/dist/lib/entries/controllers/delete-entry.controller.d.ts.map +1 -0
  84. package/dist/lib/entries/controllers/get-entry.controller.d.ts +34 -0
  85. package/dist/lib/entries/controllers/get-entry.controller.d.ts.map +1 -0
  86. package/dist/lib/entries/controllers/list-entries.controller.d.ts +20 -0
  87. package/dist/lib/entries/controllers/list-entries.controller.d.ts.map +1 -0
  88. package/dist/lib/entries/controllers/publish-entry.controller.d.ts +19 -0
  89. package/dist/lib/entries/controllers/publish-entry.controller.d.ts.map +1 -0
  90. package/dist/lib/entries/controllers/resolve-type.d.ts +9 -0
  91. package/dist/lib/entries/controllers/resolve-type.d.ts.map +1 -0
  92. package/dist/lib/entries/controllers/update-entry.controller.d.ts +18 -0
  93. package/dist/lib/entries/controllers/update-entry.controller.d.ts.map +1 -0
  94. package/dist/lib/entries/domain/entry-publish-blocked.error.d.ts +13 -0
  95. package/dist/lib/entries/domain/entry-publish-blocked.error.d.ts.map +1 -0
  96. package/dist/lib/entries/domain/entry-publish-blocked.error.js +19 -0
  97. package/dist/lib/entries/domain/entry.d.ts +71 -0
  98. package/dist/lib/entries/domain/entry.d.ts.map +1 -0
  99. package/dist/lib/entries/domain/entry.js +90 -0
  100. package/dist/lib/entries/domain/events/entry-events.d.ts +67 -0
  101. package/dist/lib/entries/domain/events/entry-events.d.ts.map +1 -0
  102. package/dist/lib/entries/domain/events/entry-events.js +100 -0
  103. package/dist/lib/entries/dto/bulk-ids.dto.d.ts +11 -0
  104. package/dist/lib/entries/dto/bulk-ids.dto.d.ts.map +1 -0
  105. package/dist/lib/entries/dto/list-entries-query.dto.d.ts +46 -0
  106. package/dist/lib/entries/dto/list-entries-query.dto.d.ts.map +1 -0
  107. package/dist/lib/entries/dto/relation-delta-map.validator.d.ts +19 -0
  108. package/dist/lib/entries/dto/relation-delta-map.validator.d.ts.map +1 -0
  109. package/dist/lib/entries/dto/save-entry.dto.d.ts +46 -0
  110. package/dist/lib/entries/dto/save-entry.dto.d.ts.map +1 -0
  111. package/dist/lib/entries/entries.constants.d.ts +19 -0
  112. package/dist/lib/entries/entries.constants.d.ts.map +1 -0
  113. package/dist/lib/entries/entries.constants.js +21 -0
  114. package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts +33 -0
  115. package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts.map +1 -0
  116. package/dist/lib/entries/http/controllers/bulk-entries.controller.js +143 -0
  117. package/dist/lib/entries/http/controllers/create-entry.controller.d.ts +21 -0
  118. package/dist/lib/entries/http/controllers/create-entry.controller.d.ts.map +1 -0
  119. package/dist/lib/entries/http/controllers/create-entry.controller.js +52 -0
  120. package/dist/lib/entries/http/controllers/delete-entry.controller.d.ts +25 -0
  121. package/dist/lib/entries/http/controllers/delete-entry.controller.d.ts.map +1 -0
  122. package/dist/lib/entries/http/controllers/delete-entry.controller.js +84 -0
  123. package/dist/lib/entries/http/controllers/get-entry.controller.d.ts +44 -0
  124. package/dist/lib/entries/http/controllers/get-entry.controller.d.ts.map +1 -0
  125. package/dist/lib/entries/http/controllers/get-entry.controller.js +124 -0
  126. package/dist/lib/entries/http/controllers/list-entries.controller.d.ts +20 -0
  127. package/dist/lib/entries/http/controllers/list-entries.controller.d.ts.map +1 -0
  128. package/dist/lib/entries/http/controllers/list-entries.controller.js +52 -0
  129. package/dist/lib/entries/http/controllers/publish-entry.controller.d.ts +22 -0
  130. package/dist/lib/entries/http/controllers/publish-entry.controller.d.ts.map +1 -0
  131. package/dist/lib/entries/http/controllers/publish-entry.controller.js +68 -0
  132. package/dist/lib/entries/http/controllers/resolve-type.d.ts +9 -0
  133. package/dist/lib/entries/http/controllers/resolve-type.d.ts.map +1 -0
  134. package/dist/lib/entries/http/controllers/resolve-type.js +16 -0
  135. package/dist/lib/entries/http/controllers/to-actor.d.ts +13 -0
  136. package/dist/lib/entries/http/controllers/to-actor.d.ts.map +1 -0
  137. package/dist/lib/entries/http/controllers/to-actor.js +15 -0
  138. package/dist/lib/entries/http/controllers/update-entry.controller.d.ts +19 -0
  139. package/dist/lib/entries/http/controllers/update-entry.controller.d.ts.map +1 -0
  140. package/dist/lib/entries/http/controllers/update-entry.controller.js +51 -0
  141. package/dist/lib/entries/http/dto/bulk-ids.dto.d.ts +11 -0
  142. package/dist/lib/entries/http/dto/bulk-ids.dto.d.ts.map +1 -0
  143. package/dist/lib/entries/http/dto/bulk-ids.dto.js +33 -0
  144. package/dist/lib/entries/http/dto/list-entries-query.dto.d.ts +66 -0
  145. package/dist/lib/entries/http/dto/list-entries-query.dto.d.ts.map +1 -0
  146. package/dist/lib/entries/http/dto/list-entries-query.dto.js +192 -0
  147. package/dist/lib/entries/http/dto/relation-delta-map.validator.d.ts +30 -0
  148. package/dist/lib/entries/http/dto/relation-delta-map.validator.d.ts.map +1 -0
  149. package/dist/lib/entries/http/dto/relation-delta-map.validator.js +102 -0
  150. package/dist/lib/entries/http/dto/save-entry.dto.d.ts +48 -0
  151. package/dist/lib/entries/http/dto/save-entry.dto.d.ts.map +1 -0
  152. package/dist/lib/entries/http/dto/save-entry.dto.js +120 -0
  153. package/dist/lib/entries/http/guards/content-grant.guard.d.ts +37 -0
  154. package/dist/lib/entries/http/guards/content-grant.guard.d.ts.map +1 -0
  155. package/dist/lib/entries/http/guards/content-grant.guard.js +67 -0
  156. package/dist/lib/entries/infrastructure/persistence/bulk-publish-verdicts.d.ts +22 -0
  157. package/dist/lib/entries/infrastructure/persistence/bulk-publish-verdicts.d.ts.map +1 -0
  158. package/dist/lib/entries/infrastructure/persistence/bulk-publish-verdicts.js +81 -0
  159. package/dist/lib/entries/infrastructure/persistence/entry-counter.service.d.ts +42 -0
  160. package/dist/lib/entries/infrastructure/persistence/entry-counter.service.d.ts.map +1 -0
  161. package/dist/lib/entries/infrastructure/persistence/entry-counter.service.js +73 -0
  162. package/dist/lib/entries/infrastructure/persistence/entry-row.d.ts +56 -0
  163. package/dist/lib/entries/infrastructure/persistence/entry-row.d.ts.map +1 -0
  164. package/dist/lib/entries/infrastructure/persistence/entry-row.js +185 -0
  165. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts +392 -0
  166. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts.map +1 -0
  167. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.js +1223 -0
  168. package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts +24 -0
  169. package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts.map +1 -0
  170. package/dist/lib/entries/infrastructure/persistence/media-accept.d.ts +23 -0
  171. package/dist/lib/entries/infrastructure/persistence/media-accept.d.ts.map +1 -0
  172. package/dist/lib/entries/infrastructure/persistence/media-accept.js +55 -0
  173. package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts +327 -0
  174. package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts.map +1 -0
  175. package/dist/lib/entries/infrastructure/persistence/relation-link.service.js +1008 -0
  176. package/dist/lib/entries/infrastructure/queries/bulk-publish-preview.query.d.ts +19 -0
  177. package/dist/lib/entries/infrastructure/queries/bulk-publish-preview.query.d.ts.map +1 -0
  178. package/dist/lib/entries/infrastructure/queries/bulk-publish-preview.query.js +39 -0
  179. package/dist/lib/entries/infrastructure/queries/entries.service.d.ts +64 -0
  180. package/dist/lib/entries/infrastructure/queries/entries.service.d.ts.map +1 -0
  181. package/dist/lib/entries/infrastructure/queries/entries.service.js +202 -0
  182. package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts +40 -0
  183. package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts.map +1 -0
  184. package/dist/lib/entries/infrastructure/queries/entry-filter-surface.d.ts +38 -0
  185. package/dist/lib/entries/infrastructure/queries/entry-filter-surface.d.ts.map +1 -0
  186. package/dist/lib/entries/infrastructure/queries/entry-filter-surface.js +310 -0
  187. package/dist/lib/entries/infrastructure/queries/entry-scalar-fields.d.ts +25 -0
  188. package/dist/lib/entries/infrastructure/queries/entry-scalar-fields.d.ts.map +1 -0
  189. package/dist/lib/entries/infrastructure/queries/entry-scalar-fields.js +51 -0
  190. package/dist/lib/entries/infrastructure/queries/entry-search.d.ts +19 -0
  191. package/dist/lib/entries/infrastructure/queries/entry-search.d.ts.map +1 -0
  192. package/dist/lib/entries/infrastructure/queries/entry-search.js +52 -0
  193. package/dist/lib/entries/infrastructure/queries/media-refs.query.d.ts +21 -0
  194. package/dist/lib/entries/infrastructure/queries/media-refs.query.d.ts.map +1 -0
  195. package/dist/lib/entries/infrastructure/queries/media-refs.query.js +117 -0
  196. package/dist/lib/entries/services/entries.service.d.ts +59 -0
  197. package/dist/lib/entries/services/entries.service.d.ts.map +1 -0
  198. package/dist/lib/entries/services/entry-counter.service.d.ts +31 -0
  199. package/dist/lib/entries/services/entry-counter.service.d.ts.map +1 -0
  200. package/dist/lib/entries/services/entry-filter-schema.d.ts +32 -0
  201. package/dist/lib/entries/services/entry-filter-schema.d.ts.map +1 -0
  202. package/dist/lib/entries/services/entry-row.d.ts +56 -0
  203. package/dist/lib/entries/services/entry-row.d.ts.map +1 -0
  204. package/dist/lib/entries/services/entry-writer.service.d.ts +193 -0
  205. package/dist/lib/entries/services/entry-writer.service.d.ts.map +1 -0
  206. package/dist/lib/entries/services/relation-link.service.d.ts +115 -0
  207. package/dist/lib/entries/services/relation-link.service.d.ts.map +1 -0
  208. package/dist/lib/entries/types/bulk-publish.d.ts +75 -0
  209. package/dist/lib/entries/types/bulk-publish.d.ts.map +1 -0
  210. package/dist/lib/entries/types/bulk-publish.js +22 -0
  211. package/dist/lib/entries/types/entry-list-view.d.ts +205 -0
  212. package/dist/lib/entries/types/entry-list-view.d.ts.map +1 -0
  213. package/dist/lib/entries/types/entry-list-view.js +5 -0
  214. package/dist/lib/entries/types/filter-surface.d.ts +35 -0
  215. package/dist/lib/entries/types/filter-surface.d.ts.map +1 -0
  216. package/dist/lib/entries/types/filter-surface.js +2 -0
  217. package/dist/lib/extension/entry-extension-boot-check.d.ts +16 -0
  218. package/dist/lib/extension/entry-extension-boot-check.d.ts.map +1 -0
  219. package/dist/lib/extension/entry-extension-boot-check.js +42 -0
  220. package/dist/lib/extension/entry-extension.d.ts +225 -0
  221. package/dist/lib/extension/entry-extension.d.ts.map +1 -0
  222. package/dist/lib/extension/entry-extension.js +27 -0
  223. package/dist/lib/extension/media-asset-resolver.d.ts +85 -0
  224. package/dist/lib/extension/media-asset-resolver.d.ts.map +1 -0
  225. package/dist/lib/extension/media-asset-resolver.js +26 -0
  226. package/dist/lib/extension/per-locale-relation.d.ts +18 -0
  227. package/dist/lib/extension/per-locale-relation.d.ts.map +1 -0
  228. package/dist/lib/extension/relation-locale-sync.d.ts +62 -0
  229. package/dist/lib/extension/relation-locale-sync.d.ts.map +1 -0
  230. package/dist/lib/extension/relation-locale-sync.js +88 -0
  231. package/dist/lib/fields/index.d.ts +94 -0
  232. package/dist/lib/fields/index.d.ts.map +1 -0
  233. package/dist/lib/fields/index.js +203 -0
  234. package/dist/lib/insights/http/controllers/content-pipeline.controller.d.ts +16 -0
  235. package/dist/lib/insights/http/controllers/content-pipeline.controller.d.ts.map +1 -0
  236. package/dist/lib/insights/http/controllers/content-pipeline.controller.js +39 -0
  237. package/dist/lib/insights/http/controllers/content-punchcard.controller.d.ts +18 -0
  238. package/dist/lib/insights/http/controllers/content-punchcard.controller.d.ts.map +1 -0
  239. package/dist/lib/insights/http/controllers/content-punchcard.controller.js +42 -0
  240. package/dist/lib/insights/http/controllers/content-stale.controller.d.ts +17 -0
  241. package/dist/lib/insights/http/controllers/content-stale.controller.d.ts.map +1 -0
  242. package/dist/lib/insights/http/controllers/content-stale.controller.js +40 -0
  243. package/dist/lib/insights/http/controllers/content-totals.controller.d.ts +18 -0
  244. package/dist/lib/insights/http/controllers/content-totals.controller.d.ts.map +1 -0
  245. package/dist/lib/insights/http/controllers/content-totals.controller.js +42 -0
  246. package/dist/lib/insights/http/controllers/content-unshipped.controller.d.ts +17 -0
  247. package/dist/lib/insights/http/controllers/content-unshipped.controller.d.ts.map +1 -0
  248. package/dist/lib/insights/http/controllers/content-unshipped.controller.js +40 -0
  249. package/dist/lib/insights/http/controllers/content-velocity.controller.d.ts +17 -0
  250. package/dist/lib/insights/http/controllers/content-velocity.controller.d.ts.map +1 -0
  251. package/dist/lib/insights/http/controllers/content-velocity.controller.js +41 -0
  252. package/dist/lib/insights/http/dto/insights-range-query.dto.d.ts +15 -0
  253. package/dist/lib/insights/http/dto/insights-range-query.dto.d.ts.map +1 -0
  254. package/dist/lib/insights/http/dto/insights-range-query.dto.js +38 -0
  255. package/dist/lib/insights/infrastructure/queries/content-insights.query.d.ts +77 -0
  256. package/dist/lib/insights/infrastructure/queries/content-insights.query.d.ts.map +1 -0
  257. package/dist/lib/insights/infrastructure/queries/content-insights.query.js +380 -0
  258. package/dist/lib/insights/types/content-insights-view.d.ts +134 -0
  259. package/dist/lib/insights/types/content-insights-view.d.ts.map +1 -0
  260. package/dist/lib/insights/types/content-insights-view.js +10 -0
  261. package/dist/lib/mcp/content-tools.provider.d.ts +83 -0
  262. package/dist/lib/mcp/content-tools.provider.d.ts.map +1 -0
  263. package/dist/lib/mcp/content-tools.provider.js +441 -0
  264. package/dist/lib/mcp/tool-input.d.ts +43 -0
  265. package/dist/lib/mcp/tool-input.d.ts.map +1 -0
  266. package/dist/lib/mcp/tool-input.js +117 -0
  267. package/dist/lib/mcp/tool-schemas.d.ts +34 -0
  268. package/dist/lib/mcp/tool-schemas.d.ts.map +1 -0
  269. package/dist/lib/mcp/tool-schemas.js +282 -0
  270. package/dist/lib/public/controllers/get-public-entry.controller.d.ts +26 -0
  271. package/dist/lib/public/controllers/get-public-entry.controller.d.ts.map +1 -0
  272. package/dist/lib/public/controllers/list-public-entries.controller.d.ts +24 -0
  273. package/dist/lib/public/controllers/list-public-entries.controller.d.ts.map +1 -0
  274. package/dist/lib/public/controllers/public-schema.controller.d.ts +18 -0
  275. package/dist/lib/public/controllers/public-schema.controller.d.ts.map +1 -0
  276. package/dist/lib/public-api/http/api-token-request.d.ts +41 -0
  277. package/dist/lib/public-api/http/api-token-request.d.ts.map +1 -0
  278. package/dist/lib/public-api/http/api-token-request.js +2 -0
  279. package/dist/lib/public-api/http/controllers/public-content-types.controller.d.ts +31 -0
  280. package/dist/lib/public-api/http/controllers/public-content-types.controller.d.ts.map +1 -0
  281. package/dist/lib/public-api/http/controllers/public-content-types.controller.js +93 -0
  282. package/dist/lib/public-api/http/controllers/public-entries.controller.d.ts +101 -0
  283. package/dist/lib/public-api/http/controllers/public-entries.controller.d.ts.map +1 -0
  284. package/dist/lib/public-api/http/controllers/public-entries.controller.js +307 -0
  285. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts +76 -0
  286. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts.map +1 -0
  287. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.js +353 -0
  288. package/dist/lib/public-api/http/controllers/resolve-granted-type.d.ts +42 -0
  289. package/dist/lib/public-api/http/controllers/resolve-granted-type.d.ts.map +1 -0
  290. package/dist/lib/public-api/http/controllers/resolve-granted-type.js +25 -0
  291. package/dist/lib/public-api/http/decorators/current-api-token.decorator.d.ts +8 -0
  292. package/dist/lib/public-api/http/decorators/current-api-token.decorator.d.ts.map +1 -0
  293. package/dist/lib/public-api/http/decorators/current-api-token.decorator.js +17 -0
  294. package/dist/lib/public-api/http/dto/public-bulk.dto.d.ts +58 -0
  295. package/dist/lib/public-api/http/dto/public-bulk.dto.d.ts.map +1 -0
  296. package/dist/lib/public-api/http/dto/public-bulk.dto.js +118 -0
  297. package/dist/lib/public-api/http/dto/public-list-entries-query.dto.d.ts +106 -0
  298. package/dist/lib/public-api/http/dto/public-list-entries-query.dto.d.ts.map +1 -0
  299. package/dist/lib/public-api/http/dto/public-list-entries-query.dto.js +297 -0
  300. package/dist/lib/public-api/http/dto/public-save-entry.dto.d.ts +39 -0
  301. package/dist/lib/public-api/http/dto/public-save-entry.dto.d.ts.map +1 -0
  302. package/dist/lib/public-api/http/dto/public-save-entry.dto.js +112 -0
  303. package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts +25 -0
  304. package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts.map +1 -0
  305. package/dist/lib/public-api/http/guards/api-token-workspace.guard.js +58 -0
  306. package/dist/lib/public-api/http/guards/api-token.guard.d.ts +32 -0
  307. package/dist/lib/public-api/http/guards/api-token.guard.d.ts.map +1 -0
  308. package/dist/lib/public-api/http/guards/api-token.guard.js +92 -0
  309. package/dist/lib/public-api/http/guards/draft-visibility.guard.d.ts +25 -0
  310. package/dist/lib/public-api/http/guards/draft-visibility.guard.d.ts.map +1 -0
  311. package/dist/lib/public-api/http/guards/draft-visibility.guard.js +56 -0
  312. package/dist/lib/public-api/infrastructure/bulk-save-op.d.ts +55 -0
  313. package/dist/lib/public-api/infrastructure/bulk-save-op.d.ts.map +1 -0
  314. package/dist/lib/public-api/infrastructure/bulk-save-op.js +61 -0
  315. package/dist/lib/public-api/infrastructure/field-selection.d.ts +21 -0
  316. package/dist/lib/public-api/infrastructure/field-selection.d.ts.map +1 -0
  317. package/dist/lib/public-api/infrastructure/field-selection.js +72 -0
  318. package/dist/lib/public-api/infrastructure/public-entries.query.d.ts +248 -0
  319. package/dist/lib/public-api/infrastructure/public-entries.query.d.ts.map +1 -0
  320. package/dist/lib/public-api/infrastructure/public-entries.query.js +557 -0
  321. package/dist/lib/public-api/infrastructure/public-entry-row.d.ts +31 -0
  322. package/dist/lib/public-api/infrastructure/public-entry-row.d.ts.map +1 -0
  323. package/dist/lib/public-api/infrastructure/public-entry-row.js +76 -0
  324. package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts +188 -0
  325. package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts.map +1 -0
  326. package/dist/lib/public-api/infrastructure/public-entry-writes.service.js +321 -0
  327. package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts +98 -0
  328. package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts.map +1 -0
  329. package/dist/lib/public-api/infrastructure/public-expansion.query.js +384 -0
  330. package/dist/lib/public-api/types/public-bulk.d.ts +77 -0
  331. package/dist/lib/public-api/types/public-bulk.d.ts.map +1 -0
  332. package/dist/lib/public-api/types/public-bulk.js +23 -0
  333. package/dist/lib/public-api/types/public-entry.d.ts +97 -0
  334. package/dist/lib/public-api/types/public-entry.d.ts.map +1 -0
  335. package/dist/lib/public-api/types/public-entry.js +8 -0
  336. package/dist/lib/public-api/types/public-expansion.d.ts +92 -0
  337. package/dist/lib/public-api/types/public-expansion.d.ts.map +1 -0
  338. package/dist/lib/public-api/types/public-expansion.js +2 -0
  339. package/dist/lib/registry/content-type-registry.d.ts +103 -0
  340. package/dist/lib/registry/content-type-registry.d.ts.map +1 -0
  341. package/dist/lib/registry/content-type-registry.js +155 -0
  342. package/dist/lib/revisions/application/ports/revision-store.d.ts +71 -0
  343. package/dist/lib/revisions/application/ports/revision-store.d.ts.map +1 -0
  344. package/dist/lib/revisions/application/ports/revision-store.js +9 -0
  345. package/dist/lib/revisions/application/use-cases/publish-revision.use-case.d.ts +40 -0
  346. package/dist/lib/revisions/application/use-cases/publish-revision.use-case.d.ts.map +1 -0
  347. package/dist/lib/revisions/application/use-cases/publish-revision.use-case.js +66 -0
  348. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts +36 -0
  349. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts.map +1 -0
  350. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.js +57 -0
  351. package/dist/lib/revisions/domain/revision-status.d.ts +18 -0
  352. package/dist/lib/revisions/domain/revision-status.d.ts.map +1 -0
  353. package/dist/lib/revisions/domain/revision-status.js +18 -0
  354. package/dist/lib/revisions/domain/revision.d.ts +80 -0
  355. package/dist/lib/revisions/domain/revision.d.ts.map +1 -0
  356. package/dist/lib/revisions/domain/revision.js +84 -0
  357. package/dist/lib/revisions/http/controllers/publish-revision.controller.d.ts +19 -0
  358. package/dist/lib/revisions/http/controllers/publish-revision.controller.d.ts.map +1 -0
  359. package/dist/lib/revisions/http/controllers/publish-revision.controller.js +51 -0
  360. package/dist/lib/revisions/http/controllers/restore-revision.controller.d.ts +17 -0
  361. package/dist/lib/revisions/http/controllers/restore-revision.controller.d.ts.map +1 -0
  362. package/dist/lib/revisions/http/controllers/restore-revision.controller.js +49 -0
  363. package/dist/lib/revisions/http/controllers/revisions.controller.d.ts +20 -0
  364. package/dist/lib/revisions/http/controllers/revisions.controller.d.ts.map +1 -0
  365. package/dist/lib/revisions/http/controllers/revisions.controller.js +76 -0
  366. package/dist/lib/revisions/infrastructure/persistence/drizzle-revision.store.d.ts +33 -0
  367. package/dist/lib/revisions/infrastructure/persistence/drizzle-revision.store.d.ts.map +1 -0
  368. package/dist/lib/revisions/infrastructure/persistence/drizzle-revision.store.js +174 -0
  369. package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts +17 -0
  370. package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts.map +1 -0
  371. package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.js +20 -0
  372. package/dist/lib/revisions/infrastructure/persistence/revision-table.d.ts +228 -0
  373. package/dist/lib/revisions/infrastructure/persistence/revision-table.d.ts.map +1 -0
  374. package/dist/lib/revisions/infrastructure/persistence/revision-table.js +57 -0
  375. package/dist/lib/revisions/infrastructure/queries/revision-refs.query.d.ts +22 -0
  376. package/dist/lib/revisions/infrastructure/queries/revision-refs.query.d.ts.map +1 -0
  377. package/dist/lib/revisions/infrastructure/queries/revision-refs.query.js +66 -0
  378. package/dist/lib/revisions/revisions.constants.d.ts +10 -0
  379. package/dist/lib/revisions/revisions.constants.d.ts.map +1 -0
  380. package/dist/lib/revisions/revisions.constants.js +12 -0
  381. package/dist/lib/revisions/types/revision-view.d.ts +74 -0
  382. package/dist/lib/revisions/types/revision-view.d.ts.map +1 -0
  383. package/dist/lib/revisions/types/revision-view.js +2 -0
  384. package/dist/lib/types/content-type.d.ts +131 -0
  385. package/dist/lib/types/content-type.d.ts.map +1 -0
  386. package/dist/lib/types/content-type.js +28 -0
  387. package/dist/lib/types/fields.d.ts +303 -0
  388. package/dist/lib/types/fields.d.ts.map +1 -0
  389. package/dist/lib/types/fields.js +52 -0
  390. package/dist/lib/utils/content-plugin.d.ts +35 -0
  391. package/dist/lib/utils/content-plugin.d.ts.map +1 -0
  392. package/dist/lib/utils/content-plugin.js +35 -0
  393. package/dist/lib/validation/services/entry-validation.service.d.ts +24 -0
  394. package/dist/lib/validation/services/entry-validation.service.d.ts.map +1 -0
  395. package/dist/lib/validation/services/entry-validation.service.js +35 -0
  396. package/package.json +54 -0
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ /**
3
+ * Turns a field map into physical Drizzle tables. One table per content
4
+ * type (`content_<name>`), plus one join table per many-relation
5
+ * (`content_<name>_<field>`). The HOST re-exports these from its
6
+ * drizzle-kit schema entry, so collection changes become ordinary
7
+ * committed migrations — exactly like any plugin-owned schema.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.snakeCase = snakeCase;
11
+ exports.buildTables = buildTables;
12
+ const drizzle_orm_1 = require("drizzle-orm");
13
+ const pg_core_1 = require("drizzle-orm/pg-core");
14
+ const fields_1 = require("../types/fields");
15
+ const content_type_1 = require("../types/content-type");
16
+ /** camelCase / kebab-case → snake_case column-safe identifier. */
17
+ function snakeCase(value) {
18
+ return value
19
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
20
+ .replace(/[^a-zA-Z0-9]+/g, '_')
21
+ .toLowerCase();
22
+ }
23
+ /**
24
+ * The `id` column of a generated table. Generated tables are built from a
25
+ * dynamic column record, so their columns aren't statically typed — but the
26
+ * envelope guarantees `id` exists on every one of them.
27
+ */
28
+ function idColumnOf(table) {
29
+ return table.id;
30
+ }
31
+ /**
32
+ * Builds the column for one (non-many-relation) field.
33
+ *
34
+ * `enforceRequired` decides the NOT NULL constraint: a **non-publishable** type
35
+ * is always live, so a required field is `NOT NULL`. A **publishable** type has
36
+ * a draft stage where a required field may legitimately be empty — "required"
37
+ * means "required *to publish*", enforced by `EntryValidationService` at publish
38
+ * time, not the column. So a publishable type's columns stay nullable even when
39
+ * the field is required.
40
+ */
41
+ function columnFor(fieldName, spec, enforceRequired, i18n) {
42
+ const col = snakeCase(fieldName);
43
+ let builder;
44
+ switch (spec.type) {
45
+ case fields_1.CONTENT_FIELD_TYPE.Text:
46
+ case fields_1.CONTENT_FIELD_TYPE.Select:
47
+ builder = (0, pg_core_1.text)(col);
48
+ break;
49
+ case fields_1.CONTENT_FIELD_TYPE.RichText:
50
+ // A structured document (the editor's node tree), not an HTML
51
+ // string — which is what makes a body's heading order, table
52
+ // headers and language markers checkable rather than opaque.
53
+ // A body written before that change is a JSON *string* in the same
54
+ // column, so nothing had to be rewritten to migrate: `jsonb` holds
55
+ // both, and both read back as a valid `richtext` value.
56
+ builder = (0, pg_core_1.jsonb)(col);
57
+ break;
58
+ case fields_1.CONTENT_FIELD_TYPE.Number:
59
+ builder = spec.validation.integer
60
+ ? (0, pg_core_1.integer)(col)
61
+ : (0, pg_core_1.doublePrecision)(col);
62
+ break;
63
+ case fields_1.CONTENT_FIELD_TYPE.Money:
64
+ // integer minor units — exact arithmetic, no float drift
65
+ builder = (0, pg_core_1.integer)(col);
66
+ break;
67
+ case fields_1.CONTENT_FIELD_TYPE.Boolean:
68
+ // A required boolean defaults to false so an omitted value is a
69
+ // concrete `false` rather than a NOT NULL violation. The default is
70
+ // useful regardless of whether NOT NULL is ultimately enforced.
71
+ builder = spec.required
72
+ ? (0, pg_core_1.boolean)(col).default(false)
73
+ : (0, pg_core_1.boolean)(col);
74
+ break;
75
+ case fields_1.CONTENT_FIELD_TYPE.Date:
76
+ builder = (0, pg_core_1.date)(col);
77
+ break;
78
+ case fields_1.CONTENT_FIELD_TYPE.Datetime:
79
+ builder = (0, pg_core_1.timestamp)(col, { withTimezone: true });
80
+ break;
81
+ case fields_1.CONTENT_FIELD_TYPE.Json:
82
+ case fields_1.CONTENT_FIELD_TYPE.Multiselect:
83
+ builder = (0, pg_core_1.jsonb)(col);
84
+ break;
85
+ case fields_1.CONTENT_FIELD_TYPE.Media:
86
+ // A media reference is an asset id (or an ordered list of them).
87
+ // No FK — the assets live in the media plugin's schema, which this
88
+ // package can't reference (same convention as `workspace_id`);
89
+ // existence + the `accept` restriction are enforced in the app layer.
90
+ builder = spec.multiple ? (0, pg_core_1.jsonb)(col) : (0, pg_core_1.uuid)(col);
91
+ break;
92
+ case fields_1.CONTENT_FIELD_TYPE.Relation: {
93
+ // An inverse (back-reference) owns no storage — it reuses the owning
94
+ // side's column/join table.
95
+ if (spec.relation?.inverse)
96
+ return null;
97
+ if (spec.relation?.many)
98
+ return null; // join table instead
99
+ // Lazy reference: the thunk resolves at query/diff time, so
100
+ // mutually-referencing collections can import each other.
101
+ builder = (0, pg_core_1.uuid)(`${col}_id`).references(() => idColumnOf(spec.relation.to().table), { onDelete: spec.relation.onDelete });
102
+ // One-to-one: at most one owner may point at a given target.
103
+ // Nullable-unique — Postgres allows many NULLs, so owners with no
104
+ // relation don't collide.
105
+ //
106
+ // On an **i18n** type the constraint is per-locale instead, and is
107
+ // emitted as a composite index below rather than here: a localized
108
+ // record is N rows, one per language, so a column-wide UNIQUE would
109
+ // read "one *row* may point at this target" when what the model
110
+ // means is "one *record* may". The English and German rows of one
111
+ // article legitimately share an SEO record; two different articles
112
+ // must not.
113
+ if (spec.relation.unique && !i18n)
114
+ builder = builder.unique();
115
+ break;
116
+ }
117
+ }
118
+ return enforceRequired && spec.required ? builder.notNull() : builder;
119
+ }
120
+ /** Builds the main table + join tables for a content type. */
121
+ function buildTables(typeName, fields, meta = {}) {
122
+ const tableName = `content_${snakeCase(typeName)}`;
123
+ const columns = {
124
+ /** Primary key. */
125
+ id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
126
+ /**
127
+ * Owning workspace. Stamped on create and filtered on every read/write
128
+ * by the entries services (scoped via `WorkspaceGuard`'s `X-Workspace-Id`
129
+ * header), so entries never cross workspaces. Plain uuid, no FK — the
130
+ * `workspaces` table lives in the identity plugin's schema, which this
131
+ * package can't reference; isolation is enforced in the app layer.
132
+ */
133
+ workspaceId: (0, pg_core_1.uuid)('workspace_id'),
134
+ /** Row creation timestamp. */
135
+ createdAt: (0, pg_core_1.timestamp)('created_at', { withTimezone: true })
136
+ .notNull()
137
+ .defaultNow(),
138
+ /** Last update timestamp (the service layer refreshes it). */
139
+ updatedAt: (0, pg_core_1.timestamp)('updated_at', { withTimezone: true })
140
+ .notNull()
141
+ .defaultNow()
142
+ };
143
+ // Publish workflow is opt-in: only a `publishable` type carries a
144
+ // draft/published `status` and the `published_at` stamp — two halves of
145
+ // the same concept. A non-publishable type has no publish state; every row
146
+ // is simply live. `published_at` is nullable with no default (null = "not
147
+ // yet published"; the service layer stamps it).
148
+ if (meta.publishable) {
149
+ columns['status'] = (0, pg_core_1.text)('status', {
150
+ enum: [content_type_1.ENTRY_STATUS.Draft, content_type_1.ENTRY_STATUS.Published]
151
+ })
152
+ .notNull()
153
+ .default(content_type_1.ENTRY_STATUS.Draft);
154
+ columns['publishedAt'] = (0, pg_core_1.timestamp)('published_at', {
155
+ withTimezone: true
156
+ });
157
+ }
158
+ // Soft delete: nullable `deleted_at` (null = "not deleted"; service stamps it).
159
+ if (meta.paranoid) {
160
+ columns['deletedAt'] = (0, pg_core_1.timestamp)('deleted_at', { withTimezone: true });
161
+ }
162
+ // Row-per-locale: each locale of an entry is a full row; siblings share a
163
+ // `locale_group_id`. The group id defaults to a fresh uuid so a plain
164
+ // create starts its own translation group — linking into an existing group
165
+ // (translation creation) sets it explicitly. The slug's meaning (allowed
166
+ // values, the default) is owned by the bound localization plugin.
167
+ if (meta.i18n) {
168
+ columns['locale'] = (0, pg_core_1.text)('locale').notNull();
169
+ columns['localeGroupId'] = (0, pg_core_1.uuid)('locale_group_id')
170
+ .notNull()
171
+ .defaultRandom();
172
+ }
173
+ // Publishable types keep required columns nullable (a draft may be
174
+ // incomplete; publish enforces requiredness). Non-publishable types are
175
+ // always live, so a required field is NOT NULL.
176
+ const enforceRequired = !meta.publishable;
177
+ for (const [fieldName, spec] of Object.entries(fields)) {
178
+ const column = columnFor(fieldName, spec, enforceRequired, !!meta.i18n);
179
+ if (column)
180
+ columns[fieldName] = column;
181
+ }
182
+ const table = (0, pg_core_1.pgTable)(tableName, columns, (t) => {
183
+ const cols = t;
184
+ // Every list view filters by workspace; i18n types also filter by
185
+ // locale, and publishable types by status — fold each into the list
186
+ // index only where the column exists.
187
+ const listColumns = [
188
+ cols['workspaceId'],
189
+ ...(meta.i18n ? [cols['locale']] : []),
190
+ ...(meta.publishable ? [cols['status']] : [])
191
+ ];
192
+ const listIndexName = meta.i18n
193
+ ? `${tableName}_workspace_locale_idx`
194
+ : meta.publishable
195
+ ? `${tableName}_workspace_status_idx`
196
+ : `${tableName}_workspace_idx`;
197
+ const indexes = [
198
+ (0, pg_core_1.index)(listIndexName).on(listColumns[0], ...listColumns.slice(1))
199
+ ];
200
+ // Each owning single relation's FK. The *inverse* of such a relation is
201
+ // read by filtering this column (`inArray(fk, sourceIds)` in
202
+ // `RelationLinkService.previewInverse`), which the records table now
203
+ // runs for a whole page on every render — unindexed that is a sequential
204
+ // scan of the collection per keystroke, sort click and page change.
205
+ // `unique: true` already implies an index, so skip those.
206
+ for (const [fieldName, spec] of Object.entries(fields)) {
207
+ if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation)
208
+ continue;
209
+ if (spec.relation?.many ||
210
+ spec.relation?.inverse ||
211
+ spec.relation?.unique)
212
+ continue;
213
+ const fk = cols[fieldName];
214
+ if (!fk)
215
+ continue;
216
+ indexes.push((0, pg_core_1.index)(`${tableName}_${snakeCase(fieldName)}_id_idx`).on(fk));
217
+ }
218
+ if (meta.i18n) {
219
+ // One row per (group, locale). Partial on paranoid types so a
220
+ // soft-deleted sibling never blocks re-creating that locale —
221
+ // restoring into a conflict then fails (23505 → 409 upstream).
222
+ const groupLocale = (0, pg_core_1.uniqueIndex)(`${tableName}_group_locale_unique`).on(cols['localeGroupId'], cols['locale']);
223
+ indexes.push(meta.paranoid
224
+ ? groupLocale.where((0, drizzle_orm_1.isNull)(cols['deletedAt']))
225
+ : groupLocale);
226
+ // One-to-one, **scoped to the locale** — the i18n counterpart of the
227
+ // column-level UNIQUE `columnFor` emits on a plain type.
228
+ //
229
+ // A localized record is one row per language, so "at most one owner
230
+ // points at this target" has to be counted in records, not rows.
231
+ // `(locale, <field>_id)` says exactly that: within any one language
232
+ // a target is claimed once, while the same target may be shared by
233
+ // the locale rows of the record that owns it — which is what a
234
+ // relation synced across the group *is*. Nullable-unique survives,
235
+ // since Postgres treats NULLs as distinct in a composite index too.
236
+ for (const [fieldName, spec] of Object.entries(fields)) {
237
+ if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation ||
238
+ !spec.relation?.unique ||
239
+ spec.relation.many ||
240
+ spec.relation.inverse)
241
+ continue;
242
+ const fk = cols[fieldName];
243
+ if (!fk)
244
+ continue;
245
+ // The FK leads deliberately. Uniqueness of a pair is
246
+ // order-independent, but the leading column decides what the
247
+ // index can also *serve* — and the inverse side of this
248
+ // relation reads `inArray(<fk>, sourceIds)` for a whole page on
249
+ // every records-table render. Leading with `locale` would leave
250
+ // that a sequential scan, since the skipped plain FK index just
251
+ // below assumes `unique` already provides one.
252
+ const localeUnique = (0, pg_core_1.uniqueIndex)(`${tableName}_${snakeCase(fieldName)}_locale_unique`).on(fk, cols['locale']);
253
+ // Partial on paranoid types for the same reason as the pair
254
+ // above: a trashed row must not hold a target hostage.
255
+ indexes.push(meta.paranoid
256
+ ? localeUnique.where((0, drizzle_orm_1.isNull)(cols['deletedAt']))
257
+ : localeUnique);
258
+ }
259
+ }
260
+ return indexes;
261
+ });
262
+ const joinTables = {};
263
+ for (const [fieldName, spec] of Object.entries(fields)) {
264
+ if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation ||
265
+ !spec.relation?.many ||
266
+ spec.relation.inverse // inverse reuses the owning side's join table
267
+ )
268
+ continue;
269
+ const joinName = `${tableName}_${snakeCase(fieldName)}`;
270
+ joinTables[fieldName] = (0, pg_core_1.pgTable)(joinName, {
271
+ /** The owning entry. Join rows die with it. */
272
+ sourceId: (0, pg_core_1.uuid)('source_id')
273
+ .notNull()
274
+ .references(() => idColumnOf(table), {
275
+ onDelete: 'cascade'
276
+ }),
277
+ /** The referenced entry on the target type. */
278
+ targetId: (0, pg_core_1.uuid)('target_id')
279
+ .notNull()
280
+ .references(() => idColumnOf(spec.relation.to().table), {
281
+ onDelete: 'cascade'
282
+ }),
283
+ /**
284
+ * Ordinal of this target within its **source's** ordered list —
285
+ * the source's own ordering of its many-relation, so a
286
+ * drag-reorder survives a reload. Float, so a target can be moved
287
+ * between two neighbours without renumbering the whole list.
288
+ * Defaults to 0 (append picks `max(position)+1` for the source).
289
+ * The inverse side reads by it too (stable), but doesn't own the
290
+ * order — a two-way link has one order, the owning side's.
291
+ */
292
+ position: (0, pg_core_1.doublePrecision)('position').notNull().default(0)
293
+ }, (t) => {
294
+ const cols = t;
295
+ return [
296
+ // one link per pair; leftmost prefix covers "links of an entry"
297
+ (0, pg_core_1.unique)(`${joinName}_pair_unique`).on(cols['sourceId'], cols['targetId']),
298
+ // reverse lookups: "which entries reference this target?"
299
+ (0, pg_core_1.index)(`${joinName}_target_idx`).on(cols['targetId']),
300
+ // ordered read of a source's links: `WHERE source_id ORDER BY position`
301
+ (0, pg_core_1.index)(`${joinName}_source_pos_idx`).on(cols['sourceId'], cols['position'])
302
+ ];
303
+ });
304
+ }
305
+ return { table, joinTables };
306
+ }
@@ -0,0 +1,24 @@
1
+ import type { ContentTypeRegistry, SerializedContentType } from '../../registry/content-type-registry';
2
+ import { WorkspaceGrantsQuery } from '../queries/workspace-grants.query';
3
+ /**
4
+ * `GET /api/content-schema/:name` — the full field schema of one content
5
+ * type: types, validation rules, and admin presentation props. This is
6
+ * what the admin's dynamic tables/forms render from. Authentication is
7
+ * enforced by the app-wide AuthGuard; read access is gated on `content:read`.
8
+ *
9
+ * **Workspace-scoped**, like its `/filter-fields` sibling and unlike the
10
+ * `GET /api/content-schema` catalogue: the schema of a type is the shape of
11
+ * content this workspace may open, so a type the workspace was not granted
12
+ * (`workspace_content`) answers with exactly the `404` an unknown name gets —
13
+ * same status, same message, grants read before the registry decision — and
14
+ * the route therefore discloses nothing about the content model outside the
15
+ * caller's workspace. Serving it unconditionally was the read half of the
16
+ * hole `ContentGrantGuard` closes on the entry routes.
17
+ */
18
+ export declare class GetContentSchemaController {
19
+ private readonly registry;
20
+ private readonly grants;
21
+ constructor(registry: ContentTypeRegistry, grants: WorkspaceGrantsQuery);
22
+ get(name: string, workspaceId: string): Promise<SerializedContentType>;
23
+ }
24
+ //# sourceMappingURL=get-content-schema.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-content-schema.controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/controllers/get-content-schema.controller.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACR,mBAAmB,EACnB,qBAAqB,EACxB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;;;;;;;;;;;;;GAcG;AACH,qBAGa,0BAA0B;IAG/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,oBAAoB;IAI3C,GAAG,CACU,IAAI,EAAE,MAAM,EACP,WAAW,EAAE,MAAM,GACxC,OAAO,CAAC,qBAAqB,CAAC;CAUpC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetContentSchemaController = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const identity_server_1 = require("@orthacms/identity-server");
7
+ const workspaces_server_1 = require("@orthacms/workspaces-server");
8
+ const content_tokens_1 = require("../../content.tokens");
9
+ const workspace_grants_query_1 = require("../queries/workspace-grants.query");
10
+ /**
11
+ * `GET /api/content-schema/:name` — the full field schema of one content
12
+ * type: types, validation rules, and admin presentation props. This is
13
+ * what the admin's dynamic tables/forms render from. Authentication is
14
+ * enforced by the app-wide AuthGuard; read access is gated on `content:read`.
15
+ *
16
+ * **Workspace-scoped**, like its `/filter-fields` sibling and unlike the
17
+ * `GET /api/content-schema` catalogue: the schema of a type is the shape of
18
+ * content this workspace may open, so a type the workspace was not granted
19
+ * (`workspace_content`) answers with exactly the `404` an unknown name gets —
20
+ * same status, same message, grants read before the registry decision — and
21
+ * the route therefore discloses nothing about the content model outside the
22
+ * caller's workspace. Serving it unconditionally was the read half of the
23
+ * hole `ContentGrantGuard` closes on the entry routes.
24
+ */
25
+ let GetContentSchemaController = class GetContentSchemaController {
26
+ registry;
27
+ grants;
28
+ constructor(registry, grants) {
29
+ this.registry = registry;
30
+ this.grants = grants;
31
+ }
32
+ async get(name, workspaceId) {
33
+ const serialized = this.registry.serialize(name);
34
+ // Read the grants before deciding, so an ungranted type and an unknown
35
+ // one are indistinguishable — same status, same body, same work done.
36
+ const granted = await this.grants.grantedSlugs(workspaceId);
37
+ if (!serialized || !granted.has(name)) {
38
+ throw new common_1.NotFoundException(`Unknown content type "${name}".`);
39
+ }
40
+ return serialized;
41
+ }
42
+ };
43
+ exports.GetContentSchemaController = GetContentSchemaController;
44
+ tslib_1.__decorate([
45
+ (0, common_1.Get)(':name'),
46
+ tslib_1.__param(0, (0, common_1.Param)('name')),
47
+ tslib_1.__param(1, (0, workspaces_server_1.CurrentWorkspace)()),
48
+ tslib_1.__metadata("design:type", Function),
49
+ tslib_1.__metadata("design:paramtypes", [String, String]),
50
+ tslib_1.__metadata("design:returntype", Promise)
51
+ ], GetContentSchemaController.prototype, "get", null);
52
+ exports.GetContentSchemaController = GetContentSchemaController = tslib_1.__decorate([
53
+ (0, common_1.UseGuards)(identity_server_1.PermissionsGuard, workspaces_server_1.WorkspaceGuard),
54
+ (0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.CONTENT_READ),
55
+ (0, common_1.Controller)('content-schema'),
56
+ tslib_1.__param(0, (0, content_tokens_1.InjectContentRegistry)()),
57
+ tslib_1.__metadata("design:paramtypes", [Function, workspace_grants_query_1.WorkspaceGrantsQuery])
58
+ ], GetContentSchemaController);
@@ -0,0 +1,35 @@
1
+ import type { ContentTypeRegistry } from '../../registry/content-type-registry';
2
+ import type { FilterFieldsResponse } from '../../entries/types/filter-surface';
3
+ import { WorkspaceGrantsQuery } from '../queries/workspace-grants.query';
4
+ /**
5
+ * `GET /api/content-schema/:name/filter-fields` — every scalar path the
6
+ * records-table query builder may filter on: the type's own fields plus,
7
+ * recursively within the relation-hop budget, its relations' fields
8
+ * (`author.name`, `author.company.name`). This is the admin counterpart of
9
+ * the SQL `FilterSchema` the list endpoint enforces — both come from a
10
+ * single `buildEntryFilterSurface` traversal, so the picker can never offer
11
+ * a path the API would reject with a 400.
12
+ *
13
+ * **Workspace-scoped**, unlike the sibling `/content-schema` routes (which
14
+ * serve the global, code-defined type catalogue). The response describes
15
+ * what *this* workspace may traverse, so it is pruned to the workspace's
16
+ * `workspace_content` grants in two places:
17
+ *
18
+ * - the requested `:name` must itself be granted, else **404** — the same
19
+ * answer an unknown type gets, so the endpoint carries no signal about
20
+ * which types exist outside the caller's workspace;
21
+ * - `grantedTypes` prunes the offered relations, mirroring the entry
22
+ * editor's `availableTypeNames`, so the picker never offers a traversal
23
+ * into a collection the caller cannot open.
24
+ *
25
+ * The SQL the list endpoint runs is workspace-scoped regardless, so this is
26
+ * about not *disclosing* the shape of another workspace's content model,
27
+ * not about row access.
28
+ */
29
+ export declare class GetFilterFieldsController {
30
+ private readonly registry;
31
+ private readonly grants;
32
+ constructor(registry: ContentTypeRegistry, grants: WorkspaceGrantsQuery);
33
+ filterFields(name: string, workspaceId: string): Promise<FilterFieldsResponse>;
34
+ }
35
+ //# sourceMappingURL=get-filter-fields.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-filter-fields.controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/controllers/get-filter-fields.controller.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAGa,yBAAyB;IAG9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,oBAAoB;IAI3C,YAAY,CACC,IAAI,EAAE,MAAM,EACP,WAAW,EAAE,MAAM,GACxC,OAAO,CAAC,oBAAoB,CAAC;CAenC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetFilterFieldsController = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const identity_server_1 = require("@orthacms/identity-server");
7
+ const workspaces_server_1 = require("@orthacms/workspaces-server");
8
+ const content_tokens_1 = require("../../content.tokens");
9
+ const entry_filter_surface_1 = require("../../entries/infrastructure/queries/entry-filter-surface");
10
+ const workspace_grants_query_1 = require("../queries/workspace-grants.query");
11
+ /**
12
+ * `GET /api/content-schema/:name/filter-fields` — every scalar path the
13
+ * records-table query builder may filter on: the type's own fields plus,
14
+ * recursively within the relation-hop budget, its relations' fields
15
+ * (`author.name`, `author.company.name`). This is the admin counterpart of
16
+ * the SQL `FilterSchema` the list endpoint enforces — both come from a
17
+ * single `buildEntryFilterSurface` traversal, so the picker can never offer
18
+ * a path the API would reject with a 400.
19
+ *
20
+ * **Workspace-scoped**, unlike the sibling `/content-schema` routes (which
21
+ * serve the global, code-defined type catalogue). The response describes
22
+ * what *this* workspace may traverse, so it is pruned to the workspace's
23
+ * `workspace_content` grants in two places:
24
+ *
25
+ * - the requested `:name` must itself be granted, else **404** — the same
26
+ * answer an unknown type gets, so the endpoint carries no signal about
27
+ * which types exist outside the caller's workspace;
28
+ * - `grantedTypes` prunes the offered relations, mirroring the entry
29
+ * editor's `availableTypeNames`, so the picker never offers a traversal
30
+ * into a collection the caller cannot open.
31
+ *
32
+ * The SQL the list endpoint runs is workspace-scoped regardless, so this is
33
+ * about not *disclosing* the shape of another workspace's content model,
34
+ * not about row access.
35
+ */
36
+ let GetFilterFieldsController = class GetFilterFieldsController {
37
+ registry;
38
+ grants;
39
+ constructor(registry, grants) {
40
+ this.registry = registry;
41
+ this.grants = grants;
42
+ }
43
+ async filterFields(name, workspaceId) {
44
+ const type = this.registry.get(name);
45
+ // Resolve the grants before the registry check so an ungranted type
46
+ // and an unknown one are indistinguishable — same status, same body,
47
+ // same work done.
48
+ const grantedTypes = await this.grants.grantedSlugs(workspaceId);
49
+ if (!type || !grantedTypes.has(name)) {
50
+ throw new common_1.NotFoundException(`Unknown content type "${name}".`);
51
+ }
52
+ const { fields } = (0, entry_filter_surface_1.buildEntryFilterSurface)(type, {
53
+ workspaceId,
54
+ grantedTypes
55
+ });
56
+ return { fields };
57
+ }
58
+ };
59
+ exports.GetFilterFieldsController = GetFilterFieldsController;
60
+ tslib_1.__decorate([
61
+ (0, common_1.Get)(':name/filter-fields'),
62
+ tslib_1.__param(0, (0, common_1.Param)('name')),
63
+ tslib_1.__param(1, (0, workspaces_server_1.CurrentWorkspace)()),
64
+ tslib_1.__metadata("design:type", Function),
65
+ tslib_1.__metadata("design:paramtypes", [String, String]),
66
+ tslib_1.__metadata("design:returntype", Promise)
67
+ ], GetFilterFieldsController.prototype, "filterFields", null);
68
+ exports.GetFilterFieldsController = GetFilterFieldsController = tslib_1.__decorate([
69
+ (0, common_1.UseGuards)(identity_server_1.PermissionsGuard, workspaces_server_1.WorkspaceGuard),
70
+ (0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.CONTENT_READ),
71
+ (0, common_1.Controller)('content-schema'),
72
+ tslib_1.__param(0, (0, content_tokens_1.InjectContentRegistry)()),
73
+ tslib_1.__metadata("design:paramtypes", [Function, workspace_grants_query_1.WorkspaceGrantsQuery])
74
+ ], GetFilterFieldsController);
@@ -0,0 +1,15 @@
1
+ import type { ContentTypeRegistry, SerializedContentTypeSummary } from '../../registry/content-type-registry';
2
+ /**
3
+ * `GET /api/content-schema` — summaries of every code-defined content
4
+ * type (collections and singles). Shape-compatible with identity's
5
+ * `ContentTypeDescriptor`, so once identity's workspace grants consume
6
+ * this registry, its mock `/api/content-types` retires in favor of this
7
+ * source of truth. Authentication is enforced by the app-wide AuthGuard;
8
+ * read access is gated on `content:read`.
9
+ */
10
+ export declare class ListContentSchemaController {
11
+ private readonly registry;
12
+ constructor(registry: ContentTypeRegistry);
13
+ list(): SerializedContentTypeSummary[];
14
+ }
15
+ //# sourceMappingURL=list-content-schema.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-content-schema.controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/controllers/list-content-schema.controller.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,mBAAmB,EACnB,4BAA4B,EAC/B,MAAM,sCAAsC,CAAC;AAE9C;;;;;;;GAOG;AACH,qBAGa,2BAA2B;IAGhC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,mBAAmB;IAIlD,IAAI,IAAI,4BAA4B,EAAE;CAGzC"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListContentSchemaController = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const identity_server_1 = require("@orthacms/identity-server");
7
+ const content_tokens_1 = require("../../content.tokens");
8
+ /**
9
+ * `GET /api/content-schema` — summaries of every code-defined content
10
+ * type (collections and singles). Shape-compatible with identity's
11
+ * `ContentTypeDescriptor`, so once identity's workspace grants consume
12
+ * this registry, its mock `/api/content-types` retires in favor of this
13
+ * source of truth. Authentication is enforced by the app-wide AuthGuard;
14
+ * read access is gated on `content:read`.
15
+ */
16
+ let ListContentSchemaController = class ListContentSchemaController {
17
+ registry;
18
+ constructor(registry) {
19
+ this.registry = registry;
20
+ }
21
+ list() {
22
+ return this.registry.summaries();
23
+ }
24
+ };
25
+ exports.ListContentSchemaController = ListContentSchemaController;
26
+ tslib_1.__decorate([
27
+ (0, common_1.Get)(),
28
+ tslib_1.__metadata("design:type", Function),
29
+ tslib_1.__metadata("design:paramtypes", []),
30
+ tslib_1.__metadata("design:returntype", Array)
31
+ ], ListContentSchemaController.prototype, "list", null);
32
+ exports.ListContentSchemaController = ListContentSchemaController = tslib_1.__decorate([
33
+ (0, common_1.UseGuards)(identity_server_1.PermissionsGuard),
34
+ (0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.CONTENT_READ),
35
+ (0, common_1.Controller)('content-schema'),
36
+ tslib_1.__param(0, (0, content_tokens_1.InjectContentRegistry)()),
37
+ tslib_1.__metadata("design:paramtypes", [Function])
38
+ ], ListContentSchemaController);
@@ -0,0 +1,25 @@
1
+ import { type Database } from '@orthacms/database';
2
+ /**
3
+ * Reads a workspace's **content grants** — the `workspace_content` slugs the
4
+ * open workspace may access, written by the workspace create/edit wizard.
5
+ *
6
+ * The grants are workspaces-owned data, but the dependency only runs one way:
7
+ * content-server already depends on `@orthacms/workspaces-server` for
8
+ * `WorkspaceGuard`, and that package deliberately re-exports its Drizzle
9
+ * schema. Inverting this into a port would mean workspaces depending on
10
+ * content, which is the cycle `CONTENT_CATALOG` exists to avoid.
11
+ *
12
+ * A thin CQRS read — no aggregate, no write path.
13
+ */
14
+ export declare class WorkspaceGrantsQuery {
15
+ private readonly db;
16
+ constructor(db: Database);
17
+ /**
18
+ * Every content slug granted to `workspaceId`. Returned as a `Set` so
19
+ * callers can test membership per relation hop without re-querying.
20
+ * An empty set means the workspace was granted nothing — callers must
21
+ * treat that as "no access", never as "no filtering".
22
+ */
23
+ grantedSlugs(workspaceId: string): Promise<Set<string>>;
24
+ }
25
+ //# sourceMappingURL=workspace-grants.query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-grants.query.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/queries/workspace-grants.query.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnE;;;;;;;;;;;GAWG;AACH,qBACa,oBAAoB;IACC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAE3D;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CAOhE"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkspaceGrantsQuery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const drizzle_orm_1 = require("drizzle-orm");
7
+ const database_1 = require("@orthacms/database");
8
+ const workspaces_server_1 = require("@orthacms/workspaces-server");
9
+ /**
10
+ * Reads a workspace's **content grants** — the `workspace_content` slugs the
11
+ * open workspace may access, written by the workspace create/edit wizard.
12
+ *
13
+ * The grants are workspaces-owned data, but the dependency only runs one way:
14
+ * content-server already depends on `@orthacms/workspaces-server` for
15
+ * `WorkspaceGuard`, and that package deliberately re-exports its Drizzle
16
+ * schema. Inverting this into a port would mean workspaces depending on
17
+ * content, which is the cycle `CONTENT_CATALOG` exists to avoid.
18
+ *
19
+ * A thin CQRS read — no aggregate, no write path.
20
+ */
21
+ let WorkspaceGrantsQuery = class WorkspaceGrantsQuery {
22
+ db;
23
+ constructor(db) {
24
+ this.db = db;
25
+ }
26
+ /**
27
+ * Every content slug granted to `workspaceId`. Returned as a `Set` so
28
+ * callers can test membership per relation hop without re-querying.
29
+ * An empty set means the workspace was granted nothing — callers must
30
+ * treat that as "no access", never as "no filtering".
31
+ */
32
+ async grantedSlugs(workspaceId) {
33
+ const rows = await this.db
34
+ .select({ slug: workspaces_server_1.workspaceContent.slug })
35
+ .from(workspaces_server_1.workspaceContent)
36
+ .where((0, drizzle_orm_1.eq)(workspaces_server_1.workspaceContent.workspaceId, workspaceId));
37
+ return new Set(rows.map((row) => row.slug));
38
+ }
39
+ };
40
+ exports.WorkspaceGrantsQuery = WorkspaceGrantsQuery;
41
+ exports.WorkspaceGrantsQuery = WorkspaceGrantsQuery = tslib_1.__decorate([
42
+ (0, common_1.Injectable)(),
43
+ tslib_1.__param(0, (0, database_1.InjectDatabase)()),
44
+ tslib_1.__metadata("design:paramtypes", [Object])
45
+ ], WorkspaceGrantsQuery);